From 9d74c783e4c982577b0776c9658bb095035a5273 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 14:43:41 +0200 Subject: [PATCH 01/12] docs(adr): add ADR-036 for persistent workspace sandboxes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records the decision to add a workspace lifecycle class whose state is permanent but whose compute is on-demand: workspaces suspend on idle like ephemeral sandboxes do today, and any access wakes them transparently. Deliberately not "a sandbox with no TTL" — always-running containers are what exhaust the 3 vCPU / 4 GB reference host, and suspend-and-wake gives the user the property they actually want at near-zero idle cost. Also records the two follow-ups kept out of the first phase: the interactive terminal (needs a PTY-attach method on SandboxProvider, since temps-sandbox must not depend on bollard) and AI CLI credential injection at create. --- .../adr/036-persistent-workspace-sandboxes.md | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 docs/adr/036-persistent-workspace-sandboxes.md diff --git a/docs/adr/036-persistent-workspace-sandboxes.md b/docs/adr/036-persistent-workspace-sandboxes.md new file mode 100644 index 000000000..40a9d71d0 --- /dev/null +++ b/docs/adr/036-persistent-workspace-sandboxes.md @@ -0,0 +1,115 @@ +# ADR-036: Persistent Workspace Sandboxes + +**Status:** Proposed +**Date:** 2026-08-06 +**Author:** David Viejo + +## Context + +Standalone sandboxes (`crates/temps-sandbox`, the `@vercel/sandbox`-compatible `/v1/sandboxes` API) are built for ephemeral work: create, seed from a repo or tarball, exec some commands, throw away. Every sandbox is created with a bounded `timeout_secs`, clamped to `[60, 86400]` (`services/sandbox_service.rs:212-213`), and a background sweeper stops any running sandbox whose `expires_at` has passed (`services/expiration_sweeper.rs`). + +That shape is wrong for a use case we already have the parts for: **a long-lived development workspace on a git repo, with an AI CLI in it, that a user returns to over days or weeks.** The sandbox image already ships `claude`, `codex`, `opencode`, `gh`, `glab`, `bun`, `dtach`, `socat`, and the in-sandbox `temps-pty-agent` (`crates/temps-agents/src/sandbox/docker.rs`, ADR-008). Git cloning — including private repos via a stored provider connection (`git_connection_id`) — is already a create-time source (`services/sandbox_service.rs:38-59`). What's missing is the lifecycle: today the platform will stop that workspace out from under the user, and won't bring it back without an explicit API call. + +Four specific gaps: + +1. **No lifecycle class above ephemeral.** `timeout_secs` is hard-clamped to 24h. There is no way to express "this sandbox is a workspace; don't treat its idleness as abandonment." The sweeper already has a precedent for a second class — it skips agent-run sandboxes entirely via `agent_run_id IS NULL` (`expiration_sweeper.rs:73-76`) — but nothing equivalent exists for user-owned workspaces. + +2. **`timeout_secs` is documented as idle, implemented as absolute.** `expires_at` is set once at create (`sandbox_service.rs:563`) and only moved by `resume_sandbox` and the explicit `extend_timeout` endpoint. `touch()` — called on every exec and filesystem operation — bumps `last_activity_at` and nothing else (`sandbox_service.rs:1395-1417`). The doc comment on the column says "timeout in seconds before the sandbox is considered **idle**"; the behaviour is a wall-clock deadline. A sandbox in continuous active use is stopped at its deadline anyway. This is a bug independent of anything else in this ADR. + +3. **A stopped sandbox is a hard error, not a wake.** `resolve_id` — the single choke point every exec and filesystem handler passes through — returns `InvalidState` when `status == "stopped"` (`sandbox_service.rs:1584-1590`). Correct for an ephemeral sandbox whose lifetime the caller controls; hostile for a workspace, where "I came back the next morning" is the normal case. + +4. **Nothing ties a sandbox to a project.** Creating a workspace on the repo you're already deploying means copying the clone URL by hand and re-picking the git connection, even though the project row already knows both. + +The prize is that fixing lifecycle unlocks a workspace product from parts that already exist. The risk is resource exhaustion: the reference deployment is a Hetzner cpx22 (3 vCPU / 4 GB), and "permanent" read naively — always-running containers that never stop — puts a handful of idle workspaces in a position to evict everything else on the box. + +## Decision + +Introduce a second sandbox lifecycle class, **`workspace`**, whose *state* is permanent but whose *compute* is on-demand. Concretely: workspaces suspend on idle exactly like ephemeral sandboxes do today, and any access transparently wakes them. + +This is deliberately **not** "a sandbox with no TTL". Always-running is the design that kills a small host; suspend-and-wake gives the user the property they actually want (my work is still there, and I don't have to think about it) at near-zero idle cost. + +### 1. Suspension is already non-destructive — build on that + +The sweeper stops, it does not destroy. Volumes, the bind-mounted `/workspace`, and home-directory state all survive, by explicit design (`expiration_sweeper.rs:8-12`). So data permanence needs no new mechanism. Everything below is about availability and ergonomics. + +### 2. `lifecycle` column on `sandboxes` + +``` +lifecycle VARCHAR NOT NULL DEFAULT 'ephemeral' -- 'ephemeral' | 'workspace' +``` + +Modelled as a column rather than a config flag, per the project's no-env-var-configuration rule: it is a per-row property the owner sets at create time and the API/UI can read back. + +Behavioural differences, and only these: + +| | `ephemeral` | `workspace` | +|---|---|---| +| Sweeper on idle | stop | stop (identical) | +| Access while stopped | `409 InvalidState` | transparent wake, then proceed | +| Auto-destroy | never (today) | never, and this is now a contract | +| Surfaced in UI | Sandboxes list | Sandboxes list, workspace-flagged | + +Note what is *not* different: workspaces are still swept, still bounded by the same idle window, still hold the same resource limits. A workspace is not a licence to pin RAM. + +### 3. Fix `touch()` to make the idle window real + +`touch()` gains `expires_at = now + timeout_secs` alongside its existing `last_activity_at = now`. This makes `timeout_secs` behave as its name and documentation already claim, for every sandbox class. + +Deliberately implemented by moving `expires_at` rather than by teaching the sweeper to compute `last_activity_at + timeout_secs`: the partial index the sweeper relies on is `(expires_at) WHERE status = 'running'` (migration `m20260414_000001_create_sandboxes`), and keeping the deadline materialised in the indexed column keeps that sweep query cheap. A predicate over a computed expression would not use the index. + +This is a behaviour change for existing ephemeral sandboxes — an actively-used one now survives past its original deadline. That is the documented intent of the field, and the 24h clamp still bounds a fully idle sandbox. + +### 4. Wake-on-access at `resolve_id` + +`resolve_id` is the single choke point for exec, filesystem, and job operations. For `lifecycle = 'workspace'` rows found in `stopped`, it starts the container, transitions the row to `running`, records a `woken` event, and returns normally instead of erroring. + +Ephemeral behaviour is unchanged — a stopped ephemeral sandbox still returns `InvalidState`, which is what `@vercel/sandbox` consumers expect. + +Wake latency is a container start, not a create: the image is local, the volumes exist, the work dir is populated. Callers see it as a slow first call, not a failure. + +### 5. Create a workspace from a project + +`POST /v1/sandboxes` accepts `lifecycle` and an optional `project_id`. When `project_id` is present and no explicit `source` was given, the repo URL and git connection are resolved from the project row, so "give me a workspace on this project's code" needs no copy-pasted clone URL. `project_id` is persisted (nullable, `ON DELETE SET NULL`) so workspaces can be listed per project. + +Explicit `source` always wins over the project-derived one — the project is a convenience default, not an override. + +### 6. Out of scope for this ADR's first phase + +Two follow-ups, deliberately separated because each is its own reviewable change: + +- **Interactive terminal on `/v1/sandboxes/{id}/terminal`.** The in-sandbox half exists (`temps-pty-agent` + `dtach`, ADR-008); the host-side handler does not exist in this repo. Building it requires a new PTY-attach method on the `SandboxProvider` trait, because `temps-sandbox` must not depend on `bollard` (ADR-010, enforced by `scripts/check-provider-boundary.sh`). Until then, workspaces are driven through `exec` and the CLI. +- **AI CLI credential injection at create.** The CLIs are installed in the image; the credential catalog and injector (`crates/temps-agents/src/ai_cli/`, `services/sandbox_injector.rs`) are currently wired only to agent runs. Until that is extended, users supply their own key via the existing create-time `env` map. + +## Consequences + +**Positive** + +- A workspace survives indefinitely without operator intervention, and costs nothing but disk while idle. +- `timeout_secs` stops lying, for every caller. +- Creating a workspace on a project's repo is one call. +- No new background machinery: the existing sweeper, registry recovery, and preview-gateway paths are reused unchanged. + +**Negative / risks** + +- **Disk is now the unbounded resource.** Suspended workspaces hold their work dir and home volume forever. Nothing in this ADR reclaims them; `destroy` remains the only path, and it is user-initiated. A per-owner workspace count or disk quota is the natural follow-up, and should land before this is offered on Temps Cloud. +- **Wake adds latency on a cold call**, on an endpoint that previously either worked immediately or failed immediately. Clients with tight timeouts on `exec` may see a timeout where they used to see a clean 409. +- **The `touch()` change extends real lifetimes.** An ephemeral sandbox polled by a health check every minute now never expires. That is the intended reading of an idle timeout, but it is a change to observable behaviour and is called out in the changelog. +- **Wake-on-access does not cover preview URLs.** A suspended workspace's preview URL still fails until something calls the API. Waking from the gateway path is a larger change (it crosses the proxy/console split, ADR-017) and is not attempted here. + +## Alternatives considered + +**No TTL at all — workspaces simply never stop.** Simplest to implement and closest to the literal request. Rejected: on a 3 vCPU / 4 GB reference host, a handful of idle workspaces holding memory is a worse outcome than any TTL, and the failure mode (deployments evicted by idle dev containers) is invisible until it is catastrophic. Suspend-and-wake delivers the same user-visible property. + +**A very large `timeout_secs` (e.g. 1 year) instead of a lifecycle class.** Rejected: it conflates "how long may this idle before suspending" with "may this be resumed automatically", which are genuinely different questions. It also leaves the stopped-sandbox error path unchanged, so the user still hits a 409 the morning after. + +**A separate `workspaces` table and API surface.** Rejected: workspaces and sandboxes share every operation — exec, filesystem, jobs, preview URLs, resize, preview passwords. A parallel surface would duplicate `handlers/sandboxes.rs` almost entirely to express one lifecycle difference. A column is proportionate. + +**Sweeper computes `last_activity_at + timeout_secs`.** Rejected on indexing grounds — see §3. + +## References + +- ADR-008 — in-sandbox PTY agent (the terminal follow-up builds on this) +- ADR-009 — sandbox API versioning +- ADR-010 — provider boundary traits (why the terminal needs a trait method) +- ADR-013 — sandbox egress credential proxy (threat model for long-lived sandboxes) +- ADR-029 — Firecracker sandbox backend (workspaces inherit backend selection unchanged) From bfc92b1f4a03b93a1d79bcc20c9906e0e1dd3d74 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 14:47:08 +0200 Subject: [PATCH 02/12] feat(sandbox): add persistent workspace sandboxes with wake-on-access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements ADR-036 phase one: a second sandbox lifecycle class whose state is permanent but whose compute is on-demand. - `sandboxes.lifecycle` ('ephemeral' | 'workspace'), plus `project_id` and `source_repo_url`, all defaulted so existing rows and SDK clients are unaffected. - `resolve_id` — the single choke point for exec/fs/jobs — now wakes a suspended workspace instead of returning 409. Ephemeral sandboxes keep the 409, which is what `@vercel/sandbox` consumers rely on. - Workspaces are still swept on idle. "Permanent" means the state survives, not that the container pins RAM: a handful of idle workspaces would evict real deployments on the reference host. - `POST /v1/sandboxes` accepts `lifecycle` and `project_id`; a project supplies the clone URL, branch, and git connection when no explicit `source` is given. Gated by project scope + access guards, since it reads that project's repo credential. - List gains `lifecycle` and `project_id` filters, both on partial indexes. - CLI parity: `sandbox create --workspace --project `, `sandbox list --workspace/--lifecycle/--project`, and detail output that distinguishes "suspends at" from "expires". Also fixes `timeout_secs`, which was documented and named as an idle timeout but implemented as a wall-clock deadline: `touch()` bumped `last_activity_at` and never moved `expires_at`, so a sandbox in continuous use was still stopped at its original deadline. The deadline is now pushed forward on every exec and filesystem op, materialised in the indexed column so the sweeper's partial index still applies. --- apps/temps-cli/src/commands/sandbox/index.ts | 81 ++- crates/temps-entities/src/sandboxes.rs | 20 + ...0806_000001_sandbox_workspace_lifecycle.rs | 70 +++ crates/temps-migrations/src/migration/mod.rs | 2 + crates/temps-proxy/src/preview_auth.rs | 3 + crates/temps-sandbox/src/error.rs | 14 + crates/temps-sandbox/src/handlers/mod.rs | 7 +- .../temps-sandbox/src/handlers/sandboxes.rs | 88 ++- crates/temps-sandbox/src/plugin.rs | 11 +- crates/temps-sandbox/src/services/exec.rs | 8 +- .../src/services/expiration_sweeper.rs | 16 + crates/temps-sandbox/src/services/fs.rs | 20 +- .../src/services/sandbox_service.rs | 576 +++++++++++++++++- crates/temps-sandbox/tests/vercel_compat.rs | 6 + .../sandboxes/CreateSandboxDocs.tsx | 31 + 15 files changed, 919 insertions(+), 34 deletions(-) create mode 100644 crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs diff --git a/apps/temps-cli/src/commands/sandbox/index.ts b/apps/temps-cli/src/commands/sandbox/index.ts index 0bbf7852b..a0ef795dc 100644 --- a/apps/temps-cli/src/commands/sandbox/index.ts +++ b/apps/temps-cli/src/commands/sandbox/index.ts @@ -28,6 +28,10 @@ interface SandboxResponse { created_at: string expires_at: string preview_password_hint?: string | null + /** 'ephemeral' | 'workspace' — absent on servers older than ADR-036. */ + lifecycle?: string + project_id?: number | null + source_repo_url?: string | null } interface SetPreviewPasswordResponse { @@ -218,6 +222,14 @@ export function registerSandboxCommands(program: Command): void { .option('--git-username ', 'HTTP Basic username for private repo clone (requires --git-password)') .option('--git-password ', 'HTTP Basic password/token (paired with --git-username; injected via GIT_ASKPASS)') .option('--tarball-url ', 'Tarball URL to download and extract') + .option( + '--workspace', + 'Create a persistent workspace: suspends when idle, wakes automatically on the next command, and is never destroyed for you', + ) + .option( + '--project ', + "Seed the work dir from a temps project's connected repo (and attribute the sandbox to it)", + ) .option( '--preview-password', 'Generate a random preview-URL password and print it once on stdout', @@ -235,6 +247,9 @@ export function registerSandboxCommands(program: Command): void { .description('List your sandboxes') .option('--page ', 'Page (1-indexed)') .option('--page-size ', 'Items per page (default 20, max 100)') + .option('--workspace', 'Show only persistent workspaces') + .option('--lifecycle ', 'Filter by lifecycle class: ephemeral | workspace') + .option('--project ', 'Show only sandboxes created from this project') .option('--json', 'Output as JSON') .action(listAction) @@ -370,6 +385,8 @@ interface CreateOptions { tarballUrl?: string previewPassword?: boolean previewPasswordLength?: string + workspace?: boolean + project?: string json?: boolean } @@ -454,7 +471,17 @@ async function createAction(options: CreateOptions): Promise { if (Object.keys(env).length > 0) body.env = env if (options.cpuLimit !== undefined) body.cpu_limit = Number(options.cpuLimit) if (options.memoryMb !== undefined) body.memory_limit_mb = Number(options.memoryMb) + if (options.workspace) body.lifecycle = 'workspace' + if (options.project !== undefined) { + const projectId = Number(options.project) + if (!Number.isInteger(projectId)) { + throw new Error('--project must be a numeric project ID') + } + body.project_id = projectId + } + // An explicit --git-url/--tarball-url wins over the project's repo, + // matching the server: --project is a convenience default, not a lock. const source = buildSource(options) if (source) body.source = source @@ -489,12 +516,25 @@ async function createAction(options: CreateOptions): Promise { return } - success(`Sandbox ${colors.primary(sbx.id)} created`) + const createdWorkspace = sbx.lifecycle === 'workspace' + success( + `${createdWorkspace ? 'Workspace' : 'Sandbox'} ${colors.primary(sbx.id)} created`, + ) keyValue('Name', sbx.name) keyValue('Status', statusColor(sbx.status)) keyValue('Image', sbx.image ?? '(default)') keyValue('Work dir', sbx.work_dir) - keyValue('Expires', sbx.expires_at) + keyValue(createdWorkspace ? 'Suspends at' : 'Expires', sbx.expires_at) + if (sbx.source_repo_url) { + keyValue('Repo', sbx.source_repo_url) + } + if (createdWorkspace) { + newline() + info( + `Run a command in it with: temps sandbox exec ${sbx.id} -- \n` + + ' It suspends when idle and wakes on the next command — your files stay put.', + ) + } if (generatedPassword) { newline() warning('Preview password (shown once — copy it now):') @@ -577,6 +617,9 @@ async function passwordAction( interface ListOptions { page?: string pageSize?: string + workspace?: boolean + lifecycle?: string + project?: string json?: boolean } @@ -586,6 +629,11 @@ async function listAction(options: ListOptions): Promise { const qs: string[] = [] if (options.page) qs.push(`page=${encodeURIComponent(options.page)}`) if (options.pageSize) qs.push(`page_size=${encodeURIComponent(options.pageSize)}`) + // `--workspace` is shorthand for `--lifecycle workspace`. If both are + // given, the explicit one wins rather than silently conflicting. + const lifecycle = options.lifecycle ?? (options.workspace ? 'workspace' : undefined) + if (lifecycle) qs.push(`lifecycle=${encodeURIComponent(lifecycle)}`) + if (options.project) qs.push(`project_id=${encodeURIComponent(options.project)}`) const path = qs.length ? `?${qs.join('&')}` : '' const data = await withSpinner('Fetching sandboxes...', () => @@ -610,11 +658,20 @@ async function listAction(options: ListOptions): Promise { { header: 'ID', key: 'id', color: (v) => colors.primary(v) }, { header: 'Name', key: 'name', color: (v) => colors.bold(v) }, { header: 'Status', key: 'status', color: (v) => statusColor(v) }, + { + header: 'Kind', + // Older servers don't send `lifecycle`; everything there is ephemeral. + accessor: (s) => (s.lifecycle === 'workspace' ? 'workspace' : 'ephemeral'), + color: (v) => (v === 'workspace' ? colors.primary(v) : colors.muted(v)), + }, { header: 'Image', accessor: (s) => s.image ?? '(default)', color: (v) => colors.muted(v.length > 30 ? v.slice(0, 30) + '...' : v), }, + // For a workspace this is when it suspends, not when it dies — the + // header would be misleading without that distinction, and the + // `sandbox show` output spells it out. { header: 'Expires', key: 'expires_at', color: (v) => colors.muted(v) }, ] @@ -640,10 +697,28 @@ async function showAction(id: string, options: { json?: boolean }): Promise, + + /// Repo URL the work dir was seeded from, recorded for display. + /// Never contains credentials — the create path rejects URLs with + /// embedded userinfo. + pub source_repo_url: Option, + /// Optional Docker image override. When null, the platform default /// is used (the same image agent-runs use). pub image: Option, diff --git a/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs b/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs new file mode 100644 index 000000000..2cf222e52 --- /dev/null +++ b/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs @@ -0,0 +1,70 @@ +//! Persistent workspace sandboxes (ADR-036). +//! +//! Adds the lifecycle class that separates throwaway sandboxes from +//! long-lived workspaces: +//! +//! - `sandboxes.lifecycle`: `'ephemeral'` (default, existing behaviour) or +//! `'workspace'`. A workspace is still suspended on idle by the +//! expiration sweeper — the difference is that any subsequent access +//! wakes it instead of returning `409 InvalidState`. +//! - `sandboxes.project_id` (nullable, indexed): the project a workspace +//! was created from, so workspaces can be listed per project and the +//! clone URL / git connection can be derived at create time. No FK — +//! consistent with `agent_run_id`, and a deleted project must not +//! cascade into deleting a user's working tree. +//! - `sandboxes.source_repo_url` (nullable): the repo the work dir was +//! seeded from, recorded for display. Never contains credentials — +//! the create path rejects URLs with embedded userinfo. +//! +//! Existing rows default to `'ephemeral'`, so behaviour is unchanged for +//! everything created before this migration. + +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let conn = manager.get_connection(); + conn.execute_unprepared( + "ALTER TABLE sandboxes ADD COLUMN IF NOT EXISTS lifecycle VARCHAR(32) NOT NULL DEFAULT 'ephemeral'", + ) + .await?; + conn.execute_unprepared( + "ALTER TABLE sandboxes ADD COLUMN IF NOT EXISTS project_id INTEGER", + ) + .await?; + conn.execute_unprepared( + "ALTER TABLE sandboxes ADD COLUMN IF NOT EXISTS source_repo_url TEXT", + ) + .await?; + // Partial index: workspaces are the minority of rows, and the + // only queries that filter on lifecycle are looking for them. + conn.execute_unprepared( + "CREATE INDEX IF NOT EXISTS idx_sandboxes_lifecycle ON sandboxes (lifecycle) WHERE lifecycle <> 'ephemeral'", + ) + .await?; + conn.execute_unprepared( + "CREATE INDEX IF NOT EXISTS idx_sandboxes_project_id ON sandboxes (project_id) WHERE project_id IS NOT NULL", + ) + .await?; + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let conn = manager.get_connection(); + conn.execute_unprepared("DROP INDEX IF EXISTS idx_sandboxes_project_id") + .await?; + conn.execute_unprepared("DROP INDEX IF EXISTS idx_sandboxes_lifecycle") + .await?; + conn.execute_unprepared("ALTER TABLE sandboxes DROP COLUMN IF EXISTS source_repo_url") + .await?; + conn.execute_unprepared("ALTER TABLE sandboxes DROP COLUMN IF EXISTS project_id") + .await?; + conn.execute_unprepared("ALTER TABLE sandboxes DROP COLUMN IF EXISTS lifecycle") + .await?; + Ok(()) + } +} diff --git a/crates/temps-migrations/src/migration/mod.rs b/crates/temps-migrations/src/migration/mod.rs index 444998b3f..1d3a87b71 100644 --- a/crates/temps-migrations/src/migration/mod.rs +++ b/crates/temps-migrations/src/migration/mod.rs @@ -175,6 +175,7 @@ mod m20260803_000002_add_step_up_expires_at_to_sessions; mod m20260804_000001_add_ai_data_access_to_external_services; mod m20260804_000001_add_must_change_password_to_users; pub mod m20260805_000001_index_normalized_managed_domains; +mod m20260806_000001_sandbox_workspace_lifecycle; pub struct Migrator; @@ -365,6 +366,7 @@ impl MigratorTrait for Migrator { m20260804_000001_add_ai_data_access_to_external_services::Migration, ), Box::new(m20260805_000001_index_normalized_managed_domains::Migration), + Box::new(m20260806_000001_sandbox_workspace_lifecycle::Migration), ] } } diff --git a/crates/temps-proxy/src/preview_auth.rs b/crates/temps-proxy/src/preview_auth.rs index 4c3f4fec5..6261067be 100644 --- a/crates/temps-proxy/src/preview_auth.rs +++ b/crates/temps-proxy/src/preview_auth.rs @@ -998,6 +998,9 @@ mod tests { expires_at: now, preview_password_hash: password_hash.map(|s| s.to_string()), preview_password_hint: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, } } diff --git a/crates/temps-sandbox/src/error.rs b/crates/temps-sandbox/src/error.rs index 5e5214a21..6db5f35d3 100644 --- a/crates/temps-sandbox/src/error.rs +++ b/crates/temps-sandbox/src/error.rs @@ -68,6 +68,20 @@ pub enum SandboxError { )] ManagedByAgentRun { sandbox_id: String, run_id: i32 }, + /// A workspace was requested for a project that doesn't exist (or was + /// soft-deleted). Mapped to HTTP 404. + #[error("Project {project_id} not found")] + ProjectNotFound { project_id: i32 }, + + /// The project exists but has no git repository attached, so there is + /// nothing to clone into the workspace. Mapped to HTTP 400 — the fix + /// is to connect a repo to the project, or to pass an explicit + /// `source`, and the message says so. + #[error( + "Project {project_id} ('{name}') has no git repository connected — connect a repo to the project, or pass an explicit `source` to seed the sandbox from a different URL" + )] + ProjectHasNoRepo { project_id: i32, name: String }, + /// An operation exceeded the per-sandbox timeout. #[error("Operation timed out in sandbox {sandbox_id} after {timeout_secs}s")] Timeout { diff --git a/crates/temps-sandbox/src/handlers/mod.rs b/crates/temps-sandbox/src/handlers/mod.rs index f287d9c01..90a28e117 100644 --- a/crates/temps-sandbox/src/handlers/mod.rs +++ b/crates/temps-sandbox/src/handlers/mod.rs @@ -14,9 +14,14 @@ use crate::services::sandbox_service::SandboxService; /// Shared state for sandbox HTTP handlers. Intentionally minimal — the /// service already owns db/registry/jobs/config, so handlers need only -/// the service itself. +/// the service itself plus the project access checker. pub struct SandboxAppState { pub sandbox_service: Arc, + /// Team-membership gate for `project_id`-scoped creates (ADR-028). + /// `None` when no checker is registered (OSS builds without the + /// teams plugin), in which case `project_access_guard!` is a no-op + /// and ownership/scope checks alone apply. + pub project_access_checker: Option>, } /// OpenAPI document for the `/v1/sandboxes/*` surface. diff --git a/crates/temps-sandbox/src/handlers/sandboxes.rs b/crates/temps-sandbox/src/handlers/sandboxes.rs index 86a298252..be39749a2 100644 --- a/crates/temps-sandbox/src/handlers/sandboxes.rs +++ b/crates/temps-sandbox/src/handlers/sandboxes.rs @@ -32,7 +32,7 @@ use temps_agents::sandbox::ExecStream; use tokio_stream::wrappers::BroadcastStream; use utoipa::ToSchema; -use temps_auth::{permissions::Permission, RequireAuth}; +use temps_auth::{permissions::Permission, project_access_guard, project_scope_guard, RequireAuth}; use temps_core::problemdetails::{self, Problem}; use crate::error::SandboxError; @@ -88,7 +88,9 @@ fn sandbox_permission_guard( use crate::services::exec::{ExecOptions, ExecResult}; use crate::services::fs::StatInfo; use crate::services::job_tracker::{JobState, JobStatus}; -use crate::services::sandbox_service::{CreateSandboxRequest, SandboxSource, SandboxSummary}; +use crate::services::sandbox_service::{ + CreateSandboxRequest, SandboxLifecycle, SandboxSource, SandboxSummary, +}; // ── Error → Problem conversion ────────────────────────────────────────────── @@ -123,6 +125,12 @@ impl From for Problem { SandboxError::ManagedByAgentRun { .. } => problemdetails::new(StatusCode::CONFLICT) .with_title("Sandbox Managed By Agent Run") .with_detail(error.to_string()), + SandboxError::ProjectNotFound { .. } => problemdetails::new(StatusCode::NOT_FOUND) + .with_title("Project Not Found") + .with_detail(error.to_string()), + SandboxError::ProjectHasNoRepo { .. } => problemdetails::new(StatusCode::BAD_REQUEST) + .with_title("Project Has No Repository") + .with_detail(error.to_string()), SandboxError::Timeout { .. } => problemdetails::new(StatusCode::GATEWAY_TIMEOUT) .with_title("Sandbox Operation Timed Out") .with_detail(error.to_string()), @@ -431,6 +439,25 @@ pub struct CreateSandboxBody { /// 400 rather than silently downgrading isolation. #[serde(default)] pub backend: Option, + /// Lifecycle class (ADR-036, temps-native): `"ephemeral"` (default) or + /// `"workspace"`. + /// + /// A workspace is a long-lived development environment: it is still + /// suspended after `timeout_secs` of inactivity, but the next exec or + /// filesystem call wakes it transparently instead of returning 409, and + /// nothing ever destroys it automatically. Use it for "give me a place + /// to work on this repo"; leave it unset for throwaway sandboxes. + #[serde(default)] + pub lifecycle: Option, + /// Create the sandbox against a temps project (temps-native). The + /// project's connected repo and git credential seed the work dir when + /// no explicit `source` is given, and the sandbox is attributed to the + /// project so it can be listed alongside it. + /// + /// Requires access to the project — the same team/scope rules that + /// gate every other project-scoped endpoint apply. + #[serde(default)] + pub project_id: Option, // ── `@vercel/sandbox` fields accepted for compatibility and ignored. // We accept them so SDK calls don't 422 on `deny_unknown_fields`; we @@ -459,6 +486,8 @@ impl From for CreateSandboxRequest { preview_password: b.preview_password, ports: b.ports, backend: b.backend, + lifecycle: b.lifecycle, + project_id: b.project_id, } } } @@ -524,6 +553,16 @@ pub struct SandboxInner { /// `None` for sandboxes created via this API. #[serde(skip_serializing_if = "Option::is_none")] pub agent_run_id: Option, + /// Lifecycle class (ADR-036): `"ephemeral"` or `"workspace"`. Always + /// present — a client that doesn't know about workspaces sees + /// `"ephemeral"` and behaves exactly as before. + pub lifecycle: String, + /// Project this sandbox was created from, when created from one. + #[serde(skip_serializing_if = "Option::is_none")] + pub project_id: Option, + /// Repo the work dir was seeded from. Never carries credentials. + #[serde(skip_serializing_if = "Option::is_none")] + pub source_repo_url: Option, } /// `@vercel/sandbox` wraps every single-sandbox response as @@ -582,6 +621,9 @@ impl SandboxResponse { preview_url_template: template, preview_password_hint: s.preview_password_hint, agent_run_id: s.agent_run_id, + lifecycle: s.lifecycle, + project_id: s.project_id, + source_repo_url: s.source_repo_url, }, routes, } @@ -627,10 +669,16 @@ pub struct PaginationParams { pub page_size: Option, /// SDK-compat: `limit` maps to `page_size` when the latter isn't set. pub limit: Option, - /// Accepted and ignored — temps has no project scoping on sandboxes. + /// Accepted and ignored — the SDK's opaque project slug. temps uses + /// the numeric `project_id` filter below instead. pub project: Option, pub since: Option, pub until: Option, + /// Filter by lifecycle class (temps-native): `"ephemeral"` or + /// `"workspace"`. Omit for both. + pub lifecycle: Option, + /// Filter to sandboxes created from a specific temps project. + pub project_id: Option, } #[derive(Debug, Deserialize, ToSchema)] @@ -878,6 +926,14 @@ pub async fn create_sandbox( Json(body): Json, ) -> Result { sandbox_permission_guard(&auth, Permission::SandboxesWrite, Permission::ProjectsWrite)?; + // Creating a sandbox *from* a project reads that project's repo URL and + // git credential, so it needs the same access gate as any other + // project-scoped endpoint — an API key scoped to project A must not be + // able to clone project B's private repo into a sandbox it owns. + if let Some(project_id) = body.project_id { + project_scope_guard!(auth, project_id); + project_access_guard!(auth, project_id, state.project_access_checker); + } if let Some(src) = body.source.as_ref() { src.validate_async().await?; } @@ -894,8 +950,11 @@ pub async fn create_sandbox( get, path = "/v1/sandboxes", params(("page" = Option, Query, description = "Page (1-indexed)"), - ("page_size" = Option, Query, description = "Items per page (default 20, max 100)")), - responses((status = 200, description = "List sandboxes", body = ListSandboxesResponse)), + ("page_size" = Option, Query, description = "Items per page (default 20, max 100)"), + ("lifecycle" = Option, Query, description = "Filter by lifecycle class: \"ephemeral\" or \"workspace\""), + ("project_id" = Option, Query, description = "Filter to sandboxes created from a project")), + responses((status = 200, description = "List sandboxes", body = ListSandboxesResponse), + (status = 400, description = "Unknown lifecycle value")), security(("bearer_auth" = [])) )] pub async fn list_sandboxes( @@ -906,9 +965,20 @@ pub async fn list_sandboxes( sandbox_permission_guard(&auth, Permission::SandboxesRead, Permission::ProjectsRead)?; let page = q.page.unwrap_or(1); let page_size = q.page_size.or(q.limit).unwrap_or(20); + let lifecycle = q + .lifecycle + .as_deref() + .map(SandboxLifecycle::parse) + .transpose()?; let (items, total) = state .sandbox_service - .list_for_user(auth.user_id(), Some(page), Some(page_size)) + .list_for_user( + auth.user_id(), + Some(page), + Some(page_size), + lifecycle, + q.project_id, + ) .await?; let envelopes = build_summary_responses(&state, items).await; let sandboxes: Vec = envelopes.into_iter().map(|e| e.sandbox).collect(); @@ -2618,6 +2688,9 @@ mod tests { backend: None, disk_size_mb: None, agent_run_id: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, }; let r = SandboxResponse::from(summary); assert_eq!(r.sandbox.id, "sbx_abc"); @@ -2645,6 +2718,9 @@ mod tests { backend: None, disk_size_mb: None, agent_run_id: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, }; let parts = PreviewUrlParts { protocol: "https".into(), diff --git a/crates/temps-sandbox/src/plugin.rs b/crates/temps-sandbox/src/plugin.rs index 9076f76fd..1bdbc17a1 100644 --- a/crates/temps-sandbox/src/plugin.rs +++ b/crates/temps-sandbox/src/plugin.rs @@ -251,7 +251,16 @@ impl TempsPlugin for SandboxPlugin { // warn! in `register_services` is the operator-facing signal. let sandbox_service = context.get_service::()?; - let app_state = Arc::new(SandboxAppState { sandbox_service }); + // Optional: only present when a plugin registers a checker. Absent + // means `project_access_guard!` is inert and the scope guard plus + // per-sandbox ownership are the only gates — same posture as every + // other crate that takes this dependency optionally. + let project_access_checker = context.get_service::(); + + let app_state = Arc::new(SandboxAppState { + sandbox_service, + project_access_checker, + }); let router = configure_routes().with_state(app_state); Some(PluginRoutes::new(router)) } diff --git a/crates/temps-sandbox/src/services/exec.rs b/crates/temps-sandbox/src/services/exec.rs index 895db714a..c01ce03ef 100644 --- a/crates/temps-sandbox/src/services/exec.rs +++ b/crates/temps-sandbox/src/services/exec.rs @@ -95,8 +95,8 @@ impl SandboxService { options: ExecOptions, ) -> Result { options.validate()?; - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; let handle = self .registry() .get(internal_id, public_id) @@ -124,8 +124,8 @@ impl SandboxService { options: ExecOptions, ) -> Result { options.validate()?; - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; // Verify the sandbox is alive *before* spawning the background task, // so callers get a synchronous NotFound/ExecFailed instead of a diff --git a/crates/temps-sandbox/src/services/expiration_sweeper.rs b/crates/temps-sandbox/src/services/expiration_sweeper.rs index 311c39397..87cdfc502 100644 --- a/crates/temps-sandbox/src/services/expiration_sweeper.rs +++ b/crates/temps-sandbox/src/services/expiration_sweeper.rs @@ -11,6 +11,19 @@ //! state all survive so the owner can call `/resume` later. Destroying //! would be irreversible — that's reserved for explicit `/destroy` calls. //! +//! Workspace-class sandboxes (ADR-036) are swept exactly like ephemeral +//! ones — deliberately. "Permanent" means the *state* is permanent, not +//! that the container pins RAM forever; a handful of idle workspaces +//! holding memory would evict real deployments on the 3 vCPU / 4 GB +//! reference host. The difference lives on the access path instead: +//! `SandboxService::resolve_id` wakes a suspended workspace transparently, +//! so from the user's side suspension is invisible apart from a slower +//! first call. +//! +//! `expires_at` is an *idle* deadline: `SandboxService::touch` pushes it +//! forward on every exec and filesystem operation, so a sandbox in active +//! use is never swept. Only genuine inactivity reaches this loop. +//! //! Loop shape: plain 60-second interval (not minute-aligned — we don't //! need clock phases, just periodic sweeping). Query is cheap thanks to //! the partial index on `(expires_at) WHERE status = 'running'` added by @@ -164,6 +177,9 @@ mod tests { expires_at: now + chrono::Duration::seconds(expires_in_secs), preview_password_hash: None, preview_password_hint: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, } } diff --git a/crates/temps-sandbox/src/services/fs.rs b/crates/temps-sandbox/src/services/fs.rs index 72aab6ea7..67fdc83d3 100644 --- a/crates/temps-sandbox/src/services/fs.rs +++ b/crates/temps-sandbox/src/services/fs.rs @@ -45,8 +45,8 @@ impl SandboxService { path: &str, ) -> Result, SandboxError> { validate_absolute(path, "read")?; - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; let handle = self .registry() .get(internal_id, public_id) @@ -78,8 +78,8 @@ impl SandboxService { mode: u32, ) -> Result<(), SandboxError> { validate_absolute(path, "write")?; - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; let handle = self .registry() .get(internal_id, public_id) @@ -107,8 +107,8 @@ impl SandboxService { path: &str, ) -> Result { validate_absolute(path, "stat")?; - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; let handle = self .registry() .get(internal_id, public_id) @@ -211,8 +211,8 @@ impl SandboxService { if files.is_empty() { return Ok(0); } - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; let handle = self .registry() .get(internal_id, public_id) @@ -246,8 +246,8 @@ impl SandboxService { path: &str, ) -> Result<(), SandboxError> { validate_absolute(path, "mkdir")?; - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; - self.touch(internal_id).await; + let (row, internal_id) = self.resolve_id(public_id, user_id).await?; + self.touch(internal_id, row.timeout_secs).await; let handle = self .registry() .get(internal_id, public_id) diff --git a/crates/temps-sandbox/src/services/sandbox_service.rs b/crates/temps-sandbox/src/services/sandbox_service.rs index e3090f2ae..e779bd93a 100644 --- a/crates/temps-sandbox/src/services/sandbox_service.rs +++ b/crates/temps-sandbox/src/services/sandbox_service.rs @@ -24,7 +24,7 @@ use sea_orm::{ use temps_agents::sandbox::SandboxCreateConfig; use temps_agents::services::run_service::TERMINAL_RUN_STATUSES; use temps_config::ConfigService; -use temps_entities::{agent_runs, sandbox_events, sandboxes}; +use temps_entities::{agent_runs, projects, sandbox_events, sandboxes}; use temps_git::GitProviderManager; use crate::error::{from_agent_error, SandboxError}; @@ -65,6 +65,67 @@ pub enum SandboxSource { Tarball { url: String }, } +/// Lifecycle class of a sandbox (ADR-036). +/// +/// Both classes are suspended on idle by the expiration sweeper — the +/// difference is what the *next* access does. An ephemeral sandbox is +/// owned by whoever created it and returns `InvalidState` once stopped +/// (the behaviour `@vercel/sandbox` consumers expect); a workspace is a +/// place a human comes back to, so it wakes transparently instead. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum SandboxLifecycle { + /// Throwaway sandbox. Default for every caller that doesn't ask. + #[default] + Ephemeral, + /// Long-lived workspace: suspends on idle, wakes on access, never + /// auto-destroyed. + Workspace, +} + +impl SandboxLifecycle { + pub fn as_str(self) -> &'static str { + match self { + SandboxLifecycle::Ephemeral => "ephemeral", + SandboxLifecycle::Workspace => "workspace", + } + } + + /// Parse the API-facing string. Unknown values are a validation + /// error rather than a silent fallback: a caller who typo'd + /// `"workspaces"` and got an ephemeral sandbox would lose their work + /// to the first idle sweep without ever being told. + pub fn parse(value: &str) -> Result { + match value { + "ephemeral" => Ok(SandboxLifecycle::Ephemeral), + "workspace" => Ok(SandboxLifecycle::Workspace), + other => Err(SandboxError::Validation { + message: format!( + "unknown lifecycle '{}' (expected \"ephemeral\" or \"workspace\")", + other + ), + }), + } + } + + /// Read the class off a persisted row. Unlike [`Self::parse`] this + /// cannot fail: a row carrying a value we don't recognise (written + /// by a newer binary, then rolled back) is treated as ephemeral, + /// which is the conservative reading — it never auto-starts a + /// container the caller didn't ask for. + pub fn from_row(row: &sandboxes::Model) -> Self { + match row.lifecycle.as_str() { + "workspace" => SandboxLifecycle::Workspace, + _ => SandboxLifecycle::Ephemeral, + } + } +} + +impl std::fmt::Display for SandboxLifecycle { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_str()) + } +} + /// Input to `create_sandbox`. A subset of the `@vercel/sandbox` create /// options — we accept what SDK clients send and ignore the rest. #[derive(Debug, Clone, Default)] @@ -101,6 +162,12 @@ pub struct CreateSandboxRequest { /// it). Unknown values are a validation error, and requesting a /// backend the host doesn't have fails create rather than downgrading. pub backend: Option, + /// Lifecycle class (ADR-036). `None` → ephemeral, so existing + /// callers and SDK clients are unaffected. + pub lifecycle: Option, + /// Project to derive the repo from when `source` is absent, and to + /// attribute the sandbox to. `None` → unattached sandbox. + pub project_id: Option, } /// Output DTO — what the service returns to handlers and what handlers @@ -131,6 +198,12 @@ pub struct SandboxSummary { /// Set when this sandbox executes an agent run (autofixer / workflow /// agent). `None` for sandboxes created via the standalone API. pub agent_run_id: Option, + /// Lifecycle class: `"ephemeral"` or `"workspace"` (ADR-036). + pub lifecycle: String, + /// Project this sandbox belongs to, when created from one. + pub project_id: Option, + /// Repo the work dir was seeded from, for display. + pub source_repo_url: Option, } impl From<&sandboxes::Model> for SandboxSummary { @@ -152,6 +225,9 @@ impl From<&sandboxes::Model> for SandboxSummary { .and_then(|v| v.get("disk_size_mb")) .and_then(|v| v.as_u64()), agent_run_id: m.agent_run_id, + lifecycle: m.lifecycle.clone(), + project_id: m.project_id, + source_repo_url: m.source_repo_url.clone(), } } } @@ -180,6 +256,21 @@ fn ports_from_metadata(metadata: Option<&serde_json::Value>) -> Vec { .unwrap_or_default() } +/// The idle deadline for a sandbox: the instant it becomes eligible for +/// suspension if nothing touches it in the meantime. +/// +/// One helper rather than five open-coded `now + Duration::seconds(...)` +/// sites, because every path that records activity — create, touch, +/// resume, wake — must agree on it. When they disagreed, `expires_at` +/// meant "wall-clock deadline" on some paths and "idle deadline" on +/// others, which is the bug ADR-036 §3 describes. +fn idle_deadline( + now: chrono::DateTime, + timeout_secs: i32, +) -> chrono::DateTime { + now + chrono::Duration::seconds(timeout_secs as i64) +} + /// Reject standalone lifecycle ops (`pause`/`resume`/`restart`/`resize`) /// on rows attributed to an agent run. Those containers are named /// `temps-sandbox-` — not by the row's public id — so the @@ -334,17 +425,31 @@ impl SandboxService { } /// List the caller's non-destroyed sandboxes, newest first. + /// + /// `lifecycle` and `project_id` are optional filters. Both ride + /// partial indexes added by the ADR-036 migration, so filtering to + /// "my workspaces" or "this project's workspaces" doesn't scan the + /// ephemeral rows, which are the overwhelming majority. pub async fn list_for_user( &self, user_id: i32, page: Option, page_size: Option, + lifecycle: Option, + project_id: Option, ) -> Result<(Vec, u64), SandboxError> { let page = page.unwrap_or(1).max(1); let page_size = page_size.unwrap_or(20).clamp(1, 100); - let paginator = sandboxes::Entity::find() + let mut query = sandboxes::Entity::find() .filter(sandboxes::Column::UserId.eq(user_id)) - .filter(sandboxes::Column::Status.ne("destroyed")) + .filter(sandboxes::Column::Status.ne("destroyed")); + if let Some(lifecycle) = lifecycle { + query = query.filter(sandboxes::Column::Lifecycle.eq(lifecycle.as_str())); + } + if let Some(project_id) = project_id { + query = query.filter(sandboxes::Column::ProjectId.eq(project_id)); + } + let paginator = query .order_by_desc(sandboxes::Column::CreatedAt) .paginate(self.db.as_ref(), page_size); let total = paginator.num_items().await?; @@ -578,6 +683,50 @@ impl SandboxService { Ok(()) } + /// Derive a git seed source from a project's connected repository. + /// + /// The point of `project_id` on create: a user who already deploys a + /// project should be able to say "give me a workspace on this" without + /// re-typing the clone URL or re-picking the credential. The project + /// row already knows both, so we read them here. + /// + /// Checks out the project's `main_branch` and reuses its + /// `git_provider_connection_id`, so private repos clone without the + /// caller ever handling a token. Full history (no shallow depth) — + /// this is a workspace someone will branch and rebase in, not a + /// one-shot build. + /// + /// Authorization is the caller's responsibility: handlers gate this + /// with `project_scope_guard!` + `project_access_guard!` before the + /// request reaches the service. + async fn source_from_project(&self, project_id: i32) -> Result { + let project = projects::Entity::find_by_id(project_id) + .filter(projects::Column::IsDeleted.eq(false)) + .one(self.db.as_ref()) + .await? + .ok_or(SandboxError::ProjectNotFound { project_id })?; + + let url = project + .git_url + .as_ref() + .map(|u| u.trim()) + .filter(|u| !u.is_empty()) + .ok_or_else(|| SandboxError::ProjectHasNoRepo { + project_id, + name: project.name.clone(), + })? + .to_string(); + + Ok(SandboxSource::Git { + url, + revision: Some(project.main_branch.clone()), + depth: None, + username: None, + password: None, + git_connection_id: project.git_provider_connection_id, + }) + } + // ── Lifecycle ──────────────────────────────────────────────────────── /// Create a new standalone sandbox. Inserts the DB row first (to get @@ -589,6 +738,25 @@ impl SandboxService { user_id: i32, req: CreateSandboxRequest, ) -> Result { + let lifecycle = match req.lifecycle.as_deref() { + None => SandboxLifecycle::default(), + Some(value) => SandboxLifecycle::parse(value)?, + }; + + // Resolve the effective seed source before anything is created. + // An explicit `source` always wins — `project_id` only supplies a + // default, so a caller can create a workspace attributed to a + // project while seeding it from a fork or a different branch. + let source = match (req.source.clone(), req.project_id) { + (Some(explicit), _) => Some(explicit), + (None, Some(project_id)) => Some(self.source_from_project(project_id).await?), + (None, None) => None, + }; + let source_repo_url = source.as_ref().and_then(|s| match s { + SandboxSource::Git { url, .. } => Some(url.clone()), + SandboxSource::Tarball { .. } => None, + }); + let timeout = req .timeout_secs .unwrap_or(DEFAULT_TIMEOUT_SECS) @@ -672,6 +840,9 @@ impl SandboxService { expires_at: Set(expires_at), preview_password_hash: Set(preview.as_ref().map(|p| p.hash.clone())), preview_password_hint: Set(preview.as_ref().map(|p| p.hint.clone())), + lifecycle: Set(lifecycle.as_str().to_string()), + project_id: Set(req.project_id), + source_repo_url: Set(source_repo_url), ..Default::default() }; let mut row = active.insert(self.db.as_ref()).await?; @@ -760,7 +931,7 @@ impl SandboxService { // extract now. On failure we tear the sandbox down so the user // isn't left with a half-initialized container that's billing // their timeout budget. - if let Some(source) = req.source { + if let Some(source) = source { if let Err(e) = self .seed_source(row.id, &public_id_value, user_id, &source) .await @@ -1216,7 +1387,7 @@ TEMPS_ASKPASS_EOF\n\ .await .map_err(|e| from_agent_error(public_id_value, e))?; let now = Utc::now(); - let new_expires = now + chrono::Duration::seconds(row.timeout_secs as i64); + let new_expires = idle_deadline(now, row.timeout_secs); let sandbox_id = row.id; let mut active: sandboxes::ActiveModel = row.into(); active.status = Set("running".to_string()); @@ -1389,14 +1560,34 @@ TEMPS_ASKPASS_EOF\n\ Ok(updated) } - /// Update `last_activity_at` — called by exec/fs ops to keep the - /// expiry sweeper honest. Swallows DB errors because activity - /// bumps are best-effort. - pub async fn touch(&self, sandbox_id: i32) { + /// Record activity on a sandbox: bump `last_activity_at` **and** push + /// `expires_at` out to `now + timeout_secs`. + /// + /// Moving `expires_at` here is what makes `timeout_secs` an *idle* + /// timeout, which is what the column has always been documented as + /// (and what the API calls it). Before this, `expires_at` was set once + /// at create and never moved by activity, so a sandbox in continuous + /// use was still stopped at its original deadline. + /// + /// The deadline is materialised in the indexed column rather than + /// computed by the sweeper (`last_activity_at + timeout_secs`) on + /// purpose: the sweep query rides the partial index on + /// `(expires_at) WHERE status = 'running'`, and a predicate over an + /// expression would not use it. + /// + /// Called on every exec and filesystem operation, so it must stay a + /// single UPDATE with no read-modify-write. `timeout_secs` is taken + /// from the caller (who already has the row) to avoid a SELECT here. + /// + /// Swallows DB errors: activity bumps are best-effort, and failing a + /// user's exec because a bookkeeping write lost a race would be worse + /// than a sandbox expiring slightly early. + pub async fn touch(&self, sandbox_id: i32, timeout_secs: i32) { let now = Utc::now(); let active = sandboxes::ActiveModel { id: Set(sandbox_id), last_activity_at: Set(now), + expires_at: Set(idle_deadline(now, timeout_secs)), ..Default::default() }; if let Err(e) = active.update(self.db.as_ref()).await { @@ -1582,6 +1773,14 @@ TEMPS_ASKPASS_EOF\n\ ) -> Result<(sandboxes::Model, i32), SandboxError> { let row = self.find_by_public_id(public_id_value, user_id).await?; if row.status == "stopped" { + // Workspaces (ADR-036) are places a human comes back to, so a + // suspended one wakes instead of erroring. Ephemeral sandboxes + // keep the 409: their lifetime belongs to whoever created them, + // and `@vercel/sandbox` consumers rely on a stopped sandbox + // staying stopped rather than silently restarting under them. + if SandboxLifecycle::from_row(&row) == SandboxLifecycle::Workspace { + return self.wake_workspace(row).await; + } return Err(SandboxError::InvalidState { sandbox_id: public_id_value.to_string(), state: row.status.clone(), @@ -1592,6 +1791,47 @@ TEMPS_ASKPASS_EOF\n\ Ok((row, id)) } + /// Start a suspended workspace's container and flip its row back to + /// `running`. Called from [`Self::resolve_id`] on the access path, so + /// the caller experiences it as a slow first request rather than a + /// failure. + /// + /// A wake is a container start, not a create: the image is local, the + /// home volume exists, and the work dir is still populated on the + /// host. Nothing is re-cloned and nothing is lost. + /// + /// If the provider can't start it, the row stays `stopped` and the + /// caller gets the provider's error — deliberately not swallowed. A + /// workspace that silently fails to wake and then reports "not found" + /// on every subsequent call is exactly the debugging dead end + /// self-hosted users can't escape. + async fn wake_workspace( + &self, + row: sandboxes::Model, + ) -> Result<(sandboxes::Model, i32), SandboxError> { + let public_id_value = row.public_id.clone(); + let sandbox_id = row.id; + tracing::info!( + "Waking workspace sandbox {} (internal {}) on access", + public_id_value, + sandbox_id + ); + self.registry + .start(sandbox_id, &public_id_value) + .await + .map_err(|e| from_agent_error(&public_id_value, e))?; + + let now = Utc::now(); + let new_expires = idle_deadline(now, row.timeout_secs); + let mut active: sandboxes::ActiveModel = row.into(); + active.status = Set("running".to_string()); + active.last_activity_at = Set(now); + active.expires_at = Set(new_expires); + let updated = active.update(self.db.as_ref()).await?; + self.record_event(sandbox_id, "woken", None).await; + Ok((updated, sandbox_id)) + } + /// Build a typed provider error into a `SandboxError` carrying the /// public ID. Thin wrapper — module-private modules call this. pub(crate) fn provider_err( @@ -1929,6 +2169,9 @@ mod tests { expires_at: now, preview_password_hash: None, preview_password_hint: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, } } @@ -2124,6 +2367,9 @@ mod tests { expires_at: now, preview_password_hash: None, preview_password_hint: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, }; let s = SandboxSummary::from(&m); assert_eq!(s.public_id, "sbx_abc1234567890def"); @@ -2165,7 +2411,10 @@ mod storage_cleanup_tests { /// `destroy` errors — the case where the container may still be /// running and we delete the work dir anyway. fail_destroy: bool, + /// `start` errors — the wake-on-access failure path. + fail_start: bool, destroys: AtomicUsize, + starts: AtomicUsize, } impl FakeProvider { @@ -2174,7 +2423,9 @@ mod storage_cleanup_tests { fail_create: false, fail_exec: false, fail_destroy: false, + fail_start: false, destroys: AtomicUsize::new(0), + starts: AtomicUsize::new(0), } } } @@ -2280,6 +2531,19 @@ mod storage_cleanup_tests { Ok(()) } + /// The trait's default `start` returns "not supported", so the + /// wake path needs a real implementation here. + async fn start(&self, handle: &SandboxHandle) -> Result<(), AgentError> { + self.starts.fetch_add(1, Ordering::SeqCst); + if self.fail_start { + return Err(AgentError::SandboxProviderUnavailable { + provider: "fake".into(), + reason: format!("daemon unreachable while starting {}", handle.sandbox_name), + }); + } + Ok(()) + } + async fn recover(&self, _run_id: i32) -> Result, AgentError> { Ok(None) } @@ -2424,6 +2688,9 @@ mod storage_cleanup_tests { expires_at: now + chrono::Duration::seconds(3600), preview_password_hash: None, preview_password_hint: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, } } @@ -2439,6 +2706,297 @@ mod storage_cleanup_tests { const PUBLIC_ID: &str = "sbx_deadbeef01234567"; + /// A row in the given lifecycle class and status. Used by the + /// workspace wake tests below. + fn row_with(public_id: &str, lifecycle: &str, status: &str) -> sandboxes::Model { + sandboxes::Model { + status: status.to_string(), + lifecycle: lifecycle.to_string(), + ..row(public_id, None) + } + } + + // ── Lifecycle class (ADR-036) ──────────────────────────────────────── + + #[test] + fn lifecycle_parses_both_public_values() { + assert_eq!( + SandboxLifecycle::parse("ephemeral").expect("ephemeral is valid"), + SandboxLifecycle::Ephemeral + ); + assert_eq!( + SandboxLifecycle::parse("workspace").expect("workspace is valid"), + SandboxLifecycle::Workspace + ); + } + + #[test] + fn lifecycle_rejects_unknown_values_with_a_helpful_message() { + // Silently falling back to ephemeral would cost the caller their + // work at the first idle sweep, so a typo must be a 400. + let err = SandboxLifecycle::parse("workspaces").expect_err("typo must not be accepted"); + let msg = err.to_string(); + assert!(msg.contains("workspaces"), "msg: {}", msg); + assert!(msg.contains("ephemeral"), "must list valid values: {}", msg); + assert!(msg.contains("workspace"), "must list valid values: {}", msg); + } + + #[test] + fn lifecycle_from_row_treats_unrecognised_values_as_ephemeral() { + // Forward-compat: a row written by a newer binary and then rolled + // back must not auto-start containers this binary doesn't + // understand. Ephemeral is the conservative reading. + let unknown = row_with(PUBLIC_ID, "hibernating", "stopped"); + assert_eq!( + SandboxLifecycle::from_row(&unknown), + SandboxLifecycle::Ephemeral + ); + } + + #[test] + fn lifecycle_default_is_ephemeral() { + // Every existing caller and SDK client omits the field. + assert_eq!(SandboxLifecycle::default(), SandboxLifecycle::Ephemeral); + assert_eq!(SandboxLifecycle::default().as_str(), "ephemeral"); + } + + #[test] + fn idle_deadline_is_now_plus_timeout() { + let now = Utc::now(); + assert_eq!(idle_deadline(now, 3600), now + chrono::Duration::hours(1)); + // Degenerate but representable: a zero timeout is already expired + // rather than infinite. The service clamps to >= 60 before this + // is reached, so this only pins the arithmetic. + assert_eq!(idle_deadline(now, 0), now); + } + + #[tokio::test] + async fn resolve_id_wakes_a_stopped_workspace() { + let data_root = unique_data_root("wake-workspace"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + // find_by_public_id → a suspended workspace + .append_query_results([vec![row_with(PUBLIC_ID, "workspace", "stopped")]]) + // wake_workspace's status update (RETURNING the running row) + .append_query_results([vec![row_with(PUBLIC_ID, "workspace", "running")]]) + .into_connection(); + + let (service, _) = build_service(db, FakeProvider::new(), data_root.clone()); + let (row, id) = service + .resolve_id(PUBLIC_ID, 1) + .await + .expect("a stopped workspace must wake, not error"); + + assert_eq!(id, 7); + assert_eq!( + row.status, "running", + "the caller must receive the woken row, not the stale stopped one" + ); + let _ = std::fs::remove_dir_all(&data_root); + } + + #[tokio::test] + async fn resolve_id_still_rejects_a_stopped_ephemeral_sandbox() { + // `@vercel/sandbox` consumers rely on a stopped sandbox staying + // stopped. Waking one under them would restart billing on a + // container they deliberately shut down. + let data_root = unique_data_root("no-wake-ephemeral"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + .append_query_results([vec![row_with(PUBLIC_ID, "ephemeral", "stopped")]]) + .into_connection(); + + let (service, _) = build_service(db, FakeProvider::new(), data_root.clone()); + let err = service + .resolve_id(PUBLIC_ID, 1) + .await + .expect_err("ephemeral sandboxes must not auto-wake"); + + match err { + SandboxError::InvalidState { state, .. } => assert_eq!(state, "stopped"), + other => panic!("expected InvalidState, got {:?}", other), + } + let _ = std::fs::remove_dir_all(&data_root); + } + + #[tokio::test] + async fn resolve_id_passes_through_a_running_workspace_without_starting_it() { + // A running workspace is the common case and must not pay for the + // wake path. Proven with a provider whose `start` always fails: if + // the resolve path touched it, this would error. + let data_root = unique_data_root("running-workspace"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + .append_query_results([vec![row_with(PUBLIC_ID, "workspace", "running")]]) + .into_connection(); + + let provider = FakeProvider { + fail_start: true, + ..FakeProvider::new() + }; + let (service, _) = build_service(db, provider, data_root.clone()); + let (row, _) = service + .resolve_id(PUBLIC_ID, 1) + .await + .expect("a running workspace resolves without a provider start"); + assert_eq!(row.status, "running"); + let _ = std::fs::remove_dir_all(&data_root); + } + + #[tokio::test] + async fn resolve_id_surfaces_a_failed_wake_instead_of_swallowing_it() { + // A workspace that silently fails to wake and then reports + // "not found" on every later call is exactly the dead end a + // self-hosted user can't debug. The provider error must reach them. + let data_root = unique_data_root("wake-fails"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + .append_query_results([vec![row_with(PUBLIC_ID, "workspace", "stopped")]]) + .into_connection(); + + let provider = FakeProvider { + fail_start: true, + ..FakeProvider::new() + }; + let (service, _) = build_service(db, provider, data_root.clone()); + let err = service + .resolve_id(PUBLIC_ID, 1) + .await + .expect_err("a provider start failure must not be swallowed"); + + let msg = err.to_string(); + assert!( + msg.contains("daemon unreachable"), + "the provider's reason must reach the caller: {}", + msg + ); + let _ = std::fs::remove_dir_all(&data_root); + } + + // ── Workspace-from-project (ADR-036 §5) ────────────────────────────── + + fn project_row(git_url: Option<&str>) -> projects::Model { + let now = Utc::now(); + projects::Model { + id: 12, + name: "acme-api".into(), + repo_name: "api".into(), + repo_owner: "acme".into(), + directory: String::new(), + main_branch: "main".into(), + preset: temps_entities::preset::Preset::NextJs, + preset_config: None, + deployment_config: None, + created_at: now, + updated_at: now, + slug: "acme-api".into(), + is_deleted: false, + deleted_at: None, + last_deployment: None, + is_public_repo: true, + git_url: git_url.map(str::to_string), + git_provider_connection_id: Some(3), + attack_mode: false, + ai_alert_summaries_enabled: None, + ai_debug_chat_enabled: None, + ai_write_actions_enabled: false, + error_source_context_enabled: false, + error_source_root: None, + enable_preview_environments: false, + preview_envs_on_demand: false, + preview_envs_idle_timeout_seconds: 0, + preview_envs_wake_timeout_seconds: 0, + source_type: Default::default(), + template_slug: None, + gitlab_webhook_id: None, + gitlab_webhook_signing_token: None, + gitea_webhook_signing_token: None, + bitbucket_webhook_token: None, + bitbucket_webhook_hook_id: None, + generic_webhook_token: None, + cross_project_trace_sharing: false, + } + } + + #[tokio::test] + async fn source_from_project_uses_the_projects_repo_branch_and_connection() { + let data_root = unique_data_root("project-source-ok"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + .append_query_results([vec![project_row(Some("https://github.com/acme/api.git"))]]) + .into_connection(); + + let (service, _) = build_service(db, FakeProvider::new(), data_root.clone()); + let source = service + .source_from_project(12) + .await + .expect("a connected project yields a git source"); + + match source { + SandboxSource::Git { + url, + revision, + depth, + git_connection_id, + username, + password, + } => { + assert_eq!(url, "https://github.com/acme/api.git"); + assert_eq!(revision.as_deref(), Some("main")); + assert!( + depth.is_none(), + "a workspace gets full history — you cannot rebase in a shallow clone" + ); + assert_eq!(git_connection_id, Some(3)); + assert!( + username.is_none() && password.is_none(), + "credentials must resolve server-side from the connection, \ + never be materialised here" + ); + } + other => panic!("expected a git source, got {:?}", other), + } + let _ = std::fs::remove_dir_all(&data_root); + } + + #[tokio::test] + async fn source_from_project_errors_when_the_project_has_no_repo() { + let data_root = unique_data_root("project-no-repo"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + .append_query_results([vec![project_row(None)]]) + .into_connection(); + + let (service, _) = build_service(db, FakeProvider::new(), data_root.clone()); + let err = service + .source_from_project(12) + .await + .expect_err("a project with no git_url cannot seed a workspace"); + + match err { + SandboxError::ProjectHasNoRepo { project_id, name } => { + assert_eq!(project_id, 12); + assert_eq!(name, "acme-api"); + } + other => panic!("expected ProjectHasNoRepo, got {:?}", other), + } + let _ = std::fs::remove_dir_all(&data_root); + } + + #[tokio::test] + async fn source_from_project_errors_when_the_project_is_missing() { + let data_root = unique_data_root("project-missing"); + let db = MockDatabase::new(DatabaseBackend::Postgres) + .append_query_results([Vec::::new()]) + .into_connection(); + + let (service, _) = build_service(db, FakeProvider::new(), data_root.clone()); + let err = service + .source_from_project(999) + .await + .expect_err("a missing project is a 404, not a silent empty workspace"); + + assert!(matches!( + err, + SandboxError::ProjectNotFound { project_id: 999 } + )); + let _ = std::fs::remove_dir_all(&data_root); + } + #[tokio::test] async fn destroy_sandbox_removes_the_work_dir() { let data_root = unique_data_root("destroy-ok"); diff --git a/crates/temps-sandbox/tests/vercel_compat.rs b/crates/temps-sandbox/tests/vercel_compat.rs index 98df44638..084c25f2c 100644 --- a/crates/temps-sandbox/tests/vercel_compat.rs +++ b/crates/temps-sandbox/tests/vercel_compat.rs @@ -378,6 +378,9 @@ fn sandbox_response_matches_sdk_envelope() { preview_url_template: String::new(), preview_password_hint: None, agent_run_id: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, }, routes: Vec::new(), }; @@ -453,6 +456,9 @@ fn sandbox_status_uses_sdk_enum_values() { preview_url_template: String::new(), preview_password_hint: None, agent_run_id: None, + lifecycle: "ephemeral".to_string(), + project_id: None, + source_repo_url: None, }, routes: Vec::new(), }; diff --git a/web/src/components/sandboxes/CreateSandboxDocs.tsx b/web/src/components/sandboxes/CreateSandboxDocs.tsx index c7a047416..d45c4a39e 100644 --- a/web/src/components/sandboxes/CreateSandboxDocs.tsx +++ b/web/src/components/sandboxes/CreateSandboxDocs.tsx @@ -31,6 +31,26 @@ bunx @temps-sdk/cli sandbox exec sbx_abc123 -- node --version # Remove the sandbox when done (aliases: \`stop\`, \`destroy\`) bunx @temps-sdk/cli sandbox rm sbx_abc123` +const WORKSPACE_EXAMPLE = `# A persistent workspace on one of your projects' repos. +# It suspends when idle and wakes on the next command — nothing +# is destroyed until you ask for it. +bunx @temps-sdk/cli sandbox create --workspace --project 12 --name my-workspace + +# ...or on any repo you can reach +bunx @temps-sdk/cli sandbox create --workspace \\ + --git-url https://github.com/org/repo.git \\ + --git-connection 3 + +# Come back days later — this wakes it automatically +bunx @temps-sdk/cli sandbox exec sbx_abc123 -- git status + +# The image ships claude, codex, opencode, gh and glab. Supply your +# own key at create time until credential injection lands (ADR-036). +bunx @temps-sdk/cli sandbox create --workspace --project 12 \\ + -e ANTHROPIC_API_KEY=sk-ant-... + +bunx @temps-sdk/cli sandbox list --workspace` + const REST_EXAMPLE = `# Create curl -X POST https://your-temps-instance.com/v1/sandbox \\ -H "Authorization: Bearer $TEMPS_API_TOKEN" \\ @@ -94,6 +114,7 @@ export function CreateSandboxDocs({ variant = 'full' }: CreateSandboxDocsProps) CLI + Workspace REST SDK @@ -108,6 +129,16 @@ export function CreateSandboxDocs({ variant = 'full' }: CreateSandboxDocsProps)

+ +

+ A workspace is a sandbox you keep. It still + suspends after its idle timeout so it doesn't hold memory on the + host, but the next command wakes it automatically and your files + are exactly as you left them. Nothing deletes it until you run{' '} + sandbox rm. +

+ +

Authenticate with a personal access token (create one under{' '} From 4218af1625c53dcfff3a3df2aad61e41cbe32968 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 15:05:02 +0200 Subject: [PATCH 03/12] feat(cli): resolve workspace source from project, repo, or local checkout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `sandbox create` previously accepted only a raw `--git-url` plus a numeric `--git-connection`, so creating a workspace meant looking up an ID in another command first. Every piece needed to do better already existed and was used elsewhere in the CLI — this wires it up for sandboxes. Resolution order, first match wins: explicit `--git-url`/`--tarball-url`, then `--repo owner/name` (a connected repo with no temps project), then `--project ` or the project linked in `.temps/config.json`, then the git remote of the current directory, then interactive pickers. In a linked checkout `sandbox create --workspace` now needs no flags at all. - `--project` takes a slug, not a numeric ID, resolved through the same `resolveProjectSlug` chain as every other command. It took an ID when first added, which was inconsistent with the rest of the CLI. - `--repo owner/name` resolves the clone URL and connection off a git provider, so private repos clone without the caller handling a token. - `--branch ` (alias of `--git-rev`) and `--new-branch `, which branches after the clone and reports non-fatally if git refuses. - Prompts are gated on a TTY; in CI the error names the flag that would have avoided the prompt instead of hanging. - Create output shows which source was chosen and how it was worked out — inference is only trustworthy when it's visible. Also adds schema-level coverage for the ADR-036 migration against a real Postgres: pre-existing rows default to ephemeral, `lifecycle` is NOT NULL with the right default, both partial indexes carry their predicates, and `down` fully reverses. --- apps/temps-cli/src/commands/sandbox/index.ts | 120 +++++-- .../commands/sandbox/workspace-source.test.ts | 111 ++++++ .../src/commands/sandbox/workspace-source.ts | 330 ++++++++++++++++++ crates/temps-migrations/src/lib.rs | 1 + crates/temps-migrations/src/migration/mod.rs | 2 +- .../tests/sandbox_workspace_lifecycle_test.rs | 236 +++++++++++++ .../sandboxes/CreateSandboxDocs.tsx | 30 +- 7 files changed, 796 insertions(+), 34 deletions(-) create mode 100644 apps/temps-cli/src/commands/sandbox/workspace-source.test.ts create mode 100644 apps/temps-cli/src/commands/sandbox/workspace-source.ts create mode 100644 crates/temps-migrations/tests/sandbox_workspace_lifecycle_test.rs diff --git a/apps/temps-cli/src/commands/sandbox/index.ts b/apps/temps-cli/src/commands/sandbox/index.ts index a0ef795dc..eceb53a8a 100644 --- a/apps/temps-cli/src/commands/sandbox/index.ts +++ b/apps/temps-cli/src/commands/sandbox/index.ts @@ -16,6 +16,10 @@ import { warning, keyValue, } from '../../ui/output.js' +import { + resolveWorkspaceSource, + resolveProjectIdBySlug, +} from './workspace-source.js' // ── Types mirroring /v1/sandbox/* responses ───────────────────────────────── @@ -227,8 +231,17 @@ export function registerSandboxCommands(program: Command): void { 'Create a persistent workspace: suspends when idle, wakes automatically on the next command, and is never destroyed for you', ) .option( - '--project ', - "Seed the work dir from a temps project's connected repo (and attribute the sandbox to it)", + '--project ', + "Seed from a temps project's connected repo (and attribute the sandbox to it). Defaults to the linked project in .temps/config.json", + ) + .option( + '--repo ', + 'Seed from a repo on one of your git connections that has no temps project', + ) + .option('--branch ', 'Branch, tag, or SHA to check out (alias of --git-rev)') + .option( + '--new-branch ', + 'Create and switch to a new branch after cloning, based on whatever was checked out', ) .option( '--preview-password', @@ -249,7 +262,7 @@ export function registerSandboxCommands(program: Command): void { .option('--page-size ', 'Items per page (default 20, max 100)') .option('--workspace', 'Show only persistent workspaces') .option('--lifecycle ', 'Filter by lifecycle class: ephemeral | workspace') - .option('--project ', 'Show only sandboxes created from this project') + .option('--project ', 'Show only sandboxes created from this project') .option('--json', 'Output as JSON') .action(listAction) @@ -387,6 +400,9 @@ interface CreateOptions { previewPasswordLength?: string workspace?: boolean project?: string + repo?: string + branch?: string + newBranch?: string json?: boolean } @@ -472,18 +488,29 @@ async function createAction(options: CreateOptions): Promise { if (options.cpuLimit !== undefined) body.cpu_limit = Number(options.cpuLimit) if (options.memoryMb !== undefined) body.memory_limit_mb = Number(options.memoryMb) if (options.workspace) body.lifecycle = 'workspace' - if (options.project !== undefined) { - const projectId = Number(options.project) - if (!Number.isInteger(projectId)) { - throw new Error('--project must be a numeric project ID') - } - body.project_id = projectId - } - // An explicit --git-url/--tarball-url wins over the project's repo, - // matching the server: --project is a convenience default, not a lock. - const source = buildSource(options) - if (source) body.source = source + // A workspace always needs code, so resolve one even when no source flag + // was passed — that's the whole point of `sandbox create --workspace` in + // a linked checkout. A plain sandbox stays empty unless asked, so it + // never turns into an interactive command. + const wantsSource = + options.workspace || + options.repo !== undefined || + options.project !== undefined || + options.gitUrl !== undefined || + options.tarballUrl !== undefined + + let origin: string | undefined + if (wantsSource) { + const resolved = await resolveWorkspaceSource(options) + if (resolved.projectId !== undefined) body.project_id = resolved.projectId + if (resolved.source) body.source = resolved.source + origin = resolved.origin + } else { + // Preserves the "--git-* without --git-url" guard for stray flags. + const source = buildSource(options) + if (source) body.source = source + } // Preview-password generation happens client-side so the plaintext // exists only on this machine: the server stores just an argon2 hash @@ -501,13 +528,41 @@ async function createAction(options: CreateOptions): Promise { body.preview_password = generatedPassword } - const sbx = await withSpinner('Creating sandbox...', () => - apiRequest(api, '', { - method: 'POST', - body: JSON.stringify(body), - }), + const sbx = await withSpinner( + options.workspace ? 'Creating workspace...' : 'Creating sandbox...', + () => + apiRequest(api, '', { + method: 'POST', + body: JSON.stringify(body), + }), ) + // Branch creation is a post-clone step: the server seeds the work dir at + // whatever ref was requested, then we branch off it. Non-fatal — the + // workspace exists and is usable either way, so report and carry on + // rather than leaving the user with a sandbox they think failed. + let newBranchError: string | undefined + if (options.newBranch) { + try { + const res = await apiRequest( + api, + `/${encodeURIComponent(sbx.id)}/exec`, + { + method: 'POST', + body: JSON.stringify({ + cmd: ['git', 'checkout', '-b', options.newBranch], + cwd: sbx.work_dir, + }), + }, + ) + if (res.exit_code !== 0) { + newBranchError = res.stderr.trim() || `git exited ${res.exit_code}` + } + } catch (e) { + newBranchError = e instanceof Error ? e.message : String(e) + } + } + if (options.json) { // In JSON mode the generated plaintext is part of the payload so // scripts can capture it in one call. Caller is responsible for @@ -525,9 +580,26 @@ async function createAction(options: CreateOptions): Promise { keyValue('Image', sbx.image ?? '(default)') keyValue('Work dir', sbx.work_dir) keyValue(createdWorkspace ? 'Suspends at' : 'Expires', sbx.expires_at) - if (sbx.source_repo_url) { + // `origin` says where the code came from *and how we worked that out* + // (flag, linked project, this directory's remote) — the inference is + // only trustworthy if it's visible. + if (origin) { + keyValue('Source', origin) + } else if (sbx.source_repo_url) { keyValue('Repo', sbx.source_repo_url) } + if (options.newBranch && !newBranchError) { + keyValue('Branch', `${options.newBranch} (created)`) + } + if (newBranchError) { + newline() + warning( + `Workspace created, but creating branch '${options.newBranch}' failed: ${newBranchError}`, + ) + info( + `Retry inside it: temps sandbox exec ${sbx.id} -- git checkout -b ${options.newBranch}`, + ) + } if (createdWorkspace) { newline() info( @@ -633,7 +705,13 @@ async function listAction(options: ListOptions): Promise { // given, the explicit one wins rather than silently conflicting. const lifecycle = options.lifecycle ?? (options.workspace ? 'workspace' : undefined) if (lifecycle) qs.push(`lifecycle=${encodeURIComponent(lifecycle)}`) - if (options.project) qs.push(`project_id=${encodeURIComponent(options.project)}`) + // Slug in, numeric id out — the filter is on `sandboxes.project_id`, but + // every other `--project` in this CLI takes a slug and users shouldn't + // have to know which is which. + if (options.project) { + const projectId = await resolveProjectIdBySlug(options.project) + qs.push(`project_id=${projectId}`) + } const path = qs.length ? `?${qs.join('&')}` : '' const data = await withSpinner('Fetching sandboxes...', () => diff --git a/apps/temps-cli/src/commands/sandbox/workspace-source.test.ts b/apps/temps-cli/src/commands/sandbox/workspace-source.test.ts new file mode 100644 index 000000000..99c4dcd28 --- /dev/null +++ b/apps/temps-cli/src/commands/sandbox/workspace-source.test.ts @@ -0,0 +1,111 @@ +import { describe, expect, test } from 'bun:test' + +import { resolveWorkspaceSource } from './workspace-source.js' + +/** + * Only the branches that resolve without touching the network or a TTY: + * the explicit `--git-url` / `--tarball-url` paths and the argument + * validation that must fire before any lookup. The project / --repo / + * inference branches need a live API and are covered by the server-side + * tests plus manual verification. + */ +describe('resolveWorkspaceSource', () => { + test('an explicit git url passes straight through', async () => { + const resolved = await resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + branch: 'feature/x', + }) + expect(resolved.source).toEqual({ + type: 'git', + url: 'https://github.com/org/repo.git', + revision: 'feature/x', + }) + expect(resolved.projectId).toBeUndefined() + expect(resolved.origin).toContain('feature/x') + }) + + test('--git-rev still works as an alias for --branch', async () => { + const resolved = await resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + gitRev: 'v1.2.3', + }) + expect(resolved.source?.revision).toBe('v1.2.3') + }) + + test('--branch wins over --git-rev when both are given', async () => { + const resolved = await resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + branch: 'main', + gitRev: 'v1.2.3', + }) + expect(resolved.source?.revision).toBe('main') + }) + + test('a git connection id is forwarded so private repos clone', async () => { + const resolved = await resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/private.git', + gitConnection: '7', + }) + expect(resolved.source?.git_connection_id).toBe(7) + }) + + test('a tarball url resolves without any git lookup', async () => { + const resolved = await resolveWorkspaceSource({ + tarballUrl: 'https://example.com/snapshot.tar.gz', + }) + expect(resolved.source).toEqual({ + type: 'tarball', + url: 'https://example.com/snapshot.tar.gz', + }) + }) + + test('git and tarball sources are mutually exclusive', async () => { + await expect( + resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + tarballUrl: 'https://example.com/snapshot.tar.gz', + }), + ).rejects.toThrow('mutually exclusive') + }) + + test('a connection and inline credentials are mutually exclusive', async () => { + await expect( + resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + gitConnection: '7', + gitUsername: 'x-access-token', + gitPassword: 'ghp_secret', + }), + ).rejects.toThrow('mutually exclusive') + }) + + test('inline credentials must be given as a pair', async () => { + await expect( + resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + gitUsername: 'x-access-token', + }), + ).rejects.toThrow('must be provided together') + }) + + test('a non-positive depth is rejected before the sandbox is created', async () => { + await expect( + resolveWorkspaceSource({ + gitUrl: 'https://github.com/org/repo.git', + gitDepth: '0', + }), + ).rejects.toThrow('positive integer') + }) + + // The point of --repo is that it takes what people read off a repo page. + // A bare name or a full URL are the two things they'll actually type, and + // both must say what to do instead rather than 404 against the provider. + test.each(['repo', 'https://github.com/org/repo', 'org/repo/extra'])( + 'rejects --repo %p with guidance', + async (value) => { + await expect(resolveWorkspaceSource({ repo: value })).rejects.toThrow( + 'owner/name', + ) + }, + ) +}) diff --git a/apps/temps-cli/src/commands/sandbox/workspace-source.ts b/apps/temps-cli/src/commands/sandbox/workspace-source.ts new file mode 100644 index 000000000..cad7e1f18 --- /dev/null +++ b/apps/temps-cli/src/commands/sandbox/workspace-source.ts @@ -0,0 +1,330 @@ +/** + * Works out *what code* a workspace sandbox should start from. + * + * `sandbox create` originally took only raw `--git-url` + a numeric + * `--git-connection`, which meant looking up an ID in another command + * before you could create anything. Every other part of the CLI already + * knows how to resolve this — `resolveProjectSlug` reads `.temps/`, the + * git-connection helpers offer pickers, and `detect-project` reads the + * local checkout. This module wires those together for sandboxes. + * + * Resolution order, first match wins: + * + * 1. `--git-url` / `--tarball-url` — explicit, no lookups. The escape + * hatch for anything the server can reach. + * 2. `--repo owner/name` — a repo on one of your git connections that + * has no temps project. Resolves the clone URL and connection so + * private repos work without handling a token. + * 3. `--project `, or a project resolved from `.temps/config.json` + * / `$TEMPS_PROJECT` / the active context. + * 4. The git remote of the current directory. + * 5. Interactive pickers (connection → repo → branch). + * + * Step 5 is skipped when stdin isn't a TTY, and the error then names the + * exact flag to pass instead of hanging on a prompt nothing can answer. + */ +import { client, getErrorMessage, setupClient } from '../../lib/api-client.js' +import { getProjectBySlug } from '../../api/sdk.gen.js' +import type { RepositoryResponse } from '../../api/types.gen.js' +import { + selectGitConnection, + selectRepository, + selectBranch, + findRepositoryByName, +} from '../../lib/git-connection.js' +import { resolveProjectSlug } from '../../config/resolve-project.js' +import { detectGitRemote, detectGitBranch } from '../../lib/detect-project.js' +import { info, colors } from '../../ui/output.js' + +export interface WorkspaceSourceOptions { + project?: string + repo?: string + branch?: string + gitUrl?: string + gitRev?: string + gitDepth?: string + gitConnection?: string + gitUsername?: string + gitPassword?: string + tarballUrl?: string +} + +export interface ResolvedWorkspaceSource { + /** Sent as `project_id`; the server derives repo + credential from it. */ + projectId?: number + /** Sent as `source`; wins over `projectId` server-side. */ + source?: Record + /** One line describing what was resolved and how, for the user. */ + origin: string +} + +/** + * Slug → numeric project id, for the places the API keys on the id. + * Shared with `sandbox list --project` so both accept the same thing. + */ +export async function resolveProjectIdBySlug(slug: string): Promise { + await setupClient() + const { data, error } = await getProjectBySlug({ client, path: { slug } }) + if (error || !data) { + throw new Error( + `Project "${slug}" not found${error ? `: ${getErrorMessage(error)}` : ''}`, + ) + } + return data.id +} + +/** `owner/name`, rejecting the near-misses people actually type. */ +function parseRepoFlag(value: string): { owner: string; name: string } { + const parts = value.split('/').filter((p) => p.length > 0) + if (parts.length !== 2) { + throw new Error( + `--repo must be "owner/name" (got "${value}"). ` + + 'For a URL that isn\'t on a connected git provider, use --git-url instead.', + ) + } + return { owner: parts[0]!, name: parts[1]! } +} + +function parseConnectionFlag(value: string): number { + const id = Number(value) + if (!Number.isInteger(id) || id <= 0) { + throw new Error('--git-connection must be a positive integer') + } + return id +} + +/** + * Prompts are only reachable on a TTY. In CI or a piped shell, inquirer + * would either hang or throw something opaque, so fail early with the + * flag that would have avoided the prompt. + */ +function requireInteractive(what: string, flagHint: string): void { + if (!process.stdin.isTTY) { + throw new Error( + `Cannot prompt for ${what} — stdin is not a TTY. Pass ${flagHint} explicitly.`, + ) + } +} + +/** Resolve the connection to use, prompting only if we must. */ +async function resolveConnectionId( + options: WorkspaceSourceOptions, + why: string, +): Promise { + if (options.gitConnection !== undefined) { + return parseConnectionFlag(options.gitConnection) + } + // Inline credentials are an alternative to a connection, not a companion. + if (options.gitUsername || options.gitPassword) return undefined + + requireInteractive(why, '--git-connection ') + const connection = await selectGitConnection() + return connection?.id +} + +function gitSource( + url: string, + revision: string | undefined, + connectionId: number | undefined, + options: WorkspaceSourceOptions, +): Record { + const source: Record = { type: 'git', url } + if (revision) source.revision = revision + if (connectionId !== undefined) source.git_connection_id = connectionId + if (options.gitUsername) source.username = options.gitUsername + if (options.gitPassword) source.password = options.gitPassword + if (options.gitDepth !== undefined) { + const depth = Number(options.gitDepth) + if (!Number.isInteger(depth) || depth <= 0) { + throw new Error('--git-depth must be a positive integer') + } + source.depth = depth + } + return source +} + +/** The ref to check out: `--branch` preferred, `--git-rev` kept as an alias. */ +function requestedRef(options: WorkspaceSourceOptions): string | undefined { + return options.branch ?? options.gitRev +} + +function cloneUrlFor(repository: RepositoryResponse): string { + // SSH URLs can't be cloned inside the sandbox — there's no key in there. + // The connection's token drives HTTPS Basic auth instead. + const url = repository.clone_url + if (!url) { + throw new Error( + `Repository ${repository.full_name} has no HTTPS clone URL on this connection. ` + + 'Pass --git-url with an https:// URL instead.', + ) + } + return url +} + +export async function resolveWorkspaceSource( + options: WorkspaceSourceOptions, +): Promise { + // The sandbox commands talk to /v1/sandbox with their own fetch wrapper, + // so the generated SDK client used by the project and git-connection + // lookups below hasn't been configured yet. Idempotent. + await setupClient() + + const ref = requestedRef(options) + + // 1. Explicit URLs — no lookups, no prompts. + if (options.tarballUrl) { + if (options.gitUrl) { + throw new Error('--git-url and --tarball-url are mutually exclusive') + } + return { + source: { type: 'tarball', url: options.tarballUrl }, + origin: `tarball ${options.tarballUrl}`, + } + } + if (options.gitUrl) { + const connectionId = + options.gitConnection !== undefined + ? parseConnectionFlag(options.gitConnection) + : undefined + if ((options.gitUsername || options.gitPassword) && connectionId !== undefined) { + throw new Error( + '--git-connection is mutually exclusive with --git-username/--git-password', + ) + } + if ( + (options.gitUsername && !options.gitPassword) || + (!options.gitUsername && options.gitPassword) + ) { + throw new Error('--git-username and --git-password must be provided together') + } + return { + source: gitSource(options.gitUrl, ref, connectionId, options), + origin: `${options.gitUrl}${ref ? ` @ ${ref}` : ''}`, + } + } + + // 2. `--repo owner/name` — a connected repo with no temps project. + if (options.repo) { + const { owner, name } = parseRepoFlag(options.repo) + const connectionId = await resolveConnectionId( + options, + `the git connection hosting ${options.repo}`, + ) + if (connectionId === undefined) { + throw new Error( + `No git connection available to resolve ${options.repo}. ` + + 'Connect a provider with `temps providers add`, or pass --git-url.', + ) + } + const repository = await findRepositoryByName(connectionId, owner, name) + if (!repository) { + throw new Error( + `Repository ${owner}/${name} not found on git connection ${connectionId}. ` + + 'Check the spelling, or run `temps providers repos sync` if it was added recently.', + ) + } + const revision = ref ?? repository.default_branch + return { + source: gitSource(cloneUrlFor(repository), revision, connectionId, options), + origin: `${repository.full_name} @ ${revision}`, + } + } + + // 3. A temps project, named or inferred from the working directory. + const resolvedProject = await resolveProjectSlug(options.project) + if (resolvedProject) { + const { data, error } = await getProjectBySlug({ + client, + path: { slug: resolvedProject.slug }, + }) + if (error || !data) { + // An explicit --project that doesn't resolve is a hard error; an + // inherited one (from .temps or a context default) may just be + // stale, so fall through to the remaining strategies. + if (options.project) { + throw new Error( + `Project "${resolvedProject.slug}" not found: ${error ? getErrorMessage(error) : 'no such project'}`, + ) + } + } else if (data.git_url) { + const via = + resolvedProject.source === 'flag' + ? '' + : ` (from ${resolvedProject.source.replace('-', ' ')})` + // Without a ref override, hand the server `project_id` and let it + // derive repo + branch + credential — one less thing to get wrong + // here, and the sandbox stays attributed to the project. + if (!ref) { + return { + projectId: data.id, + origin: `project ${colors.bold(resolvedProject.slug)} @ ${data.main_branch}${via}`, + } + } + // With a ref override we must build the source ourselves, but keep + // the attribution so the workspace still lists under the project. + return { + projectId: data.id, + source: gitSource( + data.git_url, + ref, + data.git_provider_connection_id ?? undefined, + options, + ), + origin: `project ${colors.bold(resolvedProject.slug)} @ ${ref}${via}`, + } + } else if (options.project) { + throw new Error( + `Project "${resolvedProject.slug}" has no git repository connected. ` + + 'Pass --repo owner/name or --git-url to choose the code yourself.', + ) + } + } + + // 4. The git remote of the current directory. + const remote = detectGitRemote() + if (remote) { + const revision = ref ?? detectGitBranch() ?? undefined + const connectionId = options.gitConnection + ? parseConnectionFlag(options.gitConnection) + : undefined + info( + `Using the git remote of this directory: ${colors.bold(`${remote.owner}/${remote.repo}`)}`, + ) + // Prefer the connection's own clone URL when the repo is connected — + // it's the one the server can authenticate. Falls back to the raw + // remote, which is fine for public repos. + if (connectionId !== undefined) { + const repository = await findRepositoryByName(connectionId, remote.owner, remote.repo) + if (repository) { + return { + source: gitSource(cloneUrlFor(repository), revision, connectionId, options), + origin: `${repository.full_name} @ ${revision ?? repository.default_branch}`, + } + } + } + const httpsUrl = `https://${remote.host}/${remote.owner}/${remote.repo}.git` + return { + source: gitSource(httpsUrl, revision, connectionId, options), + origin: `${remote.owner}/${remote.repo}${revision ? ` @ ${revision}` : ''}`, + } + } + + // 5. Nothing to infer — pick it interactively. + requireInteractive('a repository', '--repo owner/name, --project , or --git-url ') + const connection = await selectGitConnection() + if (!connection) { + throw new Error( + 'No git connections available. Run `temps providers add` to connect a provider, ' + + 'or pass --git-url to clone a public repo.', + ) + } + const repository = await selectRepository(connection.id) + if (!repository) { + throw new Error('No repository selected.') + } + const revision = ref ?? (await selectBranch(connection.id, repository)) + return { + source: gitSource(cloneUrlFor(repository), revision, connection.id, options), + origin: `${repository.full_name} @ ${revision}`, + } +} diff --git a/crates/temps-migrations/src/lib.rs b/crates/temps-migrations/src/lib.rs index 037bc59d5..df6e78b6d 100644 --- a/crates/temps-migrations/src/lib.rs +++ b/crates/temps-migrations/src/lib.rs @@ -10,4 +10,5 @@ mod migration; // Re-export for convenience // Re-export removed pub use migration::m20260805_000001_index_normalized_managed_domains::Migration as NormalizedManagedDomainIndexMigration; +pub use migration::m20260806_000001_sandbox_workspace_lifecycle::Migration as SandboxWorkspaceLifecycleMigration; pub use migration::Migrator; diff --git a/crates/temps-migrations/src/migration/mod.rs b/crates/temps-migrations/src/migration/mod.rs index 1d3a87b71..9ad65cdd3 100644 --- a/crates/temps-migrations/src/migration/mod.rs +++ b/crates/temps-migrations/src/migration/mod.rs @@ -175,7 +175,7 @@ mod m20260803_000002_add_step_up_expires_at_to_sessions; mod m20260804_000001_add_ai_data_access_to_external_services; mod m20260804_000001_add_must_change_password_to_users; pub mod m20260805_000001_index_normalized_managed_domains; -mod m20260806_000001_sandbox_workspace_lifecycle; +pub mod m20260806_000001_sandbox_workspace_lifecycle; pub struct Migrator; diff --git a/crates/temps-migrations/tests/sandbox_workspace_lifecycle_test.rs b/crates/temps-migrations/tests/sandbox_workspace_lifecycle_test.rs new file mode 100644 index 000000000..8c0606202 --- /dev/null +++ b/crates/temps-migrations/tests/sandbox_workspace_lifecycle_test.rs @@ -0,0 +1,236 @@ +//! Schema-level coverage for the ADR-036 workspace lifecycle migration. +//! +//! Three things this pins that a unit test cannot: +//! +//! 1. **Pre-existing rows stay ephemeral.** The whole compatibility story +//! rests on the column default applying to rows the migration didn't +//! write. A row inserted without `lifecycle` must read `'ephemeral'`, +//! not NULL and not an error. +//! 2. **The partial indexes carry the right predicates.** `list_for_user` +//! filters on `lifecycle`/`project_id` expecting index support; an +//! index created over the wrong predicate would still exist and still +//! be silently useless. +//! 3. **`down` is real.** A migration that can't be rolled back strands +//! an operator who upgrades and needs to go back. + +use sea_orm::{ConnectionTrait, Database, DatabaseConnection, Statement, TransactionTrait}; +use sea_orm_migration::{MigrationTrait, MigratorTrait, SchemaManager}; +use temps_migrations::{Migrator, SandboxWorkspaceLifecycleMigration}; +use testcontainers::{runners::AsyncRunner, GenericImage, ImageExt}; + +const LIFECYCLE_INDEX: &str = "idx_sandboxes_lifecycle"; +const PROJECT_INDEX: &str = "idx_sandboxes_project_id"; + +async fn connect_with_retries(database_url: &str) -> anyhow::Result { + let mut retries = 5; + loop { + match Database::connect(database_url).await { + Ok(db) => return Ok(db), + Err(error) if retries > 0 => { + retries -= 1; + tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; + if retries == 0 { + return Err(error.into()); + } + } + Err(error) => return Err(error.into()), + } + } +} + +async fn relation_exists(db: &C, name: &str) -> anyhow::Result +where + C: ConnectionTrait, +{ + let row = db + .query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + format!("SELECT to_regclass('public.{name}') IS NOT NULL AS present"), + )) + .await? + .expect("relation existence query returns one row"); + Ok(row.try_get("", "present")?) +} + +async fn index_definition(db: &C, name: &str) -> anyhow::Result +where + C: ConnectionTrait, +{ + let row = db + .query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + format!("SELECT pg_get_indexdef('{name}'::regclass) AS definition"), + )) + .await? + .expect("index definition query returns one row"); + Ok(row.try_get("", "definition")?) +} + +#[tokio::test] +async fn test_sandbox_workspace_lifecycle_migration_defaults_indexes_and_reverses( +) -> anyhow::Result<()> { + if std::env::var("TEMPS_TEST_DATABASE_URL") + .map(|value| !value.trim().is_empty()) + .unwrap_or(false) + { + eprintln!("Skipping sandbox workspace lifecycle migration test: external database in use"); + return Ok(()); + } + + let container = match GenericImage::new("timescale/timescaledb-ha", "pg18") + .with_env_var("POSTGRES_DB", "postgres") + .with_env_var("POSTGRES_USER", "postgres") + .with_env_var("POSTGRES_PASSWORD", "postgres") + .with_env_var("POSTGRES_HOST_AUTH_METHOD", "trust") + .with_cmd(vec![ + "postgres", + "-c", + "timescaledb.max_background_workers=0", + ]) + .start() + .await + { + Ok(container) => container, + Err(error) => { + eprintln!( + "Skipping sandbox workspace lifecycle migration test: Docker unavailable: {error}" + ); + return Ok(()); + } + }; + let port = container.get_host_port_ipv4(5432).await?; + let database_url = format!("postgresql://postgres:postgres@localhost:{port}/postgres"); + tokio::time::sleep(tokio::time::Duration::from_secs(3)).await; + let db = connect_with_retries(&database_url).await?; + + Migrator::up(&db, None).await?; + + // A row written the way every pre-ADR-036 caller wrote one: no + // lifecycle, no project, no repo. It must come back ephemeral. + db.execute_unprepared( + "INSERT INTO sandboxes \ + (public_id, user_id, name, status, work_dir, timeout_secs, \ + created_at, last_activity_at, expires_at) \ + VALUES \ + ('sbx_legacyrow000001', NULL, 'legacy', 'running', '/workspace', 3600, \ + NOW(), NOW(), NOW() + INTERVAL '1 hour')", + ) + .await?; + let legacy = db + .query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + "SELECT lifecycle, project_id IS NULL AS no_project, \ + source_repo_url IS NULL AS no_repo \ + FROM sandboxes WHERE public_id = 'sbx_legacyrow000001'" + .to_string(), + )) + .await? + .expect("the inserted legacy row is readable"); + assert_eq!( + legacy.try_get::("", "lifecycle")?, + "ephemeral", + "rows written without a lifecycle must default to ephemeral — \ + anything else silently changes the behaviour of existing sandboxes" + ); + assert!(legacy.try_get::("", "no_project")?); + assert!(legacy.try_get::("", "no_repo")?); + + // NOT NULL is what lets `SandboxLifecycle::from_row` read a plain + // String instead of an Option. + let nullability = db + .query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + "SELECT is_nullable, column_default \ + FROM information_schema.columns \ + WHERE table_schema = 'public' AND table_name = 'sandboxes' \ + AND column_name = 'lifecycle'" + .to_string(), + )) + .await? + .expect("lifecycle column metadata query returns one row"); + assert_eq!(nullability.try_get::("", "is_nullable")?, "NO"); + assert!(nullability + .try_get::("", "column_default")? + .contains("ephemeral")); + + assert!(relation_exists(&db, LIFECYCLE_INDEX).await?); + assert!(relation_exists(&db, PROJECT_INDEX).await?); + + // Predicates matter: an index over every row would defeat the point + // of keeping the ephemeral majority out of the workspace queries. + let lifecycle_def = index_definition(&db, LIFECYCLE_INDEX).await?; + assert!( + lifecycle_def.contains("WHERE") && lifecycle_def.contains("ephemeral"), + "lifecycle index must stay partial on non-ephemeral rows; definition was: {lifecycle_def}" + ); + let project_def = index_definition(&db, PROJECT_INDEX).await?; + assert!( + project_def.contains("project_id IS NOT NULL"), + "project index must stay partial on attributed rows; definition was: {project_def}" + ); + + // A workspace row round-trips, including the two new nullable columns. + db.execute_unprepared( + "INSERT INTO sandboxes \ + (public_id, user_id, name, status, work_dir, timeout_secs, \ + created_at, last_activity_at, expires_at, lifecycle, project_id, source_repo_url) \ + VALUES \ + ('sbx_workspacerow0001', NULL, 'ws', 'stopped', '/workspace', 3600, \ + NOW(), NOW(), NOW(), 'workspace', 42, 'https://github.com/org/repo.git')", + ) + .await?; + let workspace = db + .query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + "SELECT lifecycle, project_id, source_repo_url \ + FROM sandboxes WHERE public_id = 'sbx_workspacerow0001'" + .to_string(), + )) + .await? + .expect("the inserted workspace row is readable"); + assert_eq!(workspace.try_get::("", "lifecycle")?, "workspace"); + assert_eq!(workspace.try_get::("", "project_id")?, 42); + assert_eq!( + workspace.try_get::("", "source_repo_url")?, + "https://github.com/org/repo.git" + ); + + // Rolled back in a transaction so the assertions below don't depend on + // dropping columns that still hold the rows inserted above. + let transaction = db.begin().await?; + let manager = SchemaManager::new(&transaction); + SandboxWorkspaceLifecycleMigration.down(&manager).await?; + assert!( + !relation_exists(&transaction, LIFECYCLE_INDEX).await?, + "down must drop the lifecycle index" + ); + assert!( + !relation_exists(&transaction, PROJECT_INDEX).await?, + "down must drop the project index" + ); + let remaining = transaction + .query_one(Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + "SELECT COUNT(*) AS n FROM information_schema.columns \ + WHERE table_schema = 'public' AND table_name = 'sandboxes' \ + AND column_name IN ('lifecycle', 'project_id', 'source_repo_url')" + .to_string(), + )) + .await? + .expect("column count query returns one row"); + assert_eq!( + remaining.try_get::("", "n")?, + 0, + "down must drop all three columns" + ); + + // Re-applying inside the same transaction proves up is replayable + // after a rollback, which is what an operator retrying an upgrade does. + SandboxWorkspaceLifecycleMigration.up(&manager).await?; + SandboxWorkspaceLifecycleMigration.up(&manager).await?; + assert!(relation_exists(&transaction, LIFECYCLE_INDEX).await?); + assert!(relation_exists(&transaction, PROJECT_INDEX).await?); + transaction.rollback().await?; + + Ok(()) +} diff --git a/web/src/components/sandboxes/CreateSandboxDocs.tsx b/web/src/components/sandboxes/CreateSandboxDocs.tsx index d45c4a39e..7ff0d6f55 100644 --- a/web/src/components/sandboxes/CreateSandboxDocs.tsx +++ b/web/src/components/sandboxes/CreateSandboxDocs.tsx @@ -31,23 +31,29 @@ bunx @temps-sdk/cli sandbox exec sbx_abc123 -- node --version # Remove the sandbox when done (aliases: \`stop\`, \`destroy\`) bunx @temps-sdk/cli sandbox rm sbx_abc123` -const WORKSPACE_EXAMPLE = `# A persistent workspace on one of your projects' repos. -# It suspends when idle and wakes on the next command — nothing -# is destroyed until you ask for it. -bunx @temps-sdk/cli sandbox create --workspace --project 12 --name my-workspace +const WORKSPACE_EXAMPLE = `# From a linked checkout, nothing else is needed: the project comes +# from .temps/config.json, the repo and branch from your git remote. +cd ~/code/my-repo +bunx @temps-sdk/cli sandbox create --workspace -# ...or on any repo you can reach +# Name the project explicitly, and start a fresh branch bunx @temps-sdk/cli sandbox create --workspace \\ - --git-url https://github.com/org/repo.git \\ - --git-connection 3 + --project my-api --branch main --new-branch feat/checkout -# Come back days later — this wakes it automatically +# A repo that has no temps project — resolved off your git connection, +# so private repos clone without you handling a token +bunx @temps-sdk/cli sandbox create --workspace --repo acme/internal-tools + +# Any other URL +bunx @temps-sdk/cli sandbox create --workspace \\ + --git-url https://github.com/org/repo.git --branch develop + +# Come back days later — this wakes the workspace automatically bunx @temps-sdk/cli sandbox exec sbx_abc123 -- git status -# The image ships claude, codex, opencode, gh and glab. Supply your -# own key at create time until credential injection lands (ADR-036). -bunx @temps-sdk/cli sandbox create --workspace --project 12 \\ - -e ANTHROPIC_API_KEY=sk-ant-... +# The image ships claude, codex, opencode, gh and glab. Supply your own +# key at create time until credential injection lands (ADR-036). +bunx @temps-sdk/cli sandbox create --workspace -e ANTHROPIC_API_KEY=sk-ant-... bunx @temps-sdk/cli sandbox list --workspace` From 891df04d7e89594ca385c4471fe527bf65a6bad2 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 17:10:07 +0200 Subject: [PATCH 04/12] feat(sandbox): add interactive terminal and `sandbox shell` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completes the ADR-036 workspace story: you can now sit in a sandbox from your own terminal and run claude/codex interactively, not just fire one-shot execs at it. - `SandboxProvider::attach_pty` — a trait method, not direct Docker access, because temps-sandbox must not depend on bollard (ADR-010). Docker implements it via the relay ADR-008 specifies (`docker exec socat - UNIX-CONNECT:/run/temps-pty/agent.sock`); Firecracker and local return an explicit "not supported" rather than a terminal that silently never echoes. - `GET /v1/sandboxes/{id}/terminal` bridges a WebSocket to the agent, using the same frame shape as the container terminal in temps-deployments (binary = PTY bytes, JSON text = control) so an xterm.js client can be added later with no server change. - `temps sandbox shell [--tab] [--cmd]`, with raw-mode stdin, SIGWINCH forwarding, and guaranteed terminal restore on every exit path. Detaching does not kill the program: the agent keeps tabs alive with zero subscribers, so reattaching to the same tab lands back in the same PID with scrollback replayed. Verified against a real sandbox image — a dropped connection then reattach returned `existed: true`, the same pid, and a still-running background job. Also fixes the sweeper/terminal conflict this exposed. Activity was only recorded by exec and filesystem calls, so someone talking to an AI CLI in a terminal looked idle and would have had the container stopped out from under them — killing the agent and every PTY with it, since /run/temps-pty is tmpfs. An attached terminal now heartbeats activity every 20s, bounded below the 60s minimum timeout. And fixes a live bug found on the way: every command in the npm CLI's sandbox group built `/v1/sandbox` (singular) while the server has only ever served `/v1/sandboxes`, so the whole group 404'd against a real instance. The Rust CLI already had the fix and a comment warning about it; this one did not. Now covered by a test. --- Cargo.lock | 3 + apps/temps-cli/bun.lock | 8 +- apps/temps-cli/package.json | 4 +- apps/temps-cli/src/commands/sandbox/index.ts | 35 +- .../src/commands/sandbox/shell.test.ts | 63 +++ apps/temps-cli/src/commands/sandbox/shell.ts | 209 ++++++++ crates/temps-agents/src/sandbox/docker.rs | 95 +++- crates/temps-agents/src/sandbox/mod.rs | 47 ++ crates/temps-agents/src/sandbox/routing.rs | 7 + crates/temps-sandbox/Cargo.toml | 5 + crates/temps-sandbox/src/handlers/mod.rs | 3 + .../temps-sandbox/src/handlers/sandboxes.rs | 6 +- crates/temps-sandbox/src/handlers/terminal.rs | 482 ++++++++++++++++++ .../adr/036-persistent-workspace-sandboxes.md | 16 +- 14 files changed, 971 insertions(+), 12 deletions(-) create mode 100644 apps/temps-cli/src/commands/sandbox/shell.test.ts create mode 100644 apps/temps-cli/src/commands/sandbox/shell.ts create mode 100644 crates/temps-sandbox/src/handlers/terminal.rs diff --git a/Cargo.lock b/Cargo.lock index 5ac4a195a..128510ed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12437,6 +12437,7 @@ dependencies = [ "async-trait", "axum", "base64 0.23.0", + "bytes", "chrono", "flate2", "futures", @@ -12453,9 +12454,11 @@ dependencies = [ "temps-core", "temps-entities", "temps-git", + "temps-pty-agent", "thiserror 2.0.19", "tokio", "tokio-stream", + "tokio-util", "tower 0.5.3", "tracing", "url", diff --git a/apps/temps-cli/bun.lock b/apps/temps-cli/bun.lock index 215a50612..cbf7c2f82 100644 --- a/apps/temps-cli/bun.lock +++ b/apps/temps-cli/bun.lock @@ -8,6 +8,7 @@ "@hey-api/client-fetch": "^0.13.1", "@inquirer/prompts": "^8.0.1", "@inquirer/search": "^4.0.2", + "@types/ws": "^8.18.1", "chalk": "^5.6.2", "cli-table3": "^0.6.5", "commander": "^14.0.2", @@ -16,6 +17,7 @@ "ink-spinner": "^5.0.0", "ora": "^9.0.0", "react": "^19.2.3", + "ws": "^8.21.2", }, "devDependencies": { "@hey-api/openapi-ts": "^0.99.0", @@ -91,6 +93,8 @@ "@types/react": ["@types/react@19.2.9", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], @@ -313,7 +317,7 @@ "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], - "ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "ws": ["ws@8.21.2", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw=="], "wsl-utils": ["wsl-utils@0.3.0", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-3sFIGLiaDP7rTO4xh3g+b3AzhYDIUGGywE/WsmqzJWDxus5aJXVnPTNC/6L+r2WzrwXqVOdD262OaO+cEyPMSQ=="], @@ -389,6 +393,8 @@ "pkg-types/confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], + "react-devtools-core/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], "string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], diff --git a/apps/temps-cli/package.json b/apps/temps-cli/package.json index eaee9f741..ba6aa1f4a 100644 --- a/apps/temps-cli/package.json +++ b/apps/temps-cli/package.json @@ -35,6 +35,7 @@ "@hey-api/client-fetch": "^0.13.1", "@inquirer/prompts": "^8.0.1", "@inquirer/search": "^4.0.2", + "@types/ws": "^8.18.1", "chalk": "^5.6.2", "cli-table3": "^0.6.5", "commander": "^14.0.2", @@ -42,6 +43,7 @@ "ink": "^6.6.0", "ink-spinner": "^5.0.0", "ora": "^9.0.0", - "react": "^19.2.3" + "react": "^19.2.3", + "ws": "^8.21.2" } } diff --git a/apps/temps-cli/src/commands/sandbox/index.ts b/apps/temps-cli/src/commands/sandbox/index.ts index eceb53a8a..c277edc3a 100644 --- a/apps/temps-cli/src/commands/sandbox/index.ts +++ b/apps/temps-cli/src/commands/sandbox/index.ts @@ -20,6 +20,7 @@ import { resolveWorkspaceSource, resolveProjectIdBySlug, } from './workspace-source.js' +import { shellAction } from './shell.js' // ── Types mirroring /v1/sandbox/* responses ───────────────────────────────── @@ -94,8 +95,17 @@ async function auth(): Promise { return { baseUrl, apiKey } } -function sandboxUrl(api: SandboxApi, path: string): string { - return `${api.baseUrl}/v1/sandbox${path}` +/** + * Build the absolute URL for a sandbox API path. + * + * The route is `/v1/sandboxes` — plural. The singular form predates a + * rename and matches nothing on any current server, so every command in + * this group was returning 404 against a real instance. The Rust CLI's + * `sandbox_url` already carried both the fix and the warning; this one + * did not. Covered by a test below so it can't drift back. + */ +export function sandboxUrl(baseUrl: string, path: string): string { + return `${baseUrl.replace(/\/+$/, '')}/v1/sandboxes${path}` } async function apiRequest( @@ -109,7 +119,7 @@ async function apiRequest( headers.set('Content-Type', 'application/json') } - const response = await fetch(sandboxUrl(api, path), { ...init, headers }) + const response = await fetch(sandboxUrl(api.baseUrl, path), { ...init, headers }) if (!response.ok) { throw await readApiError(response) @@ -309,6 +319,23 @@ export function registerSandboxCommands(program: Command): void { .option('--tarball-url ', 'Tarball URL to download and extract') .action(cloneAction) + sandbox + .command('shell ') + .alias('attach') + .description( + 'Open an interactive terminal in a sandbox. Detaching leaves the program running — reattach with the same --tab', + ) + .option( + '--tab ', + 'Tab to attach to; reusing a name reattaches to the program already running in it', + 'main', + ) + .option( + '--cmd ', + 'Program to start when the tab is created, e.g. "claude" (default: login shell)', + ) + .action(shellAction) + sandbox .command('extend ') .description("Extend a sandbox's idle timeout") @@ -950,7 +977,7 @@ async function logsAction(id: string, jobId: string): Promise { const api = await auth() const response = await fetch( - sandboxUrl(api, `/${encodeURIComponent(id)}/jobs/${encodeURIComponent(jobId)}/logs`), + sandboxUrl(api.baseUrl, `/${encodeURIComponent(id)}/jobs/${encodeURIComponent(jobId)}/logs`), { headers: { Authorization: `Bearer ${api.apiKey}`, diff --git a/apps/temps-cli/src/commands/sandbox/shell.test.ts b/apps/temps-cli/src/commands/sandbox/shell.test.ts new file mode 100644 index 000000000..d1ec06cc6 --- /dev/null +++ b/apps/temps-cli/src/commands/sandbox/shell.test.ts @@ -0,0 +1,63 @@ +import { describe, expect, test } from 'bun:test' + +import { sandboxUrl } from './index.js' +import { terminalWsUrl } from './shell.js' + +describe('sandboxUrl', () => { + // This is the regression guard for a real bug: every command in this + // group built `/v1/sandbox` (singular) while the server has only ever + // served `/v1/sandboxes`, so they all 404'd against a live instance. + test('uses the plural route the server actually serves', () => { + expect(sandboxUrl('https://temps.example.com/api', '')).toBe( + 'https://temps.example.com/api/v1/sandboxes', + ) + expect(sandboxUrl('https://temps.example.com/api', '/sbx_abc')).toBe( + 'https://temps.example.com/api/v1/sandboxes/sbx_abc', + ) + }) + + test('tolerates trailing slashes on the configured API URL', () => { + expect(sandboxUrl('https://temps.example.com/api/', '/sbx_abc')).toBe( + 'https://temps.example.com/api/v1/sandboxes/sbx_abc', + ) + expect(sandboxUrl('https://temps.example.com/api///', '')).toBe( + 'https://temps.example.com/api/v1/sandboxes', + ) + }) +}) + +describe('terminalWsUrl', () => { + test('upgrades https to wss', () => { + const url = terminalWsUrl('https://temps.example.com/api', 'sbx_abc', {}) + expect(url).toBe('wss://temps.example.com/api/v1/sandboxes/sbx_abc/terminal') + }) + + test('upgrades http to ws for local instances', () => { + const url = terminalWsUrl('http://localhost:8080/api', 'sbx_abc', {}) + expect(url).toBe('ws://localhost:8080/api/v1/sandboxes/sbx_abc/terminal') + }) + + test('appends only the params that were provided', () => { + const url = terminalWsUrl('https://x.test/api', 'sbx_a', { + tab: 'main', + cmd: undefined, + cols: '120', + rows: '', + }) + expect(url).toBe( + 'wss://x.test/api/v1/sandboxes/sbx_a/terminal?tab=main&cols=120', + ) + }) + + test('encodes params so a command with spaces survives', () => { + const url = terminalWsUrl('https://x.test/api', 'sbx_a', { + cmd: 'claude --resume', + }) + expect(url).toContain('cmd=claude%20--resume') + }) + + test('encodes the sandbox id rather than trusting it', () => { + const url = terminalWsUrl('https://x.test/api', 'sbx a/b', {}) + expect(url).toBe('wss://x.test/api/v1/sandboxes/sbx%20a%2Fb/terminal') + }) +}) diff --git a/apps/temps-cli/src/commands/sandbox/shell.ts b/apps/temps-cli/src/commands/sandbox/shell.ts new file mode 100644 index 000000000..30dd66313 --- /dev/null +++ b/apps/temps-cli/src/commands/sandbox/shell.ts @@ -0,0 +1,209 @@ +/** + * `temps sandbox shell` — an interactive terminal in a sandbox, in your own + * terminal. + * + * Connects to `GET /v1/sandboxes/{id}/terminal`, which bridges to the + * in-sandbox PTY agent (ADR-008). The agent keeps the tab alive with zero + * subscribers, so this is a *reattachable* session: disconnecting — Ctrl-D, + * a dropped network, closing your laptop — leaves whatever is running in + * there running. Reconnect to the same `--tab` and you land back in it, + * with recent scrollback replayed. + * + * That is what makes `temps sandbox shell ID --cmd claude` practical: the + * agent survives your connection, so a long-running AI session isn't tied + * to your laptop staying awake. + * + * Caveat worth knowing: suspension is not disconnection. The PTY lives in + * the container's tmpfs, so if the sandbox is stopped (idle sweep, restart) + * every tab is gone. While you're attached the server heartbeats activity + * to keep the idle sweep away, so this only bites if you disconnect and + * leave it idle past the timeout. + */ +import WebSocket from 'ws' + +import { requireAuth, credentials, config } from '../../config/store.js' +import { normalizeApiUrl } from '../../lib/api-client.js' +import { colors, info, newline, warning } from '../../ui/output.js' +import { sandboxUrl } from './index.js' + +export interface ShellOptions { + tab?: string + cmd?: string +} + +/** + * Turn the HTTP API base into the WebSocket URL for a sandbox terminal. + * + * `https` → `wss` (and `http` → `ws`); anything else is left alone so a + * caller who already passed a `ws://` URL isn't second-guessed. + */ +export function terminalWsUrl( + baseUrl: string, + id: string, + params: Record, +): string { + const http = sandboxUrl(baseUrl, `/${encodeURIComponent(id)}/terminal`) + const ws = http.replace(/^http:/, 'ws:').replace(/^https:/, 'wss:') + const query = Object.entries(params) + .filter(([, v]) => v !== undefined && v !== '') + .map(([k, v]) => `${k}=${encodeURIComponent(v as string)}`) + .join('&') + return query ? `${ws}?${query}` : ws +} + +/** Current terminal size, falling back to a sane default when not a TTY. */ +function terminalSize(): { cols: number; rows: number } { + return { + cols: process.stdout.columns || 80, + rows: process.stdout.rows || 24, + } +} + +export async function shellAction( + id: string, + options: ShellOptions, +): Promise { + await requireAuth() + const apiKey = await credentials.getApiKey() + if (!apiKey) { + throw new Error('Not authenticated. Run `temps login` first.') + } + if (!process.stdin.isTTY) { + throw new Error( + 'sandbox shell needs an interactive terminal. ' + + 'For scripted commands use: temps sandbox exec ' + + id + + ' -- ', + ) + } + + const baseUrl = normalizeApiUrl(config.get('apiUrl')) + const { cols, rows } = terminalSize() + const url = terminalWsUrl(baseUrl, id, { + tab: options.tab, + cmd: options.cmd, + cols: String(cols), + rows: String(rows), + }) + + // The token goes in a header, never the query string: URLs end up in + // proxy logs and shell history, and this one is a live credential. + const socket = new WebSocket(url, { + headers: { Authorization: `Bearer ${apiKey}` }, + }) + + await runSession(socket, id, options) +} + +function runSession( + socket: WebSocket, + id: string, + options: ShellOptions, +): Promise { + return new Promise((resolve, reject) => { + let rawModeEngaged = false + let exitCode = 0 + let settled = false + + // Every exit path goes through here. Leaving the terminal in raw mode + // is the classic failure of this kind of tool — the user's shell is + // then silently broken and needs `reset`. + const restore = () => { + if (rawModeEngaged && process.stdin.isTTY) { + process.stdin.setRawMode(false) + rawModeEngaged = false + } + process.stdin.pause() + process.stdin.removeListener('data', onStdin) + process.stdout.removeListener('resize', onResize) + } + + const finish = (err?: Error) => { + if (settled) return + settled = true + restore() + if (err) reject(err) + else resolve() + } + + const onStdin = (chunk: Buffer) => { + if (socket.readyState === WebSocket.OPEN) { + socket.send(chunk) + } + } + + const onResize = () => { + if (socket.readyState !== WebSocket.OPEN) return + const { cols, rows } = terminalSize() + socket.send(JSON.stringify({ type: 'resize', cols, rows })) + } + + socket.on('open', () => { + process.stdin.setRawMode(true) + rawModeEngaged = true + process.stdin.resume() + process.stdin.on('data', onStdin) + process.stdout.on('resize', onResize) + }) + + socket.on('message', (data: Buffer, isBinary: boolean) => { + if (isBinary) { + process.stdout.write(data) + return + } + // Text frames are control events, not terminal output — writing them + // to stdout would splatter JSON into the user's session. + let event: { type?: string; code?: number; message?: string } + try { + event = JSON.parse(data.toString()) + } catch { + return + } + if (event.type === 'exit') { + exitCode = event.code ?? 0 + socket.close() + } else if (event.type === 'error') { + restore() + newline() + warning(`Terminal error: ${event.message ?? 'unknown'}`) + } + // 'ready' needs no output: the shell's own prompt is the signal, and + // announcing it would corrupt a reattached screen's replayed state. + }) + + socket.on('error', (err: Error) => { + finish( + new Error( + `Could not open a terminal in ${id}: ${err.message}. ` + + 'Check the sandbox exists and is reachable with: temps sandbox show ' + + id, + ), + ) + }) + + socket.on('close', (code: number, reason: Buffer) => { + restore() + // 1000/1005/1006 are ordinary closes (clean, no-status, and the + // "abnormal" code browsers use for a dropped TCP connection). Only a + // genuine protocol-level failure is worth reporting as an error. + if (code !== 1000 && code !== 1005 && code !== 1006) { + const detail = reason.toString().trim() + finish( + new Error( + `Terminal closed unexpectedly (code ${code})${detail ? `: ${detail}` : ''}`, + ), + ) + return + } + newline() + info( + `Detached from ${colors.primary(id)} (tab ${options.tab ?? 'main'}). ` + + 'Anything running in it keeps running — reattach with the same command.', + ) + if (exitCode !== 0) { + process.exitCode = exitCode + } + finish() + }) + }) +} diff --git a/crates/temps-agents/src/sandbox/docker.rs b/crates/temps-agents/src/sandbox/docker.rs index c446bb0a7..a1df84f96 100644 --- a/crates/temps-agents/src/sandbox/docker.rs +++ b/crates/temps-agents/src/sandbox/docker.rs @@ -9,8 +9,8 @@ use std::sync::Arc; use super::user::{SANDBOX_CHOWN, SANDBOX_HOME, SANDBOX_UID, SANDBOX_USER, SANDBOX_WORK_DIR}; use super::{ - ExecStream, OnStreamEventCallback, SandboxCreateConfig, SandboxExecResult, SandboxHandle, - SandboxProvider, + ExecStream, OnStreamEventCallback, PtyAttachment, SandboxCreateConfig, SandboxExecResult, + SandboxHandle, SandboxProvider, PTY_AGENT_SOCKET, }; use crate::ai_cli::OnEventCallback; use crate::error::AgentError; @@ -2315,6 +2315,97 @@ impl SandboxProvider for DockerSandboxProvider { } } + /// Bridge to the in-sandbox PTY agent, exactly as ADR-008 §Host-side + /// Bridge specifies: a `docker exec` running `socat` that relays the + /// exec's stdio to the agent's unix socket. + /// + /// Nothing long-lived runs inside this exec — `socat` exits when its + /// stdin closes, and the exec dies with it. The only persistent + /// in-container process is the agent itself, which is what keeps a + /// `claude` session alive across a dropped connection. + /// + /// Runs as `SANDBOX_USER` because the socket is mode 0600 owned by that + /// user. Executing as root would work but would break the "same trust + /// boundary as the sandbox user" property the ADR relies on. + async fn attach_pty(&self, handle: &SandboxHandle) -> Result { + let exec_failed = |reason: String| AgentError::SandboxExecFailed { + run_id: 0, + sandbox_id: handle.sandbox_id.clone(), + reason, + }; + + let exec_config = bollard::models::ExecConfig { + attach_stdin: Some(true), + attach_stdout: Some(true), + attach_stderr: Some(true), + // No `tty: true` here. The PTY lives *inside* the agent; this + // exec is a plain binary pipe carrying framed protocol bytes. + // Asking Docker for a TTY would mangle them with ONLCR. + tty: Some(false), + cmd: Some(vec![ + "socat".to_string(), + "-".to_string(), + format!("UNIX-CONNECT:{}", PTY_AGENT_SOCKET), + ]), + user: Some(SANDBOX_USER.to_string()), + ..Default::default() + }; + + let exec = self + .docker + .create_exec(&handle.sandbox_id, exec_config) + .await + .map_err(|e| exec_failed(format!("failed to create PTY attach exec: {}", e)))?; + + let started = self + .docker + .start_exec( + &exec.id, + Some(bollard::exec::StartExecOptions { + detach: false, + ..Default::default() + }), + ) + .await + .map_err(|e| exec_failed(format!("failed to start PTY attach exec: {}", e)))?; + + match started { + StartExecResults::Attached { output, input } => { + let sandbox_id = handle.sandbox_id.clone(); + // Docker frames the exec's stdout/stderr; the agent's bytes + // arrive as StdOut. StdErr here is socat complaining (e.g. + // the socket is missing because the image predates the + // agent), which must surface as an error rather than be + // silently mixed into the protocol stream. + let output = output.map(move |chunk| match chunk { + Ok(LogOutput::StdOut { message }) => Ok(message), + Ok(LogOutput::Console { message }) => Ok(message), + Ok(LogOutput::StdErr { message }) => Err(AgentError::SandboxExecFailed { + run_id: 0, + sandbox_id: sandbox_id.clone(), + reason: format!( + "PTY agent relay error: {}", + String::from_utf8_lossy(&message).trim() + ), + }), + Ok(LogOutput::StdIn { .. }) => Ok(bytes::Bytes::new()), + Err(e) => Err(AgentError::SandboxExecFailed { + run_id: 0, + sandbox_id: sandbox_id.clone(), + reason: format!("PTY attach stream failed: {}", e), + }), + }); + Ok(PtyAttachment { + output: Box::pin(output), + input, + }) + } + StartExecResults::Detached => Err(exec_failed( + "PTY attach exec returned detached; expected an attached stream".to_string(), + )), + } + } + async fn recover(&self, run_id: i32) -> Result, AgentError> { let container_name = Self::container_name(run_id); self.recover_container(&container_name).await diff --git a/crates/temps-agents/src/sandbox/mod.rs b/crates/temps-agents/src/sandbox/mod.rs index d19cc2c6c..f97c4ec88 100644 --- a/crates/temps-agents/src/sandbox/mod.rs +++ b/crates/temps-agents/src/sandbox/mod.rs @@ -30,12 +30,14 @@ pub use user::{ }; use async_trait::async_trait; +use futures::Stream; use std::collections::HashMap; use std::future::Future; use std::path::PathBuf; use std::pin::Pin; use std::sync::Arc; use std::time::Duration; +use tokio::io::AsyncWrite; use crate::ai_cli::OnEventCallback; use crate::error::AgentError; @@ -251,6 +253,29 @@ pub struct SandboxExecResult { pub stderr: String, } +/// A live bidirectional byte channel into a sandbox's PTY agent. +/// +/// Returned by [`SandboxProvider::attach_pty`]. The two halves are separate +/// so a caller can split them across tasks — a terminal needs to pump both +/// directions concurrently, which a single `AsyncRead + AsyncWrite` object +/// makes awkward behind `dyn`. +/// +/// The bytes are `temps-pty-agent`'s framed protocol (see ADR-008), not raw +/// PTY output. Framing is the caller's job; the provider only moves bytes. +pub struct PtyAttachment { + /// Frames from the agent. Ends when the underlying exec exits. + pub output: Pin> + Send>>, + /// Frames to the agent. Dropping this closes the agent-side stdin, + /// which makes the in-container relay exit and the attach terminate. + pub input: Pin>, +} + +/// Absolute path of the PTY agent's control socket inside every sandbox. +/// +/// Fixed by the sandbox Dockerfile (`RUN mkdir -p /run/temps-pty …`), so it +/// is a property of the image rather than something a caller chooses. +pub const PTY_AGENT_SOCKET: &str = "/run/temps-pty/agent.sock"; + /// Pluggable sandbox backend. Implementations provide container/VM isolation /// for agent runs. The executor and autofixer interact only with this trait, /// never with Docker or any specific backend directly. @@ -527,6 +552,28 @@ pub trait SandboxProvider: Send + Sync { true } + /// Open a bidirectional channel to the sandbox's PTY agent (ADR-008). + /// + /// Powers interactive terminals: the caller speaks the agent's framed + /// protocol over the returned stream to open a tab, send keystrokes, + /// forward resizes, and receive output. + /// + /// Default: unsupported. Backends that can't reach an in-sandbox unix + /// socket say so explicitly rather than returning an empty stream that + /// looks like a terminal which simply never echoes — a user facing that + /// has no way to tell "not implemented" from "my shell is broken". + async fn attach_pty(&self, handle: &SandboxHandle) -> Result { + let _ = handle; + Err(AgentError::SandboxExecFailed { + run_id: 0, + sandbox_id: String::new(), + reason: format!( + "interactive terminals are not supported by sandbox provider '{}'", + self.name() + ), + }) + } + /// Provider name for logging and error messages. fn name(&self) -> &str; diff --git a/crates/temps-agents/src/sandbox/routing.rs b/crates/temps-agents/src/sandbox/routing.rs index 631c983c0..3d5b44ca8 100644 --- a/crates/temps-agents/src/sandbox/routing.rs +++ b/crates/temps-agents/src/sandbox/routing.rs @@ -198,6 +198,13 @@ impl SandboxProvider for RoutingSandboxProvider { self.owner_of(handle).restart(handle).await } + /// Delegate to whichever backend owns this sandbox. Without this the + /// trait's default would fire and report "not supported by provider + /// 'routing'" even for a Docker sandbox that supports it perfectly well. + async fn attach_pty(&self, handle: &SandboxHandle) -> Result { + self.owner_of(handle).attach_pty(handle).await + } + async fn resize_disk( &self, handle: &SandboxHandle, diff --git a/crates/temps-sandbox/Cargo.toml b/crates/temps-sandbox/Cargo.toml index d4753a0fa..dcc066b6f 100644 --- a/crates/temps-sandbox/Cargo.toml +++ b/crates/temps-sandbox/Cargo.toml @@ -14,6 +14,9 @@ temps-auth = { path = "../temps-auth" } temps-agents = { path = "../temps-agents" } temps-config = { path = "../temps-config" } temps-git = { path = "../temps-git" } +# Frame codec for the in-sandbox PTY agent (ADR-008). Library half only — +# the binary is built into the sandbox image, not linked here. +temps-pty-agent = { path = "../temps-pty-agent" } base64 = { workspace = true } sea-orm = { workspace = true } tokio = { workspace = true } @@ -31,6 +34,8 @@ argon2 = { workspace = true } hex = "0.4" url = { workspace = true } tokio-stream = { version = "0.1.17", features = ["sync"] } +tokio-util = { workspace = true, features = ["io"] } +bytes = { workspace = true } futures = { workspace = true } async-stream = { workspace = true } flate2 = { workspace = true } diff --git a/crates/temps-sandbox/src/handlers/mod.rs b/crates/temps-sandbox/src/handlers/mod.rs index 90a28e117..ecbe5be69 100644 --- a/crates/temps-sandbox/src/handlers/mod.rs +++ b/crates/temps-sandbox/src/handlers/mod.rs @@ -3,6 +3,7 @@ //! No business logic lives here. pub mod sandboxes; +pub mod terminal; pub mod version_header; use std::sync::Arc; @@ -69,6 +70,7 @@ pub struct SandboxAppState { sandboxes::list_events, sandboxes::rootfs_report, sandboxes::rootfs_gc, + terminal::terminal, ), components(schemas( sandboxes::CreateSandboxBody, @@ -161,6 +163,7 @@ mod tests { "/v1/sandboxes/{id}/preview-link", "/v1/sandboxes/{id}/events", "/v1/sandboxes/{id}/resize", + "/v1/sandboxes/{id}/terminal", "/v1/sandboxes/rootfs", "/v1/sandboxes/rootfs/gc", ] { diff --git a/crates/temps-sandbox/src/handlers/sandboxes.rs b/crates/temps-sandbox/src/handlers/sandboxes.rs index be39749a2..2c56e998c 100644 --- a/crates/temps-sandbox/src/handlers/sandboxes.rs +++ b/crates/temps-sandbox/src/handlers/sandboxes.rs @@ -63,7 +63,7 @@ fn require_sandbox_admin(auth: &temps_auth::context::AuthContext) -> Result<(), ) } -fn sandbox_permission_guard( +pub(crate) fn sandbox_permission_guard( auth: &temps_auth::context::AuthContext, primary: Permission, fallback: Permission, @@ -2477,6 +2477,10 @@ pub fn routes() -> Router> { .route("/v1/sandboxes/rootfs", get(rootfs_report)) .route("/v1/sandboxes/rootfs/gc", post(rootfs_gc)) .route("/v1/sandboxes/{id}", get(get_sandbox)) + .route( + "/v1/sandboxes/{id}/terminal", + get(crate::handlers::terminal::terminal), + ) .route("/v1/sandboxes/{id}/stop", post(stop_sandbox)) .route("/v1/sandboxes/{id}/destroy", post(destroy_sandbox)) .route("/v1/sandboxes/{id}/events", get(list_events)) diff --git a/crates/temps-sandbox/src/handlers/terminal.rs b/crates/temps-sandbox/src/handlers/terminal.rs new file mode 100644 index 000000000..ebbcd94e3 --- /dev/null +++ b/crates/temps-sandbox/src/handlers/terminal.rs @@ -0,0 +1,482 @@ +//! Interactive terminal for a sandbox: `GET /v1/sandboxes/{id}/terminal`. +//! +//! Bridges a browser/CLI WebSocket to the in-sandbox `temps-pty-agent` +//! (ADR-008). The agent owns the PTY and keeps it alive with zero +//! subscribers, so dropping this connection does **not** kill whatever is +//! running in the tab — closing your laptop mid-`claude` and reattaching +//! later resumes the same session, with a replay of recent scrollback. +//! +//! # Protocol on the wire +//! +//! Deliberately the same shape `temps-deployments`' container terminal +//! already speaks, so one xterm.js client works against both: +//! +//! - **Binary frames** — raw PTY bytes, both directions. +//! - **Text frames (client → server)** — JSON control: +//! `{"type":"resize","cols":N,"rows":N}` +//! - **Text frames (server → client)** — JSON events: +//! `{"type":"ready","tab_id":"…","existed":bool}` once the tab is open, +//! `{"type":"exit","code":N}` when the program exits, +//! `{"type":"error","message":"…"}` for anything that went wrong. +//! +//! The agent's own framed protocol is terminated here rather than passed +//! through, so clients don't need to implement it. +//! +//! # Why the heartbeat exists +//! +//! The expiration sweeper suspends a sandbox that has been idle for +//! `timeout_secs`, and "activity" is otherwise only recorded by exec and +//! filesystem calls. Someone sitting in a terminal talking to an AI CLI +//! makes neither — so without the periodic `touch` below, the sweeper would +//! stop the container out from under a live session, killing the agent and +//! every PTY with it (`/run/temps-pty` is tmpfs). An attached terminal is +//! activity; this is what makes that true. + +use std::sync::Arc; +use std::time::Duration; + +use axum::{ + extract::{ + ws::{Message, WebSocket, WebSocketUpgrade}, + Path, State, + }, + http::StatusCode, + response::IntoResponse, +}; +use futures::{SinkExt, StreamExt}; +use serde::{Deserialize, Serialize}; +use temps_auth::{permissions::Permission, RequireAuth}; +use temps_core::problemdetails::{self, Problem}; +use temps_pty_agent::protocol as pty; +use tokio::io::AsyncWriteExt; +use tokio_util::io::StreamReader; +use utoipa::ToSchema; + +use super::sandboxes::sandbox_permission_guard; +use super::SandboxAppState; + +/// How often an attached terminal reports activity. Comfortably inside the +/// 60s minimum `timeout_secs` so even the shortest-lived sandbox can't be +/// swept while someone is typing in it. +const ACTIVITY_HEARTBEAT: Duration = Duration::from_secs(20); + +/// Scrollback replayed on attach. Matches the agent's default ring size — +/// asking for more just gets clamped agent-side. +const REPLAY_BYTES: u32 = 64 * 1024; + +/// Query parameters for the terminal upgrade. +#[derive(Debug, Deserialize, ToSchema)] +pub struct TerminalParams { + /// Which tab to attach to. Re-using a tab id reattaches to the running + /// program instead of starting a second one — that is how a `claude` + /// session survives a disconnect. Defaults to `"main"`. + #[serde(default)] + pub tab: Option, + /// Program to run when the tab is created. Ignored when the tab already + /// exists. Defaults to an interactive login shell. + #[serde(default)] + pub cmd: Option, + /// Initial terminal width in columns. Defaults to 80. + #[serde(default)] + pub cols: Option, + /// Initial terminal height in rows. Defaults to 24. + #[serde(default)] + pub rows: Option, +} + +/// Client → server control message on a text frame. +#[derive(Debug, Deserialize)] +#[serde(tag = "type", rename_all = "lowercase")] +enum ClientControl { + Resize { cols: u16, rows: u16 }, +} + +/// Server → client event on a text frame. +#[derive(Debug, Serialize)] +#[serde(tag = "type", rename_all = "lowercase")] +enum ServerEvent<'a> { + Ready { + tab_id: &'a str, + existed: bool, + }, + Exit { + code: Option, + signal: Option, + }, + Error { + message: String, + }, +} + +fn default_shell_cmd() -> String { + // Login shell so ~/.bashrc runs and the AI CLIs are on PATH. The image + // seeds PATH there precisely because non-login shells miss them. + "/bin/bash -l".to_string() +} + +/// Attach an interactive terminal to a sandbox. +#[utoipa::path( + tag = "Sandboxes", + get, + path = "/v1/sandboxes/{id}/terminal", + params( + ("id" = String, Path, description = "Sandbox public ID"), + ("tab" = Option, Query, description = "Tab to attach to (default \"main\"); reusing an id reattaches to the running program"), + ("cmd" = Option, Query, description = "Program to launch when the tab is created (default: login shell)"), + ("cols" = Option, Query, description = "Initial columns (default 80)"), + ("rows" = Option, Query, description = "Initial rows (default 24)"), + ), + responses( + (status = 101, description = "WebSocket established; PTY attached"), + (status = 401, description = "Unauthorized"), + (status = 403, description = "Insufficient permissions"), + (status = 404, description = "Sandbox not found"), + (status = 409, description = "Sandbox is not in a state that can be attached to"), + ), + security(("bearer_auth" = [])) +)] +pub async fn terminal( + RequireAuth(auth): RequireAuth, + State(state): State>, + Path(id): Path, + axum::extract::Query(params): axum::extract::Query, + ws: WebSocketUpgrade, +) -> Result { + sandbox_permission_guard(&auth, Permission::SandboxesWrite, Permission::ProjectsWrite)?; + + // Resolve *before* the upgrade so ownership failures, a missing sandbox, + // or a stopped ephemeral one surface as a real HTTP status instead of a + // WebSocket that opens and immediately dies. This also wakes a suspended + // workspace (ADR-036), which is exactly what should happen when someone + // opens a terminal on it. + let (row, internal_id) = state + .sandbox_service + .resolve_id(&id, auth.user_id()) + .await?; + + let handle = state + .sandbox_service + .registry() + .get(internal_id, &id) + .await + .map_err(|e| { + let err = crate::services::sandbox_service::SandboxService::provider_err(&id, e); + Problem::from(err) + })?; + + let attachment = state + .sandbox_service + .registry() + .provider() + .attach_pty(&handle) + .await + .map_err(|e| { + // Most likely cause on a real deployment: a sandbox created from + // a custom image that doesn't carry the PTY agent. Say so, rather + // than leaving the user with a terminal that never echoes. + problemdetails::new(StatusCode::CONFLICT) + .with_title("Terminal Unavailable") + .with_detail(format!( + "Could not attach a terminal to sandbox {}: {}. \ + Interactive terminals need the temps PTY agent, which \ + ships in the default sandbox image.", + id, e + )) + })?; + + let service = state.sandbox_service.clone(); + let timeout_secs = row.timeout_secs; + let tab = params.tab.unwrap_or_else(|| "main".to_string()); + let cmd = params.cmd.unwrap_or_else(default_shell_cmd); + let cols = params.cols.unwrap_or(80); + let rows = params.rows.unwrap_or(24); + let work_dir = row.work_dir.clone(); + + Ok(ws.on_upgrade(move |socket| async move { + let session = TerminalSession { + socket, + attachment, + service, + sandbox_id: id, + internal_id, + timeout_secs, + tab, + cmd, + cols, + rows, + work_dir, + }; + session.run().await; + })) +} + +struct TerminalSession { + socket: WebSocket, + attachment: temps_agents::sandbox::PtyAttachment, + service: Arc, + sandbox_id: String, + internal_id: i32, + timeout_secs: i32, + tab: String, + cmd: String, + cols: u16, + rows: u16, + work_dir: String, +} + +impl TerminalSession { + async fn run(self) { + let TerminalSession { + socket, + attachment, + service, + sandbox_id, + internal_id, + timeout_secs, + tab, + cmd, + cols, + rows, + work_dir, + } = self; + + let (mut ws_tx, mut ws_rx) = socket.split(); + let mut agent_in = attachment.input; + + // Map the provider's typed errors into io::Error so the frame reader + // can consume the stream. The message is preserved — it's what the + // user sees if the relay dies. + let agent_bytes = attachment + .output + .map(|chunk| chunk.map_err(|e| std::io::Error::other(e.to_string()))); + let mut agent_out = StreamReader::new(agent_bytes); + + // OPEN the tab. Reattaches when it already exists, which is what + // makes a long-running CLI survive disconnection. + let open = pty::OpenRequest { + tab_id: tab.clone(), + kind: "shell".to_string(), + cmd, + cols, + rows, + replay_bytes: REPLAY_BYTES, + label: Some(tab.clone()), + cwd: Some(work_dir), + env: None, + }; + if let Err(e) = pty::write_json_frame(&mut agent_in, pty::OP_OPEN, &open).await { + send_error(&mut ws_tx, format!("failed to open terminal tab: {}", e)).await; + return; + } + + tracing::info!( + "Terminal attached to sandbox {} (internal {}), tab '{}'", + sandbox_id, + internal_id, + tab + ); + + let mut heartbeat = tokio::time::interval(ACTIVITY_HEARTBEAT); + // The first tick fires immediately: attaching is itself activity, and + // it means a sandbox seconds from expiry is rescued on connect. + heartbeat.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + + loop { + tokio::select! { + // Keep the sweeper honest while someone is attached. + _ = heartbeat.tick() => { + service.touch(internal_id, timeout_secs).await; + } + + // Agent → client. + frame = pty::read_frame(&mut agent_out) => { + match frame { + Ok(Some((op, payload))) => { + if !forward_agent_frame(&mut ws_tx, op, payload).await { + break; + } + } + // Clean EOF: the relay exited (container stopped, or + // the agent went away). Nothing more to read. + Ok(None) => break, + Err(e) => { + send_error(&mut ws_tx, format!("terminal stream failed: {}", e)).await; + break; + } + } + } + + // Client → agent. + msg = ws_rx.next() => { + match msg { + Some(Ok(Message::Binary(data))) => { + if pty::write_frame(&mut agent_in, pty::OP_INPUT, &data).await.is_err() { + break; + } + } + Some(Ok(Message::Text(text))) => { + if !handle_client_control(&mut agent_in, &text).await { + break; + } + } + Some(Ok(Message::Close(_))) | None => break, + Some(Ok(Message::Ping(_) | Message::Pong(_))) => {} + Some(Err(_)) => break, + } + } + } + } + + // DETACH rather than KILL: the tab and its program stay alive for the + // next attach. This is the whole point — a dropped connection must + // not cost the user their session. + let _ = pty::write_frame(&mut agent_in, pty::OP_DETACH, &[]).await; + let _ = agent_in.shutdown().await; + let _ = ws_tx.close().await; + + // One last activity record so a sandbox isn't swept moments after a + // long session ends. + service.touch(internal_id, timeout_secs).await; + + tracing::debug!( + "Terminal detached from sandbox {}, tab '{}'", + sandbox_id, + tab + ); + } +} + +/// Translate one agent frame onto the WebSocket. Returns false when the +/// session should end. +async fn forward_agent_frame( + ws_tx: &mut futures::stream::SplitSink, + op: u8, + payload: Vec, +) -> bool { + match op { + pty::OP_OUTPUT => ws_tx.send(Message::Binary(payload.into())).await.is_ok(), + pty::OP_OPENED => { + let opened: Option = serde_json::from_slice(&payload).ok(); + let (tab_id, existed) = opened + .as_ref() + .map(|o| (o.tab_id.as_str(), o.existed)) + .unwrap_or(("", false)); + send_event(ws_tx, ServerEvent::Ready { tab_id, existed }).await + } + pty::OP_EXIT => { + let exit: Option = serde_json::from_slice(&payload).ok(); + let (code, signal) = exit.map(|e| (e.code, e.signal)).unwrap_or((None, None)); + send_event(ws_tx, ServerEvent::Exit { code, signal }).await; + // The program is gone; nothing left to relay. + false + } + pty::OP_ERROR => { + let err: Option = serde_json::from_slice(&payload).ok(); + let message = err + .map(|e| format!("{}: {}", e.code, e.message)) + .unwrap_or_else(|| "terminal agent reported an error".to_string()); + send_event(ws_tx, ServerEvent::Error { message }).await; + false + } + // TABS/PONG are for clients that enumerate or ping; this endpoint + // drives a single tab, so they're not interesting. Ignore rather + // than error — a newer agent may send frames we don't know yet. + _ => true, + } +} + +/// Apply a client control message. Returns false when the session should end. +async fn handle_client_control( + agent_in: &mut std::pin::Pin>, + text: &str, +) -> bool { + match serde_json::from_str::(text) { + Ok(ClientControl::Resize { cols, rows }) => { + let payload = pty::encode_resize(cols, rows); + pty::write_frame(agent_in, pty::OP_RESIZE, &payload) + .await + .is_ok() + } + // An unparsable control message is a client bug, not a reason to + // drop someone's shell. Ignore it and keep going. + Err(e) => { + tracing::debug!("Ignoring unparsable terminal control message: {}", e); + true + } + } +} + +async fn send_event( + ws_tx: &mut futures::stream::SplitSink, + event: ServerEvent<'_>, +) -> bool { + match serde_json::to_string(&event) { + Ok(text) => ws_tx.send(Message::Text(text.into())).await.is_ok(), + Err(_) => true, + } +} + +async fn send_error(ws_tx: &mut futures::stream::SplitSink, message: String) { + tracing::warn!("Sandbox terminal error: {}", message); + send_event(ws_tx, ServerEvent::Error { message }).await; + let _ = ws_tx.close().await; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn default_shell_is_a_login_shell() { + // Non-login shells don't source ~/.bashrc, and that's where the image + // puts claude/codex/opencode on PATH. Losing the `-l` makes every AI + // CLI mysteriously "not found" inside the terminal. + assert!(default_shell_cmd().contains("-l")); + } + + #[test] + fn heartbeat_stays_inside_the_shortest_idle_window() { + // MIN_TIMEOUT_SECS is 60. A heartbeat at or above that would let the + // sweeper stop a sandbox between two beats of a live session. + assert!(ACTIVITY_HEARTBEAT.as_secs() < 60); + // ...and not so chatty that an idle terminal hammers the database. + assert!(ACTIVITY_HEARTBEAT.as_secs() >= 5); + } + + #[test] + fn client_resize_control_parses() { + let parsed: ClientControl = + serde_json::from_str(r#"{"type":"resize","cols":120,"rows":40}"#).expect("resize"); + match parsed { + ClientControl::Resize { cols, rows } => { + assert_eq!(cols, 120); + assert_eq!(rows, 40); + } + } + } + + #[test] + fn server_events_are_tagged_for_xterm_clients() { + let ready = serde_json::to_string(&ServerEvent::Ready { + tab_id: "main", + existed: true, + }) + .expect("serialize"); + assert!(ready.contains(r#""type":"ready""#), "{}", ready); + assert!(ready.contains(r#""existed":true"#), "{}", ready); + + let exit = serde_json::to_string(&ServerEvent::Exit { + code: Some(0), + signal: None, + }) + .expect("serialize"); + assert!(exit.contains(r#""type":"exit""#), "{}", exit); + } + + #[test] + fn replay_request_is_bounded() { + // The agent clamps this, but sending an absurd value would be a + // pointless round trip. 64 KiB matches the agent's ring size. + assert_eq!(REPLAY_BYTES, 64 * 1024); + } +} diff --git a/docs/adr/036-persistent-workspace-sandboxes.md b/docs/adr/036-persistent-workspace-sandboxes.md index 40a9d71d0..21a4b2908 100644 --- a/docs/adr/036-persistent-workspace-sandboxes.md +++ b/docs/adr/036-persistent-workspace-sandboxes.md @@ -73,12 +73,21 @@ Wake latency is a container start, not a create: the image is local, the volumes Explicit `source` always wins over the project-derived one — the project is a convenience default, not an override. -### 6. Out of scope for this ADR's first phase +### 6. Interactive terminal, and why it must heartbeat -Two follow-ups, deliberately separated because each is its own reviewable change: +`GET /v1/sandboxes/{id}/terminal` upgrades to a WebSocket bridged to the in-sandbox PTY agent (ADR-008), via a new `SandboxProvider::attach_pty` — a trait method rather than direct Docker access, because `temps-sandbox` must not depend on `bollard` (ADR-010, enforced by `scripts/check-provider-boundary.sh`). `temps sandbox shell ` is the client. + +The agent keeps a tab alive with zero subscribers, so disconnecting does not kill the program in it. Reattaching to the same tab returns `existed: true` for the same PID with recent scrollback replayed — which is what makes `--cmd claude` viable across a closed laptop. + +**Suspension is the exception, and it forces a design constraint.** `/run/temps-pty` is tmpfs and the agent dies with the container, so a suspend destroys every tab. Combined with §3, that creates a trap: activity is otherwise recorded only by exec and filesystem calls, and someone sitting in a terminal talking to an AI CLI makes neither. Without intervention the sweeper would stop the container out from under a live session. + +So an attached terminal is itself activity: the handler calls `touch` on connect, every 20s while attached, and once more on detach. The interval is bounded below the 60s minimum `timeout_secs` so no sandbox can be swept between two beats. + +### 7. Out of scope for this ADR -- **Interactive terminal on `/v1/sandboxes/{id}/terminal`.** The in-sandbox half exists (`temps-pty-agent` + `dtach`, ADR-008); the host-side handler does not exist in this repo. Building it requires a new PTY-attach method on the `SandboxProvider` trait, because `temps-sandbox` must not depend on `bollard` (ADR-010, enforced by `scripts/check-provider-boundary.sh`). Until then, workspaces are driven through `exec` and the CLI. - **AI CLI credential injection at create.** The CLIs are installed in the image; the credential catalog and injector (`crates/temps-agents/src/ai_cli/`, `services/sandbox_injector.rs`) are currently wired only to agent runs. Until that is extended, users supply their own key via the existing create-time `env` map. +- **A browser terminal.** The WebSocket protocol is deliberately the same shape `temps-deployments`' container terminal already speaks (binary frames for PTY bytes, JSON text frames for control), so an xterm.js client can be added against the same endpoint without server changes. +- **Terminals on non-Docker backends.** `attach_pty` defaults to an explicit "not supported" error; Firecracker and the local dev provider return it. A sandbox on those backends is still fully usable through `exec`. ## Consequences @@ -95,6 +104,7 @@ Two follow-ups, deliberately separated because each is its own reviewable change - **Wake adds latency on a cold call**, on an endpoint that previously either worked immediately or failed immediately. Clients with tight timeouts on `exec` may see a timeout where they used to see a clean 409. - **The `touch()` change extends real lifetimes.** An ephemeral sandbox polled by a health check every minute now never expires. That is the intended reading of an idle timeout, but it is a change to observable behaviour and is called out in the changelog. - **Wake-on-access does not cover preview URLs.** A suspended workspace's preview URL still fails until something calls the API. Waking from the gateway path is a larger change (it crosses the proxy/console split, ADR-017) and is not attempted here. +- **A terminal left attached indefinitely keeps a sandbox alive indefinitely.** That is the intended reading of "attached is active", but it does mean a forgotten terminal pins a container. The disk/quota follow-up above should account for it. ## Alternatives considered From 794809fbff8c2ca261e4a69ef7eac78ad90852cf Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 18:02:23 +0200 Subject: [PATCH 05/12] fix(auth): only require step-up from users who have enrolled MFA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A user with no MFA got `RequireVerification { mfa_setup_required: true }`, which the UI rendered as a dialog whose only forward action was "Configure MFA". That is a dead end, not a check: step-up re-verifies a factor you already hold, and demanding one that was never enrolled cannot succeed. On a fresh self-hosted instance it was worse than an inconvenience. Every route to a CLI token is gated by `SensitiveAction::CreateApiKey` — key creation, key reveal, and the CLI device-flow login — so the first admin could not obtain a token at all without first enrolling MFA, and nothing said so until the last step of the key-creation wizard. Unenrolled principals are now allowed through. Enrolled users are unaffected: they are still challenged when their session has no recent elevation, which is the case the control was written for. The tradeoff is explicit and deliberate: because the gate applies only to enrolled users, it can be avoided by not enrolling. It therefore protects accounts that opted into MFA — bounding the damage from a stolen session cookie — rather than acting as a barrier an attacker with account access must clear. Operators wanting the stricter posture should mandate MFA enrolment at the account level, or register a custom `SensitiveActionAuthorizer`; the UI branch for that policy is kept and its copy now attributes the requirement to the instance rather than to Temps. Verified against a running instance: creating an API key as an admin with no MFA enrolled returned 201 instead of 428. Also registers temps-sandbox in the `project_access_guard!` coverage snapshot, which the ADR-036 project-scoped create added without updating. --- crates/temps-auth/src/permission_guard.rs | 4 + crates/temps-auth/src/sensitive_action.rs | 86 +++++++++++++++++-- .../SensitiveActionVerificationDialog.tsx | 10 ++- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/crates/temps-auth/src/permission_guard.rs b/crates/temps-auth/src/permission_guard.rs index beedb77f4..6d78ff48a 100644 --- a/crates/temps-auth/src/permission_guard.rs +++ b/crates/temps-auth/src/permission_guard.rs @@ -981,6 +981,10 @@ mod tests { "temps-projects", "temps-providers", "temps-revenue", + // Creating a sandbox *from* a project reads that project's repo + // URL and git credential, so it is gated like any other + // project-scoped read (ADR-036). + "temps-sandbox", "temps-status-page", // Who a project is shared with is part of that project's data: // the access-grant endpoints guard themselves with the very diff --git a/crates/temps-auth/src/sensitive_action.rs b/crates/temps-auth/src/sensitive_action.rs index 448dd25a5..3a365b852 100644 --- a/crates/temps-auth/src/sensitive_action.rs +++ b/crates/temps-auth/src/sensitive_action.rs @@ -13,10 +13,31 @@ use crate::{context::AuthContext, user_service::UserService}; pub const STEP_UP_TTL_MINUTES: i64 = 5; -/// Default policy: interactive browser sessions need recent MFA verification. -/// Machine credentials are denied because they cannot satisfy an interactive -/// identity check; installations that need narrowly scoped automation can -/// provide a different policy through [`SensitiveActionAuthorizer`]. +/// Default policy: interactive browser sessions whose user has **enrolled** +/// MFA need recent verification. Machine credentials are denied because they +/// cannot satisfy an interactive identity check; installations that need +/// narrowly scoped automation can provide a different policy through +/// [`SensitiveActionAuthorizer`]. +/// +/// # Users without MFA +/// +/// A user who has not enrolled MFA is **allowed through**, not blocked. Step-up +/// is a re-authentication of a factor you already have — asking for one you +/// never enrolled is not a check, it is a dead end. Previously such a user got +/// `RequireVerification { mfa_setup_required: true }`, which on a fresh +/// self-hosted instance meant the first admin could not create an API key or +/// complete a CLI device login at all: every route to a token is gated by +/// `SensitiveAction::CreateApiKey`, and the only way out was to enrol MFA they +/// may not want. +/// +/// The tradeoff is explicit and was accepted deliberately: because the gate now +/// applies only to enrolled users, it can be avoided by not enrolling. It is +/// therefore a protection for accounts that opted into MFA — limiting the blast +/// radius of a stolen session cookie for those users — not a barrier an +/// attacker who controls account settings must clear. Operators who want the +/// stricter posture should mandate MFA enrolment at the account level, which is +/// the control that actually enforces it, or register a custom +/// [`SensitiveActionAuthorizer`]. pub struct DefaultSensitiveActionAuthorizer { db: Arc, } @@ -45,10 +66,15 @@ impl SensitiveActionAuthorizer for DefaultSensitiveActionAuthorizer { }); }; + // No enrolled factor, nothing to re-verify — allow. See the type-level + // docs for why this is a deliberate policy choice and what it costs. if !mfa_enabled { - return Ok(SensitiveActionDecision::RequireVerification { - mfa_setup_required: true, - }); + tracing::debug!( + user_id = *user_id, + action = action.as_str(), + "Sensitive action allowed without step-up: user has no MFA enrolled" + ); + return Ok(SensitiveActionDecision::Allow); } let session = temps_entities::sessions::Entity::find_by_id(*session_id) @@ -381,16 +407,58 @@ mod tests { } #[tokio::test] - async fn unenrolled_session_surfaces_setup_requirement() { + async fn unenrolled_session_is_allowed_without_step_up() { + // Step-up re-verifies a factor you already have. Demanding one from a + // user who never enrolled is a dead end, not a check — and it made the + // first admin of a fresh self-hosted instance unable to create an API + // key or complete a CLI device login at all. let authorizer = authorizer_with_sessions(vec![session(None)]); let decision = authorizer .authorize(&SensitiveAction::CreateApiKey, &browser_principal(false)) .await .unwrap(); + assert_eq!(decision, SensitiveActionDecision::Allow); + } + + #[tokio::test] + async fn unenrolled_session_is_allowed_for_every_action_kind() { + // The policy is per-principal, not per-action: nothing should + // reintroduce the dead end for one action but not another. + let authorizer = authorizer_with_sessions(vec![session(None)]); + for action in [ + SensitiveAction::CreateApiKey, + SensitiveAction::DeleteEnvironment { + project_id: 3, + environment_id: 7, + }, + ] { + let decision = authorizer + .authorize(&action, &browser_principal(false)) + .await + .unwrap(); + assert_eq!( + decision, + SensitiveActionDecision::Allow, + "action {} must not demand step-up from an unenrolled user", + action.as_str() + ); + } + } + + #[tokio::test] + async fn enrolled_session_without_recent_elevation_still_requires_verification() { + // The other half of the contract: opting into MFA must still buy you + // the protection. A user WITH a factor and no recent elevation is + // challenged exactly as before. + let authorizer = authorizer_with_sessions(vec![session(None)]); + let decision = authorizer + .authorize(&SensitiveAction::CreateApiKey, &browser_principal(true)) + .await + .unwrap(); assert_eq!( decision, SensitiveActionDecision::RequireVerification { - mfa_setup_required: true + mfa_setup_required: false } ); } diff --git a/web/src/components/auth/SensitiveActionVerificationDialog.tsx b/web/src/components/auth/SensitiveActionVerificationDialog.tsx index c61134320..fe20f4e9e 100644 --- a/web/src/components/auth/SensitiveActionVerificationDialog.tsx +++ b/web/src/components/auth/SensitiveActionVerificationDialog.tsx @@ -93,13 +93,19 @@ export function SensitiveActionVerificationDialog({ + {/* Only reachable when an operator has registered a policy that + mandates MFA enrolment. The default policy no longer demands + step-up from users with no enrolled factor — that was a dead end + for anyone who hadn't set up MFA, and on a fresh instance it left + the first admin unable to create an API key at all. Kept so a + stricter custom authorizer still renders something actionable. */} {mfaSetupRequired ? (

- Configure multi-factor authentication before performing - sensitive actions. + This instance requires multi-factor authentication for + sensitive actions. Set up MFA on your account to continue. From c1bd3796b241ae36b07a1536b55893b3483fc326 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 18:48:54 +0200 Subject: [PATCH 06/12] fix(sandbox): restore terminal echo, work dir, and CLI response shapes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three bugs that only surfaced once a real terminal ran against a real server. All three were invisible before because the npm CLI's sandbox commands 404'd, so nobody ever got a response to be wrong about. **Typing was invisible.** `temps-pty-agent` called `cfmakeraw()` on the pty at creation, clearing ECHO for the pair. Keystrokes reached bash — commands ran — but nothing echoed them back, so users typed blind; `stty -a` in the session reported `-echo -icanon`. Raw mode is the child's decision: readline and full-screen TUIs each call `tcsetattr` when they want char-at-a-time input. The pty now keeps the kernel defaults, as ssh/script/tmux do, with a test asserting ECHO and ICANON are on at spawn. **Every shell died with `spawn_failed: No such file or directory`.** `create_sandbox` hardcoded `work_dir: "/workspace"` into the row while the image's real work dir is `/home/temps/workspace` — the agent-run path directly above already used the `SANDBOX_WORK_DIR` constant. Nothing caught it because `exec` and the filesystem ops take the work dir from the provider handle; the terminal was the first consumer of the column. The row now records the real path, and the terminal reads from the handle so sandboxes created before this fix work too. **`sandbox list` crashed on `data.items.length`.** The response types were written against a flat, pre-Vercel-compat contract: the server returns `{sandboxes, pagination}` and `{sandbox, routes}`, with `cwd` rather than `work_dir` and `createdAt`/`timeout` as epoch/duration milliseconds — there is no `expires_at` on the wire. Adds a `toSandboxView` projection mirroring `web/src/components/sandboxes/helpers.ts` so the CLI and console derive it identically, and covers the three fields that were wrong. Verified against the running instance: created a workspace from a public repo, confirmed the clone with `git log`, attached a terminal, and observed `pwd` return /home/temps/workspace and typed characters echo back. --- apps/temps-cli/src/commands/sandbox/index.ts | 112 +++++++++++++++--- .../src/commands/sandbox/shell.test.ts | 38 +++++- crates/temps-pty-agent/src/pty.rs | 59 +++++++-- crates/temps-sandbox/src/handlers/terminal.rs | 7 +- .../src/services/sandbox_service.rs | 10 +- 5 files changed, 194 insertions(+), 32 deletions(-) diff --git a/apps/temps-cli/src/commands/sandbox/index.ts b/apps/temps-cli/src/commands/sandbox/index.ts index c277edc3a..733152e1b 100644 --- a/apps/temps-cli/src/commands/sandbox/index.ts +++ b/apps/temps-cli/src/commands/sandbox/index.ts @@ -24,7 +24,52 @@ import { shellAction } from './shell.js' // ── Types mirroring /v1/sandbox/* responses ───────────────────────────────── +/** + * The `sandbox` object the server actually returns — the + * `@vercel/sandbox`-compatible shape, not the flat one this file used to + * assume. + * + * These types were written against an older contract and never corrected, + * because the singular-vs-plural URL bug meant no request ever came back + * 200 for anyone to notice. Two traps worth naming: + * + * - `cwd`, not `work_dir`. + * - `createdAt` / `timeout` are **epoch milliseconds** and a **duration in + * milliseconds**. There is no `expires_at` on the wire; it is derived. + */ +interface SandboxInner { + id: string + name: string + status: string + image: string | null + cwd: string + /** Epoch milliseconds. */ + createdAt: number + /** Idle timeout in milliseconds. */ + timeout: number + backend?: string | null + disk_size_mb?: number | null + preview_url_template?: string + preview_password_hint?: string | null + agent_run_id?: number | null + /** 'ephemeral' | 'workspace' — absent on servers older than ADR-036. */ + lifecycle?: string + project_id?: number | null + source_repo_url?: string | null +} + +/** Single-sandbox responses are wrapped: `{ sandbox, routes }`. */ interface SandboxResponse { + sandbox: SandboxInner + routes?: Array<{ url: string; subdomain: string; port: number }> +} + +/** + * Flattened view for display, mirroring + * `web/src/components/sandboxes/helpers.ts` so the CLI and the console + * derive `expires_at` identically instead of drifting apart again. + */ +interface SandboxView { id: string name: string status: string @@ -33,21 +78,35 @@ interface SandboxResponse { created_at: string expires_at: string preview_password_hint?: string | null - /** 'ephemeral' | 'workspace' — absent on servers older than ADR-036. */ lifecycle?: string project_id?: number | null source_repo_url?: string | null } +export function toSandboxView(inner: SandboxInner): SandboxView { + return { + id: inner.id, + name: inner.name, + status: inner.status, + image: inner.image ?? null, + work_dir: inner.cwd, + created_at: new Date(inner.createdAt).toISOString(), + // The server sends a duration, not a deadline. + expires_at: new Date(inner.createdAt + inner.timeout).toISOString(), + preview_password_hint: inner.preview_password_hint ?? undefined, + lifecycle: inner.lifecycle, + project_id: inner.project_id ?? null, + source_repo_url: inner.source_repo_url ?? null, + } +} + interface SetPreviewPasswordResponse { preview_password_hint: string } interface ListSandboxesResponse { - items: SandboxResponse[] - total: number - page: number - page_size: number + sandboxes: SandboxInner[] + pagination: { count: number; next: number | null; prev: number | null } } interface ExecResponse { @@ -555,7 +614,7 @@ async function createAction(options: CreateOptions): Promise { body.preview_password = generatedPassword } - const sbx = await withSpinner( + const envelope = await withSpinner( options.workspace ? 'Creating workspace...' : 'Creating sandbox...', () => apiRequest(api, '', { @@ -563,6 +622,7 @@ async function createAction(options: CreateOptions): Promise { body: JSON.stringify(body), }), ) + const sbx = toSandboxView(envelope.sandbox) // Branch creation is a post-clone step: the server seeds the work dir at // whatever ref was requested, then we branch off it. Non-fatal — the @@ -594,7 +654,11 @@ async function createAction(options: CreateOptions): Promise { // In JSON mode the generated plaintext is part of the payload so // scripts can capture it in one call. Caller is responsible for // handling it safely. - json(generatedPassword ? { ...sbx, preview_password: generatedPassword } : sbx) + json( + generatedPassword + ? { ...envelope, preview_password: generatedPassword } + : envelope, + ) return } @@ -750,16 +814,18 @@ async function listAction(options: ListOptions): Promise { return } + const items = (data.sandboxes ?? []).map(toSandboxView) + newline() - header(`${icons.info} Sandboxes (${data.total})`) + header(`${icons.info} Sandboxes (${data.pagination?.count ?? items.length})`) - if (data.items.length === 0) { + if (items.length === 0) { info('No sandboxes found. Create one with `temps sandbox create`.') newline() return } - const columns: TableColumn[] = [ + const columns: TableColumn[] = [ { header: 'ID', key: 'id', color: (v) => colors.primary(v) }, { header: 'Name', key: 'name', color: (v) => colors.bold(v) }, { header: 'Status', key: 'status', color: (v) => statusColor(v) }, @@ -780,21 +846,25 @@ async function listAction(options: ListOptions): Promise { { header: 'Expires', key: 'expires_at', color: (v) => colors.muted(v) }, ] - printTable(data.items, columns, { style: 'minimal' }) + printTable(items, columns, { style: 'minimal' }) newline() } async function showAction(id: string, options: { json?: boolean }): Promise { const api = await auth() - const sbx = await withSpinner('Fetching sandbox...', () => + const envelope = await withSpinner('Fetching sandbox...', () => apiRequest(api, `/${encodeURIComponent(id)}`), ) if (options.json) { - json(sbx) + // JSON mode passes the server's envelope through untouched — scripts + // should see the real API shape, not our display projection. + json(envelope) return } + const sbx = toSandboxView(envelope.sandbox) + newline() header(`${icons.info} ${sbx.id}`) keyValue('Name', sbx.name) @@ -849,26 +919,29 @@ async function rmAction(id: string, options: { force?: boolean }): Promise async function pauseAction(id: string): Promise { const api = await auth() - const sbx = await withSpinner('Pausing sandbox...', () => + const envelope = await withSpinner('Pausing sandbox...', () => apiRequest(api, `/${encodeURIComponent(id)}/pause`, { method: 'POST' }), ) + const sbx = toSandboxView(envelope.sandbox) success(`Sandbox ${colors.primary(id)} paused — status: ${statusColor(sbx.status)}`) info(`Resume with: temps sandbox resume ${id}`) } async function resumeAction(id: string): Promise { const api = await auth() - const sbx = await withSpinner('Resuming sandbox...', () => + const envelope = await withSpinner('Resuming sandbox...', () => apiRequest(api, `/${encodeURIComponent(id)}/resume`, { method: 'POST' }), ) + const sbx = toSandboxView(envelope.sandbox) success(`Sandbox ${colors.primary(id)} resumed — expires: ${sbx.expires_at}`) } async function restartAction(id: string): Promise { const api = await auth() - const sbx = await withSpinner('Restarting sandbox...', () => + const envelope = await withSpinner('Restarting sandbox...', () => apiRequest(api, `/${encodeURIComponent(id)}/restart`, { method: 'POST' }), ) + const sbx = toSandboxView(envelope.sandbox) success(`Sandbox ${colors.primary(id)} restarted — status: ${statusColor(sbx.status)}`) } @@ -894,8 +967,9 @@ async function cloneAction(id: string, options: CloneOptions): Promise { body: JSON.stringify(source), }), ) - success(`Source seeded into ${colors.primary(sbx.id)}`) - keyValue('Work dir', sbx.work_dir) + const view = toSandboxView(sbx.sandbox) + success(`Source seeded into ${colors.primary(view.id)}`) + keyValue('Work dir', view.work_dir) } async function extendAction(id: string, options: { secs: string }): Promise { @@ -911,7 +985,7 @@ async function extendAction(id: string, options: { secs: string }): Promise { + // The response types in this module were written against an older, flat + // contract and never corrected — the 404-ing URL meant nothing ever came + // back to contradict them. These assertions pin the three fields that + // were actually wrong. + const inner = { + id: 'sbx_abc', + name: 'ws', + status: 'running', + image: 'node:22', + cwd: '/home/temps/workspace', + createdAt: 1_700_000_000_000, + timeout: 3_600_000, + lifecycle: 'workspace', + } + + test('maps cwd to work_dir', () => { + // Not `work_dir` on the wire — reading that gave `undefined`, which the + // terminal then passed as a PTY cwd. + expect(toSandboxView(inner).work_dir).toBe('/home/temps/workspace') + }) + + test('derives expires_at from createdAt + timeout', () => { + // The server sends a duration in ms, not a deadline. There is no + // `expires_at` field to read. + const view = toSandboxView(inner) + expect(view.created_at).toBe('2023-11-14T22:13:20.000Z') + expect(view.expires_at).toBe('2023-11-14T23:13:20.000Z') + }) + + test('carries lifecycle through for the Kind column', () => { + expect(toSandboxView(inner).lifecycle).toBe('workspace') + expect(toSandboxView({ ...inner, lifecycle: undefined }).lifecycle).toBeUndefined() + }) +}) + describe('sandboxUrl', () => { // This is the regression guard for a real bug: every command in this // group built `/v1/sandbox` (singular) while the server has only ever diff --git a/crates/temps-pty-agent/src/pty.rs b/crates/temps-pty-agent/src/pty.rs index 70a95b25a..dbd6eb8db 100644 --- a/crates/temps-pty-agent/src/pty.rs +++ b/crates/temps-pty-agent/src/pty.rs @@ -20,7 +20,6 @@ use std::process::Command; use nix::libc; use nix::pty::{openpty, Winsize}; -use nix::sys::termios::{self, SetArg}; use tokio::fs::File; /// Everything we need to talk to a spawned PTY child. @@ -50,17 +49,24 @@ pub fn spawn_pty( ws_xpixel: 0, ws_ypixel: 0, }; - // Start in raw mode — the child program (bash / claude / opencode) will - // renegotiate its own termios once it opens the slave. Without this the - // PTY defaults to line-buffered cooked mode, so the user's keystrokes - // don't reach the child until they press Enter. + // Leave the pty at its kernel defaults — cooked mode with ECHO and + // ICANON on, exactly what `openpty` hands back and what every other + // terminal multiplexer (ssh, script, tmux) starts from. + // + // This used to call `cfmakeraw()` here, on the theory that raw mode was + // needed for keystrokes to reach the child before Enter. That is the + // child's decision, not ours: readline (bash) and full-screen TUIs + // (claude, vim) each call `tcsetattr` themselves when they want + // char-at-a-time input. Forcing raw up front only cleared ECHO for + // everything that *doesn't* renegotiate — which is bash, whose readline + // then assumed the driver was echoing. The result was a shell where + // commands ran but the user could not see a single character they + // typed; `stty -a` inside the session reported `-echo -icanon`. + // + // Terminals do not manage the line discipline for their children. We + // move bytes; the program on the far end owns its termios. let result = openpty(Some(&winsize), None).map_err(|e| io::Error::other(format!("openpty: {e}")))?; - // Put the master in raw mode so we don't eat characters. - if let Ok(mut t) = termios::tcgetattr(&result.master) { - termios::cfmakeraw(&mut t); - let _ = termios::tcsetattr(&result.master, SetArg::TCSANOW, &t); - } let master_fd: OwnedFd = result.master; let slave_fd: OwnedFd = result.slave; @@ -224,6 +230,39 @@ mod tests { assert!(s.contains("hello"), "output did not contain 'hello': {s:?}"); } + /// The pty must start with ECHO and ICANON on. + /// + /// This is the regression guard for a shell in which commands ran but + /// the user could not see a single character they typed: the pty was + /// put into raw mode at creation, clearing ECHO, and bash's readline + /// assumed the driver was echoing. Anything that wants raw mode — vim, + /// claude, readline itself — sets it per-program; a terminal must not + /// pre-empt that decision for the whole session. + #[tokio::test] + async fn pty_starts_with_echo_and_canonical_mode_enabled() { + use nix::sys::termios::{self, LocalFlags}; + + let pty = spawn_pty( + "sleep 5", + "/tmp", + &[("PATH".into(), "/usr/bin:/bin".into())], + 80, + 24, + ) + .expect("spawn"); + + let attrs = termios::tcgetattr(&pty.master).expect("read pty termios"); + assert!( + attrs.local_flags.contains(LocalFlags::ECHO), + "pty must start with ECHO enabled — without it the user types blind" + ); + assert!( + attrs.local_flags.contains(LocalFlags::ICANON), + "pty must start in canonical mode; programs opt into raw themselves" + ); + kill_tree(pty.pid).await; + } + #[tokio::test] async fn resize_does_not_error() { let pty = spawn_pty( diff --git a/crates/temps-sandbox/src/handlers/terminal.rs b/crates/temps-sandbox/src/handlers/terminal.rs index ebbcd94e3..6ca084306 100644 --- a/crates/temps-sandbox/src/handlers/terminal.rs +++ b/crates/temps-sandbox/src/handlers/terminal.rs @@ -190,7 +190,12 @@ pub async fn terminal( let cmd = params.cmd.unwrap_or_else(default_shell_cmd); let cols = params.cols.unwrap_or(80); let rows = params.rows.unwrap_or(24); - let work_dir = row.work_dir.clone(); + // Take the working directory from the provider handle, not the DB row. + // The handle is what the backend actually created; rows written before + // the work_dir fix carry a "/workspace" that does not exist in the + // image, and spawning a shell there fails with a bare + // "spawn_failed: No such file or directory". + let work_dir = handle.work_dir.to_string_lossy().to_string(); Ok(ws.on_upgrade(move |socket| async move { let session = TerminalSession { diff --git a/crates/temps-sandbox/src/services/sandbox_service.rs b/crates/temps-sandbox/src/services/sandbox_service.rs index e779bd93a..c1948e968 100644 --- a/crates/temps-sandbox/src/services/sandbox_service.rs +++ b/crates/temps-sandbox/src/services/sandbox_service.rs @@ -832,7 +832,15 @@ impl SandboxService { name: Set(name.clone()), status: Set("running".to_string()), image: Set(req.image.clone()), - work_dir: Set("/workspace".to_string()), + // The real directory inside the container, not a nominal + // "/workspace" — that path does not exist in the sandbox image + // and never has. The agent-run path above already used this + // constant; this one was hardcoded and wrong, which stayed + // invisible because `exec` and the filesystem ops take the work + // dir from the provider handle rather than from this row. It + // only surfaced once the terminal used the row's value as a + // PTY cwd and every shell died with ENOENT. + work_dir: Set(temps_agents::sandbox::SANDBOX_WORK_DIR.to_string()), timeout_secs: Set(timeout as i32), metadata: Set(metadata_value), created_at: Set(now), From 34765807ddc755195f19850f9eecf4d988d0c687 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 22:07:10 +0200 Subject: [PATCH 07/12] fix(sandbox): address review findings on the terminal and step-up policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Blocking: the terminal's agent->client read was `read_frame`, built on two `read_exact` calls, inside a `tokio::select!`. `read_exact` is not cancellation-safe, and a select branch expression is dropped whenever a sibling fires — here on every keystroke and every 20s heartbeat. A drop between the length header and the payload discarded the consumed bytes, so the next read parsed payload as a header and the stream desynchronised. Adds `FrameCodec`, a `tokio_util` `Decoder` living beside the frame format it decodes, and switches the handler to `FramedRead`. A `FramedRead` buffer survives cancellation. Covered by a test that streams 20 split frames while a timer cancels the read continuously, asserting no frame is lost, reordered or corrupted — it fails against `read_frame`. Major: the project-derived seed source skipped validation. The handler validates `body.source`, which by construction never sees a URL this layer derives from a project row, so `projects.git_url` reached the clone without the DNS-resolution SSRF check (IP literals are checked project-side, names are not) and without the embedded-credentials check — a legacy row carrying `user:password@` would have been persisted to `source_repo_url` and echoed back out of the API. Validated at the point of derivation. Deliberately not applied to caller-supplied sources: the handler already covers those, and duplicating it would add a DNS lookup to every create. Major: capped concurrent terminals at 32 with a semaphore, 429 past it. Each attach holds a `docker exec` for the session and writes an activity row every 20s, which was an unbounded self-service DoS on the reference host. Minor: `tab` is now validated as `[A-Za-z0-9_-]{1,64}`. It keys a PTY plus a 64 KiB ring per distinct value in the agent, and was interpolated into operator logs where a newline forges lines. Minor: the step-up bypass now logs at INFO with `step_up=skipped_no_mfa` rather than DEBUG, so an audit trail can distinguish "step-up satisfied" from "step-up skipped for want of a factor". Minor: corrected the `require_mfa_for_admins` guidance. That setting gates the password-login path only and OIDC logins are intentionally unaffected, so on an SSO instance admins keep `mfa_enabled == false` and pass this gate — the opposite of what an operator enabling it would expect. Minor: docs example passes the API key by reference, not literally. --- crates/temps-auth/src/sensitive_action.rs | 26 ++- crates/temps-pty-agent/src/protocol.rs | 149 ++++++++++++++++ crates/temps-sandbox/src/handlers/terminal.rs | 112 +++++++++++- .../src/services/sandbox_service.rs | 165 +++++++++++++++++- .../sandboxes/CreateSandboxDocs.tsx | 5 +- 5 files changed, 442 insertions(+), 15 deletions(-) diff --git a/crates/temps-auth/src/sensitive_action.rs b/crates/temps-auth/src/sensitive_action.rs index 3a365b852..db62d5610 100644 --- a/crates/temps-auth/src/sensitive_action.rs +++ b/crates/temps-auth/src/sensitive_action.rs @@ -34,10 +34,19 @@ pub const STEP_UP_TTL_MINUTES: i64 = 5; /// applies only to enrolled users, it can be avoided by not enrolling. It is /// therefore a protection for accounts that opted into MFA — limiting the blast /// radius of a stolen session cookie for those users — not a barrier an -/// attacker who controls account settings must clear. Operators who want the -/// stricter posture should mandate MFA enrolment at the account level, which is -/// the control that actually enforces it, or register a custom -/// [`SensitiveActionAuthorizer`]. +/// attacker who controls account settings must clear. +/// +/// What it is *not* weakened by: a stolen session cannot unenrol to escape the +/// challenge, because disabling MFA itself requires a valid TOTP code. +/// +/// # Operators who want the stricter posture +/// +/// `AppSettings::require_mfa_for_admins` is **not** sufficient on its own: it +/// gates the password-login path only, and OIDC logins are intentionally +/// unaffected. On an SSO instance, admins keep `users.mfa_enabled == false` +/// and so pass this gate without a challenge. Closing that requires either +/// enforcing enrolment in the identity provider, or registering a custom +/// [`SensitiveActionAuthorizer`] that denies unenrolled principals. pub struct DefaultSensitiveActionAuthorizer { db: Arc, } @@ -68,10 +77,17 @@ impl SensitiveActionAuthorizer for DefaultSensitiveActionAuthorizer { // No enrolled factor, nothing to re-verify — allow. See the type-level // docs for why this is a deliberate policy choice and what it costs. + // + // Logged at INFO, not DEBUG: this is the record that the action ran at + // a *reduced* assurance level. Without it the audit entry for e.g. + // `create_api_key` is indistinguishable from one where step-up was + // actually satisfied, and the difference is exactly what an incident + // responder needs. if !mfa_enabled { - tracing::debug!( + tracing::info!( user_id = *user_id, action = action.as_str(), + step_up = "skipped_no_mfa", "Sensitive action allowed without step-up: user has no MFA enrolled" ); return Ok(SensitiveActionDecision::Allow); diff --git a/crates/temps-pty-agent/src/protocol.rs b/crates/temps-pty-agent/src/protocol.rs index 2dc8260f9..928253d74 100644 --- a/crates/temps-pty-agent/src/protocol.rs +++ b/crates/temps-pty-agent/src/protocol.rs @@ -188,6 +188,52 @@ pub fn encode_resize(cols: u16, rows: u16) -> [u8; 4] { out } +/// A cancellation-safe decoder for the frame format above. +/// +/// [`read_frame`] is built on two sequential `read_exact` calls, which are +/// **not** cancellation-safe: dropping the future mid-call discards the bytes +/// it already consumed. That is fine for a caller that awaits it to +/// completion, but fatal inside a `tokio::select!` — the reader loses the +/// length header it just read, then parses payload bytes as the next header +/// and the stream desynchronises for good. +/// +/// A [`Decoder`] has no such problem: `FramedRead` owns a buffer that +/// survives across polls, so a cancelled `next()` leaves the bytes in place +/// for the following one. Any consumer that multiplexes this stream against +/// other events — the sandbox terminal handler multiplexes it against client +/// input and an activity heartbeat — must use this rather than `read_frame`. +pub struct FrameCodec; + +impl tokio_util::codec::Decoder for FrameCodec { + /// `(type_byte, payload)` — the same tuple `read_frame` yields. + type Item = (u8, Vec); + type Error = FrameError; + + fn decode(&mut self, src: &mut bytes::BytesMut) -> Result, Self::Error> { + // Not enough for the length header yet — ask for more. + if src.len() < 4 { + return Ok(None); + } + let len = u32::from_be_bytes([src[0], src[1], src[2], src[3]]) as usize; + if len == 0 { + return Err(FrameError::Empty); + } + if len > MAX_FRAME_BYTES { + return Err(FrameError::Oversized { size: len }); + } + // Whole frame not buffered yet. Reserve so the read side can fill it + // in one go instead of growing the buffer repeatedly on big output. + if src.len() < 4 + len { + src.reserve(4 + len - src.len()); + return Ok(None); + } + let _ = src.split_to(4); + let mut payload = src.split_to(len); + let type_byte = payload[0]; + Ok(Some((type_byte, payload.split_off(1).to_vec()))) + } +} + #[cfg(test)] mod tests { use super::*; @@ -257,4 +303,107 @@ mod tests { let err = read_frame(&mut b).await.unwrap_err(); assert!(matches!(err, FrameError::Oversized { .. })); } + + // ── FrameCodec ─────────────────────────────────────────────────────── + + #[tokio::test] + async fn codec_reassembles_frames_split_across_reads() { + use futures::StreamExt; + use tokio_util::codec::FramedRead; + + let (mut a, b) = duplex(64 * 1024); + tokio::spawn(async move { + use tokio::io::AsyncWriteExt; + // Write one frame in three pieces, straddling both the length + // header and the payload — the shape a socat relay produces. + let _ = a.write_all(&[0, 0, 0, 6]).await; + let _ = a.write_all(&[OP_OUTPUT, b'h', b'e']).await; + let _ = a.write_all(b"llo").await; + let _ = a.shutdown().await; + }); + + let mut framed = FramedRead::new(b, FrameCodec); + let (op, payload) = framed + .next() + .await + .expect("a frame") + .expect("decode succeeds"); + assert_eq!(op, OP_OUTPUT); + assert_eq!(payload, b"hello"); + } + + /// The regression guard for the bug this codec exists to prevent. + /// + /// Repeatedly cancelling the read — exactly what `tokio::select!` does + /// when a sibling branch fires — must not lose or reorder bytes. With + /// `read_frame` this test corrupts the stream; with the codec the + /// buffered bytes survive the cancellation. + #[tokio::test] + async fn codec_survives_repeated_cancellation_mid_frame() { + use futures::StreamExt; + use tokio_util::codec::FramedRead; + + let (mut a, b) = duplex(64 * 1024); + tokio::spawn(async move { + use tokio::io::AsyncWriteExt; + for i in 0..20u8 { + let body = vec![b'a' + (i % 26); 64]; + let mut frame = ((1 + body.len()) as u32).to_be_bytes().to_vec(); + frame.push(OP_OUTPUT); + frame.extend_from_slice(&body); + // Dribble each frame out in two writes so a cancellation has + // a real chance of landing between them. + let (head, tail) = frame.split_at(3); + let _ = a.write_all(head).await; + tokio::time::sleep(std::time::Duration::from_millis(1)).await; + let _ = a.write_all(tail).await; + } + let _ = a.shutdown().await; + }); + + let mut framed = FramedRead::new(b, FrameCodec); + let mut got = Vec::new(); + while got.len() < 20 { + tokio::select! { + frame = framed.next() => { + match frame { + Some(Ok((op, payload))) => { + assert_eq!(op, OP_OUTPUT, "frame type corrupted"); + assert_eq!(payload.len(), 64, "payload length corrupted"); + got.push(payload); + } + Some(Err(e)) => panic!("decode failed — stream desynchronised: {e}"), + None => break, + } + } + // The adversary: a timer that keeps cancelling the read. + _ = tokio::time::sleep(std::time::Duration::from_micros(200)) => {} + } + } + assert_eq!(got.len(), 20, "lost frames across cancellations"); + for (i, payload) in got.iter().enumerate() { + let expected = b'a' + (i as u8 % 26); + assert!( + payload.iter().all(|b| *b == expected), + "frame {i} corrupted — bytes from an adjacent frame leaked in" + ); + } + } + + #[tokio::test] + async fn codec_rejects_oversized_length_header() { + use futures::StreamExt; + use tokio_util::codec::FramedRead; + + let (mut a, b) = duplex(1024); + tokio::spawn(async move { + use tokio::io::AsyncWriteExt; + let _ = a + .write_all(&((MAX_FRAME_BYTES + 1) as u32).to_be_bytes()) + .await; + }); + let mut framed = FramedRead::new(b, FrameCodec); + let err = framed.next().await.expect("a result").unwrap_err(); + assert!(matches!(err, FrameError::Oversized { .. })); + } } diff --git a/crates/temps-sandbox/src/handlers/terminal.rs b/crates/temps-sandbox/src/handlers/terminal.rs index 6ca084306..616be2e8d 100644 --- a/crates/temps-sandbox/src/handlers/terminal.rs +++ b/crates/temps-sandbox/src/handlers/terminal.rs @@ -49,6 +49,7 @@ use temps_auth::{permissions::Permission, RequireAuth}; use temps_core::problemdetails::{self, Problem}; use temps_pty_agent::protocol as pty; use tokio::io::AsyncWriteExt; +use tokio_util::codec::FramedRead; use tokio_util::io::StreamReader; use utoipa::ToSchema; @@ -64,6 +65,44 @@ const ACTIVITY_HEARTBEAT: Duration = Duration::from_secs(20); /// asking for more just gets clamped agent-side. const REPLAY_BYTES: u32 = 64 * 1024; +/// Concurrent terminal attachments allowed across the whole process. +/// +/// Every attach holds a `docker exec` and a bollard connection for the life +/// of the session, and writes an activity row every [`ACTIVITY_HEARTBEAT`]. +/// Unbounded, that is a self-service denial of service from any account with +/// `sandboxes:write` on the 3 vCPU / 4 GB reference host. A global cap is +/// crude but bounds the daemon pressure; callers past it get a 429 telling +/// them to close a session rather than a hang. +const MAX_CONCURRENT_TERMINALS: usize = 32; + +/// Permits for [`MAX_CONCURRENT_TERMINALS`]. A process-wide static rather +/// than state on `SandboxAppState` so the bound holds even if a future +/// refactor builds more than one router. +static TERMINAL_SLOTS: tokio::sync::Semaphore = + tokio::sync::Semaphore::const_new(MAX_CONCURRENT_TERMINALS); + +/// Longest accepted `tab` identifier, and the character set. +/// +/// The agent keys tabs by this string and allocates a PTY plus a 64 KiB +/// scrollback ring per distinct value, so an unbounded one is a memory lever +/// inside the container. It is also interpolated into operator logs, where a +/// newline would forge log lines. +fn validate_tab(tab: &str) -> Result<(), Problem> { + let ok = !tab.is_empty() + && tab.len() <= 64 + && tab + .chars() + .all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_'); + if ok { + return Ok(()); + } + Err(problemdetails::new(StatusCode::BAD_REQUEST) + .with_title("Invalid Tab Name") + .with_detail( + "tab must be 1-64 characters of ASCII letters, digits, '-' or '_'".to_string(), + )) +} + /// Query parameters for the terminal upgrade. #[derive(Debug, Deserialize, ToSchema)] pub struct TerminalParams { @@ -144,6 +183,21 @@ pub async fn terminal( ) -> Result { sandbox_permission_guard(&auth, Permission::SandboxesWrite, Permission::ProjectsWrite)?; + let tab = params.tab.clone().unwrap_or_else(|| "main".to_string()); + validate_tab(&tab)?; + + // Take a slot before doing any work. Held for the whole session by moving + // the permit into the upgrade closure; dropped when the session ends. + let permit = TERMINAL_SLOTS.try_acquire().map_err(|_| { + problemdetails::new(StatusCode::TOO_MANY_REQUESTS) + .with_title("Too Many Terminals") + .with_detail(format!( + "This instance already has {} terminal sessions open. \ + Close one and retry.", + MAX_CONCURRENT_TERMINALS + )) + })?; + // Resolve *before* the upgrade so ownership failures, a missing sandbox, // or a stopped ephemeral one surface as a real HTTP status instead of a // WebSocket that opens and immediately dies. This also wakes a suspended @@ -186,7 +240,6 @@ pub async fn terminal( let service = state.sandbox_service.clone(); let timeout_secs = row.timeout_secs; - let tab = params.tab.unwrap_or_else(|| "main".to_string()); let cmd = params.cmd.unwrap_or_else(default_shell_cmd); let cols = params.cols.unwrap_or(80); let rows = params.rows.unwrap_or(24); @@ -198,6 +251,9 @@ pub async fn terminal( let work_dir = handle.work_dir.to_string_lossy().to_string(); Ok(ws.on_upgrade(move |socket| async move { + // Held for the session's lifetime; released when this future ends, + // however it ends. + let _permit = permit; let session = TerminalSession { socket, attachment, @@ -254,7 +310,13 @@ impl TerminalSession { let agent_bytes = attachment .output .map(|chunk| chunk.map_err(|e| std::io::Error::other(e.to_string()))); - let mut agent_out = StreamReader::new(agent_bytes); + // `FramedRead` + `FrameCodec`, never `read_frame`: this stream is + // multiplexed in the `select!` below against client input and the + // activity heartbeat, so the read is cancelled constantly. The codec + // buffers across polls; `read_frame`'s `read_exact` pair would drop + // whatever it had already consumed and desynchronise the stream on + // the first keystroke that landed mid-frame. + let mut agent_out = FramedRead::new(StreamReader::new(agent_bytes), pty::FrameCodec); // OPEN the tab. Reattaches when it already exists, which is what // makes a long-running CLI survive disconnection. @@ -293,18 +355,18 @@ impl TerminalSession { service.touch(internal_id, timeout_secs).await; } - // Agent → client. - frame = pty::read_frame(&mut agent_out) => { + // Agent → client. Cancellation-safe: see the codec above. + frame = agent_out.next() => { match frame { - Ok(Some((op, payload))) => { + Some(Ok((op, payload))) => { if !forward_agent_frame(&mut ws_tx, op, payload).await { break; } } // Clean EOF: the relay exited (container stopped, or // the agent went away). Nothing more to read. - Ok(None) => break, - Err(e) => { + None => break, + Some(Err(e)) => { send_error(&mut ws_tx, format!("terminal stream failed: {}", e)).await; break; } @@ -478,6 +540,42 @@ mod tests { assert!(exit.contains(r#""type":"exit""#), "{}", exit); } + #[test] + fn tab_accepts_ordinary_names() { + for ok in ["main", "claude", "tab-2", "my_work_1", &"a".repeat(64)] { + assert!(validate_tab(ok).is_ok(), "should accept {ok:?}"); + } + } + + #[test] + fn tab_rejects_log_forging_and_unbounded_names() { + // A newline would forge lines in the operator's structured log, and + // each distinct tab costs a PTY plus a 64 KiB ring in the agent. + for bad in [ + "", + "has space", + "new\nline", + "semi;colon", + "../escape", + "unicodé", + ] { + assert!(validate_tab(bad).is_err(), "should reject {bad:?}"); + } + assert!( + validate_tab(&"a".repeat(65)).is_err(), + "should reject over-long tab names" + ); + } + + #[test] + fn terminal_slot_cap_is_bounded_and_nonzero() { + // Zero would make every attach 429; unbounded would let one account + // exhaust dockerd on the reference host. + const _: () = assert!(MAX_CONCURRENT_TERMINALS > 0); + const _: () = assert!(MAX_CONCURRENT_TERMINALS <= 128); + assert_eq!(TERMINAL_SLOTS.available_permits(), MAX_CONCURRENT_TERMINALS); + } + #[test] fn replay_request_is_bounded() { // The agent clamps this, but sending an absurd value would be a diff --git a/crates/temps-sandbox/src/services/sandbox_service.rs b/crates/temps-sandbox/src/services/sandbox_service.rs index c1948e968..68d3bdadd 100644 --- a/crates/temps-sandbox/src/services/sandbox_service.rs +++ b/crates/temps-sandbox/src/services/sandbox_service.rs @@ -271,6 +271,80 @@ fn idle_deadline( now + chrono::Duration::seconds(timeout_secs as i64) } +/// Security validation for a seed source *after* it has been resolved. +/// +/// The handler validates the caller-supplied `source` DTO, which covers the +/// request-shape rules it owns (mutually exclusive auth fields, and so on). +/// It cannot cover a source this layer derives from a project row, so the +/// two checks that actually matter for safety are repeated here on whatever +/// we finally decided to clone: +/// +/// - **SSRF**, including DNS resolution. `validate_external_url` rejects +/// hosts that resolve to private, loopback, link-local or cloud-metadata +/// addresses — the project-side URL guard only checks IP *literals*, so a +/// name like `metadata.google.internal` would otherwise pass. +/// - **Embedded credentials.** A `user:password@` in the URL would be +/// persisted to `sandboxes.source_repo_url` and echoed back out of the +/// API. Rows predating the project-side guard can still carry one. +async fn validate_resolved_source(source: &SandboxSource) -> Result<(), SandboxError> { + let (url, kind) = match source { + SandboxSource::Git { url, .. } => (url.as_str(), "git"), + SandboxSource::Tarball { url } => (url.as_str(), "tarball"), + }; + + if url_has_embedded_credentials(url) { + return Err(SandboxError::Validation { + message: format!( + "{kind} source: url must not contain embedded credentials — \ + use a stored git connection instead" + ), + }); + } + + // Sync pass first: scheme + IP-literal blocklist. Cheap, and it avoids a + // DNS lookup for URLs that are already disqualified. + let parsed = temps_core::url_validation::validate_external_url(url).map_err(|_| { + SandboxError::Validation { + message: format!( + "{kind} source: scheme must be http or https, and the host must \ + not be a private, loopback, or metadata address" + ), + } + })?; + + // Then resolve: an IP literal is already covered above, but a *name* + // pointing at 169.254.169.254 is only caught here. + if let Some(url::Host::Domain(domain)) = parsed.host() { + temps_core::url_validation::validate_domain_async(domain) + .await + .map_err(|_| SandboxError::Validation { + message: format!( + "{kind} source: host resolves to a private, loopback, or \ + metadata address" + ), + })?; + } + Ok(()) +} + +/// Does the URL carry `user:password@`? +/// +/// A bare `user@` is fine — git reads that as "prompt for a password" and it +/// carries no secret. Only the colon form is a credential. +fn url_has_embedded_credentials(url: &str) -> bool { + let Some(scheme_end) = url.find("://") else { + return false; + }; + let rest = &url[scheme_end + 3..]; + // Stop at the path: an `@` after the first `/` belongs to the path, not + // to userinfo (e.g. `https://host/org/repo@v1.git`). + let authority = rest.split('/').next().unwrap_or(rest); + match authority.find('@') { + Some(at) => authority[..at].contains(':'), + None => false, + } +} + /// Reject standalone lifecycle ops (`pause`/`resume`/`restart`/`resize`) /// on rows attributed to an agent run. Those containers are named /// `temps-sandbox-` — not by the row's public id — so the @@ -748,10 +822,25 @@ impl SandboxService { // default, so a caller can create a workspace attributed to a // project while seeding it from a fork or a different branch. let source = match (req.source.clone(), req.project_id) { + // Caller-supplied: already validated by the handler, which owns + // the request-shape rules too. Re-checking here would duplicate a + // DNS lookup on every create for no gain. (Some(explicit), _) => Some(explicit), - (None, Some(project_id)) => Some(self.source_from_project(project_id).await?), + // Project-derived: the handler never saw this URL, so it is + // validated here — the layer that produced it. `projects.git_url` + // is checked for IP literals on the project side but never + // resolved, so a name pointing at the metadata endpoint would + // otherwise pass; and a row predating that guard can still carry + // `user:password@`, which would land in `source_repo_url` and be + // echoed back out of the API. + (None, Some(project_id)) => { + let derived = self.source_from_project(project_id).await?; + validate_resolved_source(&derived).await?; + Some(derived) + } (None, None) => None, }; + let source_repo_url = source.as_ref().and_then(|s| match s { SandboxSource::Git { url, .. } => Some(url.clone()), SandboxSource::Tarball { .. } => None, @@ -3005,6 +3094,80 @@ mod storage_cleanup_tests { let _ = std::fs::remove_dir_all(&data_root); } + // ── Resolved-source validation ─────────────────────────────────────── + + #[test] + fn embedded_credentials_are_detected_only_in_userinfo() { + assert!(url_has_embedded_credentials( + "https://user:secret@github.com/org/repo.git" + )); + // A bare user is not a credential — git treats it as "prompt". + assert!(!url_has_embedded_credentials( + "https://user@github.com/org/repo.git" + )); + assert!(!url_has_embedded_credentials( + "https://github.com/org/repo.git" + )); + // An `@` in the *path* must not be mistaken for userinfo, or every + // pinned-ref URL would be rejected as leaking a password. + assert!(!url_has_embedded_credentials( + "https://github.com/org/repo@v1.git" + )); + assert!(!url_has_embedded_credentials("git@github.com:org/repo.git")); + } + + #[tokio::test] + async fn resolved_source_rejects_embedded_credentials() { + // This is the project-derived path's guard: a legacy `projects.git_url` + // carrying a password would otherwise be persisted to + // `source_repo_url` and echoed back out of the API. + let source = SandboxSource::Git { + url: "https://user:secret@github.com/org/repo.git".into(), + revision: None, + depth: None, + username: None, + password: None, + git_connection_id: None, + }; + let err = validate_resolved_source(&source) + .await + .expect_err("credentials in the url must be rejected"); + let msg = err.to_string(); + assert!(msg.contains("embedded credentials"), "msg: {msg}"); + // The message must not echo the secret back at the caller. + assert!(!msg.contains("secret"), "error leaked the password: {msg}"); + } + + #[tokio::test] + async fn resolved_source_rejects_loopback_and_metadata_hosts() { + for url in [ + "http://127.0.0.1/repo.git", + "http://169.254.169.254/latest/meta-data", + "http://[::1]/repo.git", + ] { + let source = SandboxSource::Git { + url: url.into(), + revision: None, + depth: None, + username: None, + password: None, + git_connection_id: None, + }; + assert!( + validate_resolved_source(&source).await.is_err(), + "{url} must be rejected as an SSRF target" + ); + } + } + + #[tokio::test] + async fn resolved_source_rejects_non_http_schemes() { + let source = SandboxSource::Tarball { + url: "file:///etc/passwd".into(), + }; + assert!(validate_resolved_source(&source).await.is_err()); + } + #[tokio::test] async fn destroy_sandbox_removes_the_work_dir() { let data_root = unique_data_root("destroy-ok"); diff --git a/web/src/components/sandboxes/CreateSandboxDocs.tsx b/web/src/components/sandboxes/CreateSandboxDocs.tsx index 7ff0d6f55..c87ff4dff 100644 --- a/web/src/components/sandboxes/CreateSandboxDocs.tsx +++ b/web/src/components/sandboxes/CreateSandboxDocs.tsx @@ -52,8 +52,9 @@ bunx @temps-sdk/cli sandbox create --workspace \\ bunx @temps-sdk/cli sandbox exec sbx_abc123 -- git status # The image ships claude, codex, opencode, gh and glab. Supply your own -# key at create time until credential injection lands (ADR-036). -bunx @temps-sdk/cli sandbox create --workspace -e ANTHROPIC_API_KEY=sk-ant-... +# key at create time until credential injection lands (ADR-036). Pass it by +# reference so the secret stays out of your shell history. +bunx @temps-sdk/cli sandbox create --workspace -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" bunx @temps-sdk/cli sandbox list --workspace` From 14f7f64e3d00f5559f3e00b97b5b22a8bdb27628 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Thu, 6 Aug 2026 22:31:30 +0200 Subject: [PATCH 08/12] feat(web): regenerate the SDK and surface workspaces in the console MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regenerated `web/src/api/client` from the merged server, which was the blocker on the console knowing anything about workspaces. The diff is smaller than feared — 131 insertions — because the branch is now merged up to main, so the only new surface is this branch's own: `lifecycle`, `project_id` and `source_repo_url` on `SandboxInner`, the `lifecycle` and `project_id` list filters, and the `GET /v1/sandboxes/{id}/terminal` operation. With the types available, the Sandboxes list now distinguishes the two classes. A workspace carries a `workspace` badge, and its countdown reads "to suspend" / "suspended — wakes on next use" instead of "left" / "expired", never in destructive red. Without that, a suspended workspace renders identically to a dead sandbox — "stopped, expired" — which is exactly the wrong thing to tell someone whose files are intact and who only has to run a command to get it back. The codegen key was minted for the run and deleted immediately after. --- .../api/client/@tanstack/react-query.gen.ts | 22 ++++- web/src/api/client/index.ts | 4 +- web/src/api/client/sdk.gen.ts | 13 ++- web/src/api/client/types.gen.ts | 98 +++++++++++++++++++ web/src/components/sandboxes/helpers.ts | 16 +++ web/src/pages/Sandboxes.tsx | 30 +++++- 6 files changed, 173 insertions(+), 10 deletions(-) diff --git a/web/src/api/client/@tanstack/react-query.gen.ts b/web/src/api/client/@tanstack/react-query.gen.ts index 412d49858..59bf92ef8 100644 --- a/web/src/api/client/@tanstack/react-query.gen.ts +++ b/web/src/api/client/@tanstack/react-query.gen.ts @@ -3,8 +3,8 @@ import { type DefaultError, type InfiniteData, infiniteQueryOptions, queryOptions, type UseMutationOptions } from '@tanstack/react-query'; import { client } from '../client.gen'; -import { acknowledgeAlarm, activateAiProvider, activateApiKey, activateConnection, activateProvider, addClusterMember, addContext, addEnvironmentDomain, addEvents, addManagedDomain, addSessionReplayEvents, addTeamMember, adminDrainNode, adminDrainStatus, adminGetNode, adminListNodeContainers, adminListNodes, adminRemoveNode, adminUndrainNode, applyHostnameMode, archiveConversation, archiveFlag, assignRole, attachScheduleServices, blobCopy, blobDelete, blobDisable, blobDownload, blobEnable, blobList, blobPut, blobStatus, blobUpdate, cancel, cancelBackup, cancelDeployment, cancelDomainOrder, cancelPgUpgrade, cancelRun, cancelScheduleRun, changePasswordSelf, changeProjectSource, changeRequiredPassword, chatCompletions, checkAnalyticsHasEvents, checkCommitExists, checkDomainStatus, checkExplorerSupport, checkIpBlocked, checkProviderDeletionSafety, chunkUploadOptions, cleanupExpiredBackups, clearPreviewPassword, cliDeviceApprove, cliDeviceDeny, cliDeviceLookup, cliDevicePoll, cliDeviceStart, cliLogout, cmd, cmdKill, cmdLogs, confirmPendingAction, containerMetricsGetHistory, createAgent, createAlert, createAlertRule, createApiKey, createBackupSchedule, createBitbucketProvider, createCloudflareProvider, createConversation, createCustomDomain, createDashboard, createDeploymentToken, createDnsProvider, createDomain, createDsn, createEmailDomain, createEmailProvider, createEnvironment, createEnvironmentVariable, createFlag, createFunnel, createGenericProvider, createGiteaPatProvider, createGithubPatProvider, createGitlabOauthProvider, createGitlabPatProvider, createGitProvider, createGlobalMcp, createGlobalSkill, createIncident, createIpAccessControl, createMcp, createMonitor, createNotificationEmailProvider, createNotificationProvider, createOidcProvider, createOidcRoleMapping, createOrRecreateOrder, createPlan, createPr, createProject, createProjectFromTemplate, createProjectRelease, createProjectSecret, createProviderKey, createRelease, createRoute, createS3Source, createSandbox, createService, createSkill, createSlackProvider, createTeam, createUser, createWebhook, createWebhookProvider, deactivateApiKey, deactivateConnection, deactivateProvider, deleteAgent, deleteAlert, deleteAlertRule, deleteApiKey, deleteBackup, deleteBackupSchedule, deleteConnection, deleteCustomDomain, deleteDashboard, deleteDeploymentToken, deleteDnsProvider, deleteDomain, deleteEmailDomain, deleteEmailProvider, deleteEnvironment, deleteEnvironmentDomain, deleteEnvironmentVariable, deleteExternalImage, deleteFunnel, deleteGitProvider, deleteGlobalMcp, deleteGlobalSkill, deleteIpAccessControl, deleteMcp, deleteMonitor, deleteNotificationProvider, deleteOidcProvider, deleteOidcRoleMapping, deletePreferences, deleteProject, deleteProjectSecret, deleteProviderKey, deleteProviderSafely, deleteReleaseSourceFiles, deleteReleaseSourceMaps, deleteRoute, deleteS3Source, deleteScan, deleteSecret, deleteService, deleteSessionReplay, deleteSkill, deleteSourceMap, deleteStaticBundle, deleteTeam, deleteUser, deleteWebhook, deployFromImage, deployFromImageUpload, deployFromStatic, deployFromUploadedSource, deploymentMetricsGetLatest, deploymentMetricsGetRange, deploymentMetricsToggle, destroySandbox, detachScheduleService, detectPublicPresets, disableBackupSchedule, disableMfa, discoverWorkloads, domain, downloadGlobalSkillArchive, downloadObject, downloadSkillArchive, emailStatus, embeddings, enableBackupSchedule, enrichVisitor, exec, execDetached, executeDeploymentOperation, executeImport, extendTimeout, externalServiceEnablePgStatStatements, externalServiceMetricsByDatabase, externalServiceMetricsCreateAlertRule, externalServiceMetricsDeleteAlertRule, externalServiceMetricsGetAlertRules, externalServiceMetricsGetLatest, externalServiceMetricsGetRange, externalServiceMetricsStatus, externalServiceMetricsToggle, externalServiceMetricsUpdateAlertRule, externalServiceResetPgStatStatements, finalizeOrder, finalizeProjectRelease, findConversation, generateJoinToken, generatePresetDockerfile, getAccessInfo, getActiveVisitors, getActivityGraph, getAdminGate, getAgent, getAggregatedBuckets, getAiAgentBreakdown, getAiAgentPages, getAiAgentTimeline, getAiDataAccess, getAiPageBreakdown, getAiStatusBreakdown, getAlert, getAlertRule, getAllRepositoriesByName, getAnalyticsActiveVisitors, getAnalyticsEventsCount, getAnalyticsSessionEvents, getAnalyticsVisitorSessions, getApiKey, getApiKeyPermissions, getAuditLog, getBackup, getBackupSchedule, getBranchesByRepositoryId, getBucketedIncidents, getBucketedStatus, getChallengeToken, getChatReadiness, getCliStatus, getClusterHealth, getClusterMember, getCmd, getContainerDetail, getContainerEnvironmentVariable, getContainerLogs, getContainerLogsById, getContainerMetrics, getConversation, getConversationDetail, getConversations, getCronById, getCronExecutions, getCrossProjectTraceSiblings, getCurrentMonitorStatus, getCurrentUser, getCustomDomain, getDashboard, getDashboardProjectsAnalytics, getDelivery, getDeployment, getDeploymentContainerLogContent, getDeploymentJobLogs, getDeploymentJobs, getDeploymentOperations, getDeploymentOperationStatus, getDeploymentToken, getDiskStatus, getDnsChanges, getDnsProvider, getDomain, getDomainByHost, getDomainById, getDomainByName, getDomainDnsRecords, getDomainOrder, getEmail, getEmailEvents, getEmailLinks, getEmailProvider, getEmailStats, getEmailTracking, getEmailTrackingStatus, getEntityInfo, getEnvironment, getEnvironmentCrons, getEnvironmentDomains, getEnvironments, getEnvironmentVariables, getEnvironmentVariableValue, getErrorDashboardStats, getErrorEvent, getErrorGroup, getErrorStats, getErrorTimeSeries, getEventDetail, getEventEntries, getEventsCount, getEventsTimeline, getEventTypeBreakdown, getEventVisitors, getExternalImage, getFile, getFlag, getFlagSnapshot, getFunnelMetrics, getGenaiTrace, getGeneralStats, getGitProvider, getGlobalEvents, getGlobalEventStats, getGlobalMcp, getGlobalSandboxStatus, getGlobalSkill, getGroupedPageMetrics, getHealth, getHourlyVisits, getHttpChallengeDebug, getImportStatus, getIncident, getIncidentUpdates, getIpAccessControl, getIpGeolocation, getJoinTokenStatus, getLastDeployment, getLatestScan, getLatestScansPerEnvironment, getLiveVisitorsList, getLogContext, getMcp, getMetricsOverTime, getMonitor, getNotificationProvider, getOnDemandCertStatus, getOrCreateDsn, getPageFlow, getPageHourlySessions, getPagePathDetail, getPagePaths, getPagePathsSparklines, getPagePathVisitors, getPendingAction, getPerformanceMetrics, getPgUpgrade, getPgUpgradeLogs, getPipelineStats, getPlatformInfo, getPostgresWalHealth, getPreferences, getPreviewGatewayLogs, getPreviewGatewaySettings, getPreviewGatewayStatus, getPricing, getPrivateIp, getProject, getProjectAlarmsSummary, getProjectBySlug, getProjectDeployments, getProjects, getProjectServiceEnvironmentVariables, getProjectSessionReplays, getProjectsHealth, getProjectsMonitorHealth, getProjectStatistics, getProjectTemplate, getPropertyBreakdown, getPropertyTimeline, getProviderConnections, getProviderMetadata, getProvidersMetadata, getProxyLogById, getProxyLogByRequestId, getProxyLogs, getPublicBranches, getPublicIp, getPublicRepository, getQueryContainerInfo, getQuota, getRecentActivity, getRemoteExternalImage, getRepositoryBranches, getRepositoryById, getRepositoryByName, getRepositoryPresetByName, getRepositoryPresetLive, getRepositoryTags, getResolvedEnvironmentVariables, getResolvedEnvironmentVariableValue, getRestoreCapabilities, getRestoreRun, getRoute, getRun, getRunWithLogs, getS3Credentials, getS3Source, getSandbox, getSandboxStatus, getScan, getScanByDeployment, getScanVulnerabilities, getService, getServiceBySlug, getServiceEnvironmentVariable, getServiceEnvironmentVariables, getServiceHealthStatus, getServicePreviewEnvironmentVariableNames, getServicePreviewEnvironmentVariablesMasked, getServiceRuntime, getServiceStats, getServiceTypeParameters, getServiceTypes, getSessionDetails, getSessionEvents, getSessionLogs, getSessionReplay, getSessionReplayEvents, getSettings, getSkill, getSlowQueries, getStaticBundle, getStatusOverview, getTagsByRepositoryId, getTeam, getTimeBucketStats, getTodayStats, getTrace, getUnifiedTrace, getUniqueCounts, getUniqueEvents, getUpdateStatus, getUptimeHistory, getUsageByProvider, getUsageRecent, getUsageSummary, getUsageTimeseries, getUsageTopModels, getVisitorByGuid, getVisitorById, getVisitorDetails, getVisitorFacets, getVisitorInfo, getVisitorJourney, getVisitors, getVisitorSessions, getVisitorStats, getWebhook, grantProjectAccess, handleGitProviderOauthCallback, hasAnalyticsEvents, hasErrorGroups, hasPerformanceMetrics, importExternalService, ingestLogs, ingestLogsByPath, ingestMetrics, ingestMetricsByPath, ingestSentryEnvelope, ingestSentryEvent, ingestTraces, ingestTracesByPath, initSessionReplay, inspectDropArchive, jobLogs, jobStatus, killJob, kvDel, kvDisable, kvEnable, kvExpire, kvGet, kvIncr, kvKeys, kvSet, kvStatus, kvTtl, kvUpdate, latestRunForSource, linkCustomDomainToCertificate, linkServiceToProject, listAgentRuns, listAgents, listAiProviders, listAlertRules, listAlerts, listAllConversations, listAllRuns, listApiKeys, listAuditLogs, listAvailableContainers, listBackupAlerts, listBackupChildren, listBackupSchedules, listBackupsForSchedule, listCommitsByRepositoryId, listConnections, listContainers, listContainersAtPath, listConversations, listCustomDomainsForProject, listDashboards, listDeliveries, listDeploymentContainerLogs, listDeploymentTokens, listDnsProviders, listDomains, listDsns, listEmailDomains, listEmailProviders, listEmails, listEnrollmentTokens, listEntities, listErrorEvents, listErrorGroups, listEvents, listEventTypes, listExternalImages, listExternalPlugins, listExternalServiceBackups, listFlags, listFunnels, listGitProviders, listGlobalMcps, listGlobalSkills, listIncidents, listInsights, listIpAccessControl, listJobs, listKnownAiAgents, listManagedDomains, listMcps, listMetricLabelKeys, listMetricLabelValues, listMetricNames, listModels, listMonitors, listNotificationProviders, listOidcProviders, listOidcProviderUsers, listOidcRoleMappings, listOnDemandCerts, listOrders, listPeers, listPendingActions, listPgUpgrades, listPresets, listProjectAccess, listProjectAlarms, listProjectScans, listProjectSecrets, listProjectServices, listProjectTemplates, listProjectTemplateTags, listProviderKeys, listProviderZones, listPublicProviders, listReleaseFiles, listReleases, listRemoteExternalImages, listRepositoriesByConnection, listRepositoriesByProvider, listRestoreRunsForService, listRootContainers, listRoutes, listS3Sources, listSandboxes, listScheduleRunJobs, listScheduleRuns, listScheduleServices, listSecrets, listServiceHealthStatuses, listServiceProjects, listServices, listServiceSchedules, listSkills, listSourceBackups, listSourceFiles, listSourceMaps, listSources, listStaticBundles, listSyncedRepositories, listTeamMembers, listTeamProjects, listTeams, listUsers, listWebhooks, login, logout, lookupDnsARecords, mintEnrollmentToken, mkdir, nodeHeartbeat, nodeMetricsGetRange, observabilityFullEvent, observabilityListEvents, oidcCallback, type Options, patchAdminGate, patchPreviewGatewaySettings, pauseDeployment, pauseSandbox, planRestore, postDnsAck, previewAlert, previewFunnelMetrics, previewHostnameMode, promoteClusterMember, promoteDeployment, provisionDomain, purgeProjectLogs, pushExternalImage, queryData, queryGenaiTraces, queryLogs, queryMetrics, querySpanStats, queryTraces, queryTraceSummaries, readEntityRows, readFile, reAnalyze, recordConsoleEvent, recordEventMetrics, recordFlagExposure, recordSpeedMetrics, refreshRouteTable, regenerateDsn, registerExternalImage, registerNode, reinstallGitlabWebhook, rejectPendingAction, reloadPlugins, removeClusterMember, removeManagedDomain, removeRole, removeTeamMember, renameConversation, renewDomain, requestPasswordReset, resetPassword, resizeSandbox, resolveAlarm, restartContainer, restartPreviewGateway, restartSandbox, restoreFlag, restoreUser, resumeDeployment, resumeSandbox, retryCluster, retryDelivery, retryPgUpgrade, retryRun, revealGlobalMcpConfig, revealMcpConfig, revealNotificationProviderConfig, revealServiceParameter, revenueCreateIntegration, revenueDeleteIntegration, revenueGlobalEvents, revenueImportInvoicesCsv, revenueImportSubscriptionsCsv, revenueListIntegrations, revenueListProviders, revenueMetricsCustomers, revenueMetricsGlobalMrr, revenueMetricsGlobalSummary, revenueMetricsMrr, revenueMetricsSummary, revenueRecentEvents, revenueRotateToken, revenueUpdateConfig, revenueUpdateSecret, revokeDsn, revokeEnrollmentToken, revokeJoinToken, revokeProjectAccess, rollbackPgUpgrade, rollbackToDeployment, rootfsGc, rootfsReport, rotateApiKey, rotateDeploymentToken, runBackupForSource, runConnectionHealthCheck, runExternalServiceBackup, runScheduleNow, sandboxCreatePreviewLink, saveAgentToken, saveAiProviderCredential, searchLogs, sendEmail, setAiDataAccess, setDefaultS3Source, setFlagEnvironment, setPreviewPassword, setupDns, setupDnsChallenge, setupEmailTracking, setupMfa, sleepEnvironment, smokeTestAgent, sourceSandbox, startAnalysis, startContainer, startFix, startGitProviderOauth, startOidcLoginBySlug, startPgUpgrade, startRestore, startService, statPath, stopContainer, stopSandbox, stopService, streamContainerMetrics, syncRepositories, tailDeploymentJobLogs, tailLogs, teardownDeployment, teardownEnvironment, testNotificationProvider, testOidcProvider, testProvider, testProviderConnection, testProviderKeyById, testProviderKeyInline, testS3ConnectionPreview, testS3SourceConnection, trackClick, trackOpen, triggerAgent, triggerProjectPipeline, triggerScan, triggerServiceHealthCheck, triggerWeeklyDigest, unlinkServiceFromProject, updateAgent, updateAiProvider, updateAlert, updateAlertRule, updateApiKey, updateAutomaticDeploy, updateBackupSchedule, updateCloudflareProvider, updateConnectionToken, updateCustomDomain, updateDashboard, updateDeploymentToken, updateEmailProvider, updateEnvironmentSettings, updateEnvironmentSubdomain, updateEnvironmentVariable, updateErrorGroup, updateFlag, updateFunnel, updateGitProviderCredentials, updateGitSettings, updateGlobalMcp, updateGlobalSkill, updateIncidentStatus, updateIpAccessControl, updateManagedDomain, updateMcp, updateNotificationEmailProvider, updateNotificationProvider, updateOidcProvider, updatePreferences, updateProject, updateProjectDeploymentConfig, updateProjectSecret, updateProjectSettings, updateProvider, updateProviderKey, updateRoute, updateS3Source, updateSelf, updateService, updateServiceResources, updateSessionDuration, updateSettings, updateSkill, updateSlackProvider, updateSpeedMetrics, updateTeam, updateTeamMemberRole, updateUser, updateWebhook, updateWebhookProvider, upgradePreviewGateway, upgradeService, uploadGlobalSkill, uploadReleaseFile, uploadSkill, uploadSourceFile, uploadSourceMap, uploadStaticBundle, upsertSecret, validateConnection, validateEmail, verifyAndEnableMfa, verifyDomain, verifyEmail, verifyManagedDomain, verifyMfaChallenge, verifyStepUp, wakeEnvironment, webhookTrigger, workflowDryRun, writeFile, writeFiles } from '../sdk.gen'; -import type { AcknowledgeAlarmData, ActivateAiProviderData, ActivateAiProviderResponse, ActivateApiKeyData, ActivateApiKeyResponse, ActivateConnectionData, ActivateProviderData, AddClusterMemberData, AddClusterMemberResponse, AddContextData, AddEnvironmentDomainData, AddEnvironmentDomainResponse, AddEventsData, AddEventsError, AddEventsResponse2, AddManagedDomainData, AddManagedDomainResponse, AddSessionReplayEventsData, AddSessionReplayEventsError, AddSessionReplayEventsResponse, AddTeamMemberData, AddTeamMemberResponse, AdminDrainNodeData, AdminDrainNodeResponse, AdminDrainStatusData, AdminDrainStatusResponse, AdminGetNodeData, AdminGetNodeResponse, AdminListNodeContainersData, AdminListNodeContainersResponse, AdminListNodesData, AdminListNodesResponse, AdminRemoveNodeData, AdminRemoveNodeResponse, AdminUndrainNodeData, AdminUndrainNodeResponse, ApplyHostnameModeData, ApplyHostnameModeResponse, ArchiveConversationData, ArchiveConversationResponse, ArchiveFlagData, ArchiveFlagResponse2, AssignRoleData, AttachScheduleServicesData, AttachScheduleServicesError, AttachScheduleServicesResponse2, BlobCopyData, BlobCopyError, BlobCopyResponse, BlobDeleteData, BlobDeleteError, BlobDeleteResponse, BlobDisableData, BlobDisableResponse, BlobDownloadData, BlobDownloadError, BlobEnableData, BlobEnableResponse, BlobListData, BlobListError, BlobListResponse, BlobPutData, BlobPutError, BlobPutResponse, BlobStatusData, BlobStatusResponse2, BlobUpdateData, BlobUpdateResponse, CancelBackupData, CancelBackupError, CancelBackupResponse2, CancelData, CancelDeploymentData, CancelDeploymentResponse, CancelDomainOrderData, CancelDomainOrderResponse, CancelPgUpgradeData, CancelPgUpgradeResponse, CancelRunData, CancelRunResponse, CancelScheduleRunData, CancelScheduleRunError, CancelScheduleRunResponse, ChangePasswordSelfData, ChangePasswordSelfResponse, ChangeProjectSourceData, ChangeProjectSourceResponse, ChangeRequiredPasswordData, ChangeRequiredPasswordResponse, ChatCompletionsData, ChatCompletionsError, ChatCompletionsResponse, CheckAnalyticsHasEventsData, CheckAnalyticsHasEventsResponse, CheckCommitExistsData, CheckCommitExistsResponse, CheckDomainStatusData, CheckDomainStatusResponse, CheckExplorerSupportData, CheckExplorerSupportResponse, CheckIpBlockedData, CheckIpBlockedError, CheckProviderDeletionSafetyData, CheckProviderDeletionSafetyResponse, ChunkUploadOptionsData, ChunkUploadOptionsResponse, CleanupExpiredBackupsData, CleanupExpiredBackupsError, CleanupExpiredBackupsResponse, ClearPreviewPasswordData, ClearPreviewPasswordResponse, CliDeviceApproveData, CliDeviceApproveResponse2, CliDeviceDenyData, CliDeviceDenyResponse, CliDeviceLookupData, CliDeviceLookupResponse2, CliDevicePollData, CliDevicePollResponse2, CliDeviceStartData, CliDeviceStartResponse2, CliLogoutData, CliLogoutResponse, CmdData, CmdKillData, CmdKillResponse, CmdLogsData, CmdResponse2, ConfirmPendingActionData, ConfirmPendingActionResponse, ContainerMetricsGetHistoryData, ContainerMetricsGetHistoryResponse, CreateAgentData, CreateAgentResponse, CreateAlertData, CreateAlertError, CreateAlertResponse, CreateAlertRuleData, CreateAlertRuleResponse, CreateApiKeyData, CreateApiKeyResponse2, CreateBackupScheduleData, CreateBackupScheduleError, CreateBackupScheduleResponse, CreateBitbucketProviderData, CreateBitbucketProviderResponse, CreateCloudflareProviderData, CreateCloudflareProviderResponse, CreateConversationData, CreateConversationResponse, CreateCustomDomainData, CreateCustomDomainResponse, CreateDashboardData, CreateDashboardError, CreateDashboardResponse, CreateDeploymentTokenData, CreateDeploymentTokenResponse2, CreateDnsProviderData, CreateDnsProviderResponse, CreateDomainData, CreateDomainResponse, CreateDsnData, CreateDsnResponse, CreateEmailDomainData, CreateEmailDomainResponse, CreateEmailProviderData, CreateEmailProviderResponse, CreateEnvironmentData, CreateEnvironmentResponse, CreateEnvironmentVariableData, CreateEnvironmentVariableResponse, CreateFlagData, CreateFlagResponse, CreateFunnelData, CreateFunnelResponse2, CreateGenericProviderData, CreateGenericProviderResponse, CreateGiteaPatProviderData, CreateGiteaPatProviderResponse, CreateGithubPatProviderData, CreateGithubPatProviderResponse, CreateGitlabOauthProviderData, CreateGitlabOauthProviderResponse, CreateGitlabPatProviderData, CreateGitlabPatProviderResponse, CreateGitProviderData, CreateGitProviderResponse, CreateGlobalMcpData, CreateGlobalMcpResponse, CreateGlobalSkillData, CreateGlobalSkillResponse, CreateIncidentData, CreateIncidentResponse, CreateIpAccessControlData, CreateIpAccessControlError, CreateIpAccessControlResponse, CreateMcpData, CreateMcpResponse, CreateMonitorData, CreateMonitorResponse, CreateNotificationEmailProviderData, CreateNotificationEmailProviderResponse, CreateNotificationProviderData, CreateNotificationProviderResponse, CreateOidcProviderData, CreateOidcProviderResponse, CreateOidcRoleMappingData, CreateOidcRoleMappingResponse, CreateOrRecreateOrderData, CreateOrRecreateOrderResponse, CreatePlanData, CreatePlanResponse2, CreatePrData, CreateProjectData, CreateProjectFromTemplateData, CreateProjectFromTemplateResponse2, CreateProjectReleaseData, CreateProjectReleaseResponse, CreateProjectResponse, CreateProjectSecretData, CreateProjectSecretResponse, CreateProviderKeyData, CreateProviderKeyError, CreateProviderKeyResponse, CreatePrResponse2, CreateReleaseData, CreateReleaseResponse, CreateRouteData, CreateRouteResponse, CreateS3SourceData, CreateS3SourceError, CreateS3SourceResponse, CreateSandboxData, CreateSandboxResponse, CreateServiceData, CreateServiceResponse, CreateSkillData, CreateSkillResponse, CreateSlackProviderData, CreateSlackProviderResponse, CreateTeamData, CreateTeamResponse, CreateUserData, CreateUserResponse, CreateWebhookData, CreateWebhookProviderData, CreateWebhookProviderResponse, CreateWebhookResponse, DeactivateApiKeyData, DeactivateApiKeyResponse, DeactivateConnectionData, DeactivateProviderData, DeleteAgentData, DeleteAgentResponse, DeleteAlertData, DeleteAlertError, DeleteAlertResponse, DeleteAlertRuleData, DeleteAlertRuleResponse, DeleteApiKeyData, DeleteApiKeyResponse, DeleteBackupData, DeleteBackupError, DeleteBackupResponse, DeleteBackupScheduleData, DeleteBackupScheduleError, DeleteBackupScheduleResponse, DeleteConnectionData, DeleteConnectionResponse, DeleteCustomDomainData, DeleteCustomDomainResponse, DeleteDashboardData, DeleteDashboardError, DeleteDashboardResponse, DeleteDeploymentTokenData, DeleteDeploymentTokenResponse, DeleteDnsProviderData, DeleteDnsProviderResponse, DeleteDomainData, DeleteDomainResponse, DeleteEmailDomainData, DeleteEmailDomainResponse, DeleteEmailProviderData, DeleteEmailProviderResponse, DeleteEnvironmentData, DeleteEnvironmentDomainData, DeleteEnvironmentDomainResponse, DeleteEnvironmentResponse, DeleteEnvironmentVariableData, DeleteEnvironmentVariableResponse, DeleteExternalImageData, DeleteExternalImageResponse, DeleteFunnelData, DeleteGitProviderData, DeleteGitProviderResponse, DeleteGlobalMcpData, DeleteGlobalMcpResponse, DeleteGlobalSkillData, DeleteGlobalSkillResponse, DeleteIpAccessControlData, DeleteIpAccessControlError, DeleteIpAccessControlResponse, DeleteMcpData, DeleteMcpResponse, DeleteMonitorData, DeleteMonitorResponse, DeleteNotificationProviderData, DeleteNotificationProviderResponse, DeleteOidcProviderData, DeleteOidcProviderResponse, DeleteOidcRoleMappingData, DeleteOidcRoleMappingResponse, DeletePreferencesData, DeletePreferencesResponse, DeleteProjectData, DeleteProjectResponse, DeleteProjectSecretData, DeleteProjectSecretResponse, DeleteProviderKeyData, DeleteProviderKeyError, DeleteProviderKeyResponse, DeleteProviderSafelyData, DeleteProviderSafelyResponse, DeleteReleaseSourceFilesData, DeleteReleaseSourceFilesResponse, DeleteReleaseSourceMapsData, DeleteReleaseSourceMapsResponse, DeleteRouteData, DeleteRouteResponse, DeleteS3SourceData, DeleteS3SourceError, DeleteS3SourceResponse, DeleteScanData, DeleteScanError, DeleteScanResponse, DeleteSecretData, DeleteSecretResponse, DeleteServiceData, DeleteServiceResponse, DeleteSessionReplayData, DeleteSessionReplayError, DeleteSkillData, DeleteSkillResponse, DeleteSourceMapData, DeleteSourceMapResponse, DeleteStaticBundleData, DeleteStaticBundleResponse, DeleteTeamData, DeleteTeamResponse, DeleteUserData, DeleteUserResponse, DeleteWebhookData, DeleteWebhookResponse, DeployFromImageData, DeployFromImageResponse, DeployFromImageUploadData, DeployFromImageUploadResponse, DeployFromStaticData, DeployFromStaticResponse, DeployFromUploadedSourceData, DeployFromUploadedSourceResponse, DeploymentMetricsGetLatestData, DeploymentMetricsGetLatestResponse, DeploymentMetricsGetRangeData, DeploymentMetricsGetRangeResponse, DeploymentMetricsToggleData, DestroySandboxData, DestroySandboxResponse, DetachScheduleServiceData, DetachScheduleServiceError, DetachScheduleServiceResponse, DetectPublicPresetsData, DetectPublicPresetsResponse, DisableBackupScheduleData, DisableBackupScheduleResponse, DisableMfaData, DisableMfaResponse, DiscoverWorkloadsData, DiscoverWorkloadsResponse, DomainData, DomainResponse2, DownloadGlobalSkillArchiveData, DownloadGlobalSkillArchiveResponse, DownloadObjectData, DownloadObjectResponse, DownloadSkillArchiveData, DownloadSkillArchiveResponse, EmailStatusData, EmailStatusResponse2, EmbeddingsData, EmbeddingsError, EmbeddingsResponse, EnableBackupScheduleData, EnableBackupScheduleResponse, EnrichVisitorData, EnrichVisitorResponse2, ExecData, ExecDetachedData, ExecDetachedResponse2, ExecResponse2, ExecuteDeploymentOperationData, ExecuteDeploymentOperationResponse, ExecuteImportData, ExecuteImportResponse2, ExtendTimeoutData, ExtendTimeoutResponse, ExternalServiceEnablePgStatStatementsData, ExternalServiceEnablePgStatStatementsResponse, ExternalServiceMetricsByDatabaseData, ExternalServiceMetricsByDatabaseResponse, ExternalServiceMetricsCreateAlertRuleData, ExternalServiceMetricsCreateAlertRuleResponse, ExternalServiceMetricsDeleteAlertRuleData, ExternalServiceMetricsDeleteAlertRuleResponse, ExternalServiceMetricsGetAlertRulesData, ExternalServiceMetricsGetAlertRulesResponse, ExternalServiceMetricsGetLatestData, ExternalServiceMetricsGetLatestResponse, ExternalServiceMetricsGetRangeData, ExternalServiceMetricsGetRangeResponse, ExternalServiceMetricsStatusData, ExternalServiceMetricsStatusResponse, ExternalServiceMetricsToggleData, ExternalServiceMetricsUpdateAlertRuleData, ExternalServiceMetricsUpdateAlertRuleResponse, ExternalServiceResetPgStatStatementsData, ExternalServiceResetPgStatStatementsResponse, FinalizeOrderData, FinalizeOrderResponse, FinalizeProjectReleaseData, FinalizeProjectReleaseResponse, FindConversationData, FindConversationResponse, GenerateJoinTokenData, GenerateJoinTokenResponse2, GeneratePresetDockerfileData, GeneratePresetDockerfileResponse, GetAccessInfoData, GetAccessInfoResponse, GetActiveVisitorsData, GetActiveVisitorsResponse, GetActivityGraphData, GetActivityGraphResponse, GetAdminGateData, GetAdminGateResponse, GetAgentData, GetAgentResponse, GetAggregatedBucketsData, GetAggregatedBucketsResponse, GetAiAgentBreakdownData, GetAiAgentBreakdownError, GetAiAgentBreakdownResponse, GetAiAgentPagesData, GetAiAgentPagesError, GetAiAgentPagesResponse, GetAiAgentTimelineData, GetAiAgentTimelineError, GetAiAgentTimelineResponse, GetAiDataAccessData, GetAiDataAccessResponse, GetAiPageBreakdownData, GetAiPageBreakdownError, GetAiPageBreakdownResponse, GetAiStatusBreakdownData, GetAiStatusBreakdownError, GetAiStatusBreakdownResponse, GetAlertData, GetAlertError, GetAlertResponse, GetAlertRuleData, GetAlertRuleResponse, GetAllRepositoriesByNameData, GetAllRepositoriesByNameResponse, GetAnalyticsActiveVisitorsData, GetAnalyticsActiveVisitorsResponse, GetAnalyticsEventsCountData, GetAnalyticsEventsCountResponse, GetAnalyticsSessionEventsData, GetAnalyticsSessionEventsResponse, GetAnalyticsVisitorSessionsData, GetAnalyticsVisitorSessionsResponse, GetApiKeyData, GetApiKeyPermissionsData, GetApiKeyPermissionsResponse, GetApiKeyResponse, GetAuditLogData, GetAuditLogResponse, GetBackupData, GetBackupError, GetBackupResponse, GetBackupScheduleData, GetBackupScheduleResponse, GetBranchesByRepositoryIdData, GetBranchesByRepositoryIdResponse, GetBucketedIncidentsData, GetBucketedIncidentsResponse, GetBucketedStatusData, GetBucketedStatusResponse, GetChallengeTokenData, GetChallengeTokenResponse, GetChatReadinessData, GetChatReadinessResponse, GetCliStatusData, GetClusterHealthData, GetClusterHealthResponse, GetClusterMemberData, GetClusterMemberResponse, GetCmdData, GetCmdResponse, GetContainerDetailData, GetContainerDetailResponse, GetContainerEnvironmentVariableData, GetContainerEnvironmentVariableResponse, GetContainerLogsByIdData, GetContainerLogsData, GetContainerMetricsData, GetContainerMetricsResponse, GetConversationData, GetConversationDetailData, GetConversationDetailError, GetConversationDetailResponse, GetConversationResponse, GetConversationsData, GetConversationsError, GetConversationsResponse, GetCronByIdData, GetCronByIdResponse, GetCronExecutionsData, GetCronExecutionsResponse, GetCrossProjectTraceSiblingsData, GetCrossProjectTraceSiblingsError, GetCrossProjectTraceSiblingsResponse, GetCurrentMonitorStatusData, GetCurrentMonitorStatusResponse, GetCurrentUserData, GetCurrentUserResponse, GetCustomDomainData, GetCustomDomainResponse, GetDashboardData, GetDashboardError, GetDashboardProjectsAnalyticsData, GetDashboardProjectsAnalyticsResponse, GetDashboardResponse, GetDeliveryData, GetDeliveryResponse, GetDeploymentContainerLogContentData, GetDeploymentContainerLogContentResponse, GetDeploymentData, GetDeploymentJobLogsData, GetDeploymentJobLogsResponse, GetDeploymentJobsData, GetDeploymentJobsResponse, GetDeploymentOperationsData, GetDeploymentOperationsResponse, GetDeploymentOperationStatusData, GetDeploymentOperationStatusResponse, GetDeploymentResponse, GetDeploymentTokenData, GetDeploymentTokenResponse, GetDiskStatusData, GetDiskStatusResponse, GetDnsChangesData, GetDnsChangesResponse, GetDnsProviderData, GetDnsProviderResponse, GetDomainByHostData, GetDomainByHostResponse, GetDomainByIdData, GetDomainByIdResponse, GetDomainByNameData, GetDomainByNameResponse, GetDomainData, GetDomainDnsRecordsData, GetDomainDnsRecordsResponse, GetDomainOrderData, GetDomainOrderResponse, GetDomainResponse, GetEmailData, GetEmailEventsData, GetEmailEventsResponse, GetEmailLinksData, GetEmailLinksResponse, GetEmailProviderData, GetEmailProviderResponse, GetEmailResponse, GetEmailStatsData, GetEmailStatsResponse, GetEmailTrackingData, GetEmailTrackingResponse, GetEmailTrackingStatusData, GetEmailTrackingStatusResponse, GetEntityInfoData, GetEntityInfoResponse, GetEnvironmentCronsData, GetEnvironmentCronsResponse, GetEnvironmentData, GetEnvironmentDomainsData, GetEnvironmentDomainsResponse, GetEnvironmentResponse, GetEnvironmentsData, GetEnvironmentsResponse, GetEnvironmentVariablesData, GetEnvironmentVariablesResponse, GetEnvironmentVariableValueData, GetEnvironmentVariableValueResponse, GetErrorDashboardStatsData, GetErrorDashboardStatsResponse, GetErrorEventData, GetErrorEventResponse, GetErrorGroupData, GetErrorGroupResponse, GetErrorStatsData, GetErrorStatsResponse, GetErrorTimeSeriesData, GetErrorTimeSeriesResponse, GetEventDetailData, GetEventDetailResponse, GetEventEntriesData, GetEventEntriesResponse, GetEventsCountData, GetEventsCountResponse, GetEventsTimelineData, GetEventsTimelineResponse, GetEventTypeBreakdownData, GetEventTypeBreakdownResponse, GetEventVisitorsData, GetEventVisitorsResponse, GetExternalImageData, GetExternalImageResponse, GetFileData, GetFileResponse, GetFlagData, GetFlagResponse, GetFlagSnapshotData, GetFlagSnapshotResponse, GetFunnelMetricsData, GetFunnelMetricsResponse, GetGenaiTraceData, GetGenaiTraceError, GetGenaiTraceResponse, GetGeneralStatsData, GetGeneralStatsResponse, GetGitProviderData, GetGitProviderResponse, GetGlobalEventsData, GetGlobalEventsResponse, GetGlobalEventStatsData, GetGlobalEventStatsResponse, GetGlobalMcpData, GetGlobalMcpResponse, GetGlobalSandboxStatusData, GetGlobalSandboxStatusResponse, GetGlobalSkillData, GetGlobalSkillResponse, GetGroupedPageMetricsData, GetGroupedPageMetricsError, GetGroupedPageMetricsResponse, GetHealthData, GetHealthError, GetHealthResponse, GetHourlyVisitsData, GetHourlyVisitsResponse, GetHttpChallengeDebugData, GetHttpChallengeDebugResponse, GetImportStatusData, GetImportStatusResponse, GetIncidentData, GetIncidentResponse, GetIncidentUpdatesData, GetIncidentUpdatesResponse, GetIpAccessControlData, GetIpAccessControlError, GetIpAccessControlResponse, GetIpGeolocationData, GetIpGeolocationError, GetIpGeolocationResponse, GetJoinTokenStatusData, GetJoinTokenStatusResponse, GetLastDeploymentData, GetLastDeploymentResponse, GetLatestScanData, GetLatestScanError, GetLatestScanResponse, GetLatestScansPerEnvironmentData, GetLatestScansPerEnvironmentError, GetLatestScansPerEnvironmentResponse, GetLiveVisitorsListData, GetLiveVisitorsListResponse, GetLogContextData, GetLogContextError, GetLogContextResponse, GetMcpData, GetMcpResponse, GetMetricsOverTimeData, GetMetricsOverTimeError, GetMetricsOverTimeResponse, GetMonitorData, GetMonitorResponse, GetNotificationProviderData, GetNotificationProviderResponse, GetOnDemandCertStatusData, GetOnDemandCertStatusResponse, GetOrCreateDsnData, GetOrCreateDsnResponse, GetPageFlowData, GetPageFlowResponse, GetPageHourlySessionsData, GetPageHourlySessionsResponse, GetPagePathDetailData, GetPagePathDetailResponse, GetPagePathsData, GetPagePathsResponse, GetPagePathsSparklinesData, GetPagePathsSparklinesResponse, GetPagePathVisitorsData, GetPagePathVisitorsResponse, GetPendingActionData, GetPendingActionResponse, GetPerformanceMetricsData, GetPerformanceMetricsError, GetPerformanceMetricsResponse, GetPgUpgradeData, GetPgUpgradeLogsData, GetPgUpgradeLogsResponse, GetPgUpgradeResponse, GetPipelineStatsData, GetPipelineStatsError, GetPipelineStatsResponse, GetPlatformInfoData, GetPlatformInfoResponse, GetPostgresWalHealthData, GetPostgresWalHealthResponse, GetPreferencesData, GetPreferencesResponse, GetPreviewGatewayLogsData, GetPreviewGatewayLogsResponse, GetPreviewGatewaySettingsData, GetPreviewGatewaySettingsResponse, GetPreviewGatewayStatusData, GetPreviewGatewayStatusResponse, GetPricingData, GetPricingError, GetPricingResponse, GetPrivateIpData, GetProjectAlarmsSummaryData, GetProjectAlarmsSummaryResponse, GetProjectBySlugData, GetProjectBySlugResponse, GetProjectData, GetProjectDeploymentsData, GetProjectDeploymentsResponse, GetProjectResponse, GetProjectsData, GetProjectServiceEnvironmentVariablesData, GetProjectServiceEnvironmentVariablesResponse, GetProjectSessionReplaysData, GetProjectSessionReplaysError, GetProjectSessionReplaysResponse2, GetProjectsHealthData, GetProjectsHealthError, GetProjectsHealthResponse, GetProjectsMonitorHealthData, GetProjectsMonitorHealthResponse, GetProjectsResponse, GetProjectStatisticsData, GetProjectStatisticsResponse, GetProjectTemplateData, GetProjectTemplateResponse, GetPropertyBreakdownData, GetPropertyBreakdownResponse, GetPropertyTimelineData, GetPropertyTimelineResponse, GetProviderConnectionsData, GetProviderConnectionsResponse, GetProviderMetadataData, GetProviderMetadataResponse, GetProvidersMetadataData, GetProvidersMetadataResponse, GetProxyLogByIdData, GetProxyLogByIdError, GetProxyLogByIdResponse, GetProxyLogByRequestIdData, GetProxyLogByRequestIdError, GetProxyLogByRequestIdResponse, GetProxyLogsData, GetProxyLogsError, GetProxyLogsResponse, GetPublicBranchesData, GetPublicBranchesResponse, GetPublicIpData, GetPublicRepositoryData, GetPublicRepositoryResponse, GetQueryContainerInfoData, GetQueryContainerInfoResponse, GetQuotaData, GetQuotaError, GetQuotaResponse, GetRecentActivityData, GetRecentActivityResponse, GetRemoteExternalImageData, GetRemoteExternalImageResponse, GetRepositoryBranchesData, GetRepositoryBranchesResponse, GetRepositoryByIdData, GetRepositoryByIdResponse, GetRepositoryByNameData, GetRepositoryByNameResponse, GetRepositoryPresetByNameData, GetRepositoryPresetByNameResponse, GetRepositoryPresetLiveData, GetRepositoryPresetLiveResponse, GetRepositoryTagsData, GetRepositoryTagsResponse, GetResolvedEnvironmentVariablesData, GetResolvedEnvironmentVariablesResponse, GetResolvedEnvironmentVariableValueData, GetResolvedEnvironmentVariableValueResponse, GetRestoreCapabilitiesData, GetRestoreCapabilitiesError, GetRestoreCapabilitiesResponse, GetRestoreRunData, GetRestoreRunError, GetRestoreRunResponse, GetRouteData, GetRouteResponse, GetRunData, GetRunResponse, GetRunWithLogsData, GetRunWithLogsResponse, GetS3CredentialsData, GetS3CredentialsResponse, GetS3SourceData, GetS3SourceError, GetS3SourceResponse, GetSandboxData, GetSandboxResponse, GetSandboxStatusData, GetSandboxStatusResponse, GetScanByDeploymentData, GetScanByDeploymentError, GetScanByDeploymentResponse, GetScanData, GetScanError, GetScanResponse, GetScanVulnerabilitiesData, GetScanVulnerabilitiesError, GetScanVulnerabilitiesResponse, GetServiceBySlugData, GetServiceBySlugResponse, GetServiceData, GetServiceEnvironmentVariableData, GetServiceEnvironmentVariableResponse, GetServiceEnvironmentVariablesData, GetServiceEnvironmentVariablesResponse, GetServiceHealthStatusData, GetServiceHealthStatusResponse, GetServicePreviewEnvironmentVariableNamesData, GetServicePreviewEnvironmentVariableNamesResponse, GetServicePreviewEnvironmentVariablesMaskedData, GetServicePreviewEnvironmentVariablesMaskedResponse, GetServiceResponse, GetServiceRuntimeData, GetServiceRuntimeResponse, GetServiceStatsData, GetServiceStatsResponse, GetServiceTypeParametersData, GetServiceTypesData, GetServiceTypesResponse, GetSessionDetailsData, GetSessionDetailsResponse, GetSessionEventsData, GetSessionEventsResponse, GetSessionLogsData, GetSessionLogsResponse, GetSessionReplayData, GetSessionReplayError, GetSessionReplayEventsData, GetSessionReplayEventsError, GetSessionReplayEventsResponse, GetSessionReplayResponse2, GetSettingsData, GetSettingsResponse, GetSkillData, GetSkillResponse, GetSlowQueriesData, GetSlowQueriesResponse, GetStaticBundleData, GetStaticBundleResponse, GetStatusOverviewData, GetStatusOverviewResponse, GetTagsByRepositoryIdData, GetTagsByRepositoryIdResponse, GetTeamData, GetTeamResponse, GetTimeBucketStatsData, GetTimeBucketStatsError, GetTimeBucketStatsResponse, GetTodayStatsData, GetTodayStatsError, GetTodayStatsResponse, GetTraceData, GetTraceError, GetTraceResponse, GetUnifiedTraceData, GetUnifiedTraceError, GetUnifiedTraceResponse, GetUniqueCountsData, GetUniqueCountsResponse, GetUniqueEventsData, GetUniqueEventsResponse, GetUpdateStatusData, GetUpdateStatusResponse, GetUptimeHistoryData, GetUptimeHistoryResponse, GetUsageByProviderData, GetUsageByProviderError, GetUsageByProviderResponse, GetUsageRecentData, GetUsageRecentError, GetUsageRecentResponse, GetUsageSummaryData, GetUsageSummaryError, GetUsageSummaryResponse, GetUsageTimeseriesData, GetUsageTimeseriesError, GetUsageTimeseriesResponse, GetUsageTopModelsData, GetUsageTopModelsError, GetUsageTopModelsResponse, GetVisitorByGuidData, GetVisitorByGuidResponse, GetVisitorByIdData, GetVisitorByIdResponse, GetVisitorDetailsData, GetVisitorDetailsResponse, GetVisitorFacetsData, GetVisitorFacetsResponse, GetVisitorInfoData, GetVisitorInfoResponse, GetVisitorJourneyData, GetVisitorJourneyResponse, GetVisitorsData, GetVisitorSessionsData, GetVisitorSessionsError, GetVisitorSessionsResponse2, GetVisitorsResponse, GetVisitorStatsData, GetVisitorStatsResponse, GetWebhookData, GetWebhookResponse, GrantProjectAccessData, GrantProjectAccessResponse, HandleGitProviderOauthCallbackData, HasAnalyticsEventsData, HasAnalyticsEventsResponse2, HasErrorGroupsData, HasErrorGroupsResponse2, HasPerformanceMetricsData, HasPerformanceMetricsError, HasPerformanceMetricsResponse, ImportExternalServiceData, ImportExternalServiceResponse, IngestLogsByPathData, IngestLogsByPathError, IngestLogsData, IngestLogsError, IngestMetricsByPathData, IngestMetricsByPathError, IngestMetricsData, IngestMetricsError, IngestSentryEnvelopeData, IngestSentryEventData, IngestSentryEventResponse, IngestTracesByPathData, IngestTracesByPathError, IngestTracesData, IngestTracesError, InitSessionReplayData, InitSessionReplayError, InitSessionReplayResponse, InspectDropArchiveData, InspectDropArchiveResponse, JobLogsData, JobStatusData, JobStatusResponse2, KillJobData, KillJobResponse, KvDelData, KvDelResponse, KvDisableData, KvDisableResponse, KvEnableData, KvEnableResponse, KvExpireData, KvExpireResponse, KvGetData, KvGetResponse, KvIncrData, KvIncrResponse, KvKeysData, KvKeysResponse, KvSetData, KvSetResponse, KvStatusData, KvStatusResponse2, KvTtlData, KvTtlResponse, KvUpdateData, KvUpdateResponse, LatestRunForSourceData, LatestRunForSourceResponse, LinkCustomDomainToCertificateData, LinkCustomDomainToCertificateResponse, LinkServiceToProjectData, LinkServiceToProjectResponse, ListAgentRunsData, ListAgentRunsResponse, ListAgentsData, ListAgentsResponse2, ListAiProvidersData, ListAiProvidersResponse, ListAlertRulesData, ListAlertRulesResponse, ListAlertsData, ListAlertsError, ListAlertsResponse, ListAllConversationsData, ListAllConversationsResponse, ListAllRunsData, ListAllRunsResponse, ListApiKeysData, ListApiKeysResponse, ListAuditLogsData, ListAuditLogsResponse, ListAvailableContainersData, ListAvailableContainersResponse, ListBackupAlertsData, ListBackupAlertsError, ListBackupAlertsResponse, ListBackupChildrenData, ListBackupChildrenError, ListBackupChildrenResponse, ListBackupSchedulesData, ListBackupSchedulesError, ListBackupSchedulesResponse, ListBackupsForScheduleData, ListBackupsForScheduleResponse, ListCommitsByRepositoryIdData, ListCommitsByRepositoryIdResponse, ListConnectionsData, ListConnectionsResponse, ListContainersAtPathData, ListContainersAtPathResponse, ListContainersData, ListContainersResponse, ListConversationsData, ListConversationsResponse, ListCustomDomainsForProjectData, ListCustomDomainsForProjectResponse, ListDashboardsData, ListDashboardsError, ListDashboardsResponse, ListDeliveriesData, ListDeliveriesResponse, ListDeploymentContainerLogsData, ListDeploymentContainerLogsResponse, ListDeploymentTokensData, ListDeploymentTokensResponse, ListDnsProvidersData, ListDnsProvidersResponse, ListDomainsData, ListDomainsResponse2, ListDsnsData, ListDsnsResponse, ListEmailDomainsData, ListEmailDomainsResponse, ListEmailProvidersData, ListEmailProvidersResponse, ListEmailsData, ListEmailsResponse, ListEnrollmentTokensData, ListEnrollmentTokensResponse, ListEntitiesData, ListEntitiesResponse, ListErrorEventsData, ListErrorEventsResponse, ListErrorGroupsData, ListErrorGroupsResponse, ListEventsData, ListEventsResponse, ListEventTypesData, ListEventTypesResponse, ListExternalImagesData, ListExternalImagesResponse, ListExternalPluginsData, ListExternalPluginsResponse, ListExternalServiceBackupsData, ListExternalServiceBackupsError, ListExternalServiceBackupsResponse, ListFlagsData, ListFlagsResponse, ListFunnelsData, ListFunnelsResponse, ListGitProvidersData, ListGitProvidersResponse, ListGlobalMcpsData, ListGlobalMcpsResponse, ListGlobalSkillsData, ListGlobalSkillsResponse, ListIncidentsData, ListInsightsData, ListInsightsError, ListInsightsResponse, ListIpAccessControlData, ListIpAccessControlError, ListIpAccessControlResponse, ListJobsData, ListJobsResponse2, ListKnownAiAgentsData, ListKnownAiAgentsError, ListKnownAiAgentsResponse, ListManagedDomainsData, ListManagedDomainsResponse, ListMcpsData, ListMcpsResponse2, ListMetricLabelKeysData, ListMetricLabelKeysError, ListMetricLabelKeysResponse, ListMetricLabelValuesData, ListMetricLabelValuesError, ListMetricLabelValuesResponse, ListMetricNamesData, ListMetricNamesError, ListMetricNamesResponse, ListModelsData, ListModelsError, ListModelsResponse, ListMonitorsData, ListMonitorsResponse, ListNotificationProvidersData, ListNotificationProvidersResponse, ListOidcProvidersData, ListOidcProvidersResponse, ListOidcProviderUsersData, ListOidcProviderUsersResponse, ListOidcRoleMappingsData, ListOidcRoleMappingsResponse, ListOnDemandCertsData, ListOnDemandCertsResponse2, ListOrdersData, ListOrdersResponse2, ListPeersData, ListPeersResponse, ListPendingActionsData, ListPendingActionsResponse, ListPgUpgradesData, ListPgUpgradesResponse, ListPresetsData, ListPresetsResponse2, ListProjectAccessData, ListProjectAccessResponse, ListProjectAlarmsData, ListProjectAlarmsResponse, ListProjectScansData, ListProjectScansError, ListProjectScansResponse, ListProjectSecretsData, ListProjectSecretsResponse, ListProjectServicesData, ListProjectServicesResponse, ListProjectTemplatesData, ListProjectTemplatesResponse, ListProjectTemplateTagsData, ListProjectTemplateTagsResponse, ListProviderKeysData, ListProviderKeysError, ListProviderKeysResponse, ListProviderZonesData, ListProviderZonesResponse, ListPublicProvidersData, ListPublicProvidersResponse, ListReleaseFilesData, ListReleaseFilesResponse, ListReleasesData, ListReleasesResponse, ListRemoteExternalImagesData, ListRemoteExternalImagesResponse, ListRepositoriesByConnectionData, ListRepositoriesByConnectionResponse, ListRepositoriesByProviderData, ListRepositoriesByProviderResponse, ListRestoreRunsForServiceData, ListRestoreRunsForServiceResponse, ListRootContainersData, ListRootContainersResponse, ListRoutesData, ListRoutesResponse, ListS3SourcesData, ListS3SourcesError, ListS3SourcesResponse, ListSandboxesData, ListSandboxesResponse2, ListScheduleRunJobsData, ListScheduleRunJobsError, ListScheduleRunJobsResponse, ListScheduleRunsData, ListScheduleRunsError, ListScheduleRunsResponse, ListScheduleServicesData, ListScheduleServicesError, ListScheduleServicesResponse, ListSecretsData, ListSecretsResponse2, ListServiceHealthStatusesData, ListServiceHealthStatusesResponse, ListServiceProjectsData, ListServiceProjectsResponse, ListServiceSchedulesData, ListServiceSchedulesError, ListServiceSchedulesResponse, ListServicesData, ListServicesResponse, ListSkillsData, ListSkillsResponse2, ListSourceBackupsData, ListSourceBackupsError, ListSourceBackupsResponse, ListSourceFilesData, ListSourceFilesResponse, ListSourceMapsData, ListSourceMapsResponse, ListSourcesData, ListSourcesResponse, ListStaticBundlesData, ListStaticBundlesResponse, ListSyncedRepositoriesData, ListSyncedRepositoriesResponse, ListTeamMembersData, ListTeamMembersResponse, ListTeamProjectsData, ListTeamProjectsResponse, ListTeamsData, ListTeamsResponse, ListUsersData, ListUsersResponse, ListWebhooksData, ListWebhooksResponse, LoginData, LoginResponse, LogoutData, LookupDnsARecordsData, LookupDnsARecordsError, LookupDnsARecordsResponse, MintEnrollmentTokenData, MintEnrollmentTokenResponse2, MkdirData, MkdirResponse, NodeHeartbeatData, NodeHeartbeatResponse, NodeMetricsGetRangeData, NodeMetricsGetRangeResponse, ObservabilityFullEventData, ObservabilityFullEventError, ObservabilityFullEventResponse, ObservabilityListEventsData, ObservabilityListEventsError, ObservabilityListEventsResponse, OidcCallbackData, PatchAdminGateData, PatchAdminGateResponse, PatchPreviewGatewaySettingsData, PatchPreviewGatewaySettingsResponse, PauseDeploymentData, PauseDeploymentResponse, PauseSandboxData, PauseSandboxResponse, PlanRestoreData, PlanRestoreError, PlanRestoreResponse, PostDnsAckData, PostDnsAckResponse, PreviewAlertData, PreviewAlertError, PreviewAlertResponse, PreviewFunnelMetricsData, PreviewFunnelMetricsResponse, PreviewHostnameModeData, PreviewHostnameModeResponse, PromoteClusterMemberData, PromoteDeploymentData, PromoteDeploymentResponse, ProvisionDomainData, ProvisionDomainResponse, PurgeProjectLogsData, PurgeProjectLogsError, PushExternalImageData, PushExternalImageResponse, QueryDataData, QueryDataResponse2, QueryGenaiTracesData, QueryGenaiTracesError, QueryGenaiTracesResponse, QueryLogsData, QueryLogsError, QueryLogsResponse, QueryMetricsData, QueryMetricsError, QueryMetricsResponse, QuerySpanStatsData, QuerySpanStatsError, QuerySpanStatsResponse, QueryTracesData, QueryTracesError, QueryTracesResponse, QueryTraceSummariesData, QueryTraceSummariesError, QueryTraceSummariesResponse, ReadEntityRowsData, ReadEntityRowsResponse, ReadFileData, ReadFileResponse2, ReAnalyzeData, RecordConsoleEventData, RecordEventMetricsData, RecordEventMetricsResponse, RecordFlagExposureData, RecordFlagExposureResponse, RecordSpeedMetricsData, RecordSpeedMetricsError, RecordSpeedMetricsResponse, RefreshRouteTableData, RefreshRouteTableResponse, RegenerateDsnData, RegenerateDsnResponse, RegisterExternalImageData, RegisterExternalImageResponse, RegisterNodeData, RegisterNodeResponse2, ReinstallGitlabWebhookData, ReinstallGitlabWebhookResponse, RejectPendingActionData, RejectPendingActionResponse, ReloadPluginsData, ReloadPluginsResponse, RemoveClusterMemberData, RemoveClusterMemberResponse, RemoveManagedDomainData, RemoveManagedDomainResponse, RemoveRoleData, RemoveRoleResponse, RemoveTeamMemberData, RemoveTeamMemberResponse, RenameConversationData, RenameConversationResponse, RenewDomainData, RenewDomainResponse, RequestPasswordResetData, RequestPasswordResetResponse, ResetPasswordData, ResetPasswordResponse, ResizeSandboxData, ResizeSandboxResponse, ResolveAlarmData, RestartContainerData, RestartContainerResponse, RestartPreviewGatewayData, RestartPreviewGatewayResponse, RestartSandboxData, RestartSandboxResponse, RestoreFlagData, RestoreFlagResponse, RestoreUserData, RestoreUserResponse, ResumeDeploymentData, ResumeDeploymentResponse, ResumeSandboxData, ResumeSandboxResponse, RetryClusterData, RetryClusterResponse, RetryDeliveryData, RetryDeliveryResponse, RetryPgUpgradeData, RetryPgUpgradeResponse, RetryRunData, RetryRunResponse, RevealGlobalMcpConfigData, RevealGlobalMcpConfigResponse, RevealMcpConfigData, RevealMcpConfigResponse, RevealNotificationProviderConfigData, RevealNotificationProviderConfigResponse, RevealServiceParameterData, RevealServiceParameterResponse, RevenueCreateIntegrationData, RevenueCreateIntegrationResponse, RevenueDeleteIntegrationData, RevenueDeleteIntegrationResponse, RevenueGlobalEventsData, RevenueGlobalEventsResponse, RevenueImportInvoicesCsvData, RevenueImportInvoicesCsvResponse, RevenueImportSubscriptionsCsvData, RevenueImportSubscriptionsCsvResponse, RevenueListIntegrationsData, RevenueListIntegrationsResponse, RevenueListProvidersData, RevenueListProvidersResponse, RevenueMetricsCustomersData, RevenueMetricsCustomersResponse, RevenueMetricsGlobalMrrData, RevenueMetricsGlobalMrrResponse, RevenueMetricsGlobalSummaryData, RevenueMetricsGlobalSummaryResponse, RevenueMetricsMrrData, RevenueMetricsMrrResponse, RevenueMetricsSummaryData, RevenueMetricsSummaryResponse, RevenueRecentEventsData, RevenueRecentEventsResponse, RevenueRotateTokenData, RevenueRotateTokenResponse, RevenueUpdateConfigData, RevenueUpdateConfigResponse, RevenueUpdateSecretData, RevenueUpdateSecretResponse, RevokeDsnData, RevokeDsnResponse, RevokeEnrollmentTokenData, RevokeEnrollmentTokenResponse, RevokeJoinTokenData, RevokeJoinTokenResponse, RevokeProjectAccessData, RevokeProjectAccessResponse, RollbackPgUpgradeData, RollbackPgUpgradeResponse, RollbackToDeploymentData, RollbackToDeploymentResponse, RootfsGcData, RootfsReportData, RotateApiKeyData, RotateApiKeyResponse, RotateDeploymentTokenData, RotateDeploymentTokenResponse, RunBackupForSourceData, RunBackupForSourceError, RunBackupForSourceResponse, RunConnectionHealthCheckData, RunConnectionHealthCheckResponse, RunExternalServiceBackupData, RunExternalServiceBackupError, RunExternalServiceBackupResponse, RunScheduleNowData, RunScheduleNowError, RunScheduleNowResponse, SandboxCreatePreviewLinkData, SandboxCreatePreviewLinkResponse, SaveAgentTokenData, SaveAgentTokenResponse2, SaveAiProviderCredentialData, SaveAiProviderCredentialResponse, SearchLogsData, SearchLogsError, SearchLogsResponse2, SendEmailData, SendEmailResponse, SetAiDataAccessData, SetAiDataAccessResponse, SetDefaultS3SourceData, SetDefaultS3SourceError, SetDefaultS3SourceResponse, SetFlagEnvironmentData, SetFlagEnvironmentResponse, SetPreviewPasswordData, SetPreviewPasswordResponse2, SetupDnsChallengeData, SetupDnsChallengeResponse2, SetupDnsData, SetupDnsResponse2, SetupEmailTrackingData, SetupEmailTrackingResponse, SetupMfaData, SetupMfaResponse, SleepEnvironmentData, SleepEnvironmentResponse, SmokeTestAgentData, SmokeTestAgentResponse, SourceSandboxData, SourceSandboxResponse, StartAnalysisData, StartAnalysisResponse, StartContainerData, StartContainerResponse, StartFixData, StartGitProviderOauthData, StartOidcLoginBySlugData, StartPgUpgradeData, StartPgUpgradeResponse, StartRestoreData, StartRestoreError, StartRestoreResponse, StartServiceData, StartServiceResponse, StatPathData, StatPathResponse, StopContainerData, StopContainerResponse, StopSandboxData, StopSandboxResponse, StopServiceData, StopServiceResponse, StreamContainerMetricsData, SyncRepositoriesData, SyncRepositoriesResponse, TailDeploymentJobLogsData, TailLogsData, TailLogsError, TeardownDeploymentData, TeardownDeploymentResponse, TeardownEnvironmentData, TeardownEnvironmentResponse, TestNotificationProviderData, TestNotificationProviderResponse, TestOidcProviderData, TestOidcProviderResponse, TestProviderConnectionData, TestProviderConnectionResponse, TestProviderData, TestProviderKeyByIdData, TestProviderKeyByIdError, TestProviderKeyByIdResponse, TestProviderKeyInlineData, TestProviderKeyInlineError, TestProviderKeyInlineResponse, TestProviderResponse2, TestS3ConnectionPreviewData, TestS3ConnectionPreviewError, TestS3ConnectionPreviewResponse, TestS3SourceConnectionData, TestS3SourceConnectionError, TestS3SourceConnectionResponse, TrackClickData, TrackOpenData, TriggerAgentData, TriggerAgentResponse, TriggerProjectPipelineData, TriggerProjectPipelineResponse, TriggerScanData, TriggerScanError, TriggerScanResponse2, TriggerServiceHealthCheckData, TriggerServiceHealthCheckResponse, TriggerWeeklyDigestData, TriggerWeeklyDigestResponse, UnlinkServiceFromProjectData, UnlinkServiceFromProjectResponse, UpdateAgentData, UpdateAgentResponse, UpdateAiProviderData, UpdateAiProviderResponse2, UpdateAlertData, UpdateAlertError, UpdateAlertResponse, UpdateAlertRuleData, UpdateAlertRuleResponse, UpdateApiKeyData, UpdateApiKeyResponse, UpdateAutomaticDeployData, UpdateAutomaticDeployResponse, UpdateBackupScheduleData, UpdateBackupScheduleError, UpdateBackupScheduleResponse, UpdateCloudflareProviderData, UpdateCloudflareProviderResponse, UpdateConnectionTokenData, UpdateConnectionTokenResponse, UpdateCustomDomainData, UpdateCustomDomainResponse, UpdateDashboardData, UpdateDashboardError, UpdateDashboardResponse, UpdateDeploymentTokenData, UpdateDeploymentTokenResponse, UpdateEmailProviderData, UpdateEmailProviderResponse, UpdateEnvironmentSettingsData, UpdateEnvironmentSettingsResponse, UpdateEnvironmentSubdomainData, UpdateEnvironmentSubdomainResponse, UpdateEnvironmentVariableData, UpdateEnvironmentVariableResponse, UpdateErrorGroupData, UpdateFlagData, UpdateFlagResponse, UpdateFunnelData, UpdateGitProviderCredentialsData, UpdateGitProviderCredentialsResponse, UpdateGitSettingsData, UpdateGitSettingsResponse, UpdateGlobalMcpData, UpdateGlobalMcpResponse, UpdateGlobalSkillData, UpdateGlobalSkillResponse, UpdateIncidentStatusData, UpdateIncidentStatusResponse, UpdateIpAccessControlData, UpdateIpAccessControlError, UpdateIpAccessControlResponse, UpdateManagedDomainData, UpdateManagedDomainResponse, UpdateMcpData, UpdateMcpResponse, UpdateNotificationEmailProviderData, UpdateNotificationEmailProviderResponse, UpdateNotificationProviderData, UpdateNotificationProviderResponse, UpdateOidcProviderData, UpdateOidcProviderResponse, UpdatePreferencesData, UpdatePreferencesResponse, UpdateProjectData, UpdateProjectDeploymentConfigData, UpdateProjectDeploymentConfigResponse, UpdateProjectResponse, UpdateProjectSecretData, UpdateProjectSecretResponse, UpdateProjectSettingsData, UpdateProjectSettingsResponse, UpdateProviderData, UpdateProviderKeyData, UpdateProviderKeyError, UpdateProviderKeyResponse, UpdateProviderResponse, UpdateRouteData, UpdateRouteResponse, UpdateS3SourceData, UpdateS3SourceError, UpdateS3SourceResponse, UpdateSelfData, UpdateSelfResponse, UpdateServiceData, UpdateServiceResourcesData, UpdateServiceResourcesResponse, UpdateServiceResponse, UpdateSessionDurationData, UpdateSessionDurationError, UpdateSessionDurationResponse2, UpdateSettingsData, UpdateSettingsResponse, UpdateSkillData, UpdateSkillResponse, UpdateSlackProviderData, UpdateSlackProviderResponse, UpdateSpeedMetricsData, UpdateSpeedMetricsError, UpdateSpeedMetricsResponse, UpdateTeamData, UpdateTeamMemberRoleData, UpdateTeamMemberRoleResponse, UpdateTeamResponse, UpdateUserData, UpdateUserResponse, UpdateWebhookData, UpdateWebhookProviderData, UpdateWebhookProviderResponse, UpdateWebhookResponse, UpgradePreviewGatewayData, UpgradePreviewGatewayResponse, UpgradeServiceData, UpgradeServiceResponse, UploadGlobalSkillData, UploadGlobalSkillResponse, UploadReleaseFileData, UploadReleaseFileResponse, UploadSkillData, UploadSkillResponse, UploadSourceFileData, UploadSourceFileResponse, UploadSourceMapData, UploadSourceMapResponse, UploadStaticBundleData, UploadStaticBundleResponse, UpsertSecretData, UpsertSecretResponse, ValidateConnectionData, ValidateConnectionResponse, ValidateEmailData, ValidateEmailResponse2, VerifyAndEnableMfaData, VerifyAndEnableMfaResponse, VerifyDomainData, VerifyDomainResponse, VerifyEmailData, VerifyEmailResponse, VerifyManagedDomainData, VerifyManagedDomainResponse, VerifyMfaChallengeData, VerifyMfaChallengeResponse, VerifyStepUpData, VerifyStepUpResponse, WakeEnvironmentData, WakeEnvironmentResponse, WebhookTriggerData, WebhookTriggerResponse2, WorkflowDryRunData, WorkflowDryRunResponse, WriteFileData, WriteFileResponse, WriteFilesData, WriteFilesResponse2 } from '../types.gen'; +import { acknowledgeAlarm, activateAiProvider, activateApiKey, activateConnection, activateProvider, addClusterMember, addContext, addEnvironmentDomain, addEvents, addManagedDomain, addSessionReplayEvents, addTeamMember, adminDrainNode, adminDrainStatus, adminGetNode, adminListNodeContainers, adminListNodes, adminRemoveNode, adminUndrainNode, applyHostnameMode, archiveConversation, archiveFlag, assignRole, attachScheduleServices, blobCopy, blobDelete, blobDisable, blobDownload, blobEnable, blobList, blobPut, blobStatus, blobUpdate, cancel, cancelBackup, cancelDeployment, cancelDomainOrder, cancelPgUpgrade, cancelRun, cancelScheduleRun, changePasswordSelf, changeProjectSource, changeRequiredPassword, chatCompletions, checkAnalyticsHasEvents, checkCommitExists, checkDomainStatus, checkExplorerSupport, checkIpBlocked, checkProviderDeletionSafety, chunkUploadOptions, cleanupExpiredBackups, clearPreviewPassword, cliDeviceApprove, cliDeviceDeny, cliDeviceLookup, cliDevicePoll, cliDeviceStart, cliLogout, cmd, cmdKill, cmdLogs, confirmPendingAction, containerMetricsGetHistory, createAgent, createAlert, createAlertRule, createApiKey, createBackupSchedule, createBitbucketProvider, createCloudflareProvider, createConversation, createCustomDomain, createDashboard, createDeploymentToken, createDnsProvider, createDomain, createDsn, createEmailDomain, createEmailProvider, createEnvironment, createEnvironmentVariable, createFlag, createFunnel, createGenericProvider, createGiteaPatProvider, createGithubPatProvider, createGitlabOauthProvider, createGitlabPatProvider, createGitProvider, createGlobalMcp, createGlobalSkill, createIncident, createIpAccessControl, createMcp, createMonitor, createNotificationEmailProvider, createNotificationProvider, createOidcProvider, createOidcRoleMapping, createOrRecreateOrder, createPlan, createPr, createProject, createProjectFromTemplate, createProjectRelease, createProjectSecret, createProviderKey, createRelease, createRoute, createS3Source, createSandbox, createService, createSkill, createSlackProvider, createTeam, createUser, createWebhook, createWebhookProvider, deactivateApiKey, deactivateConnection, deactivateProvider, deleteAgent, deleteAlert, deleteAlertRule, deleteApiKey, deleteBackup, deleteBackupSchedule, deleteConnection, deleteCustomDomain, deleteDashboard, deleteDeploymentToken, deleteDnsProvider, deleteDomain, deleteEmailDomain, deleteEmailProvider, deleteEnvironment, deleteEnvironmentDomain, deleteEnvironmentVariable, deleteExternalImage, deleteFunnel, deleteGitProvider, deleteGlobalMcp, deleteGlobalSkill, deleteIpAccessControl, deleteMcp, deleteMonitor, deleteNotificationProvider, deleteOidcProvider, deleteOidcRoleMapping, deletePreferences, deleteProject, deleteProjectSecret, deleteProviderKey, deleteProviderSafely, deleteReleaseSourceFiles, deleteReleaseSourceMaps, deleteRoute, deleteS3Source, deleteScan, deleteSecret, deleteService, deleteSessionReplay, deleteSkill, deleteSourceMap, deleteStaticBundle, deleteTeam, deleteUser, deleteWebhook, deployFromImage, deployFromImageUpload, deployFromStatic, deployFromUploadedSource, deploymentMetricsGetLatest, deploymentMetricsGetRange, deploymentMetricsToggle, destroySandbox, detachScheduleService, detectPublicPresets, disableBackupSchedule, disableMfa, discoverWorkloads, domain, downloadGlobalSkillArchive, downloadObject, downloadSkillArchive, emailStatus, embeddings, enableBackupSchedule, enrichVisitor, exec, execDetached, executeDeploymentOperation, executeImport, extendTimeout, externalServiceEnablePgStatStatements, externalServiceMetricsByDatabase, externalServiceMetricsCreateAlertRule, externalServiceMetricsDeleteAlertRule, externalServiceMetricsGetAlertRules, externalServiceMetricsGetLatest, externalServiceMetricsGetRange, externalServiceMetricsStatus, externalServiceMetricsToggle, externalServiceMetricsUpdateAlertRule, externalServiceResetPgStatStatements, finalizeOrder, finalizeProjectRelease, findConversation, generateJoinToken, generatePresetDockerfile, getAccessInfo, getActiveVisitors, getActivityGraph, getAdminGate, getAgent, getAggregatedBuckets, getAiAgentBreakdown, getAiAgentPages, getAiAgentTimeline, getAiDataAccess, getAiPageBreakdown, getAiStatusBreakdown, getAlert, getAlertRule, getAllRepositoriesByName, getAnalyticsActiveVisitors, getAnalyticsEventsCount, getAnalyticsSessionEvents, getAnalyticsVisitorSessions, getApiKey, getApiKeyPermissions, getAuditLog, getBackup, getBackupSchedule, getBranchesByRepositoryId, getBucketedIncidents, getBucketedStatus, getChallengeToken, getChatReadiness, getCliStatus, getClusterHealth, getClusterMember, getCmd, getContainerDetail, getContainerEnvironmentVariable, getContainerLogs, getContainerLogsById, getContainerMetrics, getConversation, getConversationDetail, getConversations, getCronById, getCronExecutions, getCrossProjectTraceSiblings, getCurrentMonitorStatus, getCurrentUser, getCustomDomain, getDashboard, getDashboardProjectsAnalytics, getDelivery, getDeployment, getDeploymentContainerLogContent, getDeploymentJobLogs, getDeploymentJobs, getDeploymentOperations, getDeploymentOperationStatus, getDeploymentToken, getDiskStatus, getDnsChanges, getDnsProvider, getDomain, getDomainByHost, getDomainById, getDomainByName, getDomainDnsRecords, getDomainOrder, getEmail, getEmailEvents, getEmailLinks, getEmailProvider, getEmailStats, getEmailTracking, getEmailTrackingStatus, getEntityInfo, getEnvironment, getEnvironmentCrons, getEnvironmentDomains, getEnvironments, getEnvironmentVariables, getEnvironmentVariableValue, getErrorDashboardStats, getErrorEvent, getErrorGroup, getErrorStats, getErrorTimeSeries, getEventDetail, getEventEntries, getEventsCount, getEventsTimeline, getEventTypeBreakdown, getEventVisitors, getExternalImage, getFile, getFlag, getFlagSnapshot, getFunnelMetrics, getGenaiTrace, getGeneralStats, getGitProvider, getGlobalEvents, getGlobalEventStats, getGlobalMcp, getGlobalSandboxStatus, getGlobalSkill, getGroupedPageMetrics, getHealth, getHourlyVisits, getHttpChallengeDebug, getImportStatus, getIncident, getIncidentUpdates, getIpAccessControl, getIpGeolocation, getJoinTokenStatus, getLastDeployment, getLatestScan, getLatestScansPerEnvironment, getLiveVisitorsList, getLogContext, getMcp, getMetricsOverTime, getMonitor, getNotificationProvider, getOnDemandCertStatus, getOrCreateDsn, getPageFlow, getPageHourlySessions, getPagePathDetail, getPagePaths, getPagePathsSparklines, getPagePathVisitors, getPendingAction, getPerformanceMetrics, getPgUpgrade, getPgUpgradeLogs, getPipelineStats, getPlatformInfo, getPostgresWalHealth, getPreferences, getPreviewGatewayLogs, getPreviewGatewaySettings, getPreviewGatewayStatus, getPricing, getPrivateIp, getProject, getProjectAlarmsSummary, getProjectBySlug, getProjectDeployments, getProjects, getProjectServiceEnvironmentVariables, getProjectSessionReplays, getProjectsHealth, getProjectsMonitorHealth, getProjectStatistics, getProjectTemplate, getPropertyBreakdown, getPropertyTimeline, getProviderConnections, getProviderMetadata, getProvidersMetadata, getProxyLogById, getProxyLogByRequestId, getProxyLogs, getPublicBranches, getPublicIp, getPublicRepository, getQueryContainerInfo, getQuota, getRecentActivity, getRemoteExternalImage, getRepositoryBranches, getRepositoryById, getRepositoryByName, getRepositoryPresetByName, getRepositoryPresetLive, getRepositoryTags, getResolvedEnvironmentVariables, getResolvedEnvironmentVariableValue, getRestoreCapabilities, getRestoreRun, getRoute, getRun, getRunWithLogs, getS3Credentials, getS3Source, getSandbox, getSandboxStatus, getScan, getScanByDeployment, getScanVulnerabilities, getService, getServiceBySlug, getServiceEnvironmentVariable, getServiceEnvironmentVariables, getServiceHealthStatus, getServicePreviewEnvironmentVariableNames, getServicePreviewEnvironmentVariablesMasked, getServiceRuntime, getServiceStats, getServiceTypeParameters, getServiceTypes, getSessionDetails, getSessionEvents, getSessionLogs, getSessionReplay, getSessionReplayEvents, getSettings, getSkill, getSlowQueries, getStaticBundle, getStatusOverview, getTagsByRepositoryId, getTeam, getTimeBucketStats, getTodayStats, getTrace, getUnifiedTrace, getUniqueCounts, getUniqueEvents, getUpdateStatus, getUptimeHistory, getUsageByProvider, getUsageRecent, getUsageSummary, getUsageTimeseries, getUsageTopModels, getVisitorByGuid, getVisitorById, getVisitorDetails, getVisitorFacets, getVisitorInfo, getVisitorJourney, getVisitors, getVisitorSessions, getVisitorStats, getWebhook, grantProjectAccess, handleGitProviderOauthCallback, hasAnalyticsEvents, hasErrorGroups, hasPerformanceMetrics, importExternalService, ingestLogs, ingestLogsByPath, ingestMetrics, ingestMetricsByPath, ingestSentryEnvelope, ingestSentryEvent, ingestTraces, ingestTracesByPath, initSessionReplay, inspectDropArchive, jobLogs, jobStatus, killJob, kvDel, kvDisable, kvEnable, kvExpire, kvGet, kvIncr, kvKeys, kvSet, kvStatus, kvTtl, kvUpdate, latestRunForSource, linkCustomDomainToCertificate, linkServiceToProject, listAgentRuns, listAgents, listAiProviders, listAlertRules, listAlerts, listAllConversations, listAllRuns, listApiKeys, listAuditLogs, listAvailableContainers, listBackupAlerts, listBackupChildren, listBackupSchedules, listBackupsForSchedule, listCommitsByRepositoryId, listConnections, listContainers, listContainersAtPath, listConversations, listCustomDomainsForProject, listDashboards, listDeliveries, listDeploymentContainerLogs, listDeploymentTokens, listDnsProviders, listDomains, listDsns, listEmailDomains, listEmailProviders, listEmails, listEnrollmentTokens, listEntities, listErrorEvents, listErrorGroups, listEvents, listEventTypes, listExternalImages, listExternalPlugins, listExternalServiceBackups, listFlags, listFunnels, listGitProviders, listGlobalMcps, listGlobalSkills, listIncidents, listInsights, listIpAccessControl, listJobs, listKnownAiAgents, listManagedDomains, listMcps, listMetricLabelKeys, listMetricLabelValues, listMetricNames, listModels, listMonitors, listNotificationProviders, listOidcProviders, listOidcProviderUsers, listOidcRoleMappings, listOnDemandCerts, listOrders, listPeers, listPendingActions, listPgUpgrades, listPresets, listProjectAccess, listProjectAlarms, listProjectScans, listProjectSecrets, listProjectServices, listProjectTemplates, listProjectTemplateTags, listProviderKeys, listProviderZones, listPublicProviders, listReleaseFiles, listReleases, listRemoteExternalImages, listRepositoriesByConnection, listRepositoriesByProvider, listRestoreRunsForService, listRootContainers, listRoutes, listS3Sources, listSandboxes, listScheduleRunJobs, listScheduleRuns, listScheduleServices, listSecrets, listServiceHealthStatuses, listServiceProjects, listServices, listServiceSchedules, listSkills, listSourceBackups, listSourceFiles, listSourceMaps, listSources, listStaticBundles, listSyncedRepositories, listTeamMembers, listTeamProjects, listTeams, listUsers, listWebhooks, login, logout, lookupDnsARecords, mintEnrollmentToken, mkdir, nodeHeartbeat, nodeMetricsGetRange, observabilityFullEvent, observabilityListEvents, oidcCallback, type Options, patchAdminGate, patchPreviewGatewaySettings, pauseDeployment, pauseSandbox, planRestore, postDnsAck, previewAlert, previewFunnelMetrics, previewHostnameMode, promoteClusterMember, promoteDeployment, provisionDomain, purgeProjectLogs, pushExternalImage, queryData, queryGenaiTraces, queryLogs, queryMetrics, querySpanStats, queryTraces, queryTraceSummaries, readEntityRows, readFile, reAnalyze, recordConsoleEvent, recordEventMetrics, recordFlagExposure, recordSpeedMetrics, refreshRouteTable, regenerateDsn, registerExternalImage, registerNode, reinstallGitlabWebhook, rejectPendingAction, reloadPlugins, removeClusterMember, removeManagedDomain, removeRole, removeTeamMember, renameConversation, renewDomain, requestPasswordReset, resetPassword, resizeSandbox, resolveAlarm, restartContainer, restartPreviewGateway, restartSandbox, restoreFlag, restoreUser, resumeDeployment, resumeSandbox, retryCluster, retryDelivery, retryPgUpgrade, retryRun, revealGlobalMcpConfig, revealMcpConfig, revealNotificationProviderConfig, revealServiceParameter, revenueCreateIntegration, revenueDeleteIntegration, revenueGlobalEvents, revenueImportInvoicesCsv, revenueImportSubscriptionsCsv, revenueListIntegrations, revenueListProviders, revenueMetricsCustomers, revenueMetricsGlobalMrr, revenueMetricsGlobalSummary, revenueMetricsMrr, revenueMetricsSummary, revenueRecentEvents, revenueRotateToken, revenueUpdateConfig, revenueUpdateSecret, revokeDsn, revokeEnrollmentToken, revokeJoinToken, revokeProjectAccess, rollbackPgUpgrade, rollbackToDeployment, rootfsGc, rootfsReport, rotateApiKey, rotateDeploymentToken, runBackupForSource, runConnectionHealthCheck, runExternalServiceBackup, runScheduleNow, sandboxCreatePreviewLink, saveAgentToken, saveAiProviderCredential, searchLogs, sendEmail, setAiDataAccess, setDefaultS3Source, setFlagEnvironment, setPreviewPassword, setupDns, setupDnsChallenge, setupEmailTracking, setupMfa, sleepEnvironment, smokeTestAgent, sourceSandbox, startAnalysis, startContainer, startFix, startGitProviderOauth, startOidcLoginBySlug, startPgUpgrade, startRestore, startService, statPath, stopContainer, stopSandbox, stopService, streamContainerMetrics, syncRepositories, tailDeploymentJobLogs, tailLogs, teardownDeployment, teardownEnvironment, terminal, testNotificationProvider, testOidcProvider, testProvider, testProviderConnection, testProviderKeyById, testProviderKeyInline, testS3ConnectionPreview, testS3SourceConnection, trackClick, trackOpen, triggerAgent, triggerProjectPipeline, triggerScan, triggerServiceHealthCheck, triggerWeeklyDigest, unlinkServiceFromProject, updateAgent, updateAiProvider, updateAlert, updateAlertRule, updateApiKey, updateAutomaticDeploy, updateBackupSchedule, updateCloudflareProvider, updateConnectionToken, updateCustomDomain, updateDashboard, updateDeploymentToken, updateEmailProvider, updateEnvironmentSettings, updateEnvironmentSubdomain, updateEnvironmentVariable, updateErrorGroup, updateFlag, updateFunnel, updateGitProviderCredentials, updateGitSettings, updateGlobalMcp, updateGlobalSkill, updateIncidentStatus, updateIpAccessControl, updateManagedDomain, updateMcp, updateNotificationEmailProvider, updateNotificationProvider, updateOidcProvider, updatePreferences, updateProject, updateProjectDeploymentConfig, updateProjectSecret, updateProjectSettings, updateProvider, updateProviderKey, updateRoute, updateS3Source, updateSelf, updateService, updateServiceResources, updateSessionDuration, updateSettings, updateSkill, updateSlackProvider, updateSpeedMetrics, updateTeam, updateTeamMemberRole, updateUser, updateWebhook, updateWebhookProvider, upgradePreviewGateway, upgradeService, uploadGlobalSkill, uploadReleaseFile, uploadSkill, uploadSourceFile, uploadSourceMap, uploadStaticBundle, upsertSecret, validateConnection, validateEmail, verifyAndEnableMfa, verifyDomain, verifyEmail, verifyManagedDomain, verifyMfaChallenge, verifyStepUp, wakeEnvironment, webhookTrigger, workflowDryRun, writeFile, writeFiles } from '../sdk.gen'; +import type { AcknowledgeAlarmData, ActivateAiProviderData, ActivateAiProviderResponse, ActivateApiKeyData, ActivateApiKeyResponse, ActivateConnectionData, ActivateProviderData, AddClusterMemberData, AddClusterMemberResponse, AddContextData, AddEnvironmentDomainData, AddEnvironmentDomainResponse, AddEventsData, AddEventsError, AddEventsResponse2, AddManagedDomainData, AddManagedDomainResponse, AddSessionReplayEventsData, AddSessionReplayEventsError, AddSessionReplayEventsResponse, AddTeamMemberData, AddTeamMemberResponse, AdminDrainNodeData, AdminDrainNodeResponse, AdminDrainStatusData, AdminDrainStatusResponse, AdminGetNodeData, AdminGetNodeResponse, AdminListNodeContainersData, AdminListNodeContainersResponse, AdminListNodesData, AdminListNodesResponse, AdminRemoveNodeData, AdminRemoveNodeResponse, AdminUndrainNodeData, AdminUndrainNodeResponse, ApplyHostnameModeData, ApplyHostnameModeResponse, ArchiveConversationData, ArchiveConversationResponse, ArchiveFlagData, ArchiveFlagResponse2, AssignRoleData, AttachScheduleServicesData, AttachScheduleServicesError, AttachScheduleServicesResponse2, BlobCopyData, BlobCopyError, BlobCopyResponse, BlobDeleteData, BlobDeleteError, BlobDeleteResponse, BlobDisableData, BlobDisableResponse, BlobDownloadData, BlobDownloadError, BlobEnableData, BlobEnableResponse, BlobListData, BlobListError, BlobListResponse, BlobPutData, BlobPutError, BlobPutResponse, BlobStatusData, BlobStatusResponse2, BlobUpdateData, BlobUpdateResponse, CancelBackupData, CancelBackupError, CancelBackupResponse2, CancelData, CancelDeploymentData, CancelDeploymentResponse, CancelDomainOrderData, CancelDomainOrderResponse, CancelPgUpgradeData, CancelPgUpgradeResponse, CancelRunData, CancelRunResponse, CancelScheduleRunData, CancelScheduleRunError, CancelScheduleRunResponse, ChangePasswordSelfData, ChangePasswordSelfResponse, ChangeProjectSourceData, ChangeProjectSourceResponse, ChangeRequiredPasswordData, ChangeRequiredPasswordResponse, ChatCompletionsData, ChatCompletionsError, ChatCompletionsResponse, CheckAnalyticsHasEventsData, CheckAnalyticsHasEventsResponse, CheckCommitExistsData, CheckCommitExistsResponse, CheckDomainStatusData, CheckDomainStatusResponse, CheckExplorerSupportData, CheckExplorerSupportResponse, CheckIpBlockedData, CheckIpBlockedError, CheckProviderDeletionSafetyData, CheckProviderDeletionSafetyResponse, ChunkUploadOptionsData, ChunkUploadOptionsResponse, CleanupExpiredBackupsData, CleanupExpiredBackupsError, CleanupExpiredBackupsResponse, ClearPreviewPasswordData, ClearPreviewPasswordResponse, CliDeviceApproveData, CliDeviceApproveResponse2, CliDeviceDenyData, CliDeviceDenyResponse, CliDeviceLookupData, CliDeviceLookupResponse2, CliDevicePollData, CliDevicePollResponse2, CliDeviceStartData, CliDeviceStartResponse2, CliLogoutData, CliLogoutResponse, CmdData, CmdKillData, CmdKillResponse, CmdLogsData, CmdResponse2, ConfirmPendingActionData, ConfirmPendingActionResponse, ContainerMetricsGetHistoryData, ContainerMetricsGetHistoryResponse, CreateAgentData, CreateAgentResponse, CreateAlertData, CreateAlertError, CreateAlertResponse, CreateAlertRuleData, CreateAlertRuleResponse, CreateApiKeyData, CreateApiKeyResponse2, CreateBackupScheduleData, CreateBackupScheduleError, CreateBackupScheduleResponse, CreateBitbucketProviderData, CreateBitbucketProviderResponse, CreateCloudflareProviderData, CreateCloudflareProviderResponse, CreateConversationData, CreateConversationResponse, CreateCustomDomainData, CreateCustomDomainResponse, CreateDashboardData, CreateDashboardError, CreateDashboardResponse, CreateDeploymentTokenData, CreateDeploymentTokenResponse2, CreateDnsProviderData, CreateDnsProviderResponse, CreateDomainData, CreateDomainResponse, CreateDsnData, CreateDsnResponse, CreateEmailDomainData, CreateEmailDomainResponse, CreateEmailProviderData, CreateEmailProviderResponse, CreateEnvironmentData, CreateEnvironmentResponse, CreateEnvironmentVariableData, CreateEnvironmentVariableResponse, CreateFlagData, CreateFlagResponse, CreateFunnelData, CreateFunnelResponse2, CreateGenericProviderData, CreateGenericProviderResponse, CreateGiteaPatProviderData, CreateGiteaPatProviderResponse, CreateGithubPatProviderData, CreateGithubPatProviderResponse, CreateGitlabOauthProviderData, CreateGitlabOauthProviderResponse, CreateGitlabPatProviderData, CreateGitlabPatProviderResponse, CreateGitProviderData, CreateGitProviderResponse, CreateGlobalMcpData, CreateGlobalMcpResponse, CreateGlobalSkillData, CreateGlobalSkillResponse, CreateIncidentData, CreateIncidentResponse, CreateIpAccessControlData, CreateIpAccessControlError, CreateIpAccessControlResponse, CreateMcpData, CreateMcpResponse, CreateMonitorData, CreateMonitorResponse, CreateNotificationEmailProviderData, CreateNotificationEmailProviderResponse, CreateNotificationProviderData, CreateNotificationProviderResponse, CreateOidcProviderData, CreateOidcProviderResponse, CreateOidcRoleMappingData, CreateOidcRoleMappingResponse, CreateOrRecreateOrderData, CreateOrRecreateOrderResponse, CreatePlanData, CreatePlanResponse2, CreatePrData, CreateProjectData, CreateProjectFromTemplateData, CreateProjectFromTemplateResponse2, CreateProjectReleaseData, CreateProjectReleaseResponse, CreateProjectResponse, CreateProjectSecretData, CreateProjectSecretResponse, CreateProviderKeyData, CreateProviderKeyError, CreateProviderKeyResponse, CreatePrResponse2, CreateReleaseData, CreateReleaseResponse, CreateRouteData, CreateRouteResponse, CreateS3SourceData, CreateS3SourceError, CreateS3SourceResponse, CreateSandboxData, CreateSandboxResponse, CreateServiceData, CreateServiceResponse, CreateSkillData, CreateSkillResponse, CreateSlackProviderData, CreateSlackProviderResponse, CreateTeamData, CreateTeamResponse, CreateUserData, CreateUserResponse, CreateWebhookData, CreateWebhookProviderData, CreateWebhookProviderResponse, CreateWebhookResponse, DeactivateApiKeyData, DeactivateApiKeyResponse, DeactivateConnectionData, DeactivateProviderData, DeleteAgentData, DeleteAgentResponse, DeleteAlertData, DeleteAlertError, DeleteAlertResponse, DeleteAlertRuleData, DeleteAlertRuleResponse, DeleteApiKeyData, DeleteApiKeyResponse, DeleteBackupData, DeleteBackupError, DeleteBackupResponse, DeleteBackupScheduleData, DeleteBackupScheduleError, DeleteBackupScheduleResponse, DeleteConnectionData, DeleteConnectionResponse, DeleteCustomDomainData, DeleteCustomDomainResponse, DeleteDashboardData, DeleteDashboardError, DeleteDashboardResponse, DeleteDeploymentTokenData, DeleteDeploymentTokenResponse, DeleteDnsProviderData, DeleteDnsProviderResponse, DeleteDomainData, DeleteDomainResponse, DeleteEmailDomainData, DeleteEmailDomainResponse, DeleteEmailProviderData, DeleteEmailProviderResponse, DeleteEnvironmentData, DeleteEnvironmentDomainData, DeleteEnvironmentDomainResponse, DeleteEnvironmentResponse, DeleteEnvironmentVariableData, DeleteEnvironmentVariableResponse, DeleteExternalImageData, DeleteExternalImageResponse, DeleteFunnelData, DeleteGitProviderData, DeleteGitProviderResponse, DeleteGlobalMcpData, DeleteGlobalMcpResponse, DeleteGlobalSkillData, DeleteGlobalSkillResponse, DeleteIpAccessControlData, DeleteIpAccessControlError, DeleteIpAccessControlResponse, DeleteMcpData, DeleteMcpResponse, DeleteMonitorData, DeleteMonitorResponse, DeleteNotificationProviderData, DeleteNotificationProviderResponse, DeleteOidcProviderData, DeleteOidcProviderResponse, DeleteOidcRoleMappingData, DeleteOidcRoleMappingResponse, DeletePreferencesData, DeletePreferencesResponse, DeleteProjectData, DeleteProjectResponse, DeleteProjectSecretData, DeleteProjectSecretResponse, DeleteProviderKeyData, DeleteProviderKeyError, DeleteProviderKeyResponse, DeleteProviderSafelyData, DeleteProviderSafelyResponse, DeleteReleaseSourceFilesData, DeleteReleaseSourceFilesResponse, DeleteReleaseSourceMapsData, DeleteReleaseSourceMapsResponse, DeleteRouteData, DeleteRouteResponse, DeleteS3SourceData, DeleteS3SourceError, DeleteS3SourceResponse, DeleteScanData, DeleteScanError, DeleteScanResponse, DeleteSecretData, DeleteSecretResponse, DeleteServiceData, DeleteServiceResponse, DeleteSessionReplayData, DeleteSessionReplayError, DeleteSkillData, DeleteSkillResponse, DeleteSourceMapData, DeleteSourceMapResponse, DeleteStaticBundleData, DeleteStaticBundleResponse, DeleteTeamData, DeleteTeamResponse, DeleteUserData, DeleteUserResponse, DeleteWebhookData, DeleteWebhookResponse, DeployFromImageData, DeployFromImageResponse, DeployFromImageUploadData, DeployFromImageUploadResponse, DeployFromStaticData, DeployFromStaticResponse, DeployFromUploadedSourceData, DeployFromUploadedSourceResponse, DeploymentMetricsGetLatestData, DeploymentMetricsGetLatestResponse, DeploymentMetricsGetRangeData, DeploymentMetricsGetRangeResponse, DeploymentMetricsToggleData, DestroySandboxData, DestroySandboxResponse, DetachScheduleServiceData, DetachScheduleServiceError, DetachScheduleServiceResponse, DetectPublicPresetsData, DetectPublicPresetsResponse, DisableBackupScheduleData, DisableBackupScheduleResponse, DisableMfaData, DisableMfaResponse, DiscoverWorkloadsData, DiscoverWorkloadsResponse, DomainData, DomainResponse2, DownloadGlobalSkillArchiveData, DownloadGlobalSkillArchiveResponse, DownloadObjectData, DownloadObjectResponse, DownloadSkillArchiveData, DownloadSkillArchiveResponse, EmailStatusData, EmailStatusResponse2, EmbeddingsData, EmbeddingsError, EmbeddingsResponse, EnableBackupScheduleData, EnableBackupScheduleResponse, EnrichVisitorData, EnrichVisitorResponse2, ExecData, ExecDetachedData, ExecDetachedResponse2, ExecResponse2, ExecuteDeploymentOperationData, ExecuteDeploymentOperationResponse, ExecuteImportData, ExecuteImportResponse2, ExtendTimeoutData, ExtendTimeoutResponse, ExternalServiceEnablePgStatStatementsData, ExternalServiceEnablePgStatStatementsResponse, ExternalServiceMetricsByDatabaseData, ExternalServiceMetricsByDatabaseResponse, ExternalServiceMetricsCreateAlertRuleData, ExternalServiceMetricsCreateAlertRuleResponse, ExternalServiceMetricsDeleteAlertRuleData, ExternalServiceMetricsDeleteAlertRuleResponse, ExternalServiceMetricsGetAlertRulesData, ExternalServiceMetricsGetAlertRulesResponse, ExternalServiceMetricsGetLatestData, ExternalServiceMetricsGetLatestResponse, ExternalServiceMetricsGetRangeData, ExternalServiceMetricsGetRangeResponse, ExternalServiceMetricsStatusData, ExternalServiceMetricsStatusResponse, ExternalServiceMetricsToggleData, ExternalServiceMetricsUpdateAlertRuleData, ExternalServiceMetricsUpdateAlertRuleResponse, ExternalServiceResetPgStatStatementsData, ExternalServiceResetPgStatStatementsResponse, FinalizeOrderData, FinalizeOrderResponse, FinalizeProjectReleaseData, FinalizeProjectReleaseResponse, FindConversationData, FindConversationResponse, GenerateJoinTokenData, GenerateJoinTokenResponse2, GeneratePresetDockerfileData, GeneratePresetDockerfileResponse, GetAccessInfoData, GetAccessInfoResponse, GetActiveVisitorsData, GetActiveVisitorsResponse, GetActivityGraphData, GetActivityGraphResponse, GetAdminGateData, GetAdminGateResponse, GetAgentData, GetAgentResponse, GetAggregatedBucketsData, GetAggregatedBucketsResponse, GetAiAgentBreakdownData, GetAiAgentBreakdownError, GetAiAgentBreakdownResponse, GetAiAgentPagesData, GetAiAgentPagesError, GetAiAgentPagesResponse, GetAiAgentTimelineData, GetAiAgentTimelineError, GetAiAgentTimelineResponse, GetAiDataAccessData, GetAiDataAccessResponse, GetAiPageBreakdownData, GetAiPageBreakdownError, GetAiPageBreakdownResponse, GetAiStatusBreakdownData, GetAiStatusBreakdownError, GetAiStatusBreakdownResponse, GetAlertData, GetAlertError, GetAlertResponse, GetAlertRuleData, GetAlertRuleResponse, GetAllRepositoriesByNameData, GetAllRepositoriesByNameResponse, GetAnalyticsActiveVisitorsData, GetAnalyticsActiveVisitorsResponse, GetAnalyticsEventsCountData, GetAnalyticsEventsCountResponse, GetAnalyticsSessionEventsData, GetAnalyticsSessionEventsResponse, GetAnalyticsVisitorSessionsData, GetAnalyticsVisitorSessionsResponse, GetApiKeyData, GetApiKeyPermissionsData, GetApiKeyPermissionsResponse, GetApiKeyResponse, GetAuditLogData, GetAuditLogResponse, GetBackupData, GetBackupError, GetBackupResponse, GetBackupScheduleData, GetBackupScheduleResponse, GetBranchesByRepositoryIdData, GetBranchesByRepositoryIdResponse, GetBucketedIncidentsData, GetBucketedIncidentsResponse, GetBucketedStatusData, GetBucketedStatusResponse, GetChallengeTokenData, GetChallengeTokenResponse, GetChatReadinessData, GetChatReadinessResponse, GetCliStatusData, GetClusterHealthData, GetClusterHealthResponse, GetClusterMemberData, GetClusterMemberResponse, GetCmdData, GetCmdResponse, GetContainerDetailData, GetContainerDetailResponse, GetContainerEnvironmentVariableData, GetContainerEnvironmentVariableResponse, GetContainerLogsByIdData, GetContainerLogsData, GetContainerMetricsData, GetContainerMetricsResponse, GetConversationData, GetConversationDetailData, GetConversationDetailError, GetConversationDetailResponse, GetConversationResponse, GetConversationsData, GetConversationsError, GetConversationsResponse, GetCronByIdData, GetCronByIdResponse, GetCronExecutionsData, GetCronExecutionsResponse, GetCrossProjectTraceSiblingsData, GetCrossProjectTraceSiblingsError, GetCrossProjectTraceSiblingsResponse, GetCurrentMonitorStatusData, GetCurrentMonitorStatusResponse, GetCurrentUserData, GetCurrentUserResponse, GetCustomDomainData, GetCustomDomainResponse, GetDashboardData, GetDashboardError, GetDashboardProjectsAnalyticsData, GetDashboardProjectsAnalyticsResponse, GetDashboardResponse, GetDeliveryData, GetDeliveryResponse, GetDeploymentContainerLogContentData, GetDeploymentContainerLogContentResponse, GetDeploymentData, GetDeploymentJobLogsData, GetDeploymentJobLogsResponse, GetDeploymentJobsData, GetDeploymentJobsResponse, GetDeploymentOperationsData, GetDeploymentOperationsResponse, GetDeploymentOperationStatusData, GetDeploymentOperationStatusResponse, GetDeploymentResponse, GetDeploymentTokenData, GetDeploymentTokenResponse, GetDiskStatusData, GetDiskStatusResponse, GetDnsChangesData, GetDnsChangesResponse, GetDnsProviderData, GetDnsProviderResponse, GetDomainByHostData, GetDomainByHostResponse, GetDomainByIdData, GetDomainByIdResponse, GetDomainByNameData, GetDomainByNameResponse, GetDomainData, GetDomainDnsRecordsData, GetDomainDnsRecordsResponse, GetDomainOrderData, GetDomainOrderResponse, GetDomainResponse, GetEmailData, GetEmailEventsData, GetEmailEventsResponse, GetEmailLinksData, GetEmailLinksResponse, GetEmailProviderData, GetEmailProviderResponse, GetEmailResponse, GetEmailStatsData, GetEmailStatsResponse, GetEmailTrackingData, GetEmailTrackingResponse, GetEmailTrackingStatusData, GetEmailTrackingStatusResponse, GetEntityInfoData, GetEntityInfoResponse, GetEnvironmentCronsData, GetEnvironmentCronsResponse, GetEnvironmentData, GetEnvironmentDomainsData, GetEnvironmentDomainsResponse, GetEnvironmentResponse, GetEnvironmentsData, GetEnvironmentsResponse, GetEnvironmentVariablesData, GetEnvironmentVariablesResponse, GetEnvironmentVariableValueData, GetEnvironmentVariableValueResponse, GetErrorDashboardStatsData, GetErrorDashboardStatsResponse, GetErrorEventData, GetErrorEventResponse, GetErrorGroupData, GetErrorGroupResponse, GetErrorStatsData, GetErrorStatsResponse, GetErrorTimeSeriesData, GetErrorTimeSeriesResponse, GetEventDetailData, GetEventDetailResponse, GetEventEntriesData, GetEventEntriesResponse, GetEventsCountData, GetEventsCountResponse, GetEventsTimelineData, GetEventsTimelineResponse, GetEventTypeBreakdownData, GetEventTypeBreakdownResponse, GetEventVisitorsData, GetEventVisitorsResponse, GetExternalImageData, GetExternalImageResponse, GetFileData, GetFileResponse, GetFlagData, GetFlagResponse, GetFlagSnapshotData, GetFlagSnapshotResponse, GetFunnelMetricsData, GetFunnelMetricsResponse, GetGenaiTraceData, GetGenaiTraceError, GetGenaiTraceResponse, GetGeneralStatsData, GetGeneralStatsResponse, GetGitProviderData, GetGitProviderResponse, GetGlobalEventsData, GetGlobalEventsResponse, GetGlobalEventStatsData, GetGlobalEventStatsResponse, GetGlobalMcpData, GetGlobalMcpResponse, GetGlobalSandboxStatusData, GetGlobalSandboxStatusResponse, GetGlobalSkillData, GetGlobalSkillResponse, GetGroupedPageMetricsData, GetGroupedPageMetricsError, GetGroupedPageMetricsResponse, GetHealthData, GetHealthError, GetHealthResponse, GetHourlyVisitsData, GetHourlyVisitsResponse, GetHttpChallengeDebugData, GetHttpChallengeDebugResponse, GetImportStatusData, GetImportStatusResponse, GetIncidentData, GetIncidentResponse, GetIncidentUpdatesData, GetIncidentUpdatesResponse, GetIpAccessControlData, GetIpAccessControlError, GetIpAccessControlResponse, GetIpGeolocationData, GetIpGeolocationError, GetIpGeolocationResponse, GetJoinTokenStatusData, GetJoinTokenStatusResponse, GetLastDeploymentData, GetLastDeploymentResponse, GetLatestScanData, GetLatestScanError, GetLatestScanResponse, GetLatestScansPerEnvironmentData, GetLatestScansPerEnvironmentError, GetLatestScansPerEnvironmentResponse, GetLiveVisitorsListData, GetLiveVisitorsListResponse, GetLogContextData, GetLogContextError, GetLogContextResponse, GetMcpData, GetMcpResponse, GetMetricsOverTimeData, GetMetricsOverTimeError, GetMetricsOverTimeResponse, GetMonitorData, GetMonitorResponse, GetNotificationProviderData, GetNotificationProviderResponse, GetOnDemandCertStatusData, GetOnDemandCertStatusResponse, GetOrCreateDsnData, GetOrCreateDsnResponse, GetPageFlowData, GetPageFlowResponse, GetPageHourlySessionsData, GetPageHourlySessionsResponse, GetPagePathDetailData, GetPagePathDetailResponse, GetPagePathsData, GetPagePathsResponse, GetPagePathsSparklinesData, GetPagePathsSparklinesResponse, GetPagePathVisitorsData, GetPagePathVisitorsResponse, GetPendingActionData, GetPendingActionResponse, GetPerformanceMetricsData, GetPerformanceMetricsError, GetPerformanceMetricsResponse, GetPgUpgradeData, GetPgUpgradeLogsData, GetPgUpgradeLogsResponse, GetPgUpgradeResponse, GetPipelineStatsData, GetPipelineStatsError, GetPipelineStatsResponse, GetPlatformInfoData, GetPlatformInfoResponse, GetPostgresWalHealthData, GetPostgresWalHealthResponse, GetPreferencesData, GetPreferencesResponse, GetPreviewGatewayLogsData, GetPreviewGatewayLogsResponse, GetPreviewGatewaySettingsData, GetPreviewGatewaySettingsResponse, GetPreviewGatewayStatusData, GetPreviewGatewayStatusResponse, GetPricingData, GetPricingError, GetPricingResponse, GetPrivateIpData, GetProjectAlarmsSummaryData, GetProjectAlarmsSummaryResponse, GetProjectBySlugData, GetProjectBySlugResponse, GetProjectData, GetProjectDeploymentsData, GetProjectDeploymentsResponse, GetProjectResponse, GetProjectsData, GetProjectServiceEnvironmentVariablesData, GetProjectServiceEnvironmentVariablesResponse, GetProjectSessionReplaysData, GetProjectSessionReplaysError, GetProjectSessionReplaysResponse2, GetProjectsHealthData, GetProjectsHealthError, GetProjectsHealthResponse, GetProjectsMonitorHealthData, GetProjectsMonitorHealthResponse, GetProjectsResponse, GetProjectStatisticsData, GetProjectStatisticsResponse, GetProjectTemplateData, GetProjectTemplateResponse, GetPropertyBreakdownData, GetPropertyBreakdownResponse, GetPropertyTimelineData, GetPropertyTimelineResponse, GetProviderConnectionsData, GetProviderConnectionsResponse, GetProviderMetadataData, GetProviderMetadataResponse, GetProvidersMetadataData, GetProvidersMetadataResponse, GetProxyLogByIdData, GetProxyLogByIdError, GetProxyLogByIdResponse, GetProxyLogByRequestIdData, GetProxyLogByRequestIdError, GetProxyLogByRequestIdResponse, GetProxyLogsData, GetProxyLogsError, GetProxyLogsResponse, GetPublicBranchesData, GetPublicBranchesResponse, GetPublicIpData, GetPublicRepositoryData, GetPublicRepositoryResponse, GetQueryContainerInfoData, GetQueryContainerInfoResponse, GetQuotaData, GetQuotaError, GetQuotaResponse, GetRecentActivityData, GetRecentActivityResponse, GetRemoteExternalImageData, GetRemoteExternalImageResponse, GetRepositoryBranchesData, GetRepositoryBranchesResponse, GetRepositoryByIdData, GetRepositoryByIdResponse, GetRepositoryByNameData, GetRepositoryByNameResponse, GetRepositoryPresetByNameData, GetRepositoryPresetByNameResponse, GetRepositoryPresetLiveData, GetRepositoryPresetLiveResponse, GetRepositoryTagsData, GetRepositoryTagsResponse, GetResolvedEnvironmentVariablesData, GetResolvedEnvironmentVariablesResponse, GetResolvedEnvironmentVariableValueData, GetResolvedEnvironmentVariableValueResponse, GetRestoreCapabilitiesData, GetRestoreCapabilitiesError, GetRestoreCapabilitiesResponse, GetRestoreRunData, GetRestoreRunError, GetRestoreRunResponse, GetRouteData, GetRouteResponse, GetRunData, GetRunResponse, GetRunWithLogsData, GetRunWithLogsResponse, GetS3CredentialsData, GetS3CredentialsResponse, GetS3SourceData, GetS3SourceError, GetS3SourceResponse, GetSandboxData, GetSandboxResponse, GetSandboxStatusData, GetSandboxStatusResponse, GetScanByDeploymentData, GetScanByDeploymentError, GetScanByDeploymentResponse, GetScanData, GetScanError, GetScanResponse, GetScanVulnerabilitiesData, GetScanVulnerabilitiesError, GetScanVulnerabilitiesResponse, GetServiceBySlugData, GetServiceBySlugResponse, GetServiceData, GetServiceEnvironmentVariableData, GetServiceEnvironmentVariableResponse, GetServiceEnvironmentVariablesData, GetServiceEnvironmentVariablesResponse, GetServiceHealthStatusData, GetServiceHealthStatusResponse, GetServicePreviewEnvironmentVariableNamesData, GetServicePreviewEnvironmentVariableNamesResponse, GetServicePreviewEnvironmentVariablesMaskedData, GetServicePreviewEnvironmentVariablesMaskedResponse, GetServiceResponse, GetServiceRuntimeData, GetServiceRuntimeResponse, GetServiceStatsData, GetServiceStatsResponse, GetServiceTypeParametersData, GetServiceTypesData, GetServiceTypesResponse, GetSessionDetailsData, GetSessionDetailsResponse, GetSessionEventsData, GetSessionEventsResponse, GetSessionLogsData, GetSessionLogsResponse, GetSessionReplayData, GetSessionReplayError, GetSessionReplayEventsData, GetSessionReplayEventsError, GetSessionReplayEventsResponse, GetSessionReplayResponse2, GetSettingsData, GetSettingsResponse, GetSkillData, GetSkillResponse, GetSlowQueriesData, GetSlowQueriesResponse, GetStaticBundleData, GetStaticBundleResponse, GetStatusOverviewData, GetStatusOverviewResponse, GetTagsByRepositoryIdData, GetTagsByRepositoryIdResponse, GetTeamData, GetTeamResponse, GetTimeBucketStatsData, GetTimeBucketStatsError, GetTimeBucketStatsResponse, GetTodayStatsData, GetTodayStatsError, GetTodayStatsResponse, GetTraceData, GetTraceError, GetTraceResponse, GetUnifiedTraceData, GetUnifiedTraceError, GetUnifiedTraceResponse, GetUniqueCountsData, GetUniqueCountsResponse, GetUniqueEventsData, GetUniqueEventsResponse, GetUpdateStatusData, GetUpdateStatusResponse, GetUptimeHistoryData, GetUptimeHistoryResponse, GetUsageByProviderData, GetUsageByProviderError, GetUsageByProviderResponse, GetUsageRecentData, GetUsageRecentError, GetUsageRecentResponse, GetUsageSummaryData, GetUsageSummaryError, GetUsageSummaryResponse, GetUsageTimeseriesData, GetUsageTimeseriesError, GetUsageTimeseriesResponse, GetUsageTopModelsData, GetUsageTopModelsError, GetUsageTopModelsResponse, GetVisitorByGuidData, GetVisitorByGuidResponse, GetVisitorByIdData, GetVisitorByIdResponse, GetVisitorDetailsData, GetVisitorDetailsResponse, GetVisitorFacetsData, GetVisitorFacetsResponse, GetVisitorInfoData, GetVisitorInfoResponse, GetVisitorJourneyData, GetVisitorJourneyResponse, GetVisitorsData, GetVisitorSessionsData, GetVisitorSessionsError, GetVisitorSessionsResponse2, GetVisitorsResponse, GetVisitorStatsData, GetVisitorStatsResponse, GetWebhookData, GetWebhookResponse, GrantProjectAccessData, GrantProjectAccessResponse, HandleGitProviderOauthCallbackData, HasAnalyticsEventsData, HasAnalyticsEventsResponse2, HasErrorGroupsData, HasErrorGroupsResponse2, HasPerformanceMetricsData, HasPerformanceMetricsError, HasPerformanceMetricsResponse, ImportExternalServiceData, ImportExternalServiceResponse, IngestLogsByPathData, IngestLogsByPathError, IngestLogsData, IngestLogsError, IngestMetricsByPathData, IngestMetricsByPathError, IngestMetricsData, IngestMetricsError, IngestSentryEnvelopeData, IngestSentryEventData, IngestSentryEventResponse, IngestTracesByPathData, IngestTracesByPathError, IngestTracesData, IngestTracesError, InitSessionReplayData, InitSessionReplayError, InitSessionReplayResponse, InspectDropArchiveData, InspectDropArchiveResponse, JobLogsData, JobStatusData, JobStatusResponse2, KillJobData, KillJobResponse, KvDelData, KvDelResponse, KvDisableData, KvDisableResponse, KvEnableData, KvEnableResponse, KvExpireData, KvExpireResponse, KvGetData, KvGetResponse, KvIncrData, KvIncrResponse, KvKeysData, KvKeysResponse, KvSetData, KvSetResponse, KvStatusData, KvStatusResponse2, KvTtlData, KvTtlResponse, KvUpdateData, KvUpdateResponse, LatestRunForSourceData, LatestRunForSourceResponse, LinkCustomDomainToCertificateData, LinkCustomDomainToCertificateResponse, LinkServiceToProjectData, LinkServiceToProjectResponse, ListAgentRunsData, ListAgentRunsResponse, ListAgentsData, ListAgentsResponse2, ListAiProvidersData, ListAiProvidersResponse, ListAlertRulesData, ListAlertRulesResponse, ListAlertsData, ListAlertsError, ListAlertsResponse, ListAllConversationsData, ListAllConversationsResponse, ListAllRunsData, ListAllRunsResponse, ListApiKeysData, ListApiKeysResponse, ListAuditLogsData, ListAuditLogsResponse, ListAvailableContainersData, ListAvailableContainersResponse, ListBackupAlertsData, ListBackupAlertsError, ListBackupAlertsResponse, ListBackupChildrenData, ListBackupChildrenError, ListBackupChildrenResponse, ListBackupSchedulesData, ListBackupSchedulesError, ListBackupSchedulesResponse, ListBackupsForScheduleData, ListBackupsForScheduleResponse, ListCommitsByRepositoryIdData, ListCommitsByRepositoryIdResponse, ListConnectionsData, ListConnectionsResponse, ListContainersAtPathData, ListContainersAtPathResponse, ListContainersData, ListContainersResponse, ListConversationsData, ListConversationsResponse, ListCustomDomainsForProjectData, ListCustomDomainsForProjectResponse, ListDashboardsData, ListDashboardsError, ListDashboardsResponse, ListDeliveriesData, ListDeliveriesResponse, ListDeploymentContainerLogsData, ListDeploymentContainerLogsResponse, ListDeploymentTokensData, ListDeploymentTokensResponse, ListDnsProvidersData, ListDnsProvidersResponse, ListDomainsData, ListDomainsResponse2, ListDsnsData, ListDsnsResponse, ListEmailDomainsData, ListEmailDomainsResponse, ListEmailProvidersData, ListEmailProvidersResponse, ListEmailsData, ListEmailsResponse, ListEnrollmentTokensData, ListEnrollmentTokensResponse, ListEntitiesData, ListEntitiesResponse, ListErrorEventsData, ListErrorEventsResponse, ListErrorGroupsData, ListErrorGroupsResponse, ListEventsData, ListEventsResponse, ListEventTypesData, ListEventTypesResponse, ListExternalImagesData, ListExternalImagesResponse, ListExternalPluginsData, ListExternalPluginsResponse, ListExternalServiceBackupsData, ListExternalServiceBackupsError, ListExternalServiceBackupsResponse, ListFlagsData, ListFlagsResponse, ListFunnelsData, ListFunnelsResponse, ListGitProvidersData, ListGitProvidersResponse, ListGlobalMcpsData, ListGlobalMcpsResponse, ListGlobalSkillsData, ListGlobalSkillsResponse, ListIncidentsData, ListInsightsData, ListInsightsError, ListInsightsResponse, ListIpAccessControlData, ListIpAccessControlError, ListIpAccessControlResponse, ListJobsData, ListJobsResponse2, ListKnownAiAgentsData, ListKnownAiAgentsError, ListKnownAiAgentsResponse, ListManagedDomainsData, ListManagedDomainsResponse, ListMcpsData, ListMcpsResponse2, ListMetricLabelKeysData, ListMetricLabelKeysError, ListMetricLabelKeysResponse, ListMetricLabelValuesData, ListMetricLabelValuesError, ListMetricLabelValuesResponse, ListMetricNamesData, ListMetricNamesError, ListMetricNamesResponse, ListModelsData, ListModelsError, ListModelsResponse, ListMonitorsData, ListMonitorsResponse, ListNotificationProvidersData, ListNotificationProvidersResponse, ListOidcProvidersData, ListOidcProvidersResponse, ListOidcProviderUsersData, ListOidcProviderUsersResponse, ListOidcRoleMappingsData, ListOidcRoleMappingsResponse, ListOnDemandCertsData, ListOnDemandCertsResponse2, ListOrdersData, ListOrdersResponse2, ListPeersData, ListPeersResponse, ListPendingActionsData, ListPendingActionsResponse, ListPgUpgradesData, ListPgUpgradesResponse, ListPresetsData, ListPresetsResponse2, ListProjectAccessData, ListProjectAccessResponse, ListProjectAlarmsData, ListProjectAlarmsResponse, ListProjectScansData, ListProjectScansError, ListProjectScansResponse, ListProjectSecretsData, ListProjectSecretsResponse, ListProjectServicesData, ListProjectServicesResponse, ListProjectTemplatesData, ListProjectTemplatesResponse, ListProjectTemplateTagsData, ListProjectTemplateTagsResponse, ListProviderKeysData, ListProviderKeysError, ListProviderKeysResponse, ListProviderZonesData, ListProviderZonesResponse, ListPublicProvidersData, ListPublicProvidersResponse, ListReleaseFilesData, ListReleaseFilesResponse, ListReleasesData, ListReleasesResponse, ListRemoteExternalImagesData, ListRemoteExternalImagesResponse, ListRepositoriesByConnectionData, ListRepositoriesByConnectionResponse, ListRepositoriesByProviderData, ListRepositoriesByProviderResponse, ListRestoreRunsForServiceData, ListRestoreRunsForServiceResponse, ListRootContainersData, ListRootContainersResponse, ListRoutesData, ListRoutesResponse, ListS3SourcesData, ListS3SourcesError, ListS3SourcesResponse, ListSandboxesData, ListSandboxesResponse2, ListScheduleRunJobsData, ListScheduleRunJobsError, ListScheduleRunJobsResponse, ListScheduleRunsData, ListScheduleRunsError, ListScheduleRunsResponse, ListScheduleServicesData, ListScheduleServicesError, ListScheduleServicesResponse, ListSecretsData, ListSecretsResponse2, ListServiceHealthStatusesData, ListServiceHealthStatusesResponse, ListServiceProjectsData, ListServiceProjectsResponse, ListServiceSchedulesData, ListServiceSchedulesError, ListServiceSchedulesResponse, ListServicesData, ListServicesResponse, ListSkillsData, ListSkillsResponse2, ListSourceBackupsData, ListSourceBackupsError, ListSourceBackupsResponse, ListSourceFilesData, ListSourceFilesResponse, ListSourceMapsData, ListSourceMapsResponse, ListSourcesData, ListSourcesResponse, ListStaticBundlesData, ListStaticBundlesResponse, ListSyncedRepositoriesData, ListSyncedRepositoriesResponse, ListTeamMembersData, ListTeamMembersResponse, ListTeamProjectsData, ListTeamProjectsResponse, ListTeamsData, ListTeamsResponse, ListUsersData, ListUsersResponse, ListWebhooksData, ListWebhooksResponse, LoginData, LoginResponse, LogoutData, LookupDnsARecordsData, LookupDnsARecordsError, LookupDnsARecordsResponse, MintEnrollmentTokenData, MintEnrollmentTokenResponse2, MkdirData, MkdirResponse, NodeHeartbeatData, NodeHeartbeatResponse, NodeMetricsGetRangeData, NodeMetricsGetRangeResponse, ObservabilityFullEventData, ObservabilityFullEventError, ObservabilityFullEventResponse, ObservabilityListEventsData, ObservabilityListEventsError, ObservabilityListEventsResponse, OidcCallbackData, PatchAdminGateData, PatchAdminGateResponse, PatchPreviewGatewaySettingsData, PatchPreviewGatewaySettingsResponse, PauseDeploymentData, PauseDeploymentResponse, PauseSandboxData, PauseSandboxResponse, PlanRestoreData, PlanRestoreError, PlanRestoreResponse, PostDnsAckData, PostDnsAckResponse, PreviewAlertData, PreviewAlertError, PreviewAlertResponse, PreviewFunnelMetricsData, PreviewFunnelMetricsResponse, PreviewHostnameModeData, PreviewHostnameModeResponse, PromoteClusterMemberData, PromoteDeploymentData, PromoteDeploymentResponse, ProvisionDomainData, ProvisionDomainResponse, PurgeProjectLogsData, PurgeProjectLogsError, PushExternalImageData, PushExternalImageResponse, QueryDataData, QueryDataResponse2, QueryGenaiTracesData, QueryGenaiTracesError, QueryGenaiTracesResponse, QueryLogsData, QueryLogsError, QueryLogsResponse, QueryMetricsData, QueryMetricsError, QueryMetricsResponse, QuerySpanStatsData, QuerySpanStatsError, QuerySpanStatsResponse, QueryTracesData, QueryTracesError, QueryTracesResponse, QueryTraceSummariesData, QueryTraceSummariesError, QueryTraceSummariesResponse, ReadEntityRowsData, ReadEntityRowsResponse, ReadFileData, ReadFileResponse2, ReAnalyzeData, RecordConsoleEventData, RecordEventMetricsData, RecordEventMetricsResponse, RecordFlagExposureData, RecordFlagExposureResponse, RecordSpeedMetricsData, RecordSpeedMetricsError, RecordSpeedMetricsResponse, RefreshRouteTableData, RefreshRouteTableResponse, RegenerateDsnData, RegenerateDsnResponse, RegisterExternalImageData, RegisterExternalImageResponse, RegisterNodeData, RegisterNodeResponse2, ReinstallGitlabWebhookData, ReinstallGitlabWebhookResponse, RejectPendingActionData, RejectPendingActionResponse, ReloadPluginsData, ReloadPluginsResponse, RemoveClusterMemberData, RemoveClusterMemberResponse, RemoveManagedDomainData, RemoveManagedDomainResponse, RemoveRoleData, RemoveRoleResponse, RemoveTeamMemberData, RemoveTeamMemberResponse, RenameConversationData, RenameConversationResponse, RenewDomainData, RenewDomainResponse, RequestPasswordResetData, RequestPasswordResetResponse, ResetPasswordData, ResetPasswordResponse, ResizeSandboxData, ResizeSandboxResponse, ResolveAlarmData, RestartContainerData, RestartContainerResponse, RestartPreviewGatewayData, RestartPreviewGatewayResponse, RestartSandboxData, RestartSandboxResponse, RestoreFlagData, RestoreFlagResponse, RestoreUserData, RestoreUserResponse, ResumeDeploymentData, ResumeDeploymentResponse, ResumeSandboxData, ResumeSandboxResponse, RetryClusterData, RetryClusterResponse, RetryDeliveryData, RetryDeliveryResponse, RetryPgUpgradeData, RetryPgUpgradeResponse, RetryRunData, RetryRunResponse, RevealGlobalMcpConfigData, RevealGlobalMcpConfigResponse, RevealMcpConfigData, RevealMcpConfigResponse, RevealNotificationProviderConfigData, RevealNotificationProviderConfigResponse, RevealServiceParameterData, RevealServiceParameterResponse, RevenueCreateIntegrationData, RevenueCreateIntegrationResponse, RevenueDeleteIntegrationData, RevenueDeleteIntegrationResponse, RevenueGlobalEventsData, RevenueGlobalEventsResponse, RevenueImportInvoicesCsvData, RevenueImportInvoicesCsvResponse, RevenueImportSubscriptionsCsvData, RevenueImportSubscriptionsCsvResponse, RevenueListIntegrationsData, RevenueListIntegrationsResponse, RevenueListProvidersData, RevenueListProvidersResponse, RevenueMetricsCustomersData, RevenueMetricsCustomersResponse, RevenueMetricsGlobalMrrData, RevenueMetricsGlobalMrrResponse, RevenueMetricsGlobalSummaryData, RevenueMetricsGlobalSummaryResponse, RevenueMetricsMrrData, RevenueMetricsMrrResponse, RevenueMetricsSummaryData, RevenueMetricsSummaryResponse, RevenueRecentEventsData, RevenueRecentEventsResponse, RevenueRotateTokenData, RevenueRotateTokenResponse, RevenueUpdateConfigData, RevenueUpdateConfigResponse, RevenueUpdateSecretData, RevenueUpdateSecretResponse, RevokeDsnData, RevokeDsnResponse, RevokeEnrollmentTokenData, RevokeEnrollmentTokenResponse, RevokeJoinTokenData, RevokeJoinTokenResponse, RevokeProjectAccessData, RevokeProjectAccessResponse, RollbackPgUpgradeData, RollbackPgUpgradeResponse, RollbackToDeploymentData, RollbackToDeploymentResponse, RootfsGcData, RootfsReportData, RotateApiKeyData, RotateApiKeyResponse, RotateDeploymentTokenData, RotateDeploymentTokenResponse, RunBackupForSourceData, RunBackupForSourceError, RunBackupForSourceResponse, RunConnectionHealthCheckData, RunConnectionHealthCheckResponse, RunExternalServiceBackupData, RunExternalServiceBackupError, RunExternalServiceBackupResponse, RunScheduleNowData, RunScheduleNowError, RunScheduleNowResponse, SandboxCreatePreviewLinkData, SandboxCreatePreviewLinkResponse, SaveAgentTokenData, SaveAgentTokenResponse2, SaveAiProviderCredentialData, SaveAiProviderCredentialResponse, SearchLogsData, SearchLogsError, SearchLogsResponse2, SendEmailData, SendEmailResponse, SetAiDataAccessData, SetAiDataAccessResponse, SetDefaultS3SourceData, SetDefaultS3SourceError, SetDefaultS3SourceResponse, SetFlagEnvironmentData, SetFlagEnvironmentResponse, SetPreviewPasswordData, SetPreviewPasswordResponse2, SetupDnsChallengeData, SetupDnsChallengeResponse2, SetupDnsData, SetupDnsResponse2, SetupEmailTrackingData, SetupEmailTrackingResponse, SetupMfaData, SetupMfaResponse, SleepEnvironmentData, SleepEnvironmentResponse, SmokeTestAgentData, SmokeTestAgentResponse, SourceSandboxData, SourceSandboxResponse, StartAnalysisData, StartAnalysisResponse, StartContainerData, StartContainerResponse, StartFixData, StartGitProviderOauthData, StartOidcLoginBySlugData, StartPgUpgradeData, StartPgUpgradeResponse, StartRestoreData, StartRestoreError, StartRestoreResponse, StartServiceData, StartServiceResponse, StatPathData, StatPathResponse, StopContainerData, StopContainerResponse, StopSandboxData, StopSandboxResponse, StopServiceData, StopServiceResponse, StreamContainerMetricsData, SyncRepositoriesData, SyncRepositoriesResponse, TailDeploymentJobLogsData, TailLogsData, TailLogsError, TeardownDeploymentData, TeardownDeploymentResponse, TeardownEnvironmentData, TeardownEnvironmentResponse, TerminalData, TestNotificationProviderData, TestNotificationProviderResponse, TestOidcProviderData, TestOidcProviderResponse, TestProviderConnectionData, TestProviderConnectionResponse, TestProviderData, TestProviderKeyByIdData, TestProviderKeyByIdError, TestProviderKeyByIdResponse, TestProviderKeyInlineData, TestProviderKeyInlineError, TestProviderKeyInlineResponse, TestProviderResponse2, TestS3ConnectionPreviewData, TestS3ConnectionPreviewError, TestS3ConnectionPreviewResponse, TestS3SourceConnectionData, TestS3SourceConnectionError, TestS3SourceConnectionResponse, TrackClickData, TrackOpenData, TriggerAgentData, TriggerAgentResponse, TriggerProjectPipelineData, TriggerProjectPipelineResponse, TriggerScanData, TriggerScanError, TriggerScanResponse2, TriggerServiceHealthCheckData, TriggerServiceHealthCheckResponse, TriggerWeeklyDigestData, TriggerWeeklyDigestResponse, UnlinkServiceFromProjectData, UnlinkServiceFromProjectResponse, UpdateAgentData, UpdateAgentResponse, UpdateAiProviderData, UpdateAiProviderResponse2, UpdateAlertData, UpdateAlertError, UpdateAlertResponse, UpdateAlertRuleData, UpdateAlertRuleResponse, UpdateApiKeyData, UpdateApiKeyResponse, UpdateAutomaticDeployData, UpdateAutomaticDeployResponse, UpdateBackupScheduleData, UpdateBackupScheduleError, UpdateBackupScheduleResponse, UpdateCloudflareProviderData, UpdateCloudflareProviderResponse, UpdateConnectionTokenData, UpdateConnectionTokenResponse, UpdateCustomDomainData, UpdateCustomDomainResponse, UpdateDashboardData, UpdateDashboardError, UpdateDashboardResponse, UpdateDeploymentTokenData, UpdateDeploymentTokenResponse, UpdateEmailProviderData, UpdateEmailProviderResponse, UpdateEnvironmentSettingsData, UpdateEnvironmentSettingsResponse, UpdateEnvironmentSubdomainData, UpdateEnvironmentSubdomainResponse, UpdateEnvironmentVariableData, UpdateEnvironmentVariableResponse, UpdateErrorGroupData, UpdateFlagData, UpdateFlagResponse, UpdateFunnelData, UpdateGitProviderCredentialsData, UpdateGitProviderCredentialsResponse, UpdateGitSettingsData, UpdateGitSettingsResponse, UpdateGlobalMcpData, UpdateGlobalMcpResponse, UpdateGlobalSkillData, UpdateGlobalSkillResponse, UpdateIncidentStatusData, UpdateIncidentStatusResponse, UpdateIpAccessControlData, UpdateIpAccessControlError, UpdateIpAccessControlResponse, UpdateManagedDomainData, UpdateManagedDomainResponse, UpdateMcpData, UpdateMcpResponse, UpdateNotificationEmailProviderData, UpdateNotificationEmailProviderResponse, UpdateNotificationProviderData, UpdateNotificationProviderResponse, UpdateOidcProviderData, UpdateOidcProviderResponse, UpdatePreferencesData, UpdatePreferencesResponse, UpdateProjectData, UpdateProjectDeploymentConfigData, UpdateProjectDeploymentConfigResponse, UpdateProjectResponse, UpdateProjectSecretData, UpdateProjectSecretResponse, UpdateProjectSettingsData, UpdateProjectSettingsResponse, UpdateProviderData, UpdateProviderKeyData, UpdateProviderKeyError, UpdateProviderKeyResponse, UpdateProviderResponse, UpdateRouteData, UpdateRouteResponse, UpdateS3SourceData, UpdateS3SourceError, UpdateS3SourceResponse, UpdateSelfData, UpdateSelfResponse, UpdateServiceData, UpdateServiceResourcesData, UpdateServiceResourcesResponse, UpdateServiceResponse, UpdateSessionDurationData, UpdateSessionDurationError, UpdateSessionDurationResponse2, UpdateSettingsData, UpdateSettingsResponse, UpdateSkillData, UpdateSkillResponse, UpdateSlackProviderData, UpdateSlackProviderResponse, UpdateSpeedMetricsData, UpdateSpeedMetricsError, UpdateSpeedMetricsResponse, UpdateTeamData, UpdateTeamMemberRoleData, UpdateTeamMemberRoleResponse, UpdateTeamResponse, UpdateUserData, UpdateUserResponse, UpdateWebhookData, UpdateWebhookProviderData, UpdateWebhookProviderResponse, UpdateWebhookResponse, UpgradePreviewGatewayData, UpgradePreviewGatewayResponse, UpgradeServiceData, UpgradeServiceResponse, UploadGlobalSkillData, UploadGlobalSkillResponse, UploadReleaseFileData, UploadReleaseFileResponse, UploadSkillData, UploadSkillResponse, UploadSourceFileData, UploadSourceFileResponse, UploadSourceMapData, UploadSourceMapResponse, UploadStaticBundleData, UploadStaticBundleResponse, UpsertSecretData, UpsertSecretResponse, ValidateConnectionData, ValidateConnectionResponse, ValidateEmailData, ValidateEmailResponse2, VerifyAndEnableMfaData, VerifyAndEnableMfaResponse, VerifyDomainData, VerifyDomainResponse, VerifyEmailData, VerifyEmailResponse, VerifyManagedDomainData, VerifyManagedDomainResponse, VerifyMfaChallengeData, VerifyMfaChallengeResponse, VerifyStepUpData, VerifyStepUpResponse, WakeEnvironmentData, WakeEnvironmentResponse, WebhookTriggerData, WebhookTriggerResponse2, WorkflowDryRunData, WorkflowDryRunResponse, WriteFileData, WriteFileResponse, WriteFilesData, WriteFilesResponse2 } from '../types.gen'; export type QueryKey = [ Pick & { @@ -15748,6 +15748,24 @@ export const stopSandboxMutation = (options?: Partial>) return mutationOptions; }; +export const terminalQueryKey = (options: Options) => createQueryKey('terminal', options); + +/** + * Attach an interactive terminal to a sandbox. + */ +export const terminalOptions = (options: Options) => queryOptions>({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await terminal({ + ...options, + ...queryKey[0], + signal, + throwOnError: true + }); + return data; + }, + queryKey: terminalQueryKey(options) +}); + /** * Kill a running command (`@vercel/sandbox`-compatible). The SDK * calls `POST /v1/sandboxes/{id}/{cmdId}/kill` — note the path has the diff --git a/web/src/api/client/index.ts b/web/src/api/client/index.ts index ff569f872..85b707af4 100644 --- a/web/src/api/client/index.ts +++ b/web/src/api/client/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts -export { acknowledgeAlarm, activateAiProvider, activateApiKey, activateConnection, activateProvider, addClusterMember, addContext, addEnvironmentDomain, addEvents, addManagedDomain, addSessionReplayEvents, addTeamMember, adminDrainNode, adminDrainStatus, adminGetNode, adminListNodeContainers, adminListNodes, adminRemoveNode, adminUndrainNode, applyHostnameMode, archiveConversation, archiveFlag, assignRole, attachScheduleServices, blobCopy, blobDelete, blobDisable, blobDownload, blobEnable, blobHead, blobList, blobPut, blobStatus, blobUpdate, cancel, cancelBackup, cancelDeployment, cancelDomainOrder, cancelPgUpgrade, cancelRun, cancelScheduleRun, changePasswordSelf, changeProjectSource, changeRequiredPassword, chatCompletions, checkAnalyticsHasEvents, checkCommitExists, checkDomainStatus, checkExplorerSupport, checkIpBlocked, checkProviderDeletionSafety, chunkUploadOptions, cleanupExpiredBackups, clearPreviewPassword, cliDeviceApprove, cliDeviceDeny, cliDeviceLookup, cliDevicePoll, cliDeviceStart, cliLogout, cmd, cmdKill, cmdLogs, confirmPendingAction, containerMetricsGetHistory, createAgent, createAlert, createAlertRule, createApiKey, createBackupSchedule, createBitbucketProvider, createCloudflareProvider, createConversation, createCustomDomain, createDashboard, createDeploymentToken, createDnsProvider, createDomain, createDsn, createEmailDomain, createEmailProvider, createEnvironment, createEnvironmentVariable, createFlag, createFunnel, createGenericProvider, createGiteaPatProvider, createGithubPatProvider, createGitlabOauthProvider, createGitlabPatProvider, createGitProvider, createGlobalMcp, createGlobalSkill, createIncident, createIpAccessControl, createMcp, createMonitor, createNotificationEmailProvider, createNotificationProvider, createOidcProvider, createOidcRoleMapping, createOrRecreateOrder, createPlan, createPr, createProject, createProjectFromTemplate, createProjectRelease, createProjectSecret, createProviderKey, createRelease, createRoute, createS3Source, createSandbox, createService, createSkill, createSlackProvider, createTeam, createUser, createWebhook, createWebhookProvider, deactivateApiKey, deactivateConnection, deactivateProvider, deleteAgent, deleteAlert, deleteAlertRule, deleteApiKey, deleteBackup, deleteBackupSchedule, deleteConnection, deleteCustomDomain, deleteDashboard, deleteDeploymentToken, deleteDnsProvider, deleteDomain, deleteEmailDomain, deleteEmailProvider, deleteEnvironment, deleteEnvironmentDomain, deleteEnvironmentVariable, deleteExternalImage, deleteFunnel, deleteGitProvider, deleteGlobalMcp, deleteGlobalSkill, deleteIpAccessControl, deleteMcp, deleteMonitor, deleteNotificationProvider, deleteOidcProvider, deleteOidcRoleMapping, deletePreferences, deleteProject, deleteProjectSecret, deleteProviderKey, deleteProviderSafely, deleteReleaseSourceFiles, deleteReleaseSourceMaps, deleteRoute, deleteS3Source, deleteScan, deleteSecret, deleteService, deleteSessionReplay, deleteSkill, deleteSourceMap, deleteStaticBundle, deleteTeam, deleteUser, deleteWebhook, deployFromImage, deployFromImageUpload, deployFromStatic, deployFromUploadedSource, deploymentMetricsGetLatest, deploymentMetricsGetRange, deploymentMetricsToggle, destroySandbox, detachScheduleService, detectPublicPresets, disableBackupSchedule, disableMfa, discoverWorkloads, domain, downloadGlobalSkillArchive, downloadObject, downloadSkillArchive, emailStatus, embeddings, enableBackupSchedule, enrichVisitor, exec, execDetached, executeDeploymentOperation, executeImport, extendTimeout, externalServiceEnablePgStatStatements, externalServiceMetricsByDatabase, externalServiceMetricsCreateAlertRule, externalServiceMetricsDeleteAlertRule, externalServiceMetricsGetAlertRules, externalServiceMetricsGetLatest, externalServiceMetricsGetRange, externalServiceMetricsStatus, externalServiceMetricsToggle, externalServiceMetricsUpdateAlertRule, externalServiceResetPgStatStatements, finalizeOrder, finalizeProjectRelease, findConversation, generateJoinToken, generatePresetDockerfile, getAccessInfo, getActiveVisitors, getActivityGraph, getAdminGate, getAgent, getAggregatedBuckets, getAiAgentBreakdown, getAiAgentPages, getAiAgentTimeline, getAiDataAccess, getAiPageBreakdown, getAiStatusBreakdown, getAlert, getAlertRule, getAllRepositoriesByName, getAnalyticsActiveVisitors, getAnalyticsEventsCount, getAnalyticsSessionEvents, getAnalyticsVisitorSessions, getApiKey, getApiKeyPermissions, getAuditLog, getBackup, getBackupSchedule, getBranchesByRepositoryId, getBucketedIncidents, getBucketedStatus, getChallengeToken, getChatReadiness, getCliStatus, getClusterHealth, getClusterMember, getCmd, getContainerDetail, getContainerEnvironmentVariable, getContainerLogs, getContainerLogsById, getContainerMetrics, getConversation, getConversationDetail, getConversations, getCronById, getCronExecutions, getCrossProjectTraceSiblings, getCurrentMonitorStatus, getCurrentUser, getCustomDomain, getDashboard, getDashboardProjectsAnalytics, getDelivery, getDeployment, getDeploymentContainerLogContent, getDeploymentJobLogs, getDeploymentJobs, getDeploymentOperations, getDeploymentOperationStatus, getDeploymentToken, getDiskStatus, getDnsChanges, getDnsProvider, getDomain, getDomainByHost, getDomainById, getDomainByName, getDomainDnsRecords, getDomainOrder, getEmail, getEmailEvents, getEmailLinks, getEmailProvider, getEmailStats, getEmailTracking, getEmailTrackingStatus, getEntityInfo, getEnvironment, getEnvironmentCrons, getEnvironmentDomains, getEnvironments, getEnvironmentVariables, getEnvironmentVariableValue, getErrorDashboardStats, getErrorEvent, getErrorGroup, getErrorStats, getErrorTimeSeries, getEventDetail, getEventEntries, getEventsCount, getEventsTimeline, getEventTypeBreakdown, getEventVisitors, getExternalImage, getFile, getFlag, getFlagSnapshot, getFunnelMetrics, getGenaiTrace, getGeneralStats, getGitProvider, getGlobalEvents, getGlobalEventStats, getGlobalMcp, getGlobalSandboxStatus, getGlobalSkill, getGroupedPageMetrics, getHealth, getHourlyVisits, getHttpChallengeDebug, getImportStatus, getIncident, getIncidentUpdates, getIpAccessControl, getIpGeolocation, getJoinTokenStatus, getLastDeployment, getLatestScan, getLatestScansPerEnvironment, getLiveVisitorsList, getLogContext, getMcp, getMetricsOverTime, getMonitor, getNotificationProvider, getOnDemandCertStatus, getOrCreateDsn, getPageFlow, getPageHourlySessions, getPagePathDetail, getPagePaths, getPagePathsSparklines, getPagePathVisitors, getPendingAction, getPerformanceMetrics, getPgUpgrade, getPgUpgradeLogs, getPipelineStats, getPlatformInfo, getPostgresWalHealth, getPreferences, getPreviewGatewayLogs, getPreviewGatewaySettings, getPreviewGatewayStatus, getPricing, getPrivateIp, getProject, getProjectAlarmsSummary, getProjectBySlug, getProjectDeployments, getProjects, getProjectServiceEnvironmentVariables, getProjectSessionReplays, getProjectsHealth, getProjectsMonitorHealth, getProjectStatistics, getProjectTemplate, getPropertyBreakdown, getPropertyTimeline, getProviderConnections, getProviderMetadata, getProvidersMetadata, getProxyLogById, getProxyLogByRequestId, getProxyLogs, getPublicBranches, getPublicIp, getPublicRepository, getQueryContainerInfo, getQuota, getRecentActivity, getRemoteExternalImage, getRepositoryBranches, getRepositoryById, getRepositoryByName, getRepositoryPresetByName, getRepositoryPresetLive, getRepositoryTags, getResolvedEnvironmentVariables, getResolvedEnvironmentVariableValue, getRestoreCapabilities, getRestoreRun, getRoute, getRun, getRunWithLogs, getS3Credentials, getS3Source, getSandbox, getSandboxStatus, getScan, getScanByDeployment, getScanVulnerabilities, getService, getServiceBySlug, getServiceEnvironmentVariable, getServiceEnvironmentVariables, getServiceHealthStatus, getServicePreviewEnvironmentVariableNames, getServicePreviewEnvironmentVariablesMasked, getServiceRuntime, getServiceStats, getServiceTypeParameters, getServiceTypes, getSessionDetails, getSessionEvents, getSessionLogs, getSessionReplay, getSessionReplayEvents, getSettings, getSkill, getSlowQueries, getStaticBundle, getStatusOverview, getTagsByRepositoryId, getTeam, getTimeBucketStats, getTodayStats, getTrace, getUnifiedTrace, getUniqueCounts, getUniqueEvents, getUpdateStatus, getUptimeHistory, getUsageByProvider, getUsageRecent, getUsageSummary, getUsageTimeseries, getUsageTopModels, getVisitorByGuid, getVisitorById, getVisitorDetails, getVisitorFacets, getVisitorInfo, getVisitorJourney, getVisitors, getVisitorSessions, getVisitorStats, getWebhook, grantProjectAccess, handleGitProviderOauthCallback, hasAnalyticsEvents, hasErrorGroups, hasPerformanceMetrics, importExternalService, ingestLogs, ingestLogsByPath, ingestMetrics, ingestMetricsByPath, ingestSentryEnvelope, ingestSentryEvent, ingestTraces, ingestTracesByPath, initSessionReplay, inspectDropArchive, jobLogs, jobStatus, killJob, kvDel, kvDisable, kvEnable, kvExpire, kvGet, kvIncr, kvKeys, kvSet, kvStatus, kvTtl, kvUpdate, latestRunForSource, linkCustomDomainToCertificate, linkServiceToProject, listAgentRuns, listAgents, listAiProviders, listAlertRules, listAlerts, listAllConversations, listAllRuns, listApiKeys, listAuditLogs, listAvailableContainers, listBackupAlerts, listBackupChildren, listBackupSchedules, listBackupsForSchedule, listCommitsByRepositoryId, listConnections, listContainers, listContainersAtPath, listConversations, listCustomDomainsForProject, listDashboards, listDeliveries, listDeploymentContainerLogs, listDeploymentTokens, listDnsProviders, listDomains, listDsns, listEmailDomains, listEmailProviders, listEmails, listEnrollmentTokens, listEntities, listErrorEvents, listErrorGroups, listEvents, listEventTypes, listExternalImages, listExternalPlugins, listExternalServiceBackups, listFlags, listFunnels, listGitProviders, listGlobalMcps, listGlobalSkills, listIncidents, listInsights, listIpAccessControl, listJobs, listKnownAiAgents, listManagedDomains, listMcps, listMetricLabelKeys, listMetricLabelValues, listMetricNames, listModels, listMonitors, listNotificationProviders, listOidcProviders, listOidcProviderUsers, listOidcRoleMappings, listOnDemandCerts, listOrders, listPeers, listPendingActions, listPgUpgrades, listPresets, listProjectAccess, listProjectAlarms, listProjectScans, listProjectSecrets, listProjectServices, listProjectTemplates, listProjectTemplateTags, listProviderKeys, listProviderZones, listPublicProviders, listReleaseFiles, listReleases, listRemoteExternalImages, listRepositoriesByConnection, listRepositoriesByProvider, listRestoreRunsForService, listRootContainers, listRoutes, listS3Sources, listSandboxes, listScheduleRunJobs, listScheduleRuns, listScheduleServices, listSecrets, listServiceHealthStatuses, listServiceProjects, listServices, listServiceSchedules, listSkills, listSourceBackups, listSourceFiles, listSourceMaps, listSources, listStaticBundles, listSyncedRepositories, listTeamMembers, listTeamProjects, listTeams, listUsers, listWebhooks, login, logout, lookupDnsARecords, mintEnrollmentToken, mkdir, nodeHeartbeat, nodeMetricsGetRange, observabilityFullEvent, observabilityListEvents, oidcCallback, type Options, patchAdminGate, patchPreviewGatewaySettings, pauseDeployment, pauseSandbox, planRestore, postDnsAck, previewAlert, previewFunnelMetrics, previewHostnameMode, promoteClusterMember, promoteDeployment, provisionDomain, purgeProjectLogs, pushExternalImage, queryData, queryGenaiTraces, queryLogs, queryMetrics, querySpanStats, queryTraces, queryTraceSummaries, readEntityRows, readFile, reAnalyze, recordConsoleEvent, recordEventMetrics, recordFlagExposure, recordSpeedMetrics, refreshRouteTable, regenerateDsn, registerExternalImage, registerNode, reinstallGitlabWebhook, rejectPendingAction, reloadPlugins, removeClusterMember, removeManagedDomain, removeRole, removeTeamMember, renameConversation, renewDomain, requestPasswordReset, resetPassword, resizeSandbox, resolveAlarm, restartContainer, restartPreviewGateway, restartSandbox, restoreFlag, restoreUser, resumeDeployment, resumeSandbox, retryCluster, retryDelivery, retryPgUpgrade, retryRun, revealGlobalMcpConfig, revealMcpConfig, revealNotificationProviderConfig, revealServiceParameter, revenueCreateIntegration, revenueDeleteIntegration, revenueGlobalEvents, revenueImportInvoicesCsv, revenueImportSubscriptionsCsv, revenueListIntegrations, revenueListProviders, revenueMetricsCustomers, revenueMetricsGlobalMrr, revenueMetricsGlobalSummary, revenueMetricsMrr, revenueMetricsSummary, revenueRecentEvents, revenueRotateToken, revenueUpdateConfig, revenueUpdateSecret, revokeDsn, revokeEnrollmentToken, revokeJoinToken, revokeProjectAccess, rollbackPgUpgrade, rollbackToDeployment, rootfsGc, rootfsReport, rotateApiKey, rotateDeploymentToken, runBackupForSource, runConnectionHealthCheck, runExternalServiceBackup, runScheduleNow, sandboxCreatePreviewLink, saveAgentToken, saveAiProviderCredential, searchLogs, sendEmail, setAiDataAccess, setDefaultS3Source, setFlagEnvironment, setPreviewPassword, setupDns, setupDnsChallenge, setupEmailTracking, setupMfa, sleepEnvironment, smokeTestAgent, sourceSandbox, startAnalysis, startContainer, startFix, startGitProviderOauth, startOidcLoginBySlug, startPgUpgrade, startRestore, startService, statPath, stopContainer, stopSandbox, stopService, streamContainerMetrics, streamEvents, streamRunEvents, syncRepositories, tailDeploymentJobLogs, tailLogs, teardownDeployment, teardownEnvironment, testNotificationProvider, testOidcProvider, testProvider, testProviderConnection, testProviderKeyById, testProviderKeyInline, testS3ConnectionPreview, testS3SourceConnection, trackClick, trackOpen, triggerAgent, triggerProjectPipeline, triggerScan, triggerServiceHealthCheck, triggerWeeklyDigest, unlinkServiceFromProject, updateAgent, updateAiProvider, updateAlert, updateAlertRule, updateApiKey, updateAutomaticDeploy, updateBackupSchedule, updateCloudflareProvider, updateConnectionToken, updateCustomDomain, updateDashboard, updateDeploymentToken, updateEmailProvider, updateEnvironmentSettings, updateEnvironmentSubdomain, updateEnvironmentVariable, updateErrorGroup, updateFlag, updateFunnel, updateGitProviderCredentials, updateGitSettings, updateGlobalMcp, updateGlobalSkill, updateIncidentStatus, updateIpAccessControl, updateManagedDomain, updateMcp, updateNotificationEmailProvider, updateNotificationProvider, updateOidcProvider, updatePreferences, updateProject, updateProjectDeploymentConfig, updateProjectSecret, updateProjectSettings, updateProvider, updateProviderKey, updateRoute, updateS3Source, updateSelf, updateService, updateServiceResources, updateSessionDuration, updateSettings, updateSkill, updateSlackProvider, updateSpeedMetrics, updateTeam, updateTeamMemberRole, updateUser, updateWebhook, updateWebhookProvider, upgradePreviewGateway, upgradeService, uploadGlobalSkill, uploadReleaseFile, uploadSkill, uploadSourceFile, uploadSourceMap, uploadStaticBundle, upsertSecret, validateConnection, validateEmail, verifyAndEnableMfa, verifyDomain, verifyEmail, verifyManagedDomain, verifyMfaChallenge, verifyStepUp, wakeEnvironment, webhookTrigger, workflowDryRun, writeFile, writeFiles } from './sdk.gen'; -export type { AcknowledgeAlarmData, AcknowledgeAlarmErrors, AcknowledgeAlarmResponses, AcmeOrderResponse, ActivateAiProviderData, ActivateAiProviderErrors, ActivateAiProviderResponse, ActivateAiProviderResponses, ActivateApiKeyData, ActivateApiKeyErrors, ActivateApiKeyResponse, ActivateApiKeyResponses, ActivateConnectionData, ActivateConnectionErrors, ActivateConnectionResponses, ActivateProviderData, ActivateProviderErrors, ActivateProviderResponse, ActivateProviderResponses, ActiveVisitor, ActiveVisitorsQuery, ActiveVisitorsResponse, ActivityDay, ActivityEvent, ActivityGraphQuery, ActivityGraphResponse, AddClusterMemberData, AddClusterMemberErrors, AddClusterMemberRequest, AddClusterMemberResponse, AddClusterMemberResponses, AddContextData, AddContextErrors, AddContextRequest, AddContextResponses, AddEnvironmentDomainData, AddEnvironmentDomainErrors, AddEnvironmentDomainRequest, AddEnvironmentDomainResponse, AddEnvironmentDomainResponses, AddEventsData, AddEventsError, AddEventsErrors, AddEventsRequest, AddEventsResponse, AddEventsResponse2, AddEventsResponses, AddManagedDomainApiRequest, AddManagedDomainData, AddManagedDomainErrors, AddManagedDomainResponse, AddManagedDomainResponses, AddSessionReplayEventsData, AddSessionReplayEventsError, AddSessionReplayEventsErrors, AddSessionReplayEventsResponse, AddSessionReplayEventsResponses, AddTeamMemberData, AddTeamMemberErrors, AddTeamMemberResponse, AddTeamMemberResponses, AdminDrainNodeData, AdminDrainNodeErrors, AdminDrainNodeResponse, AdminDrainNodeResponses, AdminDrainStatusData, AdminDrainStatusErrors, AdminDrainStatusResponse, AdminDrainStatusResponses, AdminGateResponse, AdminGateSource, AdminGetNodeData, AdminGetNodeErrors, AdminGetNodeResponse, AdminGetNodeResponses, AdminListNodeContainersData, AdminListNodeContainersErrors, AdminListNodeContainersResponse, AdminListNodeContainersResponses, AdminListNodesData, AdminListNodesErrors, AdminListNodesResponse, AdminListNodesResponses, AdminRemoveNodeData, AdminRemoveNodeErrors, AdminRemoveNodeResponse, AdminRemoveNodeResponses, AdminUndrainNodeData, AdminUndrainNodeErrors, AdminUndrainNodeResponse, AdminUndrainNodeResponses, AgentConfigResponse, AgentRunLogResponse, AgentRunResponse, AgentRunWithLogsResponse, AgentSandboxSettings, AgentSandboxSettingsMasked, AggregatedBucketItem, AggregatedBucketsQuery, AggregatedBucketsResponse, AggregationLevel, AggregationTemporality, AiAgentBreakdownResponse, AiAgentBreakdownRow, AiAgentDescriptor, AiAgentPageRow, AiAgentPagesResponse, AiAgentTimelineResponse, AiAgentTimelineRow, AiChatLimitsSettings, AiConfigSettings, AiDataAccessResponse, AiPageBreakdownResponse, AiPageBreakdownRow, AiStatusBreakdownResponse, AiStatusBreakdownRow, AlarmListResponse, AlarmResponse, AlarmSummaryResponse, AlertRuleResponse, AllocEntry, AnalyticsSessionEventsResponse, AnnotatedSpan, AnomalyAlgorithm, AnomalyParams, AnomalyPreviewPointResponse, AnomalyPreviewRequest, AnomalyPreviewResponse, ApiKeyListResponse, ApiKeyResponse, ApplyHostnameModeData, ApplyHostnameModeErrors, ApplyHostnameModeRequest, ApplyHostnameModeResponse, ApplyHostnameModeResponses, AppSettings, AppSettingsResponse, ArchiveConversationData, ArchiveConversationErrors, ArchiveConversationResponse, ArchiveConversationResponses, ArchiveFlagData, ArchiveFlagErrors, ArchiveFlagResponse, ArchiveFlagResponse2, ArchiveFlagResponses, ArchiveMode, AssignRoleData, AssignRoleErrors, AssignRoleRequest, AssignRoleResponses, AttachScheduleServicesData, AttachScheduleServicesError, AttachScheduleServicesErrors, AttachScheduleServicesRequest, AttachScheduleServicesResponse, AttachScheduleServicesResponse2, AttachScheduleServicesResponses, AuditLogIpInfo, AuditLogResponse, AuditLogUserInfo, AuthFlavorDto, AuthResponse, AuthStatusResponse, AuthTokenResponse, AutofixerRunResponse, AutofixerRunWithLogsResponse, AutofixRunConfig, AutoWatchParams, AvailableContainerInfo, AvailablePermissions, BackupAlertListResponse, BackupAlertResponse, BackupResponse, BackupScheduleResponse, BitbucketAuthInput, BlobCopyData, BlobCopyError, BlobCopyErrors, BlobCopyResponse, BlobCopyResponses, BlobDeleteData, BlobDeleteError, BlobDeleteErrors, BlobDeleteResponse, BlobDeleteResponses, BlobDisableData, BlobDisableErrors, BlobDisableResponse, BlobDisableResponses, BlobDownloadData, BlobDownloadError, BlobDownloadErrors, BlobDownloadResponses, BlobEnableData, BlobEnableErrors, BlobEnableResponse, BlobEnableResponses, BlobHeadData, BlobHeadError, BlobHeadErrors, BlobHeadResponses, BlobListData, BlobListError, BlobListErrors, BlobListResponse, BlobListResponses, BlobPutData, BlobPutError, BlobPutErrors, BlobPutResponse, BlobPutResponses, BlobResponse, BlobStatusData, BlobStatusErrors, BlobStatusResponse, BlobStatusResponse2, BlobStatusResponses, BlobUpdateData, BlobUpdateErrors, BlobUpdateResponse, BlobUpdateResponses, BranchInfo, BranchListResponse, BrowserCount, BrowsersQuery, BuildConfiguration, BuildLimitsSettings, CancelBackupData, CancelBackupError, CancelBackupErrors, CancelBackupResponse, CancelBackupResponse2, CancelBackupResponses, CancelData, CancelDeploymentData, CancelDeploymentErrors, CancelDeploymentResponse, CancelDeploymentResponses, CancelDomainOrderData, CancelDomainOrderErrors, CancelDomainOrderResponse, CancelDomainOrderResponses, CancelErrors, CancelPgUpgradeData, CancelPgUpgradeErrors, CancelPgUpgradeResponse, CancelPgUpgradeResponses, CancelResponses, CancelRunData, CancelRunErrors, CancelRunResponse, CancelRunResponses, CancelScheduleRunData, CancelScheduleRunError, CancelScheduleRunErrors, CancelScheduleRunResponse, CancelScheduleRunResponses, CertStatusResponse, ChallengeConfig, ChallengeError, ChallengeValidationStatus, ChangePasswordRequest, ChangePasswordSelfData, ChangePasswordSelfErrors, ChangePasswordSelfResponse, ChangePasswordSelfResponses, ChangeProjectSourceData, ChangeProjectSourceErrors, ChangeProjectSourceRequest, ChangeProjectSourceResponse, ChangeProjectSourceResponses, ChangeRequiredPasswordData, ChangeRequiredPasswordErrors, ChangeRequiredPasswordResponse, ChangeRequiredPasswordResponses, ChatCompletionChoice, ChatCompletionRequest, ChatCompletionResponse, ChatCompletionsData, ChatCompletionsError, ChatCompletionsErrors, ChatCompletionsResponse, ChatCompletionsResponses, ChatMessage, ChatReadinessResponse, CheckAnalyticsHasEventsData, CheckAnalyticsHasEventsErrors, CheckAnalyticsHasEventsResponse, CheckAnalyticsHasEventsResponses, CheckCommitExistsData, CheckCommitExistsErrors, CheckCommitExistsResponse, CheckCommitExistsResponses, CheckDomainStatusData, CheckDomainStatusErrors, CheckDomainStatusResponse, CheckDomainStatusResponses, CheckExplorerSupportData, CheckExplorerSupportErrors, CheckExplorerSupportResponse, CheckExplorerSupportResponses, CheckIpBlockedData, CheckIpBlockedError, CheckIpBlockedErrors, CheckIpBlockedResponses, CheckProviderDeletionSafetyData, CheckProviderDeletionSafetyErrors, CheckProviderDeletionSafetyResponse, CheckProviderDeletionSafetyResponses, ChildBackupEntryResponse, ChildBackupListResponse, ChunkUploadOptionsData, ChunkUploadOptionsResponse, ChunkUploadOptionsResponses, CleanupExpiredBackupsData, CleanupExpiredBackupsError, CleanupExpiredBackupsErrors, CleanupExpiredBackupsRequest, CleanupExpiredBackupsResponse, CleanupExpiredBackupsResponses, ClearPreviewPasswordData, ClearPreviewPasswordErrors, ClearPreviewPasswordResponse, ClearPreviewPasswordResponses, CliDeviceApproveData, CliDeviceApproveErrors, CliDeviceApproveRequest, CliDeviceApproveResponse, CliDeviceApproveResponse2, CliDeviceApproveResponses, CliDeviceDenyData, CliDeviceDenyErrors, CliDeviceDenyResponse, CliDeviceDenyResponses, CliDeviceLookupData, CliDeviceLookupErrors, CliDeviceLookupResponse, CliDeviceLookupResponse2, CliDeviceLookupResponses, CliDevicePollData, CliDevicePollErrors, CliDevicePollRequest, CliDevicePollResponse, CliDevicePollResponse2, CliDevicePollResponses, CliDeviceStartData, CliDeviceStartErrors, CliDeviceStartRequest, CliDeviceStartResponse, CliDeviceStartResponse2, CliDeviceStartResponses, ClientOptions, CliLoginRequest, CliLogoutData, CliLogoutErrors, CliLogoutResponse, CliLogoutResponses, CloudflareConfig, CloudProvider, ClusterCapacity, ClusterDnsSettings, ClusterHealthReportResponse, ClusterMemberHealthResponse, ClusterMemberRequest, CmdBody, CmdData, CmdErrors, CmdInner, CmdKillBody, CmdKillData, CmdKillErrors, CmdKillResponse, CmdKillResponses, CmdLogsData, CmdLogsErrors, CmdLogsResponses, CmdResponse, CmdResponse2, CmdResponses, CommitExistsResponse, CommitInfo, CommitListResponse, Comparator, ComposePublicPort, ConfirmPendingActionData, ConfirmPendingActionErrors, ConfirmPendingActionResponse, ConfirmPendingActionResponses, ConnectionListQuery, ConnectionListResponse, ConnectionResponse, ConnectionTestResult, ConsoleEventPayload, ContainerActionResponse, ContainerDetailResponse, ContainerEnvironmentVariableValueResponse, ContainerInfoResponse, ContainerInventoryItem, ContainerListResponse, ContainerLogSettings, ContainerLogsQuery, ContainerMetricHistoryPoint, ContainerMetricsGetHistoryData, ContainerMetricsGetHistoryErrors, ContainerMetricsGetHistoryResponse, ContainerMetricsGetHistoryResponses, ContainerMetricsHistoryQuery, ContainerMetricsResponse, ContainerResponse, ContainerRuntimeInfo, ContainerStatsSample, ContentPart, ContextLine, ContextLogsRequest, ContextLogsResponse, ConversationDetailResponse, ConversationResponse, ConversationsQueryParams, ConversationSummary, CopyBlobRequest, CostAnalysis, CreateAgentData, CreateAgentErrors, CreateAgentResponse, CreateAgentResponses, CreateAlertData, CreateAlertError, CreateAlertErrors, CreateAlertResponse, CreateAlertResponses, CreateAlertRuleData, CreateAlertRuleErrors, CreateAlertRuleRequest, CreateAlertRuleResponse, CreateAlertRuleResponses, CreateApiKeyData, CreateApiKeyErrors, CreateApiKeyRequest, CreateApiKeyResponse, CreateApiKeyResponse2, CreateApiKeyResponses, CreateBackupScheduleData, CreateBackupScheduleError, CreateBackupScheduleErrors, CreateBackupScheduleRequest, CreateBackupScheduleResponse, CreateBackupScheduleResponses, CreateBitbucketProviderData, CreateBitbucketProviderErrors, CreateBitbucketProviderResponse, CreateBitbucketProviderResponses, CreateBitbucketRequest, CreateCloudflareProviderData, CreateCloudflareProviderErrors, CreateCloudflareProviderRequest, CreateCloudflareProviderResponse, CreateCloudflareProviderResponses, CreateConversationData, CreateConversationErrors, CreateConversationRequest, CreateConversationResponse, CreateConversationResponses, CreateCustomDomainData, CreateCustomDomainErrors, CreateCustomDomainResponse, CreateCustomDomainResponses, CreateDashboardData, CreateDashboardError, CreateDashboardErrors, CreateDashboardRequest, CreateDashboardResponse, CreateDashboardResponses, CreateDeploymentTokenData, CreateDeploymentTokenErrors, CreateDeploymentTokenRequest, CreateDeploymentTokenResponse, CreateDeploymentTokenResponse2, CreateDeploymentTokenResponses, CreateDnsProviderData, CreateDnsProviderErrors, CreateDnsProviderRequest, CreateDnsProviderResponse, CreateDnsProviderResponses, CreateDomainData, CreateDomainErrors, CreateDomainRequest, CreateDomainResponse, CreateDomainResponses, CreatedResource, CreateDsnData, CreateDsnErrors, CreateDsnRequest, CreateDsnResponse, CreateDsnResponses, CreateEmailDomainData, CreateEmailDomainErrors, CreateEmailDomainRequest, CreateEmailDomainResponse, CreateEmailDomainResponses, CreateEmailProviderData, CreateEmailProviderErrors, CreateEmailProviderRequest, CreateEmailProviderResponse, CreateEmailProviderResponses, CreateEnvironmentData, CreateEnvironmentErrors, CreateEnvironmentRequest, CreateEnvironmentResponse, CreateEnvironmentResponses, CreateEnvironmentVariableData, CreateEnvironmentVariableErrors, CreateEnvironmentVariableRequest, CreateEnvironmentVariableResponse, CreateEnvironmentVariableResponses, CreateExternalServiceRequest, CreateFlagData, CreateFlagErrors, CreateFlagRequest, CreateFlagResponse, CreateFlagResponses, CreateFunnelData, CreateFunnelErrors, CreateFunnelRequest, CreateFunnelResponse, CreateFunnelResponse2, CreateFunnelResponses, CreateFunnelStep, CreateGenericProviderData, CreateGenericProviderErrors, CreateGenericProviderResponse, CreateGenericProviderResponses, CreateGenericRequest, CreateGiteaPatProviderData, CreateGiteaPatProviderErrors, CreateGiteaPatProviderResponse, CreateGiteaPatProviderResponses, CreateGiteaPatRequest, CreateGithubPatProviderData, CreateGithubPatProviderErrors, CreateGithubPatProviderResponse, CreateGithubPatProviderResponses, CreateGitHubPatRequest, CreateGitlabOauthProviderData, CreateGitlabOauthProviderErrors, CreateGitlabOauthProviderResponse, CreateGitlabOauthProviderResponses, CreateGitLabOAuthRequest, CreateGitlabPatProviderData, CreateGitlabPatProviderErrors, CreateGitlabPatProviderResponse, CreateGitlabPatProviderResponses, CreateGitLabPatRequest, CreateGitProviderData, CreateGitProviderErrors, CreateGitProviderResponse, CreateGitProviderResponses, CreateGlobalMcpData, CreateGlobalMcpErrors, CreateGlobalMcpResponse, CreateGlobalMcpResponses, CreateGlobalSkillData, CreateGlobalSkillErrors, CreateGlobalSkillResponse, CreateGlobalSkillResponses, CreateIncidentData, CreateIncidentErrors, CreateIncidentRequest, CreateIncidentResponse, CreateIncidentResponses, CreateIntegrationBody, CreateIpAccessControlData, CreateIpAccessControlError, CreateIpAccessControlErrors, CreateIpAccessControlRequest, CreateIpAccessControlResponse, CreateIpAccessControlResponses, CreateMcpData, CreateMcpErrors, CreateMcpRequest, CreateMcpResponse, CreateMcpResponses, CreateMetricAlertRequest, CreateMonitorData, CreateMonitorErrors, CreateMonitorRequest, CreateMonitorResponse, CreateMonitorResponses, CreateNotificationEmailProviderData, CreateNotificationEmailProviderErrors, CreateNotificationEmailProviderRequest, CreateNotificationEmailProviderResponse, CreateNotificationEmailProviderResponses, CreateNotificationProviderData, CreateNotificationProviderErrors, CreateNotificationProviderResponse, CreateNotificationProviderResponses, CreateOidcProviderData, CreateOidcProviderErrors, CreateOidcProviderRequest, CreateOidcProviderResponse, CreateOidcProviderResponses, CreateOidcRoleMappingData, CreateOidcRoleMappingRequest, CreateOidcRoleMappingResponse, CreateOidcRoleMappingResponses, CreateOrRecreateOrderData, CreateOrRecreateOrderErrors, CreateOrRecreateOrderResponse, CreateOrRecreateOrderResponses, CreatePlanData, CreatePlanErrors, CreatePlanRequest, CreatePlanResponse, CreatePlanResponse2, CreatePlanResponses, CreatePrData, CreatePrErrors, CreateProjectAccessRequest, CreateProjectData, CreateProjectErrors, CreateProjectFromTemplateData, CreateProjectFromTemplateErrors, CreateProjectFromTemplateRequest, CreateProjectFromTemplateResponse, CreateProjectFromTemplateResponse2, CreateProjectFromTemplateResponses, CreateProjectReleaseData, CreateProjectReleaseErrors, CreateProjectReleaseResponse, CreateProjectReleaseResponses, CreateProjectRequest, CreateProjectResponse, CreateProjectResponses, CreateProjectSecretData, CreateProjectSecretErrors, CreateProjectSecretRequest, CreateProjectSecretResponse, CreateProjectSecretResponses, CreateProviderKeyData, CreateProviderKeyError, CreateProviderKeyErrors, CreateProviderKeyRequest, CreateProviderKeyResponse, CreateProviderKeyResponses, CreateProviderRequest, CreatePrResponse, CreatePrResponse2, CreatePrResponses, CreateReleaseData, CreateReleaseErrors, CreateReleaseResponse, CreateReleaseResponses, CreateRouteData, CreateRouteErrors, CreateRouteRequest, CreateRouteResponse, CreateRouteResponses, CreateS3SourceData, CreateS3SourceError, CreateS3SourceErrors, CreateS3SourceRequest, CreateS3SourceResponse, CreateS3SourceResponses, CreateSandboxBody, CreateSandboxData, CreateSandboxErrors, CreateSandboxResponse, CreateSandboxResponses, CreateServiceData, CreateServiceErrors, CreateServiceResponse, CreateServiceResponses, CreateSkillData, CreateSkillErrors, CreateSkillRequest, CreateSkillResponse, CreateSkillResponses, CreateSlackProviderData, CreateSlackProviderErrors, CreateSlackProviderRequest, CreateSlackProviderResponse, CreateSlackProviderResponses, CreateTeamData, CreateTeamErrors, CreateTeamMemberRequest, CreateTeamRequest, CreateTeamResponse, CreateTeamResponses, CreateUserData, CreateUserErrors, CreateUserRequest, CreateUserResponse, CreateUserResponses, CreateWebhookData, CreateWebhookErrors, CreateWebhookProviderData, CreateWebhookProviderErrors, CreateWebhookProviderRequest, CreateWebhookProviderResponse, CreateWebhookProviderResponses, CreateWebhookRequestBody, CreateWebhookResponse, CreateWebhookResponses, CronExecutionInfo, CronInfo, CrossProjectSiblingRef, CrossProjectTraceResponse, CurrentStatusResponse, CustomDomainRequest, CustomDomainResponse, CustomerMovementResponse, DashboardLayout, DashboardProjectsAnalyticsQuery, DashboardProjectsAnalyticsResponse, DashboardSection, DashboardTile, DatabaseMetricsResponse, DatabaseMetricsRow, DataImplication, DataImplicationSeverity, DeactivateApiKeyData, DeactivateApiKeyErrors, DeactivateApiKeyResponse, DeactivateApiKeyResponses, DeactivateConnectionData, DeactivateConnectionErrors, DeactivateConnectionResponses, DeactivateProviderData, DeactivateProviderErrors, DeactivateProviderResponses, DeleteAgentData, DeleteAgentErrors, DeleteAgentResponse, DeleteAgentResponses, DeleteAlertData, DeleteAlertError, DeleteAlertErrors, DeleteAlertResponse, DeleteAlertResponses, DeleteAlertRuleData, DeleteAlertRuleErrors, DeleteAlertRuleResponse, DeleteAlertRuleResponses, DeleteApiKeyData, DeleteApiKeyErrors, DeleteApiKeyResponse, DeleteApiKeyResponses, DeleteBackupData, DeleteBackupError, DeleteBackupErrors, DeleteBackupResponse, DeleteBackupResponses, DeleteBackupScheduleData, DeleteBackupScheduleError, DeleteBackupScheduleErrors, DeleteBackupScheduleResponse, DeleteBackupScheduleResponses, DeleteBlobRequest, DeleteBlobResponse, DeleteConnectionData, DeleteConnectionErrors, DeleteConnectionResponse, DeleteConnectionResponses, DeleteCustomDomainData, DeleteCustomDomainErrors, DeleteCustomDomainResponse, DeleteCustomDomainResponses, DeleteDashboardData, DeleteDashboardError, DeleteDashboardErrors, DeleteDashboardResponse, DeleteDashboardResponses, DeleteDeploymentTokenData, DeleteDeploymentTokenErrors, DeleteDeploymentTokenResponse, DeleteDeploymentTokenResponses, DeleteDnsProviderData, DeleteDnsProviderErrors, DeleteDnsProviderResponse, DeleteDnsProviderResponses, DeleteDomainData, DeleteDomainErrors, DeleteDomainResponse, DeleteDomainResponses, DeleteEmailDomainData, DeleteEmailDomainErrors, DeleteEmailDomainResponse, DeleteEmailDomainResponses, DeleteEmailProviderData, DeleteEmailProviderErrors, DeleteEmailProviderResponse, DeleteEmailProviderResponses, DeleteEnvironmentData, DeleteEnvironmentDomainData, DeleteEnvironmentDomainErrors, DeleteEnvironmentDomainResponse, DeleteEnvironmentDomainResponses, DeleteEnvironmentErrors, DeleteEnvironmentResponse, DeleteEnvironmentResponses, DeleteEnvironmentVariableData, DeleteEnvironmentVariableErrors, DeleteEnvironmentVariableResponse, DeleteEnvironmentVariableResponses, DeleteExternalImageData, DeleteExternalImageErrors, DeleteExternalImageResponse, DeleteExternalImageResponses, DeleteFunnelData, DeleteFunnelErrors, DeleteFunnelResponses, DeleteGitProviderData, DeleteGitProviderErrors, DeleteGitProviderResponse, DeleteGitProviderResponses, DeleteGlobalMcpData, DeleteGlobalMcpErrors, DeleteGlobalMcpResponse, DeleteGlobalMcpResponses, DeleteGlobalSkillData, DeleteGlobalSkillErrors, DeleteGlobalSkillResponse, DeleteGlobalSkillResponses, DeleteIpAccessControlData, DeleteIpAccessControlError, DeleteIpAccessControlErrors, DeleteIpAccessControlResponse, DeleteIpAccessControlResponses, DeleteMcpData, DeleteMcpErrors, DeleteMcpResponse, DeleteMcpResponses, DeleteMonitorData, DeleteMonitorErrors, DeleteMonitorResponse, DeleteMonitorResponses, DeleteNotificationProviderData, DeleteNotificationProviderErrors, DeleteNotificationProviderResponse, DeleteNotificationProviderResponses, DeleteOidcProviderData, DeleteOidcProviderResponse, DeleteOidcProviderResponses, DeleteOidcRoleMappingData, DeleteOidcRoleMappingResponse, DeleteOidcRoleMappingResponses, DeletePreferencesData, DeletePreferencesErrors, DeletePreferencesResponse, DeletePreferencesResponses, DeleteProjectData, DeleteProjectErrors, DeleteProjectResponse, DeleteProjectResponses, DeleteProjectSecretData, DeleteProjectSecretErrors, DeleteProjectSecretResponse, DeleteProjectSecretResponses, DeleteProviderKeyData, DeleteProviderKeyError, DeleteProviderKeyErrors, DeleteProviderKeyResponse, DeleteProviderKeyResponses, DeleteProviderSafelyData, DeleteProviderSafelyErrors, DeleteProviderSafelyResponse, DeleteProviderSafelyResponses, DeleteReleaseSourceFilesData, DeleteReleaseSourceFilesErrors, DeleteReleaseSourceFilesResponse, DeleteReleaseSourceFilesResponses, DeleteReleaseSourceMapsData, DeleteReleaseSourceMapsErrors, DeleteReleaseSourceMapsResponse, DeleteReleaseSourceMapsResponses, DeleteResponse, DeleteRouteData, DeleteRouteErrors, DeleteRouteResponse, DeleteRouteResponses, DeleteS3SourceData, DeleteS3SourceError, DeleteS3SourceErrors, DeleteS3SourceResponse, DeleteS3SourceResponses, DeleteScanData, DeleteScanError, DeleteScanErrors, DeleteScanResponse, DeleteScanResponses, DeleteSecretData, DeleteSecretErrors, DeleteSecretResponse, DeleteSecretResponses, DeleteServiceData, DeleteServiceErrors, DeleteServiceResponse, DeleteServiceResponses, DeleteSessionReplayData, DeleteSessionReplayError, DeleteSessionReplayErrors, DeleteSessionReplayResponses, DeleteSkillData, DeleteSkillErrors, DeleteSkillResponse, DeleteSkillResponses, DeleteSourceMapData, DeleteSourceMapErrors, DeleteSourceMapResponse, DeleteSourceMapResponses, DeleteStaticBundleData, DeleteStaticBundleErrors, DeleteStaticBundleResponse, DeleteStaticBundleResponses, DeleteTeamData, DeleteTeamErrors, DeleteTeamResponse, DeleteTeamResponses, DeleteUserData, DeleteUserErrors, DeleteUserResponse, DeleteUserResponses, DeleteWebhookData, DeleteWebhookErrors, DeleteWebhookResponse, DeleteWebhookResponses, DelRequest, DelResponse, DeployFromImageData, DeployFromImageErrors, DeployFromImageRequest, DeployFromImageResponse, DeployFromImageResponses, DeployFromImageUploadData, DeployFromImageUploadErrors, DeployFromImageUploadQuery, DeployFromImageUploadResponse, DeployFromImageUploadResponses, DeployFromStaticData, DeployFromStaticErrors, DeployFromStaticRequest, DeployFromStaticResponse, DeployFromStaticResponses, DeployFromUploadedSourceData, DeployFromUploadedSourceErrors, DeployFromUploadedSourceResponse, DeployFromUploadedSourceResponses, DeploymentConfig, DeploymentConfigSnapshot, DeploymentConfiguration, DeploymentContainerLogContentResponse, DeploymentContainerLogResponse, DeploymentContainerLogsListResponse, DeploymentEnvironmentResponse, DeploymentJobResponse, DeploymentJobsResponse, DeploymentListResponse, DeploymentMetadata, DeploymentMetricsGetLatestData, DeploymentMetricsGetLatestErrors, DeploymentMetricsGetLatestResponse, DeploymentMetricsGetLatestResponses, DeploymentMetricsGetRangeData, DeploymentMetricsGetRangeErrors, DeploymentMetricsGetRangeResponse, DeploymentMetricsGetRangeResponses, DeploymentMetricsToggleData, DeploymentMetricsToggleErrors, DeploymentMetricsToggleResponses, DeploymentResponse, DeploymentStateResponse, DeploymentStrategy, DeploymentTokenListResponse, DeploymentTokenResponse, DestroySandboxData, DestroySandboxErrors, DestroySandboxResponse, DestroySandboxResponses, DetachScheduleServiceData, DetachScheduleServiceError, DetachScheduleServiceErrors, DetachScheduleServiceResponse, DetachScheduleServiceResponses, DetectionConfig, DetectPublicPresetsData, DetectPublicPresetsErrors, DetectPublicPresetsResponse, DetectPublicPresetsResponses, DeviceCount, DigestSections, Direction, DisableBackupScheduleData, DisableBackupScheduleErrors, DisableBackupScheduleResponse, DisableBackupScheduleResponses, DisableBlobResponse, DisableKvResponse, DisableMfaData, DisableMfaErrors, DisableMfaRequest, DisableMfaResponse, DisableMfaResponses, DiscoverRequest, DiscoverResponse, DiscoverWorkloadsData, DiscoverWorkloadsErrors, DiscoverWorkloadsResponse, DiscoverWorkloadsResponses, DiskInfo, DiskSpaceAlert, DiskSpaceAlertSettings, DiskSpaceCheckResult, DnsAckRequest, DnsAckResponse, DnsChallengeRecordResult, DnsChangesResponse, DnsCompletionResponse, DnsLookupError, DnsLookupRequest, DnsLookupResponse, DnsProviderCredentials, DnsProviderResponse, DnsProviderSettings, DnsProviderSettingsMasked, DnsProviderType, DnsRecord, DnsRecordChange, DnsRecordContent, DnsRecordResponse, DnsRecordSetupResult, DnsRecordStatusResponse, DnsZone, DockerComposePresetConfig, DockerfilePresetConfig, DockerfileVariant, DockerRegistrySettings, DockerRegistrySettingsMasked, DomainAction, DomainChallengeResponse, DomainData, DomainEnvironmentResponse, DomainError, DomainErrors, DomainPlan, DomainResponse, DomainResponse2, DomainResponses, DownloadGlobalSkillArchiveData, DownloadGlobalSkillArchiveErrors, DownloadGlobalSkillArchiveResponse, DownloadGlobalSkillArchiveResponses, DownloadObjectData, DownloadObjectErrors, DownloadObjectResponse, DownloadObjectResponses, DownloadSkillArchiveData, DownloadSkillArchiveErrors, DownloadSkillArchiveResponse, DownloadSkillArchiveResponses, DrainNodeResponse, DrainStatusResponse, DropArchiveUpload, DropInspectionResponse, DropOffPoint, DropPresetCandidate, EmailConfig, EmailDomainResponse, EmailDomainWithDnsResponse, EmailProviderResponse, EmailProviderTypeRoute, EmailRequest, EmailResponse, EmailStatsResponse, EmailStatusData, EmailStatusErrors, EmailStatusResponse, EmailStatusResponse2, EmailStatusResponses, EmailTrackingResponse, EmailTrackingSetupResponse, EmailTrackingStatusResponse, EmbeddingData, EmbeddingInput, EmbeddingRequest, EmbeddingResponse, EmbeddingsData, EmbeddingsError, EmbeddingsErrors, EmbeddingsResponse, EmbeddingsResponses, EmbeddingUsage, EnableBackupScheduleData, EnableBackupScheduleErrors, EnableBackupScheduleResponse, EnableBackupScheduleResponses, EnableBlobRequest, EnableBlobResponse, EnableKvRequest, EnableKvResponse, EnablePgStatStatementsResponse, EndpointDto, EnqueuedJob, EnrichVisitorData, EnrichVisitorErrors, EnrichVisitorRequest, EnrichVisitorResponse, EnrichVisitorResponse2, EnrichVisitorResponses, EnrollmentTokenInfo, EnrollmentTokenListResponse, EntityInfoResponse, EntityResponse, EnvironmentConfiguration, EnvironmentDomainResponse, EnvironmentInfo, EnvironmentResponse, EnvironmentVariable, EnvironmentVariableInfo, EnvironmentVariableResponse, EnvironmentVariableValueResponse, EnvVarInput, EnvVarIntegrationInfo, EnvVarResponse, EnvVarTemplateResponse, ErrorDashboardStatsQuery, ErrorDashboardStatsResponse, ErrorEventResponse, ErrorGroupResponse, ErrorGroupStatsResponse, ErrorResponse, ErrorRow, ErrorTimeSeriesDataResponse, ErrorTimeSeriesQuery, EventActivityBucket, EventBreakdown, EventBrowserStats, EventCount, EventCountryStats, EventDetailQuery, EventDetailResponse, EventEntriesQuery, EventEntriesResponse, EventEntryInfo, EventKind, EventMetricsPayload, EventReferrerStats, EventsCountQuery, EventsResponse, EventTimeline, EventTimelineQuery, EventType, EventTypeBreakdown, EventTypeBreakdownQuery, EventTypeResponse, EventTypesResponse, EventVisitorInfo, EventVisitorsQuery, EventVisitorsResponse, ExecBody, ExecData, ExecDetachedData, ExecDetachedErrors, ExecDetachedResponse, ExecDetachedResponse2, ExecDetachedResponses, ExecErrors, ExecResponse, ExecResponse2, ExecResponses, ExecuteDeploymentOperationData, ExecuteDeploymentOperationErrors, ExecuteDeploymentOperationResponse, ExecuteDeploymentOperationResponses, ExecuteImportData, ExecuteImportErrors, ExecuteImportRequest, ExecuteImportResponse, ExecuteImportResponse2, ExecuteImportResponses, ExecuteOperationRequest, ExpireRequest, ExpireResponse, ExplorerSupportResponse, ExtendTimeoutBody, ExtendTimeoutData, ExtendTimeoutErrors, ExtendTimeoutResponse, ExtendTimeoutResponses, ExternalImageResponse, ExternalServiceBackupResponse, ExternalServiceDetails, ExternalServiceEnablePgStatStatementsData, ExternalServiceEnablePgStatStatementsErrors, ExternalServiceEnablePgStatStatementsResponse, ExternalServiceEnablePgStatStatementsResponses, ExternalServiceInfo, ExternalServiceMetricsByDatabaseData, ExternalServiceMetricsByDatabaseErrors, ExternalServiceMetricsByDatabaseResponse, ExternalServiceMetricsByDatabaseResponses, ExternalServiceMetricsCreateAlertRuleData, ExternalServiceMetricsCreateAlertRuleErrors, ExternalServiceMetricsCreateAlertRuleResponse, ExternalServiceMetricsCreateAlertRuleResponses, ExternalServiceMetricsDeleteAlertRuleData, ExternalServiceMetricsDeleteAlertRuleErrors, ExternalServiceMetricsDeleteAlertRuleResponse, ExternalServiceMetricsDeleteAlertRuleResponses, ExternalServiceMetricsGetAlertRulesData, ExternalServiceMetricsGetAlertRulesErrors, ExternalServiceMetricsGetAlertRulesResponse, ExternalServiceMetricsGetAlertRulesResponses, ExternalServiceMetricsGetLatestData, ExternalServiceMetricsGetLatestErrors, ExternalServiceMetricsGetLatestResponse, ExternalServiceMetricsGetLatestResponses, ExternalServiceMetricsGetRangeData, ExternalServiceMetricsGetRangeErrors, ExternalServiceMetricsGetRangeResponse, ExternalServiceMetricsGetRangeResponses, ExternalServiceMetricsStatusData, ExternalServiceMetricsStatusErrors, ExternalServiceMetricsStatusResponse, ExternalServiceMetricsStatusResponses, ExternalServiceMetricsToggleData, ExternalServiceMetricsToggleErrors, ExternalServiceMetricsToggleResponses, ExternalServiceMetricsUpdateAlertRuleData, ExternalServiceMetricsUpdateAlertRuleErrors, ExternalServiceMetricsUpdateAlertRuleResponse, ExternalServiceMetricsUpdateAlertRuleResponses, ExternalServiceResetPgStatStatementsData, ExternalServiceResetPgStatStatementsErrors, ExternalServiceResetPgStatStatementsResponse, ExternalServiceResetPgStatStatementsResponses, ExternalServiceSummary, FieldResponse, FinalizeOrderData, FinalizeOrderErrors, FinalizeOrderResponse, FinalizeOrderResponses, FinalizeProjectReleaseData, FinalizeProjectReleaseErrors, FinalizeProjectReleaseResponse, FinalizeProjectReleaseResponses, FindConversationData, FindConversationErrors, FindConversationResponse, FindConversationResponses, FiringSeriesEntry, FlagEnvironmentResponse, FlagListResponse, FlagResponse, FlagSnapshot, FlagSnapshotResponse, FlagValueType, ForecastAlgorithm, ForecastParams, FullError, FullEvent, FullRequest, FunnelMetricsResponse, FunnelResponse, GatewayStatus, GenAiEvent, GenAiSpanDetail, GenAiTraceDetailResponse, GenAiTraceSummariesResponse, GenAiTraceSummary, GeneralStatsQuery, GeneralStatsResponse, GenerateDockerfileRequest, GenerateDockerfileResponse, GenerateJoinTokenData, GenerateJoinTokenErrors, GenerateJoinTokenResponse, GenerateJoinTokenResponse2, GenerateJoinTokenResponses, GeneratePresetDockerfileData, GeneratePresetDockerfileErrors, GeneratePresetDockerfileResponse, GeneratePresetDockerfileResponses, GeoLocationResponse, GeoRestrictionsConfig, GetAccessInfoData, GetAccessInfoErrors, GetAccessInfoResponse, GetAccessInfoResponses, GetActiveVisitorsData, GetActiveVisitorsErrors, GetActiveVisitorsResponse, GetActiveVisitorsResponses, GetActivityGraphData, GetActivityGraphErrors, GetActivityGraphResponse, GetActivityGraphResponses, GetAdminGateData, GetAdminGateErrors, GetAdminGateResponse, GetAdminGateResponses, GetAgentData, GetAgentErrors, GetAgentResponse, GetAgentResponses, GetAggregatedBucketsData, GetAggregatedBucketsErrors, GetAggregatedBucketsResponse, GetAggregatedBucketsResponses, GetAiAgentBreakdownData, GetAiAgentBreakdownError, GetAiAgentBreakdownErrors, GetAiAgentBreakdownResponse, GetAiAgentBreakdownResponses, GetAiAgentPagesData, GetAiAgentPagesError, GetAiAgentPagesErrors, GetAiAgentPagesResponse, GetAiAgentPagesResponses, GetAiAgentTimelineData, GetAiAgentTimelineError, GetAiAgentTimelineErrors, GetAiAgentTimelineResponse, GetAiAgentTimelineResponses, GetAiDataAccessData, GetAiDataAccessErrors, GetAiDataAccessResponse, GetAiDataAccessResponses, GetAiPageBreakdownData, GetAiPageBreakdownError, GetAiPageBreakdownErrors, GetAiPageBreakdownResponse, GetAiPageBreakdownResponses, GetAiStatusBreakdownData, GetAiStatusBreakdownError, GetAiStatusBreakdownErrors, GetAiStatusBreakdownResponse, GetAiStatusBreakdownResponses, GetAlertData, GetAlertError, GetAlertErrors, GetAlertResponse, GetAlertResponses, GetAlertRuleData, GetAlertRuleErrors, GetAlertRuleResponse, GetAlertRuleResponses, GetAllRepositoriesByNameData, GetAllRepositoriesByNameErrors, GetAllRepositoriesByNameResponse, GetAllRepositoriesByNameResponses, GetAnalyticsActiveVisitorsData, GetAnalyticsActiveVisitorsErrors, GetAnalyticsActiveVisitorsResponse, GetAnalyticsActiveVisitorsResponses, GetAnalyticsEventsCountData, GetAnalyticsEventsCountErrors, GetAnalyticsEventsCountResponse, GetAnalyticsEventsCountResponses, GetAnalyticsSessionEventsData, GetAnalyticsSessionEventsErrors, GetAnalyticsSessionEventsResponse, GetAnalyticsSessionEventsResponses, GetAnalyticsVisitorSessionsData, GetAnalyticsVisitorSessionsErrors, GetAnalyticsVisitorSessionsResponse, GetAnalyticsVisitorSessionsResponses, GetApiKeyData, GetApiKeyErrors, GetApiKeyPermissionsData, GetApiKeyPermissionsErrors, GetApiKeyPermissionsResponse, GetApiKeyPermissionsResponses, GetApiKeyResponse, GetApiKeyResponses, GetAuditLogData, GetAuditLogErrors, GetAuditLogResponse, GetAuditLogResponses, GetBackupData, GetBackupError, GetBackupErrors, GetBackupResponse, GetBackupResponses, GetBackupScheduleData, GetBackupScheduleErrors, GetBackupScheduleResponse, GetBackupScheduleResponses, GetBranchesByRepositoryIdData, GetBranchesByRepositoryIdErrors, GetBranchesByRepositoryIdResponse, GetBranchesByRepositoryIdResponses, GetBucketedIncidentsData, GetBucketedIncidentsErrors, GetBucketedIncidentsResponse, GetBucketedIncidentsResponses, GetBucketedStatusData, GetBucketedStatusErrors, GetBucketedStatusResponse, GetBucketedStatusResponses, GetChallengeTokenData, GetChallengeTokenErrors, GetChallengeTokenResponse, GetChallengeTokenResponses, GetChatReadinessData, GetChatReadinessErrors, GetChatReadinessResponse, GetChatReadinessResponses, GetCliStatusData, GetCliStatusErrors, GetCliStatusResponses, GetClusterHealthData, GetClusterHealthErrors, GetClusterHealthResponse, GetClusterHealthResponses, GetClusterMemberData, GetClusterMemberErrors, GetClusterMemberResponse, GetClusterMemberResponses, GetCmdData, GetCmdErrors, GetCmdResponse, GetCmdResponses, GetContainerDetailData, GetContainerDetailErrors, GetContainerDetailResponse, GetContainerDetailResponses, GetContainerEnvironmentVariableData, GetContainerEnvironmentVariableErrors, GetContainerEnvironmentVariableResponse, GetContainerEnvironmentVariableResponses, GetContainerLogsByIdData, GetContainerLogsByIdErrors, GetContainerLogsData, GetContainerLogsErrors, GetContainerMetricsData, GetContainerMetricsErrors, GetContainerMetricsResponse, GetContainerMetricsResponses, GetConversationData, GetConversationDetailData, GetConversationDetailError, GetConversationDetailErrors, GetConversationDetailResponse, GetConversationDetailResponses, GetConversationErrors, GetConversationResponse, GetConversationResponses, GetConversationsData, GetConversationsError, GetConversationsErrors, GetConversationsResponse, GetConversationsResponses, GetCronByIdData, GetCronByIdErrors, GetCronByIdResponse, GetCronByIdResponses, GetCronExecutionsData, GetCronExecutionsErrors, GetCronExecutionsResponse, GetCronExecutionsResponses, GetCrossProjectTraceSiblingsData, GetCrossProjectTraceSiblingsError, GetCrossProjectTraceSiblingsErrors, GetCrossProjectTraceSiblingsResponse, GetCrossProjectTraceSiblingsResponses, GetCurrentMonitorStatusData, GetCurrentMonitorStatusErrors, GetCurrentMonitorStatusResponse, GetCurrentMonitorStatusResponses, GetCurrentUserData, GetCurrentUserErrors, GetCurrentUserResponse, GetCurrentUserResponses, GetCustomDomainData, GetCustomDomainErrors, GetCustomDomainResponse, GetCustomDomainResponses, GetDashboardData, GetDashboardError, GetDashboardErrors, GetDashboardProjectsAnalyticsData, GetDashboardProjectsAnalyticsErrors, GetDashboardProjectsAnalyticsResponse, GetDashboardProjectsAnalyticsResponses, GetDashboardResponse, GetDashboardResponses, GetDeliveryData, GetDeliveryErrors, GetDeliveryResponse, GetDeliveryResponses, GetDeploymentContainerLogContentData, GetDeploymentContainerLogContentErrors, GetDeploymentContainerLogContentResponse, GetDeploymentContainerLogContentResponses, GetDeploymentData, GetDeploymentErrors, GetDeploymentJobLogsData, GetDeploymentJobLogsErrors, GetDeploymentJobLogsResponse, GetDeploymentJobLogsResponses, GetDeploymentJobsData, GetDeploymentJobsErrors, GetDeploymentJobsResponse, GetDeploymentJobsResponses, GetDeploymentOperationsData, GetDeploymentOperationsErrors, GetDeploymentOperationsResponse, GetDeploymentOperationsResponses, GetDeploymentOperationStatusData, GetDeploymentOperationStatusErrors, GetDeploymentOperationStatusResponse, GetDeploymentOperationStatusResponses, GetDeploymentResponse, GetDeploymentResponses, GetDeploymentsParams, GetDeploymentTokenData, GetDeploymentTokenErrors, GetDeploymentTokenResponse, GetDeploymentTokenResponses, GetDiskStatusData, GetDiskStatusErrors, GetDiskStatusResponse, GetDiskStatusResponses, GetDnsChangesData, GetDnsChangesErrors, GetDnsChangesResponse, GetDnsChangesResponses, GetDnsProviderData, GetDnsProviderErrors, GetDnsProviderResponse, GetDnsProviderResponses, GetDomainByHostData, GetDomainByHostErrors, GetDomainByHostResponse, GetDomainByHostResponses, GetDomainByIdData, GetDomainByIdErrors, GetDomainByIdResponse, GetDomainByIdResponses, GetDomainByNameData, GetDomainByNameErrors, GetDomainByNameResponse, GetDomainByNameResponses, GetDomainData, GetDomainDnsRecordsData, GetDomainDnsRecordsErrors, GetDomainDnsRecordsResponse, GetDomainDnsRecordsResponses, GetDomainErrors, GetDomainOrderData, GetDomainOrderErrors, GetDomainOrderResponse, GetDomainOrderResponses, GetDomainResponse, GetDomainResponses, GetEmailData, GetEmailErrors, GetEmailEventsData, GetEmailEventsErrors, GetEmailEventsResponse, GetEmailEventsResponses, GetEmailLinksData, GetEmailLinksErrors, GetEmailLinksResponse, GetEmailLinksResponses, GetEmailProviderData, GetEmailProviderErrors, GetEmailProviderResponse, GetEmailProviderResponses, GetEmailResponse, GetEmailResponses, GetEmailStatsData, GetEmailStatsErrors, GetEmailStatsResponse, GetEmailStatsResponses, GetEmailTrackingData, GetEmailTrackingErrors, GetEmailTrackingResponse, GetEmailTrackingResponses, GetEmailTrackingStatusData, GetEmailTrackingStatusErrors, GetEmailTrackingStatusResponse, GetEmailTrackingStatusResponses, GetEntityInfoData, GetEntityInfoErrors, GetEntityInfoResponse, GetEntityInfoResponses, GetEnvironmentCronsData, GetEnvironmentCronsErrors, GetEnvironmentCronsResponse, GetEnvironmentCronsResponses, GetEnvironmentData, GetEnvironmentDomainsData, GetEnvironmentDomainsErrors, GetEnvironmentDomainsResponse, GetEnvironmentDomainsResponses, GetEnvironmentErrors, GetEnvironmentResponse, GetEnvironmentResponses, GetEnvironmentsData, GetEnvironmentsErrors, GetEnvironmentsResponse, GetEnvironmentsResponses, GetEnvironmentVariablesData, GetEnvironmentVariablesErrors, GetEnvironmentVariablesQuery, GetEnvironmentVariablesResponse, GetEnvironmentVariablesResponses, GetEnvironmentVariableValueData, GetEnvironmentVariableValueErrors, GetEnvironmentVariableValueResponse, GetEnvironmentVariableValueResponses, GetErrorDashboardStatsData, GetErrorDashboardStatsErrors, GetErrorDashboardStatsResponse, GetErrorDashboardStatsResponses, GetErrorEventData, GetErrorEventErrors, GetErrorEventResponse, GetErrorEventResponses, GetErrorGroupData, GetErrorGroupErrors, GetErrorGroupResponse, GetErrorGroupResponses, GetErrorStatsData, GetErrorStatsErrors, GetErrorStatsResponse, GetErrorStatsResponses, GetErrorTimeSeriesData, GetErrorTimeSeriesErrors, GetErrorTimeSeriesResponse, GetErrorTimeSeriesResponses, GetEventDetailData, GetEventDetailErrors, GetEventDetailResponse, GetEventDetailResponses, GetEventEntriesData, GetEventEntriesErrors, GetEventEntriesResponse, GetEventEntriesResponses, GetEventsCountData, GetEventsCountErrors, GetEventsCountResponse, GetEventsCountResponses, GetEventsTimelineData, GetEventsTimelineErrors, GetEventsTimelineResponse, GetEventsTimelineResponses, GetEventTypeBreakdownData, GetEventTypeBreakdownErrors, GetEventTypeBreakdownResponse, GetEventTypeBreakdownResponses, GetEventVisitorsData, GetEventVisitorsErrors, GetEventVisitorsResponse, GetEventVisitorsResponses, GetExternalImageData, GetExternalImageErrors, GetExternalImageResponse, GetExternalImageResponses, GetFileData, GetFileErrors, GetFileResponse, GetFileResponses, GetFlagData, GetFlagErrors, GetFlagResponse, GetFlagResponses, GetFlagSnapshotData, GetFlagSnapshotErrors, GetFlagSnapshotResponse, GetFlagSnapshotResponses, GetFunnelMetricsData, GetFunnelMetricsErrors, GetFunnelMetricsQuery, GetFunnelMetricsResponse, GetFunnelMetricsResponses, GetGenaiTraceData, GetGenaiTraceError, GetGenaiTraceErrors, GetGenaiTraceResponse, GetGenaiTraceResponses, GetGeneralStatsData, GetGeneralStatsErrors, GetGeneralStatsResponse, GetGeneralStatsResponses, GetGitProviderData, GetGitProviderErrors, GetGitProviderResponse, GetGitProviderResponses, GetGlobalEventsData, GetGlobalEventsErrors, GetGlobalEventsResponse, GetGlobalEventsResponses, GetGlobalEventStatsData, GetGlobalEventStatsErrors, GetGlobalEventStatsResponse, GetGlobalEventStatsResponses, GetGlobalMcpData, GetGlobalMcpErrors, GetGlobalMcpResponse, GetGlobalMcpResponses, GetGlobalSandboxStatusData, GetGlobalSandboxStatusErrors, GetGlobalSandboxStatusResponse, GetGlobalSandboxStatusResponses, GetGlobalSkillData, GetGlobalSkillErrors, GetGlobalSkillResponse, GetGlobalSkillResponses, GetGroupedPageMetricsData, GetGroupedPageMetricsError, GetGroupedPageMetricsErrors, GetGroupedPageMetricsResponse, GetGroupedPageMetricsResponses, GetHealthData, GetHealthError, GetHealthErrors, GetHealthResponse, GetHealthResponses, GetHourlyVisitsData, GetHourlyVisitsErrors, GetHourlyVisitsResponse, GetHourlyVisitsResponses, GetHttpChallengeDebugData, GetHttpChallengeDebugErrors, GetHttpChallengeDebugResponse, GetHttpChallengeDebugResponses, GetImportStatusData, GetImportStatusErrors, GetImportStatusResponse, GetImportStatusResponses, GetIncidentData, GetIncidentErrors, GetIncidentResponse, GetIncidentResponses, GetIncidentUpdatesData, GetIncidentUpdatesErrors, GetIncidentUpdatesResponse, GetIncidentUpdatesResponses, GetIpAccessControlData, GetIpAccessControlError, GetIpAccessControlErrors, GetIpAccessControlResponse, GetIpAccessControlResponses, GetIpGeolocationData, GetIpGeolocationError, GetIpGeolocationErrors, GetIpGeolocationResponse, GetIpGeolocationResponses, GetJoinTokenStatusData, GetJoinTokenStatusErrors, GetJoinTokenStatusResponse, GetJoinTokenStatusResponses, GetLastDeploymentData, GetLastDeploymentErrors, GetLastDeploymentResponse, GetLastDeploymentResponses, GetLatestScanData, GetLatestScanError, GetLatestScanErrors, GetLatestScanResponse, GetLatestScanResponses, GetLatestScansPerEnvironmentData, GetLatestScansPerEnvironmentError, GetLatestScansPerEnvironmentErrors, GetLatestScansPerEnvironmentResponse, GetLatestScansPerEnvironmentResponses, GetLiveVisitorsListData, GetLiveVisitorsListErrors, GetLiveVisitorsListResponse, GetLiveVisitorsListResponses, GetLogContextData, GetLogContextError, GetLogContextErrors, GetLogContextResponse, GetLogContextResponses, GetMcpData, GetMcpErrors, GetMcpResponse, GetMcpResponses, GetMetricsOverTimeData, GetMetricsOverTimeError, GetMetricsOverTimeErrors, GetMetricsOverTimeResponse, GetMetricsOverTimeResponses, GetMonitorData, GetMonitorErrors, GetMonitorResponse, GetMonitorResponses, GetNotificationProviderData, GetNotificationProviderErrors, GetNotificationProviderResponse, GetNotificationProviderResponses, GetOnDemandCertStatusData, GetOnDemandCertStatusErrors, GetOnDemandCertStatusResponse, GetOnDemandCertStatusResponses, GetOrCreateDsnData, GetOrCreateDsnErrors, GetOrCreateDsnRequest, GetOrCreateDsnResponse, GetOrCreateDsnResponses, GetPageFlowData, GetPageFlowErrors, GetPageFlowResponse, GetPageFlowResponses, GetPageHourlySessionsData, GetPageHourlySessionsErrors, GetPageHourlySessionsResponse, GetPageHourlySessionsResponses, GetPagePathDetailData, GetPagePathDetailErrors, GetPagePathDetailResponse, GetPagePathDetailResponses, GetPagePathsData, GetPagePathsErrors, GetPagePathsResponse, GetPagePathsResponses, GetPagePathsSparklinesData, GetPagePathsSparklinesErrors, GetPagePathsSparklinesResponse, GetPagePathsSparklinesResponses, GetPagePathVisitorsData, GetPagePathVisitorsErrors, GetPagePathVisitorsResponse, GetPagePathVisitorsResponses, GetPendingActionData, GetPendingActionErrors, GetPendingActionResponse, GetPendingActionResponses, GetPerformanceMetricsData, GetPerformanceMetricsError, GetPerformanceMetricsErrors, GetPerformanceMetricsResponse, GetPerformanceMetricsResponses, GetPgUpgradeData, GetPgUpgradeErrors, GetPgUpgradeLogsData, GetPgUpgradeLogsErrors, GetPgUpgradeLogsResponse, GetPgUpgradeLogsResponses, GetPgUpgradeResponse, GetPgUpgradeResponses, GetPipelineStatsData, GetPipelineStatsError, GetPipelineStatsErrors, GetPipelineStatsResponse, GetPipelineStatsResponses, GetPlatformInfoData, GetPlatformInfoErrors, GetPlatformInfoResponse, GetPlatformInfoResponses, GetPostgresWalHealthData, GetPostgresWalHealthErrors, GetPostgresWalHealthResponse, GetPostgresWalHealthResponses, GetPreferencesData, GetPreferencesErrors, GetPreferencesResponse, GetPreferencesResponses, GetPreviewGatewayLogsData, GetPreviewGatewayLogsResponse, GetPreviewGatewayLogsResponses, GetPreviewGatewaySettingsData, GetPreviewGatewaySettingsResponse, GetPreviewGatewaySettingsResponses, GetPreviewGatewayStatusData, GetPreviewGatewayStatusResponse, GetPreviewGatewayStatusResponses, GetPricingData, GetPricingError, GetPricingErrors, GetPricingResponse, GetPricingResponses, GetPrivateIpData, GetPrivateIpErrors, GetPrivateIpResponses, GetProjectAlarmsSummaryData, GetProjectAlarmsSummaryErrors, GetProjectAlarmsSummaryResponse, GetProjectAlarmsSummaryResponses, GetProjectBySlugData, GetProjectBySlugErrors, GetProjectBySlugResponse, GetProjectBySlugResponses, GetProjectData, GetProjectDeploymentsData, GetProjectDeploymentsErrors, GetProjectDeploymentsResponse, GetProjectDeploymentsResponses, GetProjectErrors, GetProjectResponse, GetProjectResponses, GetProjectsData, GetProjectSecretsQuery, GetProjectsErrors, GetProjectServiceEnvironmentVariablesData, GetProjectServiceEnvironmentVariablesErrors, GetProjectServiceEnvironmentVariablesResponse, GetProjectServiceEnvironmentVariablesResponses, GetProjectSessionReplaysData, GetProjectSessionReplaysError, GetProjectSessionReplaysErrors, GetProjectSessionReplaysQuery, GetProjectSessionReplaysResponse, GetProjectSessionReplaysResponse2, GetProjectSessionReplaysResponses, GetProjectsHealthData, GetProjectsHealthError, GetProjectsHealthErrors, GetProjectsHealthResponse, GetProjectsHealthResponses, GetProjectsMonitorHealthData, GetProjectsMonitorHealthErrors, GetProjectsMonitorHealthResponse, GetProjectsMonitorHealthResponses, GetProjectsResponse, GetProjectsResponses, GetProjectStatisticsData, GetProjectStatisticsErrors, GetProjectStatisticsResponse, GetProjectStatisticsResponses, GetProjectTemplateData, GetProjectTemplateErrors, GetProjectTemplateResponse, GetProjectTemplateResponses, GetPropertyBreakdownData, GetPropertyBreakdownErrors, GetPropertyBreakdownResponse, GetPropertyBreakdownResponses, GetPropertyTimelineData, GetPropertyTimelineErrors, GetPropertyTimelineResponse, GetPropertyTimelineResponses, GetProviderConnectionsData, GetProviderConnectionsErrors, GetProviderConnectionsResponse, GetProviderConnectionsResponses, GetProviderMetadataData, GetProviderMetadataErrors, GetProviderMetadataResponse, GetProviderMetadataResponses, GetProvidersMetadataData, GetProvidersMetadataErrors, GetProvidersMetadataResponse, GetProvidersMetadataResponses, GetProxyLogByIdData, GetProxyLogByIdError, GetProxyLogByIdErrors, GetProxyLogByIdResponse, GetProxyLogByIdResponses, GetProxyLogByRequestIdData, GetProxyLogByRequestIdError, GetProxyLogByRequestIdErrors, GetProxyLogByRequestIdResponse, GetProxyLogByRequestIdResponses, GetProxyLogsData, GetProxyLogsError, GetProxyLogsErrors, GetProxyLogsResponse, GetProxyLogsResponses, GetPublicBranchesData, GetPublicBranchesErrors, GetPublicBranchesResponse, GetPublicBranchesResponses, GetPublicIpData, GetPublicIpErrors, GetPublicIpResponses, GetPublicRepositoryData, GetPublicRepositoryErrors, GetPublicRepositoryResponse, GetPublicRepositoryResponses, GetQueryContainerInfoData, GetQueryContainerInfoErrors, GetQueryContainerInfoResponse, GetQueryContainerInfoResponses, GetQuotaData, GetQuotaError, GetQuotaErrors, GetQuotaResponse, GetQuotaResponses, GetRecentActivityData, GetRecentActivityErrors, GetRecentActivityResponse, GetRecentActivityResponses, GetRemoteExternalImageData, GetRemoteExternalImageErrors, GetRemoteExternalImageResponse, GetRemoteExternalImageResponses, GetRepositoryBranchesData, GetRepositoryBranchesErrors, GetRepositoryBranchesResponse, GetRepositoryBranchesResponses, GetRepositoryByIdData, GetRepositoryByIdErrors, GetRepositoryByIdResponse, GetRepositoryByIdResponses, GetRepositoryByNameData, GetRepositoryByNameErrors, GetRepositoryByNameResponse, GetRepositoryByNameResponses, GetRepositoryPresetByNameData, GetRepositoryPresetByNameErrors, GetRepositoryPresetByNameResponse, GetRepositoryPresetByNameResponses, GetRepositoryPresetLiveData, GetRepositoryPresetLiveErrors, GetRepositoryPresetLiveResponse, GetRepositoryPresetLiveResponses, GetRepositoryTagsData, GetRepositoryTagsErrors, GetRepositoryTagsResponse, GetRepositoryTagsResponses, GetRequest, GetResolvedEnvironmentVariablesData, GetResolvedEnvironmentVariablesErrors, GetResolvedEnvironmentVariablesResponse, GetResolvedEnvironmentVariablesResponses, GetResolvedEnvironmentVariableValueData, GetResolvedEnvironmentVariableValueErrors, GetResolvedEnvironmentVariableValueResponse, GetResolvedEnvironmentVariableValueResponses, GetResponse, GetRestoreCapabilitiesData, GetRestoreCapabilitiesError, GetRestoreCapabilitiesErrors, GetRestoreCapabilitiesResponse, GetRestoreCapabilitiesResponses, GetRestoreRunData, GetRestoreRunError, GetRestoreRunErrors, GetRestoreRunResponse, GetRestoreRunResponses, GetRouteData, GetRouteErrors, GetRouteResponse, GetRouteResponses, GetRunData, GetRunErrors, GetRunResponse, GetRunResponses, GetRunWithLogsData, GetRunWithLogsErrors, GetRunWithLogsResponse, GetRunWithLogsResponses, GetS3CredentialsData, GetS3CredentialsErrors, GetS3CredentialsResponse, GetS3CredentialsResponses, GetS3SourceData, GetS3SourceError, GetS3SourceErrors, GetS3SourceResponse, GetS3SourceResponses, GetSandboxData, GetSandboxErrors, GetSandboxResponse, GetSandboxResponses, GetSandboxStatusData, GetSandboxStatusErrors, GetSandboxStatusResponse, GetSandboxStatusResponses, GetScanByDeploymentData, GetScanByDeploymentError, GetScanByDeploymentErrors, GetScanByDeploymentResponse, GetScanByDeploymentResponses, GetScanData, GetScanError, GetScanErrors, GetScanResponse, GetScanResponses, GetScanVulnerabilitiesData, GetScanVulnerabilitiesError, GetScanVulnerabilitiesErrors, GetScanVulnerabilitiesResponse, GetScanVulnerabilitiesResponses, GetServiceBySlugData, GetServiceBySlugErrors, GetServiceBySlugResponse, GetServiceBySlugResponses, GetServiceData, GetServiceEnvironmentVariableData, GetServiceEnvironmentVariableErrors, GetServiceEnvironmentVariableResponse, GetServiceEnvironmentVariableResponses, GetServiceEnvironmentVariablesData, GetServiceEnvironmentVariablesErrors, GetServiceEnvironmentVariablesResponse, GetServiceEnvironmentVariablesResponses, GetServiceErrors, GetServiceHealthStatusData, GetServiceHealthStatusErrors, GetServiceHealthStatusResponse, GetServiceHealthStatusResponses, GetServicePreviewEnvironmentVariableNamesData, GetServicePreviewEnvironmentVariableNamesErrors, GetServicePreviewEnvironmentVariableNamesResponse, GetServicePreviewEnvironmentVariableNamesResponses, GetServicePreviewEnvironmentVariablesMaskedData, GetServicePreviewEnvironmentVariablesMaskedErrors, GetServicePreviewEnvironmentVariablesMaskedResponse, GetServicePreviewEnvironmentVariablesMaskedResponses, GetServiceResponse, GetServiceResponses, GetServiceRuntimeData, GetServiceRuntimeErrors, GetServiceRuntimeResponse, GetServiceRuntimeResponses, GetServiceStatsData, GetServiceStatsErrors, GetServiceStatsResponse, GetServiceStatsResponses, GetServiceTypeParametersData, GetServiceTypeParametersErrors, GetServiceTypeParametersResponses, GetServiceTypesData, GetServiceTypesErrors, GetServiceTypesResponse, GetServiceTypesResponses, GetSessionDetailsData, GetSessionDetailsErrors, GetSessionDetailsResponse, GetSessionDetailsResponses, GetSessionEventsData, GetSessionEventsErrors, GetSessionEventsResponse, GetSessionEventsResponses, GetSessionLogsData, GetSessionLogsErrors, GetSessionLogsResponse, GetSessionLogsResponses, GetSessionReplayData, GetSessionReplayError, GetSessionReplayErrors, GetSessionReplayEventsData, GetSessionReplayEventsError, GetSessionReplayEventsErrors, GetSessionReplayEventsResponse, GetSessionReplayEventsResponses, GetSessionReplayResponse, GetSessionReplayResponse2, GetSessionReplayResponses, GetSettingsData, GetSettingsErrors, GetSettingsResponse, GetSettingsResponses, GetSkillData, GetSkillErrors, GetSkillResponse, GetSkillResponses, GetSlowQueriesData, GetSlowQueriesErrors, GetSlowQueriesResponse, GetSlowQueriesResponses, GetStaticBundleData, GetStaticBundleErrors, GetStaticBundleResponse, GetStaticBundleResponses, GetStatusOverviewData, GetStatusOverviewErrors, GetStatusOverviewResponse, GetStatusOverviewResponses, GetTagsByRepositoryIdData, GetTagsByRepositoryIdErrors, GetTagsByRepositoryIdResponse, GetTagsByRepositoryIdResponses, GetTeamData, GetTeamErrors, GetTeamResponse, GetTeamResponses, GetTimeBucketStatsData, GetTimeBucketStatsError, GetTimeBucketStatsErrors, GetTimeBucketStatsResponse, GetTimeBucketStatsResponses, GetTodayStatsData, GetTodayStatsError, GetTodayStatsErrors, GetTodayStatsResponse, GetTodayStatsResponses, GetTraceData, GetTraceError, GetTraceErrors, GetTraceResponse, GetTraceResponses, GetUnifiedTraceData, GetUnifiedTraceError, GetUnifiedTraceErrors, GetUnifiedTraceResponse, GetUnifiedTraceResponses, GetUniqueCountsData, GetUniqueCountsErrors, GetUniqueCountsResponse, GetUniqueCountsResponses, GetUniqueEventsData, GetUniqueEventsErrors, GetUniqueEventsQuery, GetUniqueEventsResponse, GetUniqueEventsResponses, GetUpdateStatusData, GetUpdateStatusErrors, GetUpdateStatusResponse, GetUpdateStatusResponses, GetUptimeHistoryData, GetUptimeHistoryErrors, GetUptimeHistoryResponse, GetUptimeHistoryResponses, GetUsageByProviderData, GetUsageByProviderError, GetUsageByProviderErrors, GetUsageByProviderResponse, GetUsageByProviderResponses, GetUsageRecentData, GetUsageRecentError, GetUsageRecentErrors, GetUsageRecentResponse, GetUsageRecentResponses, GetUsageSummaryData, GetUsageSummaryError, GetUsageSummaryErrors, GetUsageSummaryResponse, GetUsageSummaryResponses, GetUsageTimeseriesData, GetUsageTimeseriesError, GetUsageTimeseriesErrors, GetUsageTimeseriesResponse, GetUsageTimeseriesResponses, GetUsageTopModelsData, GetUsageTopModelsError, GetUsageTopModelsErrors, GetUsageTopModelsResponse, GetUsageTopModelsResponses, GetVisitorByGuidData, GetVisitorByGuidErrors, GetVisitorByGuidResponse, GetVisitorByGuidResponses, GetVisitorByIdData, GetVisitorByIdErrors, GetVisitorByIdResponse, GetVisitorByIdResponses, GetVisitorDetailsData, GetVisitorDetailsErrors, GetVisitorDetailsResponse, GetVisitorDetailsResponses, GetVisitorFacetsData, GetVisitorFacetsErrors, GetVisitorFacetsResponse, GetVisitorFacetsResponses, GetVisitorInfoData, GetVisitorInfoErrors, GetVisitorInfoResponse, GetVisitorInfoResponses, GetVisitorJourneyData, GetVisitorJourneyErrors, GetVisitorJourneyResponse, GetVisitorJourneyResponses, GetVisitorsData, GetVisitorsErrors, GetVisitorSessionsData, GetVisitorSessionsError, GetVisitorSessionsErrors, GetVisitorSessionsQuery, GetVisitorSessionsResponse, GetVisitorSessionsResponse2, GetVisitorSessionsResponses, GetVisitorsResponse, GetVisitorsResponses, GetVisitorStatsData, GetVisitorStatsErrors, GetVisitorStatsResponse, GetVisitorStatsResponses, GetWebhookData, GetWebhookErrors, GetWebhookResponse, GetWebhookResponses, GitPushEvent, GitRefResponse, GitSourcePlan, GlobalConversationResponse, GlobalEventStatsResponse, GlobalMrrResponse, GlobalRecentEventResponse, GlobalRevenueSummaryResponse, GrantProjectAccessData, GrantProjectAccessErrors, GrantProjectAccessResponse, GrantProjectAccessResponses, GroupedPageMetric, GroupedPageMetricsQuery, GroupedPageMetricsResponse, HandleGitProviderOauthCallbackData, HandleGitProviderOauthCallbackErrors, HasAnalyticsEventsData, HasAnalyticsEventsErrors, HasAnalyticsEventsResponse, HasAnalyticsEventsResponse2, HasAnalyticsEventsResponses, HasErrorGroupsData, HasErrorGroupsErrors, HasErrorGroupsResponse, HasErrorGroupsResponse2, HasErrorGroupsResponses, HasEventsQuery, HasEventsResponse, HasMetricsQuery, HasMetricsResponse, HasPerformanceMetricsData, HasPerformanceMetricsError, HasPerformanceMetricsErrors, HasPerformanceMetricsResponse, HasPerformanceMetricsResponses, HealthCheckConfiguration, HealthCheckEntryResponse, HealthResponse, HealthStatus, HealthSummary, HeartbeatApiRequest, HeartbeatResponse, HierarchyLevel, HistogramSummary, HostnameChange, HostnamePreviewResponse, HourlyPageSessions, HourlyVisitsQuery, HttpChallengeDebugResponse, ImportCredentials, ImportExecutionStatus, ImportExternalServiceData, ImportExternalServiceErrors, ImportExternalServiceRequest, ImportExternalServiceResponse, ImportExternalServiceResponses, ImportOutcomeResponse, ImportPlan, ImportRowErrorResponse, ImportSelector, ImportSource, ImportSourceCapabilities, ImportSourceInfo, ImportStatusResponse, IncidentBucket, IncidentBucketedResponse, IncidentResponse, IncidentUpdateResponse, IncrRequest, IncrResponse, IngestLogsByPathData, IngestLogsByPathError, IngestLogsByPathErrors, IngestLogsByPathResponses, IngestLogsData, IngestLogsError, IngestLogsErrors, IngestLogsResponses, IngestMetricsByPathData, IngestMetricsByPathError, IngestMetricsByPathErrors, IngestMetricsByPathResponses, IngestMetricsData, IngestMetricsError, IngestMetricsErrors, IngestMetricsResponses, IngestSentryEnvelopeData, IngestSentryEnvelopeErrors, IngestSentryEnvelopeResponses, IngestSentryEventData, IngestSentryEventErrors, IngestSentryEventResponse, IngestSentryEventResponses, IngestTracesByPathData, IngestTracesByPathError, IngestTracesByPathErrors, IngestTracesByPathResponses, IngestTracesData, IngestTracesError, IngestTracesErrors, IngestTracesResponses, InitAuthResponse, InitSessionReplayData, InitSessionReplayError, InitSessionReplayErrors, InitSessionReplayResponse, InitSessionReplayResponses, Insight, InsightSeverity, InsightsResponse, InsightStatus, InspectDropArchiveData, InspectDropArchiveErrors, InspectDropArchiveResponse, InspectDropArchiveResponses, IntegrationResponse, IpAccessControlQuery, IpAccessControlResponse, JobLogsData, JobLogsErrors, JobLogsResponses, JobStatusData, JobStatusErrors, JobStatusResponse, JobStatusResponse2, JobStatusResponses, JobSummaryResponse, JoinTokenStatusResponse, JourneyEvent, JourneySession, KeysRequest, KeysResponse, KillJobBody, KillJobData, KillJobErrors, KillJobResponse, KillJobResponses, KnownAiAgentsResponse, KvDelData, KvDelErrors, KvDelResponse, KvDelResponses, KvDisableData, KvDisableErrors, KvDisableResponse, KvDisableResponses, KvEnableData, KvEnableErrors, KvEnableResponse, KvEnableResponses, KvExpireData, KvExpireErrors, KvExpireResponse, KvExpireResponses, KvGetData, KvGetErrors, KvGetResponse, KvGetResponses, KvIncrData, KvIncrErrors, KvIncrResponse, KvIncrResponses, KvKeysData, KvKeysErrors, KvKeysResponse, KvKeysResponses, KvSetData, KvSetErrors, KvSetResponse, KvSetResponses, KvStatusData, KvStatusErrors, KvStatusResponse, KvStatusResponse2, KvStatusResponses, KvTtlData, KvTtlErrors, KvTtlResponse, KvTtlResponses, KvUpdateData, KvUpdateErrors, KvUpdateResponse, KvUpdateResponses, LatestRunForSourceData, LatestRunForSourceErrors, LatestRunForSourceResponse, LatestRunForSourceResponses, LemonSqueezyConfig, LetsEncryptSettings, LineContext, LinkCustomDomainToCertificateData, LinkCustomDomainToCertificateErrors, LinkCustomDomainToCertificateResponse, LinkCustomDomainToCertificateResponses, LinkServiceRequest, LinkServiceToProjectData, LinkServiceToProjectErrors, LinkServiceToProjectResponse, LinkServiceToProjectResponses, ListAgentRunsData, ListAgentRunsErrors, ListAgentRunsResponse, ListAgentRunsResponses, ListAgentsData, ListAgentsErrors, ListAgentsResponse, ListAgentsResponse2, ListAgentsResponses, ListAiProvidersData, ListAiProvidersErrors, ListAiProvidersResponse, ListAiProvidersResponses, ListAlertRulesData, ListAlertRulesErrors, ListAlertRulesResponse, ListAlertRulesResponses, ListAlertsData, ListAlertsError, ListAlertsErrors, ListAlertsResponse, ListAlertsResponses, ListAllConversationsData, ListAllConversationsErrors, ListAllConversationsResponse, ListAllConversationsResponses, ListAllRunsData, ListAllRunsErrors, ListAllRunsResponse, ListAllRunsResponses, ListApiKeysData, ListApiKeysErrors, ListApiKeysQuery, ListApiKeysResponse, ListApiKeysResponses, ListAuditLogsData, ListAuditLogsErrors, ListAuditLogsQuery, ListAuditLogsResponse, ListAuditLogsResponses, ListAvailableContainersData, ListAvailableContainersErrors, ListAvailableContainersResponse, ListAvailableContainersResponses, ListBackupAlertsData, ListBackupAlertsError, ListBackupAlertsErrors, ListBackupAlertsResponse, ListBackupAlertsResponses, ListBackupChildrenData, ListBackupChildrenError, ListBackupChildrenErrors, ListBackupChildrenResponse, ListBackupChildrenResponses, ListBackupSchedulesData, ListBackupSchedulesError, ListBackupSchedulesErrors, ListBackupSchedulesResponse, ListBackupSchedulesResponses, ListBackupsForScheduleData, ListBackupsForScheduleErrors, ListBackupsForScheduleResponse, ListBackupsForScheduleResponses, ListBlobsQuery, ListBlobsResponse, ListCommitsByRepositoryIdData, ListCommitsByRepositoryIdErrors, ListCommitsByRepositoryIdResponse, ListCommitsByRepositoryIdResponses, ListConnectionsData, ListConnectionsErrors, ListConnectionsResponse, ListConnectionsResponses, ListContainersAtPathData, ListContainersAtPathErrors, ListContainersAtPathResponse, ListContainersAtPathResponses, ListContainersData, ListContainersErrors, ListContainersResponse, ListContainersResponses, ListConversationsData, ListConversationsErrors, ListConversationsResponse, ListConversationsResponses, ListCustomDomainsForProjectData, ListCustomDomainsForProjectErrors, ListCustomDomainsForProjectResponse, ListCustomDomainsForProjectResponses, ListCustomDomainsResponse, ListDashboardsData, ListDashboardsError, ListDashboardsErrors, ListDashboardsResponse, ListDashboardsResponses, ListDeliveriesData, ListDeliveriesErrors, ListDeliveriesResponse, ListDeliveriesResponses, ListDeploymentContainerLogsData, ListDeploymentContainerLogsErrors, ListDeploymentContainerLogsResponse, ListDeploymentContainerLogsResponses, ListDeploymentTokensData, ListDeploymentTokensErrors, ListDeploymentTokensQuery, ListDeploymentTokensResponse, ListDeploymentTokensResponses, ListDnsProvidersData, ListDnsProvidersErrors, ListDnsProvidersResponse, ListDnsProvidersResponses, ListDomainsData, ListDomainsErrors, ListDomainsResponse, ListDomainsResponse2, ListDomainsResponses, ListDsnsData, ListDsnsErrors, ListDsnsResponse, ListDsnsResponses, ListEmailDomainsData, ListEmailDomainsErrors, ListEmailDomainsResponse, ListEmailDomainsResponses, ListEmailProvidersData, ListEmailProvidersErrors, ListEmailProvidersResponse, ListEmailProvidersResponses, ListEmailsData, ListEmailsErrors, ListEmailsResponse, ListEmailsResponses, ListEnrollmentTokensData, ListEnrollmentTokensErrors, ListEnrollmentTokensResponse, ListEnrollmentTokensResponses, ListEntitiesData, ListEntitiesErrors, ListEntitiesQuery, ListEntitiesResponse, ListEntitiesResponses, ListErrorEventsData, ListErrorEventsErrors, ListErrorEventsQuery, ListErrorEventsResponse, ListErrorEventsResponses, ListErrorGroupsData, ListErrorGroupsErrors, ListErrorGroupsQuery, ListErrorGroupsResponse, ListErrorGroupsResponses, ListEventsData, ListEventsResponse, ListEventsResponses, ListEventTypesData, ListEventTypesResponse, ListEventTypesResponses, ListExternalImagesData, ListExternalImagesErrors, ListExternalImagesResponse, ListExternalImagesResponses, ListExternalPluginsData, ListExternalPluginsErrors, ListExternalPluginsResponse, ListExternalPluginsResponses, ListExternalServiceBackupsData, ListExternalServiceBackupsError, ListExternalServiceBackupsErrors, ListExternalServiceBackupsResponse, ListExternalServiceBackupsResponses, ListFlagsData, ListFlagsErrors, ListFlagsResponse, ListFlagsResponses, ListFunnelsData, ListFunnelsErrors, ListFunnelsResponse, ListFunnelsResponses, ListGitProvidersData, ListGitProvidersErrors, ListGitProvidersResponse, ListGitProvidersResponses, ListGlobalMcpsData, ListGlobalMcpsErrors, ListGlobalMcpsResponse, ListGlobalMcpsResponses, ListGlobalSkillsData, ListGlobalSkillsErrors, ListGlobalSkillsResponse, ListGlobalSkillsResponses, ListIncidentsData, ListIncidentsErrors, ListIncidentsResponses, ListInsightsData, ListInsightsError, ListInsightsErrors, ListInsightsResponse, ListInsightsResponses, ListIpAccessControlData, ListIpAccessControlError, ListIpAccessControlErrors, ListIpAccessControlResponse, ListIpAccessControlResponses, ListJobsData, ListJobsErrors, ListJobsResponse, ListJobsResponse2, ListJobsResponses, ListKnownAiAgentsData, ListKnownAiAgentsError, ListKnownAiAgentsErrors, ListKnownAiAgentsResponse, ListKnownAiAgentsResponses, ListManagedDomainsData, ListManagedDomainsErrors, ListManagedDomainsResponse, ListManagedDomainsResponses, ListMcpsData, ListMcpsErrors, ListMcpsResponse, ListMcpsResponse2, ListMcpsResponses, ListMetricLabelKeysData, ListMetricLabelKeysError, ListMetricLabelKeysErrors, ListMetricLabelKeysResponse, ListMetricLabelKeysResponses, ListMetricLabelValuesData, ListMetricLabelValuesError, ListMetricLabelValuesErrors, ListMetricLabelValuesResponse, ListMetricLabelValuesResponses, ListMetricNamesData, ListMetricNamesError, ListMetricNamesErrors, ListMetricNamesResponse, ListMetricNamesResponses, ListModelsData, ListModelsError, ListModelsErrors, ListModelsResponse, ListModelsResponses, ListMonitorsData, ListMonitorsErrors, ListMonitorsResponse, ListMonitorsResponses, ListNotificationProvidersData, ListNotificationProvidersErrors, ListNotificationProvidersResponse, ListNotificationProvidersResponses, ListOidcProvidersData, ListOidcProvidersResponse, ListOidcProvidersResponses, ListOidcProviderUsersData, ListOidcProviderUsersErrors, ListOidcProviderUsersResponse, ListOidcProviderUsersResponses, ListOidcRoleMappingsData, ListOidcRoleMappingsResponse, ListOidcRoleMappingsResponses, ListOnDemandCertsData, ListOnDemandCertsErrors, ListOnDemandCertsResponse, ListOnDemandCertsResponse2, ListOnDemandCertsResponses, ListOrdersData, ListOrdersErrors, ListOrdersResponse, ListOrdersResponse2, ListOrdersResponses, ListPeersData, ListPeersErrors, ListPeersResponse, ListPeersResponses, ListPendingActionsData, ListPendingActionsErrors, ListPendingActionsResponse, ListPendingActionsResponses, ListPgUpgradesData, ListPgUpgradesErrors, ListPgUpgradesResponse, ListPgUpgradesResponses, ListPresetsData, ListPresetsErrors, ListPresetsResponse, ListPresetsResponse2, ListPresetsResponses, ListProjectAccessData, ListProjectAccessErrors, ListProjectAccessResponse, ListProjectAccessResponses, ListProjectAlarmsData, ListProjectAlarmsErrors, ListProjectAlarmsResponse, ListProjectAlarmsResponses, ListProjectScansData, ListProjectScansError, ListProjectScansErrors, ListProjectScansResponse, ListProjectScansResponses, ListProjectSecretsData, ListProjectSecretsErrors, ListProjectSecretsResponse, ListProjectSecretsResponses, ListProjectServicesData, ListProjectServicesErrors, ListProjectServicesResponse, ListProjectServicesResponses, ListProjectTemplatesData, ListProjectTemplatesErrors, ListProjectTemplatesResponse, ListProjectTemplatesResponses, ListProjectTemplateTagsData, ListProjectTemplateTagsErrors, ListProjectTemplateTagsResponse, ListProjectTemplateTagsResponses, ListProviderKeysData, ListProviderKeysError, ListProviderKeysErrors, ListProviderKeysResponse, ListProviderKeysResponses, ListProviderZonesData, ListProviderZonesErrors, ListProviderZonesResponse, ListProviderZonesResponses, ListPublicProvidersData, ListPublicProvidersResponse, ListPublicProvidersResponses, ListReleaseFilesData, ListReleaseFilesErrors, ListReleaseFilesResponse, ListReleaseFilesResponses, ListReleasesData, ListReleasesErrors, ListReleasesResponse, ListReleasesResponses, ListRemoteExternalImagesData, ListRemoteExternalImagesErrors, ListRemoteExternalImagesResponse, ListRemoteExternalImagesResponses, ListRepositoriesByConnectionData, ListRepositoriesByConnectionErrors, ListRepositoriesByConnectionResponse, ListRepositoriesByConnectionResponses, ListRepositoriesByProviderData, ListRepositoriesByProviderErrors, ListRepositoriesByProviderResponse, ListRepositoriesByProviderResponses, ListRestoreRunsForServiceData, ListRestoreRunsForServiceResponse, ListRestoreRunsForServiceResponses, ListRootContainersData, ListRootContainersErrors, ListRootContainersResponse, ListRootContainersResponses, ListRoutesData, ListRoutesErrors, ListRoutesResponse, ListRoutesResponses, ListRunsResponse, ListS3SourcesData, ListS3SourcesError, ListS3SourcesErrors, ListS3SourcesResponse, ListS3SourcesResponses, ListSandboxesData, ListSandboxesResponse, ListSandboxesResponse2, ListSandboxesResponses, ListScansQuery, ListScheduleRunJobsData, ListScheduleRunJobsError, ListScheduleRunJobsErrors, ListScheduleRunJobsResponse, ListScheduleRunJobsResponses, ListScheduleRunsData, ListScheduleRunsError, ListScheduleRunsErrors, ListScheduleRunsResponse, ListScheduleRunsResponses, ListScheduleServicesData, ListScheduleServicesError, ListScheduleServicesErrors, ListScheduleServicesResponse, ListScheduleServicesResponses, ListSecretsData, ListSecretsErrors, ListSecretsResponse, ListSecretsResponse2, ListSecretsResponses, ListServiceHealthStatusesData, ListServiceHealthStatusesErrors, ListServiceHealthStatusesResponse, ListServiceHealthStatusesResponses, ListServiceProjectsData, ListServiceProjectsErrors, ListServiceProjectsResponse, ListServiceProjectsResponses, ListServiceSchedulesData, ListServiceSchedulesError, ListServiceSchedulesErrors, ListServiceSchedulesResponse, ListServiceSchedulesResponses, ListServicesData, ListServicesErrors, ListServicesResponse, ListServicesResponses, ListSkillsData, ListSkillsErrors, ListSkillsResponse, ListSkillsResponse2, ListSkillsResponses, ListSourceBackupsData, ListSourceBackupsError, ListSourceBackupsErrors, ListSourceBackupsResponse, ListSourceBackupsResponses, ListSourceFilesData, ListSourceFilesErrors, ListSourceFilesResponse, ListSourceFilesResponses, ListSourceMapsData, ListSourceMapsErrors, ListSourceMapsResponse, ListSourceMapsResponses, ListSourcesData, ListSourcesErrors, ListSourcesResponse, ListSourcesResponses, ListStaticBundlesData, ListStaticBundlesErrors, ListStaticBundlesResponse, ListStaticBundlesResponses, ListSyncedRepositoriesData, ListSyncedRepositoriesErrors, ListSyncedRepositoriesResponse, ListSyncedRepositoriesResponses, ListTagsResponse, ListTeamMembersData, ListTeamMembersErrors, ListTeamMembersResponse, ListTeamMembersResponses, ListTeamProjectsData, ListTeamProjectsErrors, ListTeamProjectsResponse, ListTeamProjectsResponses, ListTeamsData, ListTeamsErrors, ListTeamsResponse, ListTeamsResponses, ListTemplatesQuery, ListTemplatesResponse, ListUsersData, ListUsersErrors, ListUsersResponse, ListUsersResponses, ListVulnerabilitiesQuery, ListWebhooksData, ListWebhooksErrors, ListWebhooksResponse, ListWebhooksResponses, LiveVisitorInfo, LiveVisitorsListResponse, LocationCount, LocationGranularity, LocationInfo, LoginData, LoginErrors, LoginRequest, LoginResponse, LoginResponses, LogLevel, LogoutData, LogoutErrors, LogoutResponses, LogRecord, LogSearchLine, LogSeverity, LogSource, LogsQuery, LogsResponse, LogStream, LookupDnsARecordsData, LookupDnsARecordsError, LookupDnsARecordsErrors, LookupDnsARecordsResponse, LookupDnsARecordsResponses, ManagedDomainResponse, ManualAction, ManualActionTiming, McpDefinitionResponse, MessageContent, MessagePart, MessageResponse, MeteredMode, MetricAggregation, MetricBucket, MetricDataPoint, MetricsOverTimeResponse, MetricsQuery, MetricsRangeQuery, MetricsStatusResponse, MetricsStoreKind, MetricsSummaryResponse, MetricType, MfaRequiredResponse, MfaSetupResponse, MfaVerificationRequest, MigrationStep, MigrationSummary, MintEnrollmentTokenData, MintEnrollmentTokenErrors, MintEnrollmentTokenRequest, MintEnrollmentTokenResponse, MintEnrollmentTokenResponse2, MintEnrollmentTokenResponses, MiscResult, MkdirBody, MkdirData, MkdirErrors, MkdirResponse, MkdirResponses, ModelInfo, ModelListResponse, ModelPricing, ModelUsage, MonitoringSettings, MonitoringSettingsMasked, MonitorResponse, MonitorStatus, MrrBucketResponse, MultiNodeSettings, MultiNodeSettingsMasked, MxResult, NavEntry, NavSection, NetworkConfiguration, NetworkMode, NixpacksPresetConfig, NixpacksProvider, NodeContainerListResponse, NodeContainerResponse, NodeCostInfo, NodeHeartbeatData, NodeHeartbeatErrors, NodeHeartbeatResponse, NodeHeartbeatResponses, NodeInfoResponse, NodeListResponse, NodeMetricsGetRangeData, NodeMetricsGetRangeErrors, NodeMetricsGetRangeResponse, NodeMetricsGetRangeResponses, NotificationPreferencesResponse, NotificationProviderResponse, ObservabilityCompressionSettings, ObservabilityEvent, ObservabilityFullEventData, ObservabilityFullEventError, ObservabilityFullEventErrors, ObservabilityFullEventResponse, ObservabilityFullEventResponses, ObservabilityListEventsData, ObservabilityListEventsError, ObservabilityListEventsErrors, ObservabilityListEventsResponse, ObservabilityListEventsResponses, ObservabilityRetentionSettings, OidcCallbackData, OidcProviderResponse, OidcProvidersListResponse, OidcProviderSummary, OidcProviderUserResponse, OidcRoleMappingResponse, OidcTestConnectionResponse, OnDemandCertAttemptResponse, OnDemandCertRow, OnDemandTlsSettings, OpenAiError, OpenAiErrorResponse, OperatingSystemCount, OperationResultResponse, OperationResultsResponse, OtelDashboardResponse, OtelDashboardsResponse, OtelMetricAlertRuleResponse, OtelMetricAlertsResponse, OtelMetricLabelKeysResponse, OtelMetricLabelValuesResponse, OtelMetricNamesResponse, OtelMetricsResponse, OutlierAlgorithm, OutlierParams, OverprovisioningAssessment, OverprovisioningVerdict, PageActivityBucket, PageCountryStats, PageFlowEntry, PageFlowQuery, PageFlowResponse, PageHourlySessionsQuery, PageHourlySessionsResponse, PagePathDetailQuery, PagePathDetailResponse, PagePathInfo, PagePathSparkline, PagePathSparklinePoint, PagePathsQuery, PagePathsResponse, PagePathsSparklineQuery, PagePathsSparklineResponse, PagePathVisitorsQuery, PagePathVisitorsResponse, PageReferrerStats, PagesComparisonResponse, PageSessionComparison, PageSessionStats, PageSessionStatsQuery, PageTransition, PageVisit, PageVisitorSession, PaginatedEmailsResponse, PaginatedEntitiesResponse, PaginatedErrorEventsResponse, PaginatedErrorGroupsResponse, PaginatedEventsResponse, PaginatedExternalImagesResponse, PaginatedProjectList, PaginatedStaticBundlesResponse, Pagination, PaginationMeta, PaginationParams, PasswordProtectionConfig, PatchAdminGateData, PatchAdminGateErrors, PatchAdminGateResponse, PatchAdminGateResponses, PatchPreviewGatewaySettingsData, PatchPreviewGatewaySettingsResponse, PatchPreviewGatewaySettingsResponses, PatchSettingsRequest, PathVisitors, PathVisitorsAnalyticsQuery, PathVisitorsResponse, PauseDeploymentData, PauseDeploymentErrors, PauseDeploymentResponse, PauseDeploymentResponses, PauseSandboxData, PauseSandboxErrors, PauseSandboxResponse, PauseSandboxResponses, PeerEntry, PeerListResponse, PendingActionResponse, PerformanceMetricsQuery, PerformanceMetricsResponse, PermissionInfo, PgUpgradeLogResponse, PgUpgradeResponse, PipelineStats, PipelineStatsResponse, PlanComplexity, PlanMetadata, PlanRestoreData, PlanRestoreError, PlanRestoreErrors, PlanRestoreResponse, PlanRestoreResponses, PlanSourceBackup, PlanTarget, PlatformInfo, PluginManifest, PortMapping, PostDnsAckData, PostDnsAckErrors, PostDnsAckResponse, PostDnsAckResponses, PostgresWalHealth, PresetConfigSchema, PresetInfo, PresetResponse, PreviewAlertData, PreviewAlertError, PreviewAlertErrors, PreviewAlertResponse, PreviewAlertResponses, PreviewFunnelMetricsData, PreviewFunnelMetricsErrors, PreviewFunnelMetricsResponse, PreviewFunnelMetricsResponses, PreviewGatewaySettings, PreviewGatewaySettingsMasked, PreviewGatewaySettingsResponse, PreviewHostnameModeData, PreviewHostnameModeErrors, PreviewHostnameModeResponse, PreviewHostnameModeResponses, PreviewShareLinkBody, PreviewShareLinkResponse, PricingResponse, ProblemDetails, ProjectAccessResponse, ProjectConfiguration, ProjectDashboardAnalytics, ProjectDsnResponse, ProjectHealthSummary, ProjectInfo, ProjectMonitorHealth, ProjectPresetResponse, ProjectQuery, ProjectRef, ProjectResponse, ProjectSecretEnvironmentInfo, ProjectSecretResponse, ProjectServiceInfo, ProjectsHealthResponse, ProjectsMonitorHealthResponse, ProjectStatisticsResponse, ProjectStatsBreakdown, ProjectType, ProjectUsageInfoResponse, PromoteClusterMemberData, PromoteClusterMemberErrors, PromoteClusterMemberResponses, PromoteDeploymentData, PromoteDeploymentErrors, PromoteDeploymentRequest, PromoteDeploymentResponse, PromoteDeploymentResponses, PropertyBreakdownItem, PropertyBreakdownQuery, PropertyBreakdownResponse, PropertyColumn, PropertyTimelineItem, PropertyTimelineQuery, PropertyTimelineResponse, Protocol, ProviderCatalogDto, ProviderCatalogResponse, ProviderConfig, ProviderConfigMasked, ProviderDeletionCheckResponse, ProviderDescriptor, ProviderKeyResponse, ProviderMetadata, ProviderResponse, ProviderUsage, ProvisionDomainData, ProvisionDomainErrors, ProvisionDomainResponse, ProvisionDomainResponses, ProvisionResponse, ProxyLogResponse, ProxyLogsPaginatedResponse, PublicHostnameStrategy, PublicPresetResponse, PublicRepositoryInfo, PurgeLogsRequest, PurgeProjectLogsData, PurgeProjectLogsError, PurgeProjectLogsErrors, PurgeProjectLogsResponses, PushedExternalImageResponse, PushExternalImageData, PushExternalImageErrors, PushExternalImageResponse, PushExternalImageResponses, PushImageRequest, QueryDataData, QueryDataErrors, QueryDataRequest, QueryDataResponse, QueryDataResponse2, QueryDataResponses, QueryGenaiTracesData, QueryGenaiTracesError, QueryGenaiTracesErrors, QueryGenaiTracesResponse, QueryGenaiTracesResponses, QueryLogsData, QueryLogsError, QueryLogsErrors, QueryLogsResponse, QueryLogsResponses, QueryMetricsData, QueryMetricsError, QueryMetricsErrors, QueryMetricsResponse, QueryMetricsResponses, QuerySpanStatsData, QuerySpanStatsError, QuerySpanStatsErrors, QuerySpanStatsResponse, QuerySpanStatsResponses, QueryTracesData, QueryTracesError, QueryTracesErrors, QueryTracesResponse, QueryTracesResponses, QueryTraceSummariesData, QueryTraceSummariesError, QueryTraceSummariesErrors, QueryTraceSummariesResponse, QueryTraceSummariesResponses, QuotaResponse, RateLimitConfig, RateLimitSettings, ReachabilityStatus, ReadEntityRowsData, ReadEntityRowsErrors, ReadEntityRowsResponse, ReadEntityRowsResponses, ReadFileData, ReadFileErrors, ReadFileResponse, ReadFileResponse2, ReadFileResponses, ReadRowsQuery, ReAnalyzeData, ReAnalyzeErrors, ReAnalyzeResponses, RecentActivityQuery, RecentActivityResponse, RecentEventResponse, RecentQueryParams, RecordConsoleEventData, RecordConsoleEventErrors, RecordConsoleEventResponses, RecordEventMetricsData, RecordEventMetricsErrors, RecordEventMetricsResponse, RecordEventMetricsResponses, RecordExposureRequest, RecordExposureResponse, RecordFlagExposureData, RecordFlagExposureErrors, RecordFlagExposureResponse, RecordFlagExposureResponses, RecordListResponse, RecordSpeedMetricsData, RecordSpeedMetricsError, RecordSpeedMetricsErrors, RecordSpeedMetricsResponse, RecordSpeedMetricsResponses, RecoveryTarget, ReferrerCount, ReferrersAnalyticsQuery, RefreshRouteTableData, RefreshRouteTableErrors, RefreshRouteTableResponse, RefreshRouteTableResponses, RegenerateDsnData, RegenerateDsnErrors, RegenerateDsnRequest, RegenerateDsnResponse, RegenerateDsnResponses, RegisterExternalImageData, RegisterExternalImageErrors, RegisterExternalImageResponse, RegisterExternalImageResponses, RegisterImageRequest, RegisterNodeApiRequest, RegisterNodeData, RegisterNodeErrors, RegisterNodeResponse, RegisterNodeResponse2, RegisterNodeResponses, RegisterRequest, ReinstallGitlabWebhookData, ReinstallGitlabWebhookErrors, ReinstallGitlabWebhookResponse, ReinstallGitlabWebhookResponses, ReinstallWebhookResponse, RejectPendingActionData, RejectPendingActionErrors, RejectPendingActionResponse, RejectPendingActionResponses, ReleaseListResponse, ReloadPluginsData, ReloadPluginsErrors, ReloadPluginsResponse, ReloadPluginsResponses, ReloadResponse, RemoteDeploymentResponse, RemoveClusterMemberData, RemoveClusterMemberErrors, RemoveClusterMemberResponse, RemoveClusterMemberResponses, RemoveManagedDomainData, RemoveManagedDomainErrors, RemoveManagedDomainResponse, RemoveManagedDomainResponses, RemoveNodeResponse, RemoveRoleData, RemoveRoleErrors, RemoveRoleResponse, RemoveRoleResponses, RemoveTeamMemberData, RemoveTeamMemberErrors, RemoveTeamMemberResponse, RemoveTeamMemberResponses, RenameConversationData, RenameConversationErrors, RenameConversationRequest, RenameConversationResponse, RenameConversationResponses, RenewDomainData, RenewDomainErrors, RenewDomainResponse, RenewDomainResponses, RepositoryListQuery, RepositoryListResponse, RepositoryPresetResponse, RepositoryResponse, RepositorySyncStartedResponse, RequestPasswordResetData, RequestPasswordResetErrors, RequestPasswordResetResponse, RequestPasswordResetResponses, RequestRow, RequiredPasswordChangeRequest, RequiredPasswordChangeResponse, ResetPasswordData, ResetPasswordErrors, ResetPasswordRequest, ResetPasswordResponse, ResetPasswordResponses, ResetPgStatStatementsRequest, ResetPgStatStatementsResponse, ResizeSandboxBody, ResizeSandboxData, ResizeSandboxErrors, ResizeSandboxResponse, ResizeSandboxResponses, ResolveAlarmData, ResolveAlarmErrors, ResolveAlarmResponses, ResolvedEnvVarResponse, ResolvedEnvVarSource, ResourceCounts, ResourceFootprint, ResourceInfo, ResourceLimitApplyResult, ResourceLimits, ResourceLimitsResponse, ResourceLimitsUpdateResponse, ResourcesBody, RestartContainerData, RestartContainerErrors, RestartContainerResponse, RestartContainerResponses, RestartPreviewGatewayData, RestartPreviewGatewayResponse, RestartPreviewGatewayResponses, RestartSandboxData, RestartSandboxErrors, RestartSandboxResponse, RestartSandboxResponses, RestoreCapabilities, RestoreCapabilitiesResponse, RestoreFlagData, RestoreFlagErrors, RestoreFlagResponse, RestoreFlagResponses, RestorePlan, RestoreRequestMode, RestoreRunView, RestoreUserData, RestoreUserErrors, RestoreUserResponse, RestoreUserResponses, ResumeDeploymentData, ResumeDeploymentErrors, ResumeDeploymentResponse, ResumeDeploymentResponses, ResumeSandboxData, ResumeSandboxErrors, ResumeSandboxResponse, ResumeSandboxResponses, RetentionCleanupFailure, RetentionCleanupReport, RetryClusterData, RetryClusterErrors, RetryClusterRequest, RetryClusterResponse, RetryClusterResponses, RetryDeliveryData, RetryDeliveryErrors, RetryDeliveryResponse, RetryDeliveryResponses, RetryPgUpgradeData, RetryPgUpgradeErrors, RetryPgUpgradeResponse, RetryPgUpgradeResponses, RetryRunData, RetryRunErrors, RetryRunResponse, RetryRunResponses, RevealGlobalMcpConfigData, RevealGlobalMcpConfigErrors, RevealGlobalMcpConfigResponse, RevealGlobalMcpConfigResponses, RevealMcpConfigData, RevealMcpConfigErrors, RevealMcpConfigResponse, RevealMcpConfigResponses, RevealNotificationProviderConfigData, RevealNotificationProviderConfigErrors, RevealNotificationProviderConfigResponse, RevealNotificationProviderConfigResponses, RevealServiceParameterData, RevealServiceParameterErrors, RevealServiceParameterResponse, RevealServiceParameterResponses, RevenueCreateIntegrationData, RevenueCreateIntegrationErrors, RevenueCreateIntegrationResponse, RevenueCreateIntegrationResponses, RevenueDeleteIntegrationData, RevenueDeleteIntegrationResponse, RevenueDeleteIntegrationResponses, RevenueGlobalEventsData, RevenueGlobalEventsResponse, RevenueGlobalEventsResponses, RevenueImportInvoicesCsvData, RevenueImportInvoicesCsvErrors, RevenueImportInvoicesCsvResponse, RevenueImportInvoicesCsvResponses, RevenueImportSubscriptionsCsvData, RevenueImportSubscriptionsCsvErrors, RevenueImportSubscriptionsCsvResponse, RevenueImportSubscriptionsCsvResponses, RevenueListIntegrationsData, RevenueListIntegrationsResponse, RevenueListIntegrationsResponses, RevenueListProvidersData, RevenueListProvidersResponse, RevenueListProvidersResponses, RevenueMetricsCustomersData, RevenueMetricsCustomersResponse, RevenueMetricsCustomersResponses, RevenueMetricsGlobalMrrData, RevenueMetricsGlobalMrrResponse, RevenueMetricsGlobalMrrResponses, RevenueMetricsGlobalSummaryData, RevenueMetricsGlobalSummaryResponse, RevenueMetricsGlobalSummaryResponses, RevenueMetricsMrrData, RevenueMetricsMrrResponse, RevenueMetricsMrrResponses, RevenueMetricsSummaryData, RevenueMetricsSummaryResponse, RevenueMetricsSummaryResponses, RevenueRecentEventsData, RevenueRecentEventsResponse, RevenueRecentEventsResponses, RevenueRotateTokenData, RevenueRotateTokenResponse, RevenueRotateTokenResponses, RevenueRow, RevenueUpdateConfigData, RevenueUpdateConfigErrors, RevenueUpdateConfigResponse, RevenueUpdateConfigResponses, RevenueUpdateSecretData, RevenueUpdateSecretErrors, RevenueUpdateSecretResponse, RevenueUpdateSecretResponses, RevokeDsnData, RevokeDsnErrors, RevokeDsnResponse, RevokeDsnResponses, RevokeEnrollmentTokenData, RevokeEnrollmentTokenErrors, RevokeEnrollmentTokenResponse, RevokeEnrollmentTokenResponses, RevokeJoinTokenData, RevokeJoinTokenErrors, RevokeJoinTokenResponse, RevokeJoinTokenResponses, RevokeProjectAccessData, RevokeProjectAccessErrors, RevokeProjectAccessResponse, RevokeProjectAccessResponses, RiskLevel, RoleInfo, RollbackPgUpgradeData, RollbackPgUpgradeErrors, RollbackPgUpgradeResponse, RollbackPgUpgradeResponses, RollbackToDeploymentData, RollbackToDeploymentErrors, RollbackToDeploymentResponse, RollbackToDeploymentResponses, RootfsCacheEntry, RootfsGcData, RootfsGcReport, RootfsGcResponses, RootfsReport, RootfsReportData, RootfsReportResponses, RootfsVmEntry, RotateApiKeyData, RotateApiKeyErrors, RotateApiKeyResponse, RotateApiKeyResponses, RotateDeploymentTokenData, RotateDeploymentTokenErrors, RotateDeploymentTokenResponse, RotateDeploymentTokenResponses, RouteRefreshResponse, RouteResponse, RouteRole, RouteUser, RouteUserWithRoles, RunBackupForSourceData, RunBackupForSourceError, RunBackupForSourceErrors, RunBackupForSourceResponse, RunBackupForSourceResponses, RunBackupRequest, RunConnectionHealthCheckData, RunConnectionHealthCheckErrors, RunConnectionHealthCheckResponse, RunConnectionHealthCheckResponses, RunExternalServiceBackupData, RunExternalServiceBackupError, RunExternalServiceBackupErrors, RunExternalServiceBackupRequest, RunExternalServiceBackupResponse, RunExternalServiceBackupResponses, RunScheduleNowData, RunScheduleNowError, RunScheduleNowErrors, RunScheduleNowResponse, RunScheduleNowResponses, S3ConnectionTestResponse, S3CredentialsResponse, S3SourceResponse, S3SourceResponseWritable, SandboxCreatePreviewLinkData, SandboxCreatePreviewLinkErrors, SandboxCreatePreviewLinkResponse, SandboxCreatePreviewLinkResponses, SandboxDomainResponse, SandboxEvent, SandboxEventsResponse, SandboxInner, SandboxResponse, SandboxRoute, SandboxStatusResponse, SaveAgentTokenData, SaveAgentTokenErrors, SaveAgentTokenRequest, SaveAgentTokenResponse, SaveAgentTokenResponse2, SaveAgentTokenResponses, SaveAiProviderCredentialData, SaveAiProviderCredentialErrors, SaveAiProviderCredentialResponse, SaveAiProviderCredentialResponses, SaveCredentialRequest, SaveCredentialResponse, ScalewayCredentialsRequest, ScanResponse, ScheduleRunEntry, ScheduleRunJobEntry, ScheduleRunListResponse, ScheduleRunResponse, ScheduleRunSummary, ScheduleRunSummaryList, ScreenshotSettings, SearchLogsData, SearchLogsError, SearchLogsErrors, SearchLogsRequest, SearchLogsResponse, SearchLogsResponse2, SearchLogsResponses, SearchMode, Seasonality, SecretResponse, SecurityConfig, SecurityHeadersConfig, SecurityHeadersSettings, SendEmailData, SendEmailErrors, SendEmailRequestBody, SendEmailResponse, SendEmailResponseBody, SendEmailResponses, SendMessageRequest, SensitiveConfigValueResponse, SensitiveMcpConfigValueResponse, SensitiveValueResponse, SentryChunkUploadResponse, SentryCreateReleaseRequest, SentryEventRequest, SentryEventResponse, SentryReleaseFileResponse, SentryReleaseProjectRef, SentryReleaseResponse, SeriesStateEntry, ServiceAccessInfo, ServiceAction, ServiceAlertRuleResponse, ServiceBackupEntryResponse, ServiceBackupListResponse, ServiceCreateAlertRuleRequest, ServiceHealthResponse, ServiceHealthStatusBatchResponse, ServiceHealthStatusEntryResponse, ServiceMemberInfo, ServiceParameter, ServicePlan, ServiceResourceLimits, ServiceRuntimeReport, ServiceStatsReport, ServiceTypeInfo, ServiceTypeRoute, ServiceUpdateAlertRuleRequest, SesCredentialsRequest, SessionDetails, SessionDetailsQuery, SessionEvent, SessionEventDto, SessionEventsQuery, SessionEventsResponse, SessionLogsQuery, SessionLogsResponse, SessionReplayEventsRequest, SessionReplayInfoDto, SessionReplayInitRequest, SessionReplayInitResponse, SessionReplayWithEventsDto, SessionReplayWithVisitorDto, SessionRequestLog, SessionSummary, SetAiDataAccessData, SetAiDataAccessErrors, SetAiDataAccessResponse, SetAiDataAccessResponses, SetDefaultS3SourceData, SetDefaultS3SourceError, SetDefaultS3SourceErrors, SetDefaultS3SourceResponse, SetDefaultS3SourceResponses, SetFlagEnvironmentData, SetFlagEnvironmentErrors, SetFlagEnvironmentRequest, SetFlagEnvironmentResponse, SetFlagEnvironmentResponses, SetPreviewPasswordBody, SetPreviewPasswordData, SetPreviewPasswordErrors, SetPreviewPasswordResponse, SetPreviewPasswordResponse2, SetPreviewPasswordResponses, SetRequest, SetResponse, SettingsUpdateResponse, SetupDnsChallengeData, SetupDnsChallengeErrors, SetupDnsChallengeRequest, SetupDnsChallengeResponse, SetupDnsChallengeResponse2, SetupDnsChallengeResponses, SetupDnsData, SetupDnsErrors, SetupDnsRequest, SetupDnsResponse, SetupDnsResponse2, SetupDnsResponses, SetupEmailTrackingData, SetupEmailTrackingErrors, SetupEmailTrackingResponse, SetupEmailTrackingResponses, SetupMfaData, SetupMfaErrors, SetupMfaResponse, SetupMfaResponses, SiblingRef, SkillDefinitionResponse, SlackConfig, SleepEnvironmentData, SleepEnvironmentErrors, SleepEnvironmentResponse, SleepEnvironmentResponses, SlowQueriesResponse, SlowQueryRow, SmartFilter, SmokeTestAgentData, SmokeTestAgentErrors, SmokeTestAgentResponse, SmokeTestAgentResponses, SmokeTestResponse, SmtpCredentialsRequest, SmtpEncryptionRoute, SmtpResult, SourceArchiveUpload, SourceBackupEntry, SourceBackupIndexResponse, SourceBody, SourceFileListResponse, SourceFileResponse, SourceMapListResponse, SourceMapResponse, SourceSandboxData, SourceSandboxErrors, SourceSandboxResponse, SourceSandboxResponses, SourceType, SpanEvent, SpanKind, SpanRecord, SpanRow, SpanStats, SpanStatsResponse, SpanStatusCode, SpeedMetricsPayload, SpeedSegmentFilters, StaleSlot, StartAnalysisData, StartAnalysisErrors, StartAnalysisRequest, StartAnalysisResponse, StartAnalysisResponses, StartContainerData, StartContainerErrors, StartContainerResponse, StartContainerResponses, StartFixData, StartFixErrors, StartFixResponses, StartGitProviderOauthData, StartGitProviderOauthErrors, StartOidcLoginBySlugData, StartOidcLoginBySlugErrors, StartPgUpgradeData, StartPgUpgradeErrors, StartPgUpgradeRequest, StartPgUpgradeResponse, StartPgUpgradeResponses, StartRestoreData, StartRestoreError, StartRestoreErrors, StartRestoreRequest, StartRestoreResponse, StartRestoreResponses, StartServiceData, StartServiceErrors, StartServiceResponse, StartServiceResponses, StaticBundleResponse, StaticParams, StaticPresetConfig, StatPathData, StatPathErrors, StatPathResponse, StatPathResponses, StatResponse, StatsFilters, StatusBucket, StatusBucketedResponse, StatusCodeCount, StatusCodesQuery, StatusPageOverview, StepConversionResponse, StepResourceType, StepResult, StepUpResponse, StopContainerData, StopContainerErrors, StopContainerResponse, StopContainerResponses, StopSandboxData, StopSandboxErrors, StopSandboxResponse, StopSandboxResponses, StopSequence, StopServiceData, StopServiceErrors, StopServiceResponse, StopServiceResponses, StorageQuota, StreamContainerMetricsData, StreamContainerMetricsErrors, StreamContainerMetricsResponses, StreamEventsData, StreamEventsErrors, StreamEventsResponses, StreamRunEventsData, StreamRunEventsErrors, StreamRunEventsResponses, StripeConfig, SyncedRepositoryListQuery, SyncRepositoriesData, SyncRepositoriesErrors, SyncRepositoriesResponse, SyncRepositoriesResponses, SyntaxResult, TagInfo, TagListResponse, TailDeploymentJobLogsData, TailDeploymentJobLogsErrors, TailLogsData, TailLogsError, TailLogsErrors, TailLogsRequest, TailLogsResponses, TargetRecommendation, TeamListResponse, TeamMemberResponse, TeamResponse, TeamRole, TeardownDeploymentData, TeardownDeploymentErrors, TeardownDeploymentResponse, TeardownDeploymentResponses, TeardownEnvironmentData, TeardownEnvironmentErrors, TeardownEnvironmentResponse, TeardownEnvironmentResponses, TemplateResponse, TestEmailRequest, TestEmailResponse, TestNotificationProviderData, TestNotificationProviderErrors, TestNotificationProviderResponse, TestNotificationProviderResponses, TestOidcProviderData, TestOidcProviderResponse, TestOidcProviderResponses, TestProviderConnectionData, TestProviderConnectionErrors, TestProviderConnectionResponse, TestProviderConnectionResponses, TestProviderData, TestProviderErrors, TestProviderKeyByIdData, TestProviderKeyByIdError, TestProviderKeyByIdErrors, TestProviderKeyByIdResponse, TestProviderKeyByIdResponses, TestProviderKeyInlineData, TestProviderKeyInlineError, TestProviderKeyInlineErrors, TestProviderKeyInlineResponse, TestProviderKeyInlineResponses, TestProviderKeyRequest, TestProviderKeyResponse, TestProviderResponse, TestProviderResponse2, TestProviderResponses, TestS3ConnectionPreviewData, TestS3ConnectionPreviewError, TestS3ConnectionPreviewErrors, TestS3ConnectionPreviewResponse, TestS3ConnectionPreviewResponses, TestS3SourceConnectionData, TestS3SourceConnectionError, TestS3SourceConnectionErrors, TestS3SourceConnectionResponse, TestS3SourceConnectionResponses, TimeBucketStats, TimeBucketStatsResponse, TimeseriesBucket, TimeseriesQueryParams, TlsMode, TodayStatsResponse, ToggleAiDataAccessRequest, ToggleDeploymentMetricsRequest, ToggleServiceMetricsRequest, TokenRenewalRequest, ToolCallEvent, ToolInfo, ToolResultEvent, TopModelsQueryParams, TraceProjectRef, TracesResponse, TraceSummariesResponse, TraceSummary, TrackClickData, TrackClickErrors, TrackedLinkResponse, TrackingEventResponse, TrackOpenData, TrackOpenErrors, TrackOpenResponses, TriggerAgentData, TriggerAgentErrors, TriggerAgentRequest, TriggerAgentResponse, TriggerAgentResponses, TriggerDigestResponse, TriggerPipelinePayload, TriggerPipelineResponse, TriggerProjectPipelineData, TriggerProjectPipelineErrors, TriggerProjectPipelineResponse, TriggerProjectPipelineResponses, TriggerScanData, TriggerScanError, TriggerScanErrors, TriggerScanRequest, TriggerScanResponse, TriggerScanResponse2, TriggerScanResponses, TriggerServiceHealthCheckData, TriggerServiceHealthCheckErrors, TriggerServiceHealthCheckResponse, TriggerServiceHealthCheckResponses, TriggerWeeklyDigestData, TriggerWeeklyDigestErrors, TriggerWeeklyDigestResponse, TriggerWeeklyDigestResponses, TtlRequest, TtlResponse, TxtRecord, UiManifest, UiRoute, UndrainNodeResponse, UnifiedTrace, UniqueCountsQuery, UniqueCountsResponse, UnlinkServiceFromProjectData, UnlinkServiceFromProjectErrors, UnlinkServiceFromProjectResponse, UnlinkServiceFromProjectResponses, UnsupportedFeature, UpdateAdminGateRequest, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponse, UpdateAgentResponses, UpdateAiProviderData, UpdateAiProviderErrors, UpdateAiProviderRequest, UpdateAiProviderResponse, UpdateAiProviderResponse2, UpdateAiProviderResponses, UpdateAlertData, UpdateAlertError, UpdateAlertErrors, UpdateAlertResponse, UpdateAlertResponses, UpdateAlertRuleData, UpdateAlertRuleErrors, UpdateAlertRuleRequest, UpdateAlertRuleResponse, UpdateAlertRuleResponses, UpdateApiKeyData, UpdateApiKeyErrors, UpdateApiKeyRequest, UpdateApiKeyResponse, UpdateApiKeyResponses, UpdateAutomaticDeployData, UpdateAutomaticDeployErrors, UpdateAutomaticDeployRequest, UpdateAutomaticDeployResponse, UpdateAutomaticDeployResponses, UpdateBackupScheduleData, UpdateBackupScheduleError, UpdateBackupScheduleErrors, UpdateBackupScheduleRequest, UpdateBackupScheduleResponse, UpdateBackupScheduleResponses, UpdateBlobRequest, UpdateBlobResponse, UpdateCloudflareProviderData, UpdateCloudflareProviderErrors, UpdateCloudflareProviderRequest, UpdateCloudflareProviderResponse, UpdateCloudflareProviderResponses, UpdateConfigBody, UpdateConnectionTokenData, UpdateConnectionTokenErrors, UpdateConnectionTokenResponse, UpdateConnectionTokenResponses, UpdateCustomDomainData, UpdateCustomDomainErrors, UpdateCustomDomainRequest, UpdateCustomDomainResponse, UpdateCustomDomainResponses, UpdateDashboardData, UpdateDashboardError, UpdateDashboardErrors, UpdateDashboardRequest, UpdateDashboardResponse, UpdateDashboardResponses, UpdateDeploymentConfigRequest, UpdateDeploymentTokenData, UpdateDeploymentTokenErrors, UpdateDeploymentTokenRequest, UpdateDeploymentTokenResponse, UpdateDeploymentTokenResponses, UpdateDnsProviderRequest, UpdateEmailProviderData, UpdateEmailProviderErrors, UpdateEmailProviderRequest, UpdateEmailProviderResponse, UpdateEmailProviderResponses, UpdateEnvironmentSettingsData, UpdateEnvironmentSettingsErrors, UpdateEnvironmentSettingsRequest, UpdateEnvironmentSettingsResponse, UpdateEnvironmentSettingsResponses, UpdateEnvironmentSubdomainData, UpdateEnvironmentSubdomainErrors, UpdateEnvironmentSubdomainRequest, UpdateEnvironmentSubdomainResponse, UpdateEnvironmentSubdomainResponses, UpdateEnvironmentVariableData, UpdateEnvironmentVariableErrors, UpdateEnvironmentVariableRequest, UpdateEnvironmentVariableResponse, UpdateEnvironmentVariableResponses, UpdateErrorGroupData, UpdateErrorGroupErrors, UpdateErrorGroupRequest, UpdateErrorGroupResponses, UpdateExternalServiceRequest, UpdateFlagData, UpdateFlagErrors, UpdateFlagRequest, UpdateFlagResponse, UpdateFlagResponses, UpdateFunnelData, UpdateFunnelErrors, UpdateFunnelResponses, UpdateGitProviderCredentialsData, UpdateGitProviderCredentialsErrors, UpdateGitProviderCredentialsResponse, UpdateGitProviderCredentialsResponses, UpdateGitSettingsData, UpdateGitSettingsErrors, UpdateGitSettingsRequest, UpdateGitSettingsResponse, UpdateGitSettingsResponses, UpdateGlobalMcpData, UpdateGlobalMcpErrors, UpdateGlobalMcpResponse, UpdateGlobalMcpResponses, UpdateGlobalSkillData, UpdateGlobalSkillErrors, UpdateGlobalSkillResponse, UpdateGlobalSkillResponses, UpdateIncidentStatusData, UpdateIncidentStatusErrors, UpdateIncidentStatusRequest, UpdateIncidentStatusResponse, UpdateIncidentStatusResponses, UpdateIpAccessControlData, UpdateIpAccessControlError, UpdateIpAccessControlErrors, UpdateIpAccessControlRequest, UpdateIpAccessControlResponse, UpdateIpAccessControlResponses, UpdateKvRequest, UpdateKvResponse, UpdateManagedDomainApiRequest, UpdateManagedDomainData, UpdateManagedDomainErrors, UpdateManagedDomainResponse, UpdateManagedDomainResponses, UpdateMcpData, UpdateMcpErrors, UpdateMcpRequest, UpdateMcpResponse, UpdateMcpResponses, UpdateMemberRoleRequest, UpdateMetricAlertRequest, UpdateNotificationEmailProviderData, UpdateNotificationEmailProviderErrors, UpdateNotificationEmailProviderRequest, UpdateNotificationEmailProviderResponse, UpdateNotificationEmailProviderResponses, UpdateNotificationProviderData, UpdateNotificationProviderErrors, UpdateNotificationProviderResponse, UpdateNotificationProviderResponses, UpdateOidcProviderData, UpdateOidcProviderRequest, UpdateOidcProviderResponse, UpdateOidcProviderResponses, UpdatePreferencesData, UpdatePreferencesErrors, UpdatePreferencesRequest, UpdatePreferencesResponse, UpdatePreferencesResponses, UpdateProjectData, UpdateProjectDeploymentConfigData, UpdateProjectDeploymentConfigErrors, UpdateProjectDeploymentConfigResponse, UpdateProjectDeploymentConfigResponses, UpdateProjectErrors, UpdateProjectResponse, UpdateProjectResponses, UpdateProjectSecretData, UpdateProjectSecretErrors, UpdateProjectSecretRequest, UpdateProjectSecretResponse, UpdateProjectSecretResponses, UpdateProjectSettingsData, UpdateProjectSettingsErrors, UpdateProjectSettingsRequest, UpdateProjectSettingsResponse, UpdateProjectSettingsResponses, UpdateProviderCredentialsRequest, UpdateProviderData, UpdateProviderErrors, UpdateProviderKeyData, UpdateProviderKeyError, UpdateProviderKeyErrors, UpdateProviderKeyRequest, UpdateProviderKeyResponse, UpdateProviderKeyResponses, UpdateProviderRequest, UpdateProviderResponse, UpdateProviderResponses, UpdateRouteData, UpdateRouteErrors, UpdateRouteRequest, UpdateRouteResponse, UpdateRouteResponses, UpdateS3SourceData, UpdateS3SourceError, UpdateS3SourceErrors, UpdateS3SourceRequest, UpdateS3SourceResponse, UpdateS3SourceResponses, UpdateSecretBody, UpdateSelfData, UpdateSelfErrors, UpdateSelfRequest, UpdateSelfResponse, UpdateSelfResponses, UpdateServiceData, UpdateServiceErrors, UpdateServiceResourcesData, UpdateServiceResourcesErrors, UpdateServiceResourcesResponse, UpdateServiceResourcesResponses, UpdateServiceResponse, UpdateServiceResponses, UpdateSessionDurationData, UpdateSessionDurationError, UpdateSessionDurationErrors, UpdateSessionDurationRequest, UpdateSessionDurationResponse, UpdateSessionDurationResponse2, UpdateSessionDurationResponses, UpdateSettingsData, UpdateSettingsErrors, UpdateSettingsResponse, UpdateSettingsResponses, UpdateSkillData, UpdateSkillErrors, UpdateSkillRequest, UpdateSkillResponse, UpdateSkillResponses, UpdateSlackProviderData, UpdateSlackProviderErrors, UpdateSlackProviderRequest, UpdateSlackProviderResponse, UpdateSlackProviderResponses, UpdateSpeedMetricsData, UpdateSpeedMetricsError, UpdateSpeedMetricsErrors, UpdateSpeedMetricsPayload, UpdateSpeedMetricsResponse, UpdateSpeedMetricsResponses, UpdateStatusResponse, UpdateTeamData, UpdateTeamErrors, UpdateTeamMemberRoleData, UpdateTeamMemberRoleErrors, UpdateTeamMemberRoleResponse, UpdateTeamMemberRoleResponses, UpdateTeamRequest, UpdateTeamResponse, UpdateTeamResponses, UpdateTokenRequest, UpdateTokenResponse, UpdateUserData, UpdateUserErrors, UpdateUserRequest, UpdateUserResponse, UpdateUserResponses, UpdateWebhookData, UpdateWebhookErrors, UpdateWebhookProviderData, UpdateWebhookProviderErrors, UpdateWebhookProviderRequest, UpdateWebhookProviderResponse, UpdateWebhookProviderResponses, UpdateWebhookRequestBody, UpdateWebhookResponse, UpdateWebhookResponses, UpgradeExternalServiceRequest, UpgradePreviewGatewayData, UpgradePreviewGatewayResponse, UpgradePreviewGatewayResponses, UpgradeRequest, UpgradeServiceData, UpgradeServiceErrors, UpgradeServiceResponse, UpgradeServiceResponses, UploadGlobalSkillData, UploadGlobalSkillErrors, UploadGlobalSkillResponse, UploadGlobalSkillResponses, UploadReleaseFileData, UploadReleaseFileErrors, UploadReleaseFileResponse, UploadReleaseFileResponses, UploadSkillData, UploadSkillErrors, UploadSkillResponse, UploadSkillResponses, UploadSourceFileData, UploadSourceFileErrors, UploadSourceFileResponse, UploadSourceFileResponses, UploadSourceMapData, UploadSourceMapErrors, UploadSourceMapResponse, UploadSourceMapResponses, UploadStaticBundleData, UploadStaticBundleErrors, UploadStaticBundleResponse, UploadStaticBundleResponses, UpsertAgentRequest, UpsertSecretData, UpsertSecretErrors, UpsertSecretRequest, UpsertSecretResponse, UpsertSecretResponses, UptimeDataPoint, UptimeHistoryResponse, UsageFilter, UsageInfo, UsageLogEntry, UsageLogPage, UsageQueryParams, UsageSource, UsageSummary, UserResponse, ValidateConnectionData, ValidateConnectionErrors, ValidateConnectionResponse, ValidateConnectionResponses, ValidateEmailData, ValidateEmailErrors, ValidateEmailRequest, ValidateEmailResponse, ValidateEmailResponse2, ValidateEmailResponses, ValidationLevel, ValidationReport, ValidationResponse, ValidationResult, ValidationStatus, ValidationSummary, VerifyAndEnableMfaData, VerifyAndEnableMfaErrors, VerifyAndEnableMfaResponse, VerifyAndEnableMfaResponses, VerifyDomainData, VerifyDomainErrors, VerifyDomainResponse, VerifyDomainResponses, VerifyEmailData, VerifyEmailErrors, VerifyEmailResponse, VerifyEmailResponses, VerifyManagedDomainData, VerifyManagedDomainErrors, VerifyManagedDomainResponse, VerifyManagedDomainResponses, VerifyMfaChallengeData, VerifyMfaChallengeErrors, VerifyMfaChallengeResponse, VerifyMfaChallengeResponses, VerifyMfaRequest, VerifyStepUpData, VerifyStepUpErrors, VerifyStepUpRequest, VerifyStepUpResponse, VerifyStepUpResponses, ViewItem, ViewsOverTime, ViewsOverTimeQuery, VisitorDetails, VisitorFacets, VisitorFacetsQuery, VisitorFacetValue, VisitorInfo, VisitorJourneyQuery, VisitorJourneyResponse, VisitorLocationsQuery, VisitorRecord, VisitorSegmentFilters, VisitorSessionsQuery, VisitorSessionsResponse, VisitorsListQuery, VisitorsResponse, VisitorStats, VisitorWithGeolocation, VolumeMount, VolumeType, VulnerabilityResponse, WakeEnvironmentData, WakeEnvironmentErrors, WakeEnvironmentResponse, WakeEnvironmentResponses, WalWarning, WalWarningSeverity, WebhookConfig, WebhookDeliveryResponse, WebhookResponse, WebhookTriggerData, WebhookTriggerErrors, WebhookTriggerRequest, WebhookTriggerResponse, WebhookTriggerResponse2, WebhookTriggerResponses, WorkflowDryRunData, WorkflowDryRunErrors, WorkflowDryRunRequest, WorkflowDryRunResponse, WorkflowDryRunResponses, WorkloadDescriptor, WorkloadId, WorkloadStatus, WorkloadType, WriteFileBody, WriteFileData, WriteFileErrors, WriteFileResponse, WriteFileResponses, WriteFilesBody, WriteFilesData, WriteFilesErrors, WriteFilesResponse, WriteFilesResponse2, WriteFilesResponses, ZoneListResponse } from './types.gen'; +export { acknowledgeAlarm, activateAiProvider, activateApiKey, activateConnection, activateProvider, addClusterMember, addContext, addEnvironmentDomain, addEvents, addManagedDomain, addSessionReplayEvents, addTeamMember, adminDrainNode, adminDrainStatus, adminGetNode, adminListNodeContainers, adminListNodes, adminRemoveNode, adminUndrainNode, applyHostnameMode, archiveConversation, archiveFlag, assignRole, attachScheduleServices, blobCopy, blobDelete, blobDisable, blobDownload, blobEnable, blobHead, blobList, blobPut, blobStatus, blobUpdate, cancel, cancelBackup, cancelDeployment, cancelDomainOrder, cancelPgUpgrade, cancelRun, cancelScheduleRun, changePasswordSelf, changeProjectSource, changeRequiredPassword, chatCompletions, checkAnalyticsHasEvents, checkCommitExists, checkDomainStatus, checkExplorerSupport, checkIpBlocked, checkProviderDeletionSafety, chunkUploadOptions, cleanupExpiredBackups, clearPreviewPassword, cliDeviceApprove, cliDeviceDeny, cliDeviceLookup, cliDevicePoll, cliDeviceStart, cliLogout, cmd, cmdKill, cmdLogs, confirmPendingAction, containerMetricsGetHistory, createAgent, createAlert, createAlertRule, createApiKey, createBackupSchedule, createBitbucketProvider, createCloudflareProvider, createConversation, createCustomDomain, createDashboard, createDeploymentToken, createDnsProvider, createDomain, createDsn, createEmailDomain, createEmailProvider, createEnvironment, createEnvironmentVariable, createFlag, createFunnel, createGenericProvider, createGiteaPatProvider, createGithubPatProvider, createGitlabOauthProvider, createGitlabPatProvider, createGitProvider, createGlobalMcp, createGlobalSkill, createIncident, createIpAccessControl, createMcp, createMonitor, createNotificationEmailProvider, createNotificationProvider, createOidcProvider, createOidcRoleMapping, createOrRecreateOrder, createPlan, createPr, createProject, createProjectFromTemplate, createProjectRelease, createProjectSecret, createProviderKey, createRelease, createRoute, createS3Source, createSandbox, createService, createSkill, createSlackProvider, createTeam, createUser, createWebhook, createWebhookProvider, deactivateApiKey, deactivateConnection, deactivateProvider, deleteAgent, deleteAlert, deleteAlertRule, deleteApiKey, deleteBackup, deleteBackupSchedule, deleteConnection, deleteCustomDomain, deleteDashboard, deleteDeploymentToken, deleteDnsProvider, deleteDomain, deleteEmailDomain, deleteEmailProvider, deleteEnvironment, deleteEnvironmentDomain, deleteEnvironmentVariable, deleteExternalImage, deleteFunnel, deleteGitProvider, deleteGlobalMcp, deleteGlobalSkill, deleteIpAccessControl, deleteMcp, deleteMonitor, deleteNotificationProvider, deleteOidcProvider, deleteOidcRoleMapping, deletePreferences, deleteProject, deleteProjectSecret, deleteProviderKey, deleteProviderSafely, deleteReleaseSourceFiles, deleteReleaseSourceMaps, deleteRoute, deleteS3Source, deleteScan, deleteSecret, deleteService, deleteSessionReplay, deleteSkill, deleteSourceMap, deleteStaticBundle, deleteTeam, deleteUser, deleteWebhook, deployFromImage, deployFromImageUpload, deployFromStatic, deployFromUploadedSource, deploymentMetricsGetLatest, deploymentMetricsGetRange, deploymentMetricsToggle, destroySandbox, detachScheduleService, detectPublicPresets, disableBackupSchedule, disableMfa, discoverWorkloads, domain, downloadGlobalSkillArchive, downloadObject, downloadSkillArchive, emailStatus, embeddings, enableBackupSchedule, enrichVisitor, exec, execDetached, executeDeploymentOperation, executeImport, extendTimeout, externalServiceEnablePgStatStatements, externalServiceMetricsByDatabase, externalServiceMetricsCreateAlertRule, externalServiceMetricsDeleteAlertRule, externalServiceMetricsGetAlertRules, externalServiceMetricsGetLatest, externalServiceMetricsGetRange, externalServiceMetricsStatus, externalServiceMetricsToggle, externalServiceMetricsUpdateAlertRule, externalServiceResetPgStatStatements, finalizeOrder, finalizeProjectRelease, findConversation, generateJoinToken, generatePresetDockerfile, getAccessInfo, getActiveVisitors, getActivityGraph, getAdminGate, getAgent, getAggregatedBuckets, getAiAgentBreakdown, getAiAgentPages, getAiAgentTimeline, getAiDataAccess, getAiPageBreakdown, getAiStatusBreakdown, getAlert, getAlertRule, getAllRepositoriesByName, getAnalyticsActiveVisitors, getAnalyticsEventsCount, getAnalyticsSessionEvents, getAnalyticsVisitorSessions, getApiKey, getApiKeyPermissions, getAuditLog, getBackup, getBackupSchedule, getBranchesByRepositoryId, getBucketedIncidents, getBucketedStatus, getChallengeToken, getChatReadiness, getCliStatus, getClusterHealth, getClusterMember, getCmd, getContainerDetail, getContainerEnvironmentVariable, getContainerLogs, getContainerLogsById, getContainerMetrics, getConversation, getConversationDetail, getConversations, getCronById, getCronExecutions, getCrossProjectTraceSiblings, getCurrentMonitorStatus, getCurrentUser, getCustomDomain, getDashboard, getDashboardProjectsAnalytics, getDelivery, getDeployment, getDeploymentContainerLogContent, getDeploymentJobLogs, getDeploymentJobs, getDeploymentOperations, getDeploymentOperationStatus, getDeploymentToken, getDiskStatus, getDnsChanges, getDnsProvider, getDomain, getDomainByHost, getDomainById, getDomainByName, getDomainDnsRecords, getDomainOrder, getEmail, getEmailEvents, getEmailLinks, getEmailProvider, getEmailStats, getEmailTracking, getEmailTrackingStatus, getEntityInfo, getEnvironment, getEnvironmentCrons, getEnvironmentDomains, getEnvironments, getEnvironmentVariables, getEnvironmentVariableValue, getErrorDashboardStats, getErrorEvent, getErrorGroup, getErrorStats, getErrorTimeSeries, getEventDetail, getEventEntries, getEventsCount, getEventsTimeline, getEventTypeBreakdown, getEventVisitors, getExternalImage, getFile, getFlag, getFlagSnapshot, getFunnelMetrics, getGenaiTrace, getGeneralStats, getGitProvider, getGlobalEvents, getGlobalEventStats, getGlobalMcp, getGlobalSandboxStatus, getGlobalSkill, getGroupedPageMetrics, getHealth, getHourlyVisits, getHttpChallengeDebug, getImportStatus, getIncident, getIncidentUpdates, getIpAccessControl, getIpGeolocation, getJoinTokenStatus, getLastDeployment, getLatestScan, getLatestScansPerEnvironment, getLiveVisitorsList, getLogContext, getMcp, getMetricsOverTime, getMonitor, getNotificationProvider, getOnDemandCertStatus, getOrCreateDsn, getPageFlow, getPageHourlySessions, getPagePathDetail, getPagePaths, getPagePathsSparklines, getPagePathVisitors, getPendingAction, getPerformanceMetrics, getPgUpgrade, getPgUpgradeLogs, getPipelineStats, getPlatformInfo, getPostgresWalHealth, getPreferences, getPreviewGatewayLogs, getPreviewGatewaySettings, getPreviewGatewayStatus, getPricing, getPrivateIp, getProject, getProjectAlarmsSummary, getProjectBySlug, getProjectDeployments, getProjects, getProjectServiceEnvironmentVariables, getProjectSessionReplays, getProjectsHealth, getProjectsMonitorHealth, getProjectStatistics, getProjectTemplate, getPropertyBreakdown, getPropertyTimeline, getProviderConnections, getProviderMetadata, getProvidersMetadata, getProxyLogById, getProxyLogByRequestId, getProxyLogs, getPublicBranches, getPublicIp, getPublicRepository, getQueryContainerInfo, getQuota, getRecentActivity, getRemoteExternalImage, getRepositoryBranches, getRepositoryById, getRepositoryByName, getRepositoryPresetByName, getRepositoryPresetLive, getRepositoryTags, getResolvedEnvironmentVariables, getResolvedEnvironmentVariableValue, getRestoreCapabilities, getRestoreRun, getRoute, getRun, getRunWithLogs, getS3Credentials, getS3Source, getSandbox, getSandboxStatus, getScan, getScanByDeployment, getScanVulnerabilities, getService, getServiceBySlug, getServiceEnvironmentVariable, getServiceEnvironmentVariables, getServiceHealthStatus, getServicePreviewEnvironmentVariableNames, getServicePreviewEnvironmentVariablesMasked, getServiceRuntime, getServiceStats, getServiceTypeParameters, getServiceTypes, getSessionDetails, getSessionEvents, getSessionLogs, getSessionReplay, getSessionReplayEvents, getSettings, getSkill, getSlowQueries, getStaticBundle, getStatusOverview, getTagsByRepositoryId, getTeam, getTimeBucketStats, getTodayStats, getTrace, getUnifiedTrace, getUniqueCounts, getUniqueEvents, getUpdateStatus, getUptimeHistory, getUsageByProvider, getUsageRecent, getUsageSummary, getUsageTimeseries, getUsageTopModels, getVisitorByGuid, getVisitorById, getVisitorDetails, getVisitorFacets, getVisitorInfo, getVisitorJourney, getVisitors, getVisitorSessions, getVisitorStats, getWebhook, grantProjectAccess, handleGitProviderOauthCallback, hasAnalyticsEvents, hasErrorGroups, hasPerformanceMetrics, importExternalService, ingestLogs, ingestLogsByPath, ingestMetrics, ingestMetricsByPath, ingestSentryEnvelope, ingestSentryEvent, ingestTraces, ingestTracesByPath, initSessionReplay, inspectDropArchive, jobLogs, jobStatus, killJob, kvDel, kvDisable, kvEnable, kvExpire, kvGet, kvIncr, kvKeys, kvSet, kvStatus, kvTtl, kvUpdate, latestRunForSource, linkCustomDomainToCertificate, linkServiceToProject, listAgentRuns, listAgents, listAiProviders, listAlertRules, listAlerts, listAllConversations, listAllRuns, listApiKeys, listAuditLogs, listAvailableContainers, listBackupAlerts, listBackupChildren, listBackupSchedules, listBackupsForSchedule, listCommitsByRepositoryId, listConnections, listContainers, listContainersAtPath, listConversations, listCustomDomainsForProject, listDashboards, listDeliveries, listDeploymentContainerLogs, listDeploymentTokens, listDnsProviders, listDomains, listDsns, listEmailDomains, listEmailProviders, listEmails, listEnrollmentTokens, listEntities, listErrorEvents, listErrorGroups, listEvents, listEventTypes, listExternalImages, listExternalPlugins, listExternalServiceBackups, listFlags, listFunnels, listGitProviders, listGlobalMcps, listGlobalSkills, listIncidents, listInsights, listIpAccessControl, listJobs, listKnownAiAgents, listManagedDomains, listMcps, listMetricLabelKeys, listMetricLabelValues, listMetricNames, listModels, listMonitors, listNotificationProviders, listOidcProviders, listOidcProviderUsers, listOidcRoleMappings, listOnDemandCerts, listOrders, listPeers, listPendingActions, listPgUpgrades, listPresets, listProjectAccess, listProjectAlarms, listProjectScans, listProjectSecrets, listProjectServices, listProjectTemplates, listProjectTemplateTags, listProviderKeys, listProviderZones, listPublicProviders, listReleaseFiles, listReleases, listRemoteExternalImages, listRepositoriesByConnection, listRepositoriesByProvider, listRestoreRunsForService, listRootContainers, listRoutes, listS3Sources, listSandboxes, listScheduleRunJobs, listScheduleRuns, listScheduleServices, listSecrets, listServiceHealthStatuses, listServiceProjects, listServices, listServiceSchedules, listSkills, listSourceBackups, listSourceFiles, listSourceMaps, listSources, listStaticBundles, listSyncedRepositories, listTeamMembers, listTeamProjects, listTeams, listUsers, listWebhooks, login, logout, lookupDnsARecords, mintEnrollmentToken, mkdir, nodeHeartbeat, nodeMetricsGetRange, observabilityFullEvent, observabilityListEvents, oidcCallback, type Options, patchAdminGate, patchPreviewGatewaySettings, pauseDeployment, pauseSandbox, planRestore, postDnsAck, previewAlert, previewFunnelMetrics, previewHostnameMode, promoteClusterMember, promoteDeployment, provisionDomain, purgeProjectLogs, pushExternalImage, queryData, queryGenaiTraces, queryLogs, queryMetrics, querySpanStats, queryTraces, queryTraceSummaries, readEntityRows, readFile, reAnalyze, recordConsoleEvent, recordEventMetrics, recordFlagExposure, recordSpeedMetrics, refreshRouteTable, regenerateDsn, registerExternalImage, registerNode, reinstallGitlabWebhook, rejectPendingAction, reloadPlugins, removeClusterMember, removeManagedDomain, removeRole, removeTeamMember, renameConversation, renewDomain, requestPasswordReset, resetPassword, resizeSandbox, resolveAlarm, restartContainer, restartPreviewGateway, restartSandbox, restoreFlag, restoreUser, resumeDeployment, resumeSandbox, retryCluster, retryDelivery, retryPgUpgrade, retryRun, revealGlobalMcpConfig, revealMcpConfig, revealNotificationProviderConfig, revealServiceParameter, revenueCreateIntegration, revenueDeleteIntegration, revenueGlobalEvents, revenueImportInvoicesCsv, revenueImportSubscriptionsCsv, revenueListIntegrations, revenueListProviders, revenueMetricsCustomers, revenueMetricsGlobalMrr, revenueMetricsGlobalSummary, revenueMetricsMrr, revenueMetricsSummary, revenueRecentEvents, revenueRotateToken, revenueUpdateConfig, revenueUpdateSecret, revokeDsn, revokeEnrollmentToken, revokeJoinToken, revokeProjectAccess, rollbackPgUpgrade, rollbackToDeployment, rootfsGc, rootfsReport, rotateApiKey, rotateDeploymentToken, runBackupForSource, runConnectionHealthCheck, runExternalServiceBackup, runScheduleNow, sandboxCreatePreviewLink, saveAgentToken, saveAiProviderCredential, searchLogs, sendEmail, setAiDataAccess, setDefaultS3Source, setFlagEnvironment, setPreviewPassword, setupDns, setupDnsChallenge, setupEmailTracking, setupMfa, sleepEnvironment, smokeTestAgent, sourceSandbox, startAnalysis, startContainer, startFix, startGitProviderOauth, startOidcLoginBySlug, startPgUpgrade, startRestore, startService, statPath, stopContainer, stopSandbox, stopService, streamContainerMetrics, streamEvents, streamRunEvents, syncRepositories, tailDeploymentJobLogs, tailLogs, teardownDeployment, teardownEnvironment, terminal, testNotificationProvider, testOidcProvider, testProvider, testProviderConnection, testProviderKeyById, testProviderKeyInline, testS3ConnectionPreview, testS3SourceConnection, trackClick, trackOpen, triggerAgent, triggerProjectPipeline, triggerScan, triggerServiceHealthCheck, triggerWeeklyDigest, unlinkServiceFromProject, updateAgent, updateAiProvider, updateAlert, updateAlertRule, updateApiKey, updateAutomaticDeploy, updateBackupSchedule, updateCloudflareProvider, updateConnectionToken, updateCustomDomain, updateDashboard, updateDeploymentToken, updateEmailProvider, updateEnvironmentSettings, updateEnvironmentSubdomain, updateEnvironmentVariable, updateErrorGroup, updateFlag, updateFunnel, updateGitProviderCredentials, updateGitSettings, updateGlobalMcp, updateGlobalSkill, updateIncidentStatus, updateIpAccessControl, updateManagedDomain, updateMcp, updateNotificationEmailProvider, updateNotificationProvider, updateOidcProvider, updatePreferences, updateProject, updateProjectDeploymentConfig, updateProjectSecret, updateProjectSettings, updateProvider, updateProviderKey, updateRoute, updateS3Source, updateSelf, updateService, updateServiceResources, updateSessionDuration, updateSettings, updateSkill, updateSlackProvider, updateSpeedMetrics, updateTeam, updateTeamMemberRole, updateUser, updateWebhook, updateWebhookProvider, upgradePreviewGateway, upgradeService, uploadGlobalSkill, uploadReleaseFile, uploadSkill, uploadSourceFile, uploadSourceMap, uploadStaticBundle, upsertSecret, validateConnection, validateEmail, verifyAndEnableMfa, verifyDomain, verifyEmail, verifyManagedDomain, verifyMfaChallenge, verifyStepUp, wakeEnvironment, webhookTrigger, workflowDryRun, writeFile, writeFiles } from './sdk.gen'; +export type { AcknowledgeAlarmData, AcknowledgeAlarmErrors, AcknowledgeAlarmResponses, AcmeOrderResponse, ActivateAiProviderData, ActivateAiProviderErrors, ActivateAiProviderResponse, ActivateAiProviderResponses, ActivateApiKeyData, ActivateApiKeyErrors, ActivateApiKeyResponse, ActivateApiKeyResponses, ActivateConnectionData, ActivateConnectionErrors, ActivateConnectionResponses, ActivateProviderData, ActivateProviderErrors, ActivateProviderResponse, ActivateProviderResponses, ActiveVisitor, ActiveVisitorsQuery, ActiveVisitorsResponse, ActivityDay, ActivityEvent, ActivityGraphQuery, ActivityGraphResponse, AddClusterMemberData, AddClusterMemberErrors, AddClusterMemberRequest, AddClusterMemberResponse, AddClusterMemberResponses, AddContextData, AddContextErrors, AddContextRequest, AddContextResponses, AddEnvironmentDomainData, AddEnvironmentDomainErrors, AddEnvironmentDomainRequest, AddEnvironmentDomainResponse, AddEnvironmentDomainResponses, AddEventsData, AddEventsError, AddEventsErrors, AddEventsRequest, AddEventsResponse, AddEventsResponse2, AddEventsResponses, AddManagedDomainApiRequest, AddManagedDomainData, AddManagedDomainErrors, AddManagedDomainResponse, AddManagedDomainResponses, AddSessionReplayEventsData, AddSessionReplayEventsError, AddSessionReplayEventsErrors, AddSessionReplayEventsResponse, AddSessionReplayEventsResponses, AddTeamMemberData, AddTeamMemberErrors, AddTeamMemberResponse, AddTeamMemberResponses, AdminDrainNodeData, AdminDrainNodeErrors, AdminDrainNodeResponse, AdminDrainNodeResponses, AdminDrainStatusData, AdminDrainStatusErrors, AdminDrainStatusResponse, AdminDrainStatusResponses, AdminGateResponse, AdminGateSource, AdminGetNodeData, AdminGetNodeErrors, AdminGetNodeResponse, AdminGetNodeResponses, AdminListNodeContainersData, AdminListNodeContainersErrors, AdminListNodeContainersResponse, AdminListNodeContainersResponses, AdminListNodesData, AdminListNodesErrors, AdminListNodesResponse, AdminListNodesResponses, AdminRemoveNodeData, AdminRemoveNodeErrors, AdminRemoveNodeResponse, AdminRemoveNodeResponses, AdminUndrainNodeData, AdminUndrainNodeErrors, AdminUndrainNodeResponse, AdminUndrainNodeResponses, AgentConfigResponse, AgentRunLogResponse, AgentRunResponse, AgentRunWithLogsResponse, AgentSandboxSettings, AgentSandboxSettingsMasked, AggregatedBucketItem, AggregatedBucketsQuery, AggregatedBucketsResponse, AggregationLevel, AggregationTemporality, AiAgentBreakdownResponse, AiAgentBreakdownRow, AiAgentDescriptor, AiAgentPageRow, AiAgentPagesResponse, AiAgentTimelineResponse, AiAgentTimelineRow, AiChatLimitsSettings, AiConfigSettings, AiDataAccessResponse, AiPageBreakdownResponse, AiPageBreakdownRow, AiStatusBreakdownResponse, AiStatusBreakdownRow, AlarmListResponse, AlarmResponse, AlarmSummaryResponse, AlertRuleResponse, AllocEntry, AnalyticsSessionEventsResponse, AnnotatedSpan, AnomalyAlgorithm, AnomalyParams, AnomalyPreviewPointResponse, AnomalyPreviewRequest, AnomalyPreviewResponse, ApiKeyListResponse, ApiKeyResponse, ApplyHostnameModeData, ApplyHostnameModeErrors, ApplyHostnameModeRequest, ApplyHostnameModeResponse, ApplyHostnameModeResponses, AppSettings, AppSettingsResponse, ArchiveConversationData, ArchiveConversationErrors, ArchiveConversationResponse, ArchiveConversationResponses, ArchiveFlagData, ArchiveFlagErrors, ArchiveFlagResponse, ArchiveFlagResponse2, ArchiveFlagResponses, ArchiveMode, AssignRoleData, AssignRoleErrors, AssignRoleRequest, AssignRoleResponses, AttachScheduleServicesData, AttachScheduleServicesError, AttachScheduleServicesErrors, AttachScheduleServicesRequest, AttachScheduleServicesResponse, AttachScheduleServicesResponse2, AttachScheduleServicesResponses, AuditLogIpInfo, AuditLogResponse, AuditLogUserInfo, AuthFlavorDto, AuthResponse, AuthStatusResponse, AuthTokenResponse, AutofixerRunResponse, AutofixerRunWithLogsResponse, AutofixRunConfig, AutoWatchParams, AvailableContainerInfo, AvailablePermissions, BackupAlertListResponse, BackupAlertResponse, BackupResponse, BackupScheduleResponse, BitbucketAuthInput, BlobCopyData, BlobCopyError, BlobCopyErrors, BlobCopyResponse, BlobCopyResponses, BlobDeleteData, BlobDeleteError, BlobDeleteErrors, BlobDeleteResponse, BlobDeleteResponses, BlobDisableData, BlobDisableErrors, BlobDisableResponse, BlobDisableResponses, BlobDownloadData, BlobDownloadError, BlobDownloadErrors, BlobDownloadResponses, BlobEnableData, BlobEnableErrors, BlobEnableResponse, BlobEnableResponses, BlobHeadData, BlobHeadError, BlobHeadErrors, BlobHeadResponses, BlobListData, BlobListError, BlobListErrors, BlobListResponse, BlobListResponses, BlobPutData, BlobPutError, BlobPutErrors, BlobPutResponse, BlobPutResponses, BlobResponse, BlobStatusData, BlobStatusErrors, BlobStatusResponse, BlobStatusResponse2, BlobStatusResponses, BlobUpdateData, BlobUpdateErrors, BlobUpdateResponse, BlobUpdateResponses, BranchInfo, BranchListResponse, BrowserCount, BrowsersQuery, BuildConfiguration, BuildLimitsSettings, CancelBackupData, CancelBackupError, CancelBackupErrors, CancelBackupResponse, CancelBackupResponse2, CancelBackupResponses, CancelData, CancelDeploymentData, CancelDeploymentErrors, CancelDeploymentResponse, CancelDeploymentResponses, CancelDomainOrderData, CancelDomainOrderErrors, CancelDomainOrderResponse, CancelDomainOrderResponses, CancelErrors, CancelPgUpgradeData, CancelPgUpgradeErrors, CancelPgUpgradeResponse, CancelPgUpgradeResponses, CancelResponses, CancelRunData, CancelRunErrors, CancelRunResponse, CancelRunResponses, CancelScheduleRunData, CancelScheduleRunError, CancelScheduleRunErrors, CancelScheduleRunResponse, CancelScheduleRunResponses, CertStatusResponse, ChallengeConfig, ChallengeError, ChallengeValidationStatus, ChangePasswordRequest, ChangePasswordSelfData, ChangePasswordSelfErrors, ChangePasswordSelfResponse, ChangePasswordSelfResponses, ChangeProjectSourceData, ChangeProjectSourceErrors, ChangeProjectSourceRequest, ChangeProjectSourceResponse, ChangeProjectSourceResponses, ChangeRequiredPasswordData, ChangeRequiredPasswordErrors, ChangeRequiredPasswordResponse, ChangeRequiredPasswordResponses, ChatCompletionChoice, ChatCompletionRequest, ChatCompletionResponse, ChatCompletionsData, ChatCompletionsError, ChatCompletionsErrors, ChatCompletionsResponse, ChatCompletionsResponses, ChatMessage, ChatReadinessResponse, CheckAnalyticsHasEventsData, CheckAnalyticsHasEventsErrors, CheckAnalyticsHasEventsResponse, CheckAnalyticsHasEventsResponses, CheckCommitExistsData, CheckCommitExistsErrors, CheckCommitExistsResponse, CheckCommitExistsResponses, CheckDomainStatusData, CheckDomainStatusErrors, CheckDomainStatusResponse, CheckDomainStatusResponses, CheckExplorerSupportData, CheckExplorerSupportErrors, CheckExplorerSupportResponse, CheckExplorerSupportResponses, CheckIpBlockedData, CheckIpBlockedError, CheckIpBlockedErrors, CheckIpBlockedResponses, CheckProviderDeletionSafetyData, CheckProviderDeletionSafetyErrors, CheckProviderDeletionSafetyResponse, CheckProviderDeletionSafetyResponses, ChildBackupEntryResponse, ChildBackupListResponse, ChunkUploadOptionsData, ChunkUploadOptionsResponse, ChunkUploadOptionsResponses, CleanupExpiredBackupsData, CleanupExpiredBackupsError, CleanupExpiredBackupsErrors, CleanupExpiredBackupsRequest, CleanupExpiredBackupsResponse, CleanupExpiredBackupsResponses, ClearPreviewPasswordData, ClearPreviewPasswordErrors, ClearPreviewPasswordResponse, ClearPreviewPasswordResponses, CliDeviceApproveData, CliDeviceApproveErrors, CliDeviceApproveRequest, CliDeviceApproveResponse, CliDeviceApproveResponse2, CliDeviceApproveResponses, CliDeviceDenyData, CliDeviceDenyErrors, CliDeviceDenyResponse, CliDeviceDenyResponses, CliDeviceLookupData, CliDeviceLookupErrors, CliDeviceLookupResponse, CliDeviceLookupResponse2, CliDeviceLookupResponses, CliDevicePollData, CliDevicePollErrors, CliDevicePollRequest, CliDevicePollResponse, CliDevicePollResponse2, CliDevicePollResponses, CliDeviceStartData, CliDeviceStartErrors, CliDeviceStartRequest, CliDeviceStartResponse, CliDeviceStartResponse2, CliDeviceStartResponses, ClientOptions, CliLoginRequest, CliLogoutData, CliLogoutErrors, CliLogoutResponse, CliLogoutResponses, CloudflareConfig, CloudProvider, ClusterCapacity, ClusterDnsSettings, ClusterHealthReportResponse, ClusterMemberHealthResponse, ClusterMemberRequest, CmdBody, CmdData, CmdErrors, CmdInner, CmdKillBody, CmdKillData, CmdKillErrors, CmdKillResponse, CmdKillResponses, CmdLogsData, CmdLogsErrors, CmdLogsResponses, CmdResponse, CmdResponse2, CmdResponses, CommitExistsResponse, CommitInfo, CommitListResponse, Comparator, ComposePublicPort, ConfirmPendingActionData, ConfirmPendingActionErrors, ConfirmPendingActionResponse, ConfirmPendingActionResponses, ConnectionListQuery, ConnectionListResponse, ConnectionResponse, ConnectionTestResult, ConsoleEventPayload, ContainerActionResponse, ContainerDetailResponse, ContainerEnvironmentVariableValueResponse, ContainerInfoResponse, ContainerInventoryItem, ContainerListResponse, ContainerLogSettings, ContainerLogsQuery, ContainerMetricHistoryPoint, ContainerMetricsGetHistoryData, ContainerMetricsGetHistoryErrors, ContainerMetricsGetHistoryResponse, ContainerMetricsGetHistoryResponses, ContainerMetricsHistoryQuery, ContainerMetricsResponse, ContainerResponse, ContainerRuntimeInfo, ContainerStatsSample, ContentPart, ContextLine, ContextLogsRequest, ContextLogsResponse, ConversationDetailResponse, ConversationResponse, ConversationsQueryParams, ConversationSummary, CopyBlobRequest, CostAnalysis, CreateAgentData, CreateAgentErrors, CreateAgentResponse, CreateAgentResponses, CreateAlertData, CreateAlertError, CreateAlertErrors, CreateAlertResponse, CreateAlertResponses, CreateAlertRuleData, CreateAlertRuleErrors, CreateAlertRuleRequest, CreateAlertRuleResponse, CreateAlertRuleResponses, CreateApiKeyData, CreateApiKeyErrors, CreateApiKeyRequest, CreateApiKeyResponse, CreateApiKeyResponse2, CreateApiKeyResponses, CreateBackupScheduleData, CreateBackupScheduleError, CreateBackupScheduleErrors, CreateBackupScheduleRequest, CreateBackupScheduleResponse, CreateBackupScheduleResponses, CreateBitbucketProviderData, CreateBitbucketProviderErrors, CreateBitbucketProviderResponse, CreateBitbucketProviderResponses, CreateBitbucketRequest, CreateCloudflareProviderData, CreateCloudflareProviderErrors, CreateCloudflareProviderRequest, CreateCloudflareProviderResponse, CreateCloudflareProviderResponses, CreateConversationData, CreateConversationErrors, CreateConversationRequest, CreateConversationResponse, CreateConversationResponses, CreateCustomDomainData, CreateCustomDomainErrors, CreateCustomDomainResponse, CreateCustomDomainResponses, CreateDashboardData, CreateDashboardError, CreateDashboardErrors, CreateDashboardRequest, CreateDashboardResponse, CreateDashboardResponses, CreateDeploymentTokenData, CreateDeploymentTokenErrors, CreateDeploymentTokenRequest, CreateDeploymentTokenResponse, CreateDeploymentTokenResponse2, CreateDeploymentTokenResponses, CreateDnsProviderData, CreateDnsProviderErrors, CreateDnsProviderRequest, CreateDnsProviderResponse, CreateDnsProviderResponses, CreateDomainData, CreateDomainErrors, CreateDomainRequest, CreateDomainResponse, CreateDomainResponses, CreatedResource, CreateDsnData, CreateDsnErrors, CreateDsnRequest, CreateDsnResponse, CreateDsnResponses, CreateEmailDomainData, CreateEmailDomainErrors, CreateEmailDomainRequest, CreateEmailDomainResponse, CreateEmailDomainResponses, CreateEmailProviderData, CreateEmailProviderErrors, CreateEmailProviderRequest, CreateEmailProviderResponse, CreateEmailProviderResponses, CreateEnvironmentData, CreateEnvironmentErrors, CreateEnvironmentRequest, CreateEnvironmentResponse, CreateEnvironmentResponses, CreateEnvironmentVariableData, CreateEnvironmentVariableErrors, CreateEnvironmentVariableRequest, CreateEnvironmentVariableResponse, CreateEnvironmentVariableResponses, CreateExternalServiceRequest, CreateFlagData, CreateFlagErrors, CreateFlagRequest, CreateFlagResponse, CreateFlagResponses, CreateFunnelData, CreateFunnelErrors, CreateFunnelRequest, CreateFunnelResponse, CreateFunnelResponse2, CreateFunnelResponses, CreateFunnelStep, CreateGenericProviderData, CreateGenericProviderErrors, CreateGenericProviderResponse, CreateGenericProviderResponses, CreateGenericRequest, CreateGiteaPatProviderData, CreateGiteaPatProviderErrors, CreateGiteaPatProviderResponse, CreateGiteaPatProviderResponses, CreateGiteaPatRequest, CreateGithubPatProviderData, CreateGithubPatProviderErrors, CreateGithubPatProviderResponse, CreateGithubPatProviderResponses, CreateGitHubPatRequest, CreateGitlabOauthProviderData, CreateGitlabOauthProviderErrors, CreateGitlabOauthProviderResponse, CreateGitlabOauthProviderResponses, CreateGitLabOAuthRequest, CreateGitlabPatProviderData, CreateGitlabPatProviderErrors, CreateGitlabPatProviderResponse, CreateGitlabPatProviderResponses, CreateGitLabPatRequest, CreateGitProviderData, CreateGitProviderErrors, CreateGitProviderResponse, CreateGitProviderResponses, CreateGlobalMcpData, CreateGlobalMcpErrors, CreateGlobalMcpResponse, CreateGlobalMcpResponses, CreateGlobalSkillData, CreateGlobalSkillErrors, CreateGlobalSkillResponse, CreateGlobalSkillResponses, CreateIncidentData, CreateIncidentErrors, CreateIncidentRequest, CreateIncidentResponse, CreateIncidentResponses, CreateIntegrationBody, CreateIpAccessControlData, CreateIpAccessControlError, CreateIpAccessControlErrors, CreateIpAccessControlRequest, CreateIpAccessControlResponse, CreateIpAccessControlResponses, CreateMcpData, CreateMcpErrors, CreateMcpRequest, CreateMcpResponse, CreateMcpResponses, CreateMetricAlertRequest, CreateMonitorData, CreateMonitorErrors, CreateMonitorRequest, CreateMonitorResponse, CreateMonitorResponses, CreateNotificationEmailProviderData, CreateNotificationEmailProviderErrors, CreateNotificationEmailProviderRequest, CreateNotificationEmailProviderResponse, CreateNotificationEmailProviderResponses, CreateNotificationProviderData, CreateNotificationProviderErrors, CreateNotificationProviderResponse, CreateNotificationProviderResponses, CreateOidcProviderData, CreateOidcProviderErrors, CreateOidcProviderRequest, CreateOidcProviderResponse, CreateOidcProviderResponses, CreateOidcRoleMappingData, CreateOidcRoleMappingRequest, CreateOidcRoleMappingResponse, CreateOidcRoleMappingResponses, CreateOrRecreateOrderData, CreateOrRecreateOrderErrors, CreateOrRecreateOrderResponse, CreateOrRecreateOrderResponses, CreatePlanData, CreatePlanErrors, CreatePlanRequest, CreatePlanResponse, CreatePlanResponse2, CreatePlanResponses, CreatePrData, CreatePrErrors, CreateProjectAccessRequest, CreateProjectData, CreateProjectErrors, CreateProjectFromTemplateData, CreateProjectFromTemplateErrors, CreateProjectFromTemplateRequest, CreateProjectFromTemplateResponse, CreateProjectFromTemplateResponse2, CreateProjectFromTemplateResponses, CreateProjectReleaseData, CreateProjectReleaseErrors, CreateProjectReleaseResponse, CreateProjectReleaseResponses, CreateProjectRequest, CreateProjectResponse, CreateProjectResponses, CreateProjectSecretData, CreateProjectSecretErrors, CreateProjectSecretRequest, CreateProjectSecretResponse, CreateProjectSecretResponses, CreateProviderKeyData, CreateProviderKeyError, CreateProviderKeyErrors, CreateProviderKeyRequest, CreateProviderKeyResponse, CreateProviderKeyResponses, CreateProviderRequest, CreatePrResponse, CreatePrResponse2, CreatePrResponses, CreateReleaseData, CreateReleaseErrors, CreateReleaseResponse, CreateReleaseResponses, CreateRouteData, CreateRouteErrors, CreateRouteRequest, CreateRouteResponse, CreateRouteResponses, CreateS3SourceData, CreateS3SourceError, CreateS3SourceErrors, CreateS3SourceRequest, CreateS3SourceResponse, CreateS3SourceResponses, CreateSandboxBody, CreateSandboxData, CreateSandboxErrors, CreateSandboxResponse, CreateSandboxResponses, CreateServiceData, CreateServiceErrors, CreateServiceResponse, CreateServiceResponses, CreateSkillData, CreateSkillErrors, CreateSkillRequest, CreateSkillResponse, CreateSkillResponses, CreateSlackProviderData, CreateSlackProviderErrors, CreateSlackProviderRequest, CreateSlackProviderResponse, CreateSlackProviderResponses, CreateTeamData, CreateTeamErrors, CreateTeamMemberRequest, CreateTeamRequest, CreateTeamResponse, CreateTeamResponses, CreateUserData, CreateUserErrors, CreateUserRequest, CreateUserResponse, CreateUserResponses, CreateWebhookData, CreateWebhookErrors, CreateWebhookProviderData, CreateWebhookProviderErrors, CreateWebhookProviderRequest, CreateWebhookProviderResponse, CreateWebhookProviderResponses, CreateWebhookRequestBody, CreateWebhookResponse, CreateWebhookResponses, CronExecutionInfo, CronInfo, CrossProjectSiblingRef, CrossProjectTraceResponse, CurrentStatusResponse, CustomDomainRequest, CustomDomainResponse, CustomerMovementResponse, DashboardLayout, DashboardProjectsAnalyticsQuery, DashboardProjectsAnalyticsResponse, DashboardSection, DashboardTile, DatabaseMetricsResponse, DatabaseMetricsRow, DataImplication, DataImplicationSeverity, DeactivateApiKeyData, DeactivateApiKeyErrors, DeactivateApiKeyResponse, DeactivateApiKeyResponses, DeactivateConnectionData, DeactivateConnectionErrors, DeactivateConnectionResponses, DeactivateProviderData, DeactivateProviderErrors, DeactivateProviderResponses, DeleteAgentData, DeleteAgentErrors, DeleteAgentResponse, DeleteAgentResponses, DeleteAlertData, DeleteAlertError, DeleteAlertErrors, DeleteAlertResponse, DeleteAlertResponses, DeleteAlertRuleData, DeleteAlertRuleErrors, DeleteAlertRuleResponse, DeleteAlertRuleResponses, DeleteApiKeyData, DeleteApiKeyErrors, DeleteApiKeyResponse, DeleteApiKeyResponses, DeleteBackupData, DeleteBackupError, DeleteBackupErrors, DeleteBackupResponse, DeleteBackupResponses, DeleteBackupScheduleData, DeleteBackupScheduleError, DeleteBackupScheduleErrors, DeleteBackupScheduleResponse, DeleteBackupScheduleResponses, DeleteBlobRequest, DeleteBlobResponse, DeleteConnectionData, DeleteConnectionErrors, DeleteConnectionResponse, DeleteConnectionResponses, DeleteCustomDomainData, DeleteCustomDomainErrors, DeleteCustomDomainResponse, DeleteCustomDomainResponses, DeleteDashboardData, DeleteDashboardError, DeleteDashboardErrors, DeleteDashboardResponse, DeleteDashboardResponses, DeleteDeploymentTokenData, DeleteDeploymentTokenErrors, DeleteDeploymentTokenResponse, DeleteDeploymentTokenResponses, DeleteDnsProviderData, DeleteDnsProviderErrors, DeleteDnsProviderResponse, DeleteDnsProviderResponses, DeleteDomainData, DeleteDomainErrors, DeleteDomainResponse, DeleteDomainResponses, DeleteEmailDomainData, DeleteEmailDomainErrors, DeleteEmailDomainResponse, DeleteEmailDomainResponses, DeleteEmailProviderData, DeleteEmailProviderErrors, DeleteEmailProviderResponse, DeleteEmailProviderResponses, DeleteEnvironmentData, DeleteEnvironmentDomainData, DeleteEnvironmentDomainErrors, DeleteEnvironmentDomainResponse, DeleteEnvironmentDomainResponses, DeleteEnvironmentErrors, DeleteEnvironmentResponse, DeleteEnvironmentResponses, DeleteEnvironmentVariableData, DeleteEnvironmentVariableErrors, DeleteEnvironmentVariableResponse, DeleteEnvironmentVariableResponses, DeleteExternalImageData, DeleteExternalImageErrors, DeleteExternalImageResponse, DeleteExternalImageResponses, DeleteFunnelData, DeleteFunnelErrors, DeleteFunnelResponses, DeleteGitProviderData, DeleteGitProviderErrors, DeleteGitProviderResponse, DeleteGitProviderResponses, DeleteGlobalMcpData, DeleteGlobalMcpErrors, DeleteGlobalMcpResponse, DeleteGlobalMcpResponses, DeleteGlobalSkillData, DeleteGlobalSkillErrors, DeleteGlobalSkillResponse, DeleteGlobalSkillResponses, DeleteIpAccessControlData, DeleteIpAccessControlError, DeleteIpAccessControlErrors, DeleteIpAccessControlResponse, DeleteIpAccessControlResponses, DeleteMcpData, DeleteMcpErrors, DeleteMcpResponse, DeleteMcpResponses, DeleteMonitorData, DeleteMonitorErrors, DeleteMonitorResponse, DeleteMonitorResponses, DeleteNotificationProviderData, DeleteNotificationProviderErrors, DeleteNotificationProviderResponse, DeleteNotificationProviderResponses, DeleteOidcProviderData, DeleteOidcProviderResponse, DeleteOidcProviderResponses, DeleteOidcRoleMappingData, DeleteOidcRoleMappingResponse, DeleteOidcRoleMappingResponses, DeletePreferencesData, DeletePreferencesErrors, DeletePreferencesResponse, DeletePreferencesResponses, DeleteProjectData, DeleteProjectErrors, DeleteProjectResponse, DeleteProjectResponses, DeleteProjectSecretData, DeleteProjectSecretErrors, DeleteProjectSecretResponse, DeleteProjectSecretResponses, DeleteProviderKeyData, DeleteProviderKeyError, DeleteProviderKeyErrors, DeleteProviderKeyResponse, DeleteProviderKeyResponses, DeleteProviderSafelyData, DeleteProviderSafelyErrors, DeleteProviderSafelyResponse, DeleteProviderSafelyResponses, DeleteReleaseSourceFilesData, DeleteReleaseSourceFilesErrors, DeleteReleaseSourceFilesResponse, DeleteReleaseSourceFilesResponses, DeleteReleaseSourceMapsData, DeleteReleaseSourceMapsErrors, DeleteReleaseSourceMapsResponse, DeleteReleaseSourceMapsResponses, DeleteResponse, DeleteRouteData, DeleteRouteErrors, DeleteRouteResponse, DeleteRouteResponses, DeleteS3SourceData, DeleteS3SourceError, DeleteS3SourceErrors, DeleteS3SourceResponse, DeleteS3SourceResponses, DeleteScanData, DeleteScanError, DeleteScanErrors, DeleteScanResponse, DeleteScanResponses, DeleteSecretData, DeleteSecretErrors, DeleteSecretResponse, DeleteSecretResponses, DeleteServiceData, DeleteServiceErrors, DeleteServiceResponse, DeleteServiceResponses, DeleteSessionReplayData, DeleteSessionReplayError, DeleteSessionReplayErrors, DeleteSessionReplayResponses, DeleteSkillData, DeleteSkillErrors, DeleteSkillResponse, DeleteSkillResponses, DeleteSourceMapData, DeleteSourceMapErrors, DeleteSourceMapResponse, DeleteSourceMapResponses, DeleteStaticBundleData, DeleteStaticBundleErrors, DeleteStaticBundleResponse, DeleteStaticBundleResponses, DeleteTeamData, DeleteTeamErrors, DeleteTeamResponse, DeleteTeamResponses, DeleteUserData, DeleteUserErrors, DeleteUserResponse, DeleteUserResponses, DeleteWebhookData, DeleteWebhookErrors, DeleteWebhookResponse, DeleteWebhookResponses, DelRequest, DelResponse, DeployFromImageData, DeployFromImageErrors, DeployFromImageRequest, DeployFromImageResponse, DeployFromImageResponses, DeployFromImageUploadData, DeployFromImageUploadErrors, DeployFromImageUploadQuery, DeployFromImageUploadResponse, DeployFromImageUploadResponses, DeployFromStaticData, DeployFromStaticErrors, DeployFromStaticRequest, DeployFromStaticResponse, DeployFromStaticResponses, DeployFromUploadedSourceData, DeployFromUploadedSourceErrors, DeployFromUploadedSourceResponse, DeployFromUploadedSourceResponses, DeploymentConfig, DeploymentConfigSnapshot, DeploymentConfiguration, DeploymentContainerLogContentResponse, DeploymentContainerLogResponse, DeploymentContainerLogsListResponse, DeploymentEnvironmentResponse, DeploymentJobResponse, DeploymentJobsResponse, DeploymentListResponse, DeploymentMetadata, DeploymentMetricsGetLatestData, DeploymentMetricsGetLatestErrors, DeploymentMetricsGetLatestResponse, DeploymentMetricsGetLatestResponses, DeploymentMetricsGetRangeData, DeploymentMetricsGetRangeErrors, DeploymentMetricsGetRangeResponse, DeploymentMetricsGetRangeResponses, DeploymentMetricsToggleData, DeploymentMetricsToggleErrors, DeploymentMetricsToggleResponses, DeploymentResponse, DeploymentStateResponse, DeploymentStrategy, DeploymentTokenListResponse, DeploymentTokenResponse, DestroySandboxData, DestroySandboxErrors, DestroySandboxResponse, DestroySandboxResponses, DetachScheduleServiceData, DetachScheduleServiceError, DetachScheduleServiceErrors, DetachScheduleServiceResponse, DetachScheduleServiceResponses, DetectionConfig, DetectPublicPresetsData, DetectPublicPresetsErrors, DetectPublicPresetsResponse, DetectPublicPresetsResponses, DeviceCount, DigestSections, Direction, DisableBackupScheduleData, DisableBackupScheduleErrors, DisableBackupScheduleResponse, DisableBackupScheduleResponses, DisableBlobResponse, DisableKvResponse, DisableMfaData, DisableMfaErrors, DisableMfaRequest, DisableMfaResponse, DisableMfaResponses, DiscoverRequest, DiscoverResponse, DiscoverWorkloadsData, DiscoverWorkloadsErrors, DiscoverWorkloadsResponse, DiscoverWorkloadsResponses, DiskInfo, DiskSpaceAlert, DiskSpaceAlertSettings, DiskSpaceCheckResult, DnsAckRequest, DnsAckResponse, DnsChallengeRecordResult, DnsChangesResponse, DnsCompletionResponse, DnsLookupError, DnsLookupRequest, DnsLookupResponse, DnsProviderCredentials, DnsProviderResponse, DnsProviderSettings, DnsProviderSettingsMasked, DnsProviderType, DnsRecord, DnsRecordChange, DnsRecordContent, DnsRecordResponse, DnsRecordSetupResult, DnsRecordStatusResponse, DnsZone, DockerComposePresetConfig, DockerfilePresetConfig, DockerfileVariant, DockerRegistrySettings, DockerRegistrySettingsMasked, DomainAction, DomainChallengeResponse, DomainData, DomainEnvironmentResponse, DomainError, DomainErrors, DomainPlan, DomainResponse, DomainResponse2, DomainResponses, DownloadGlobalSkillArchiveData, DownloadGlobalSkillArchiveErrors, DownloadGlobalSkillArchiveResponse, DownloadGlobalSkillArchiveResponses, DownloadObjectData, DownloadObjectErrors, DownloadObjectResponse, DownloadObjectResponses, DownloadSkillArchiveData, DownloadSkillArchiveErrors, DownloadSkillArchiveResponse, DownloadSkillArchiveResponses, DrainNodeResponse, DrainStatusResponse, DropArchiveUpload, DropInspectionResponse, DropOffPoint, DropPresetCandidate, EmailConfig, EmailDomainResponse, EmailDomainWithDnsResponse, EmailProviderResponse, EmailProviderTypeRoute, EmailRequest, EmailResponse, EmailStatsResponse, EmailStatusData, EmailStatusErrors, EmailStatusResponse, EmailStatusResponse2, EmailStatusResponses, EmailTrackingResponse, EmailTrackingSetupResponse, EmailTrackingStatusResponse, EmbeddingData, EmbeddingInput, EmbeddingRequest, EmbeddingResponse, EmbeddingsData, EmbeddingsError, EmbeddingsErrors, EmbeddingsResponse, EmbeddingsResponses, EmbeddingUsage, EnableBackupScheduleData, EnableBackupScheduleErrors, EnableBackupScheduleResponse, EnableBackupScheduleResponses, EnableBlobRequest, EnableBlobResponse, EnableKvRequest, EnableKvResponse, EnablePgStatStatementsResponse, EndpointDto, EnqueuedJob, EnrichVisitorData, EnrichVisitorErrors, EnrichVisitorRequest, EnrichVisitorResponse, EnrichVisitorResponse2, EnrichVisitorResponses, EnrollmentTokenInfo, EnrollmentTokenListResponse, EntityInfoResponse, EntityResponse, EnvironmentConfiguration, EnvironmentDomainResponse, EnvironmentInfo, EnvironmentResponse, EnvironmentVariable, EnvironmentVariableInfo, EnvironmentVariableResponse, EnvironmentVariableValueResponse, EnvVarInput, EnvVarIntegrationInfo, EnvVarResponse, EnvVarTemplateResponse, ErrorDashboardStatsQuery, ErrorDashboardStatsResponse, ErrorEventResponse, ErrorGroupResponse, ErrorGroupStatsResponse, ErrorResponse, ErrorRow, ErrorTimeSeriesDataResponse, ErrorTimeSeriesQuery, EventActivityBucket, EventBreakdown, EventBrowserStats, EventCount, EventCountryStats, EventDetailQuery, EventDetailResponse, EventEntriesQuery, EventEntriesResponse, EventEntryInfo, EventKind, EventMetricsPayload, EventReferrerStats, EventsCountQuery, EventsResponse, EventTimeline, EventTimelineQuery, EventType, EventTypeBreakdown, EventTypeBreakdownQuery, EventTypeResponse, EventTypesResponse, EventVisitorInfo, EventVisitorsQuery, EventVisitorsResponse, ExecBody, ExecData, ExecDetachedData, ExecDetachedErrors, ExecDetachedResponse, ExecDetachedResponse2, ExecDetachedResponses, ExecErrors, ExecResponse, ExecResponse2, ExecResponses, ExecuteDeploymentOperationData, ExecuteDeploymentOperationErrors, ExecuteDeploymentOperationResponse, ExecuteDeploymentOperationResponses, ExecuteImportData, ExecuteImportErrors, ExecuteImportRequest, ExecuteImportResponse, ExecuteImportResponse2, ExecuteImportResponses, ExecuteOperationRequest, ExpireRequest, ExpireResponse, ExplorerSupportResponse, ExtendTimeoutBody, ExtendTimeoutData, ExtendTimeoutErrors, ExtendTimeoutResponse, ExtendTimeoutResponses, ExternalImageResponse, ExternalServiceBackupResponse, ExternalServiceDetails, ExternalServiceEnablePgStatStatementsData, ExternalServiceEnablePgStatStatementsErrors, ExternalServiceEnablePgStatStatementsResponse, ExternalServiceEnablePgStatStatementsResponses, ExternalServiceInfo, ExternalServiceMetricsByDatabaseData, ExternalServiceMetricsByDatabaseErrors, ExternalServiceMetricsByDatabaseResponse, ExternalServiceMetricsByDatabaseResponses, ExternalServiceMetricsCreateAlertRuleData, ExternalServiceMetricsCreateAlertRuleErrors, ExternalServiceMetricsCreateAlertRuleResponse, ExternalServiceMetricsCreateAlertRuleResponses, ExternalServiceMetricsDeleteAlertRuleData, ExternalServiceMetricsDeleteAlertRuleErrors, ExternalServiceMetricsDeleteAlertRuleResponse, ExternalServiceMetricsDeleteAlertRuleResponses, ExternalServiceMetricsGetAlertRulesData, ExternalServiceMetricsGetAlertRulesErrors, ExternalServiceMetricsGetAlertRulesResponse, ExternalServiceMetricsGetAlertRulesResponses, ExternalServiceMetricsGetLatestData, ExternalServiceMetricsGetLatestErrors, ExternalServiceMetricsGetLatestResponse, ExternalServiceMetricsGetLatestResponses, ExternalServiceMetricsGetRangeData, ExternalServiceMetricsGetRangeErrors, ExternalServiceMetricsGetRangeResponse, ExternalServiceMetricsGetRangeResponses, ExternalServiceMetricsStatusData, ExternalServiceMetricsStatusErrors, ExternalServiceMetricsStatusResponse, ExternalServiceMetricsStatusResponses, ExternalServiceMetricsToggleData, ExternalServiceMetricsToggleErrors, ExternalServiceMetricsToggleResponses, ExternalServiceMetricsUpdateAlertRuleData, ExternalServiceMetricsUpdateAlertRuleErrors, ExternalServiceMetricsUpdateAlertRuleResponse, ExternalServiceMetricsUpdateAlertRuleResponses, ExternalServiceResetPgStatStatementsData, ExternalServiceResetPgStatStatementsErrors, ExternalServiceResetPgStatStatementsResponse, ExternalServiceResetPgStatStatementsResponses, ExternalServiceSummary, FieldResponse, FinalizeOrderData, FinalizeOrderErrors, FinalizeOrderResponse, FinalizeOrderResponses, FinalizeProjectReleaseData, FinalizeProjectReleaseErrors, FinalizeProjectReleaseResponse, FinalizeProjectReleaseResponses, FindConversationData, FindConversationErrors, FindConversationResponse, FindConversationResponses, FiringSeriesEntry, FlagEnvironmentResponse, FlagListResponse, FlagResponse, FlagSnapshot, FlagSnapshotResponse, FlagValueType, ForecastAlgorithm, ForecastParams, FullError, FullEvent, FullRequest, FunnelMetricsResponse, FunnelResponse, GatewayStatus, GenAiEvent, GenAiSpanDetail, GenAiTraceDetailResponse, GenAiTraceSummariesResponse, GenAiTraceSummary, GeneralStatsQuery, GeneralStatsResponse, GenerateDockerfileRequest, GenerateDockerfileResponse, GenerateJoinTokenData, GenerateJoinTokenErrors, GenerateJoinTokenResponse, GenerateJoinTokenResponse2, GenerateJoinTokenResponses, GeneratePresetDockerfileData, GeneratePresetDockerfileErrors, GeneratePresetDockerfileResponse, GeneratePresetDockerfileResponses, GeoLocationResponse, GeoRestrictionsConfig, GetAccessInfoData, GetAccessInfoErrors, GetAccessInfoResponse, GetAccessInfoResponses, GetActiveVisitorsData, GetActiveVisitorsErrors, GetActiveVisitorsResponse, GetActiveVisitorsResponses, GetActivityGraphData, GetActivityGraphErrors, GetActivityGraphResponse, GetActivityGraphResponses, GetAdminGateData, GetAdminGateErrors, GetAdminGateResponse, GetAdminGateResponses, GetAgentData, GetAgentErrors, GetAgentResponse, GetAgentResponses, GetAggregatedBucketsData, GetAggregatedBucketsErrors, GetAggregatedBucketsResponse, GetAggregatedBucketsResponses, GetAiAgentBreakdownData, GetAiAgentBreakdownError, GetAiAgentBreakdownErrors, GetAiAgentBreakdownResponse, GetAiAgentBreakdownResponses, GetAiAgentPagesData, GetAiAgentPagesError, GetAiAgentPagesErrors, GetAiAgentPagesResponse, GetAiAgentPagesResponses, GetAiAgentTimelineData, GetAiAgentTimelineError, GetAiAgentTimelineErrors, GetAiAgentTimelineResponse, GetAiAgentTimelineResponses, GetAiDataAccessData, GetAiDataAccessErrors, GetAiDataAccessResponse, GetAiDataAccessResponses, GetAiPageBreakdownData, GetAiPageBreakdownError, GetAiPageBreakdownErrors, GetAiPageBreakdownResponse, GetAiPageBreakdownResponses, GetAiStatusBreakdownData, GetAiStatusBreakdownError, GetAiStatusBreakdownErrors, GetAiStatusBreakdownResponse, GetAiStatusBreakdownResponses, GetAlertData, GetAlertError, GetAlertErrors, GetAlertResponse, GetAlertResponses, GetAlertRuleData, GetAlertRuleErrors, GetAlertRuleResponse, GetAlertRuleResponses, GetAllRepositoriesByNameData, GetAllRepositoriesByNameErrors, GetAllRepositoriesByNameResponse, GetAllRepositoriesByNameResponses, GetAnalyticsActiveVisitorsData, GetAnalyticsActiveVisitorsErrors, GetAnalyticsActiveVisitorsResponse, GetAnalyticsActiveVisitorsResponses, GetAnalyticsEventsCountData, GetAnalyticsEventsCountErrors, GetAnalyticsEventsCountResponse, GetAnalyticsEventsCountResponses, GetAnalyticsSessionEventsData, GetAnalyticsSessionEventsErrors, GetAnalyticsSessionEventsResponse, GetAnalyticsSessionEventsResponses, GetAnalyticsVisitorSessionsData, GetAnalyticsVisitorSessionsErrors, GetAnalyticsVisitorSessionsResponse, GetAnalyticsVisitorSessionsResponses, GetApiKeyData, GetApiKeyErrors, GetApiKeyPermissionsData, GetApiKeyPermissionsErrors, GetApiKeyPermissionsResponse, GetApiKeyPermissionsResponses, GetApiKeyResponse, GetApiKeyResponses, GetAuditLogData, GetAuditLogErrors, GetAuditLogResponse, GetAuditLogResponses, GetBackupData, GetBackupError, GetBackupErrors, GetBackupResponse, GetBackupResponses, GetBackupScheduleData, GetBackupScheduleErrors, GetBackupScheduleResponse, GetBackupScheduleResponses, GetBranchesByRepositoryIdData, GetBranchesByRepositoryIdErrors, GetBranchesByRepositoryIdResponse, GetBranchesByRepositoryIdResponses, GetBucketedIncidentsData, GetBucketedIncidentsErrors, GetBucketedIncidentsResponse, GetBucketedIncidentsResponses, GetBucketedStatusData, GetBucketedStatusErrors, GetBucketedStatusResponse, GetBucketedStatusResponses, GetChallengeTokenData, GetChallengeTokenErrors, GetChallengeTokenResponse, GetChallengeTokenResponses, GetChatReadinessData, GetChatReadinessErrors, GetChatReadinessResponse, GetChatReadinessResponses, GetCliStatusData, GetCliStatusErrors, GetCliStatusResponses, GetClusterHealthData, GetClusterHealthErrors, GetClusterHealthResponse, GetClusterHealthResponses, GetClusterMemberData, GetClusterMemberErrors, GetClusterMemberResponse, GetClusterMemberResponses, GetCmdData, GetCmdErrors, GetCmdResponse, GetCmdResponses, GetContainerDetailData, GetContainerDetailErrors, GetContainerDetailResponse, GetContainerDetailResponses, GetContainerEnvironmentVariableData, GetContainerEnvironmentVariableErrors, GetContainerEnvironmentVariableResponse, GetContainerEnvironmentVariableResponses, GetContainerLogsByIdData, GetContainerLogsByIdErrors, GetContainerLogsData, GetContainerLogsErrors, GetContainerMetricsData, GetContainerMetricsErrors, GetContainerMetricsResponse, GetContainerMetricsResponses, GetConversationData, GetConversationDetailData, GetConversationDetailError, GetConversationDetailErrors, GetConversationDetailResponse, GetConversationDetailResponses, GetConversationErrors, GetConversationResponse, GetConversationResponses, GetConversationsData, GetConversationsError, GetConversationsErrors, GetConversationsResponse, GetConversationsResponses, GetCronByIdData, GetCronByIdErrors, GetCronByIdResponse, GetCronByIdResponses, GetCronExecutionsData, GetCronExecutionsErrors, GetCronExecutionsResponse, GetCronExecutionsResponses, GetCrossProjectTraceSiblingsData, GetCrossProjectTraceSiblingsError, GetCrossProjectTraceSiblingsErrors, GetCrossProjectTraceSiblingsResponse, GetCrossProjectTraceSiblingsResponses, GetCurrentMonitorStatusData, GetCurrentMonitorStatusErrors, GetCurrentMonitorStatusResponse, GetCurrentMonitorStatusResponses, GetCurrentUserData, GetCurrentUserErrors, GetCurrentUserResponse, GetCurrentUserResponses, GetCustomDomainData, GetCustomDomainErrors, GetCustomDomainResponse, GetCustomDomainResponses, GetDashboardData, GetDashboardError, GetDashboardErrors, GetDashboardProjectsAnalyticsData, GetDashboardProjectsAnalyticsErrors, GetDashboardProjectsAnalyticsResponse, GetDashboardProjectsAnalyticsResponses, GetDashboardResponse, GetDashboardResponses, GetDeliveryData, GetDeliveryErrors, GetDeliveryResponse, GetDeliveryResponses, GetDeploymentContainerLogContentData, GetDeploymentContainerLogContentErrors, GetDeploymentContainerLogContentResponse, GetDeploymentContainerLogContentResponses, GetDeploymentData, GetDeploymentErrors, GetDeploymentJobLogsData, GetDeploymentJobLogsErrors, GetDeploymentJobLogsResponse, GetDeploymentJobLogsResponses, GetDeploymentJobsData, GetDeploymentJobsErrors, GetDeploymentJobsResponse, GetDeploymentJobsResponses, GetDeploymentOperationsData, GetDeploymentOperationsErrors, GetDeploymentOperationsResponse, GetDeploymentOperationsResponses, GetDeploymentOperationStatusData, GetDeploymentOperationStatusErrors, GetDeploymentOperationStatusResponse, GetDeploymentOperationStatusResponses, GetDeploymentResponse, GetDeploymentResponses, GetDeploymentsParams, GetDeploymentTokenData, GetDeploymentTokenErrors, GetDeploymentTokenResponse, GetDeploymentTokenResponses, GetDiskStatusData, GetDiskStatusErrors, GetDiskStatusResponse, GetDiskStatusResponses, GetDnsChangesData, GetDnsChangesErrors, GetDnsChangesResponse, GetDnsChangesResponses, GetDnsProviderData, GetDnsProviderErrors, GetDnsProviderResponse, GetDnsProviderResponses, GetDomainByHostData, GetDomainByHostErrors, GetDomainByHostResponse, GetDomainByHostResponses, GetDomainByIdData, GetDomainByIdErrors, GetDomainByIdResponse, GetDomainByIdResponses, GetDomainByNameData, GetDomainByNameErrors, GetDomainByNameResponse, GetDomainByNameResponses, GetDomainData, GetDomainDnsRecordsData, GetDomainDnsRecordsErrors, GetDomainDnsRecordsResponse, GetDomainDnsRecordsResponses, GetDomainErrors, GetDomainOrderData, GetDomainOrderErrors, GetDomainOrderResponse, GetDomainOrderResponses, GetDomainResponse, GetDomainResponses, GetEmailData, GetEmailErrors, GetEmailEventsData, GetEmailEventsErrors, GetEmailEventsResponse, GetEmailEventsResponses, GetEmailLinksData, GetEmailLinksErrors, GetEmailLinksResponse, GetEmailLinksResponses, GetEmailProviderData, GetEmailProviderErrors, GetEmailProviderResponse, GetEmailProviderResponses, GetEmailResponse, GetEmailResponses, GetEmailStatsData, GetEmailStatsErrors, GetEmailStatsResponse, GetEmailStatsResponses, GetEmailTrackingData, GetEmailTrackingErrors, GetEmailTrackingResponse, GetEmailTrackingResponses, GetEmailTrackingStatusData, GetEmailTrackingStatusErrors, GetEmailTrackingStatusResponse, GetEmailTrackingStatusResponses, GetEntityInfoData, GetEntityInfoErrors, GetEntityInfoResponse, GetEntityInfoResponses, GetEnvironmentCronsData, GetEnvironmentCronsErrors, GetEnvironmentCronsResponse, GetEnvironmentCronsResponses, GetEnvironmentData, GetEnvironmentDomainsData, GetEnvironmentDomainsErrors, GetEnvironmentDomainsResponse, GetEnvironmentDomainsResponses, GetEnvironmentErrors, GetEnvironmentResponse, GetEnvironmentResponses, GetEnvironmentsData, GetEnvironmentsErrors, GetEnvironmentsResponse, GetEnvironmentsResponses, GetEnvironmentVariablesData, GetEnvironmentVariablesErrors, GetEnvironmentVariablesQuery, GetEnvironmentVariablesResponse, GetEnvironmentVariablesResponses, GetEnvironmentVariableValueData, GetEnvironmentVariableValueErrors, GetEnvironmentVariableValueResponse, GetEnvironmentVariableValueResponses, GetErrorDashboardStatsData, GetErrorDashboardStatsErrors, GetErrorDashboardStatsResponse, GetErrorDashboardStatsResponses, GetErrorEventData, GetErrorEventErrors, GetErrorEventResponse, GetErrorEventResponses, GetErrorGroupData, GetErrorGroupErrors, GetErrorGroupResponse, GetErrorGroupResponses, GetErrorStatsData, GetErrorStatsErrors, GetErrorStatsResponse, GetErrorStatsResponses, GetErrorTimeSeriesData, GetErrorTimeSeriesErrors, GetErrorTimeSeriesResponse, GetErrorTimeSeriesResponses, GetEventDetailData, GetEventDetailErrors, GetEventDetailResponse, GetEventDetailResponses, GetEventEntriesData, GetEventEntriesErrors, GetEventEntriesResponse, GetEventEntriesResponses, GetEventsCountData, GetEventsCountErrors, GetEventsCountResponse, GetEventsCountResponses, GetEventsTimelineData, GetEventsTimelineErrors, GetEventsTimelineResponse, GetEventsTimelineResponses, GetEventTypeBreakdownData, GetEventTypeBreakdownErrors, GetEventTypeBreakdownResponse, GetEventTypeBreakdownResponses, GetEventVisitorsData, GetEventVisitorsErrors, GetEventVisitorsResponse, GetEventVisitorsResponses, GetExternalImageData, GetExternalImageErrors, GetExternalImageResponse, GetExternalImageResponses, GetFileData, GetFileErrors, GetFileResponse, GetFileResponses, GetFlagData, GetFlagErrors, GetFlagResponse, GetFlagResponses, GetFlagSnapshotData, GetFlagSnapshotErrors, GetFlagSnapshotResponse, GetFlagSnapshotResponses, GetFunnelMetricsData, GetFunnelMetricsErrors, GetFunnelMetricsQuery, GetFunnelMetricsResponse, GetFunnelMetricsResponses, GetGenaiTraceData, GetGenaiTraceError, GetGenaiTraceErrors, GetGenaiTraceResponse, GetGenaiTraceResponses, GetGeneralStatsData, GetGeneralStatsErrors, GetGeneralStatsResponse, GetGeneralStatsResponses, GetGitProviderData, GetGitProviderErrors, GetGitProviderResponse, GetGitProviderResponses, GetGlobalEventsData, GetGlobalEventsErrors, GetGlobalEventsResponse, GetGlobalEventsResponses, GetGlobalEventStatsData, GetGlobalEventStatsErrors, GetGlobalEventStatsResponse, GetGlobalEventStatsResponses, GetGlobalMcpData, GetGlobalMcpErrors, GetGlobalMcpResponse, GetGlobalMcpResponses, GetGlobalSandboxStatusData, GetGlobalSandboxStatusErrors, GetGlobalSandboxStatusResponse, GetGlobalSandboxStatusResponses, GetGlobalSkillData, GetGlobalSkillErrors, GetGlobalSkillResponse, GetGlobalSkillResponses, GetGroupedPageMetricsData, GetGroupedPageMetricsError, GetGroupedPageMetricsErrors, GetGroupedPageMetricsResponse, GetGroupedPageMetricsResponses, GetHealthData, GetHealthError, GetHealthErrors, GetHealthResponse, GetHealthResponses, GetHourlyVisitsData, GetHourlyVisitsErrors, GetHourlyVisitsResponse, GetHourlyVisitsResponses, GetHttpChallengeDebugData, GetHttpChallengeDebugErrors, GetHttpChallengeDebugResponse, GetHttpChallengeDebugResponses, GetImportStatusData, GetImportStatusErrors, GetImportStatusResponse, GetImportStatusResponses, GetIncidentData, GetIncidentErrors, GetIncidentResponse, GetIncidentResponses, GetIncidentUpdatesData, GetIncidentUpdatesErrors, GetIncidentUpdatesResponse, GetIncidentUpdatesResponses, GetIpAccessControlData, GetIpAccessControlError, GetIpAccessControlErrors, GetIpAccessControlResponse, GetIpAccessControlResponses, GetIpGeolocationData, GetIpGeolocationError, GetIpGeolocationErrors, GetIpGeolocationResponse, GetIpGeolocationResponses, GetJoinTokenStatusData, GetJoinTokenStatusErrors, GetJoinTokenStatusResponse, GetJoinTokenStatusResponses, GetLastDeploymentData, GetLastDeploymentErrors, GetLastDeploymentResponse, GetLastDeploymentResponses, GetLatestScanData, GetLatestScanError, GetLatestScanErrors, GetLatestScanResponse, GetLatestScanResponses, GetLatestScansPerEnvironmentData, GetLatestScansPerEnvironmentError, GetLatestScansPerEnvironmentErrors, GetLatestScansPerEnvironmentResponse, GetLatestScansPerEnvironmentResponses, GetLiveVisitorsListData, GetLiveVisitorsListErrors, GetLiveVisitorsListResponse, GetLiveVisitorsListResponses, GetLogContextData, GetLogContextError, GetLogContextErrors, GetLogContextResponse, GetLogContextResponses, GetMcpData, GetMcpErrors, GetMcpResponse, GetMcpResponses, GetMetricsOverTimeData, GetMetricsOverTimeError, GetMetricsOverTimeErrors, GetMetricsOverTimeResponse, GetMetricsOverTimeResponses, GetMonitorData, GetMonitorErrors, GetMonitorResponse, GetMonitorResponses, GetNotificationProviderData, GetNotificationProviderErrors, GetNotificationProviderResponse, GetNotificationProviderResponses, GetOnDemandCertStatusData, GetOnDemandCertStatusErrors, GetOnDemandCertStatusResponse, GetOnDemandCertStatusResponses, GetOrCreateDsnData, GetOrCreateDsnErrors, GetOrCreateDsnRequest, GetOrCreateDsnResponse, GetOrCreateDsnResponses, GetPageFlowData, GetPageFlowErrors, GetPageFlowResponse, GetPageFlowResponses, GetPageHourlySessionsData, GetPageHourlySessionsErrors, GetPageHourlySessionsResponse, GetPageHourlySessionsResponses, GetPagePathDetailData, GetPagePathDetailErrors, GetPagePathDetailResponse, GetPagePathDetailResponses, GetPagePathsData, GetPagePathsErrors, GetPagePathsResponse, GetPagePathsResponses, GetPagePathsSparklinesData, GetPagePathsSparklinesErrors, GetPagePathsSparklinesResponse, GetPagePathsSparklinesResponses, GetPagePathVisitorsData, GetPagePathVisitorsErrors, GetPagePathVisitorsResponse, GetPagePathVisitorsResponses, GetPendingActionData, GetPendingActionErrors, GetPendingActionResponse, GetPendingActionResponses, GetPerformanceMetricsData, GetPerformanceMetricsError, GetPerformanceMetricsErrors, GetPerformanceMetricsResponse, GetPerformanceMetricsResponses, GetPgUpgradeData, GetPgUpgradeErrors, GetPgUpgradeLogsData, GetPgUpgradeLogsErrors, GetPgUpgradeLogsResponse, GetPgUpgradeLogsResponses, GetPgUpgradeResponse, GetPgUpgradeResponses, GetPipelineStatsData, GetPipelineStatsError, GetPipelineStatsErrors, GetPipelineStatsResponse, GetPipelineStatsResponses, GetPlatformInfoData, GetPlatformInfoErrors, GetPlatformInfoResponse, GetPlatformInfoResponses, GetPostgresWalHealthData, GetPostgresWalHealthErrors, GetPostgresWalHealthResponse, GetPostgresWalHealthResponses, GetPreferencesData, GetPreferencesErrors, GetPreferencesResponse, GetPreferencesResponses, GetPreviewGatewayLogsData, GetPreviewGatewayLogsResponse, GetPreviewGatewayLogsResponses, GetPreviewGatewaySettingsData, GetPreviewGatewaySettingsResponse, GetPreviewGatewaySettingsResponses, GetPreviewGatewayStatusData, GetPreviewGatewayStatusResponse, GetPreviewGatewayStatusResponses, GetPricingData, GetPricingError, GetPricingErrors, GetPricingResponse, GetPricingResponses, GetPrivateIpData, GetPrivateIpErrors, GetPrivateIpResponses, GetProjectAlarmsSummaryData, GetProjectAlarmsSummaryErrors, GetProjectAlarmsSummaryResponse, GetProjectAlarmsSummaryResponses, GetProjectBySlugData, GetProjectBySlugErrors, GetProjectBySlugResponse, GetProjectBySlugResponses, GetProjectData, GetProjectDeploymentsData, GetProjectDeploymentsErrors, GetProjectDeploymentsResponse, GetProjectDeploymentsResponses, GetProjectErrors, GetProjectResponse, GetProjectResponses, GetProjectsData, GetProjectSecretsQuery, GetProjectsErrors, GetProjectServiceEnvironmentVariablesData, GetProjectServiceEnvironmentVariablesErrors, GetProjectServiceEnvironmentVariablesResponse, GetProjectServiceEnvironmentVariablesResponses, GetProjectSessionReplaysData, GetProjectSessionReplaysError, GetProjectSessionReplaysErrors, GetProjectSessionReplaysQuery, GetProjectSessionReplaysResponse, GetProjectSessionReplaysResponse2, GetProjectSessionReplaysResponses, GetProjectsHealthData, GetProjectsHealthError, GetProjectsHealthErrors, GetProjectsHealthResponse, GetProjectsHealthResponses, GetProjectsMonitorHealthData, GetProjectsMonitorHealthErrors, GetProjectsMonitorHealthResponse, GetProjectsMonitorHealthResponses, GetProjectsResponse, GetProjectsResponses, GetProjectStatisticsData, GetProjectStatisticsErrors, GetProjectStatisticsResponse, GetProjectStatisticsResponses, GetProjectTemplateData, GetProjectTemplateErrors, GetProjectTemplateResponse, GetProjectTemplateResponses, GetPropertyBreakdownData, GetPropertyBreakdownErrors, GetPropertyBreakdownResponse, GetPropertyBreakdownResponses, GetPropertyTimelineData, GetPropertyTimelineErrors, GetPropertyTimelineResponse, GetPropertyTimelineResponses, GetProviderConnectionsData, GetProviderConnectionsErrors, GetProviderConnectionsResponse, GetProviderConnectionsResponses, GetProviderMetadataData, GetProviderMetadataErrors, GetProviderMetadataResponse, GetProviderMetadataResponses, GetProvidersMetadataData, GetProvidersMetadataErrors, GetProvidersMetadataResponse, GetProvidersMetadataResponses, GetProxyLogByIdData, GetProxyLogByIdError, GetProxyLogByIdErrors, GetProxyLogByIdResponse, GetProxyLogByIdResponses, GetProxyLogByRequestIdData, GetProxyLogByRequestIdError, GetProxyLogByRequestIdErrors, GetProxyLogByRequestIdResponse, GetProxyLogByRequestIdResponses, GetProxyLogsData, GetProxyLogsError, GetProxyLogsErrors, GetProxyLogsResponse, GetProxyLogsResponses, GetPublicBranchesData, GetPublicBranchesErrors, GetPublicBranchesResponse, GetPublicBranchesResponses, GetPublicIpData, GetPublicIpErrors, GetPublicIpResponses, GetPublicRepositoryData, GetPublicRepositoryErrors, GetPublicRepositoryResponse, GetPublicRepositoryResponses, GetQueryContainerInfoData, GetQueryContainerInfoErrors, GetQueryContainerInfoResponse, GetQueryContainerInfoResponses, GetQuotaData, GetQuotaError, GetQuotaErrors, GetQuotaResponse, GetQuotaResponses, GetRecentActivityData, GetRecentActivityErrors, GetRecentActivityResponse, GetRecentActivityResponses, GetRemoteExternalImageData, GetRemoteExternalImageErrors, GetRemoteExternalImageResponse, GetRemoteExternalImageResponses, GetRepositoryBranchesData, GetRepositoryBranchesErrors, GetRepositoryBranchesResponse, GetRepositoryBranchesResponses, GetRepositoryByIdData, GetRepositoryByIdErrors, GetRepositoryByIdResponse, GetRepositoryByIdResponses, GetRepositoryByNameData, GetRepositoryByNameErrors, GetRepositoryByNameResponse, GetRepositoryByNameResponses, GetRepositoryPresetByNameData, GetRepositoryPresetByNameErrors, GetRepositoryPresetByNameResponse, GetRepositoryPresetByNameResponses, GetRepositoryPresetLiveData, GetRepositoryPresetLiveErrors, GetRepositoryPresetLiveResponse, GetRepositoryPresetLiveResponses, GetRepositoryTagsData, GetRepositoryTagsErrors, GetRepositoryTagsResponse, GetRepositoryTagsResponses, GetRequest, GetResolvedEnvironmentVariablesData, GetResolvedEnvironmentVariablesErrors, GetResolvedEnvironmentVariablesResponse, GetResolvedEnvironmentVariablesResponses, GetResolvedEnvironmentVariableValueData, GetResolvedEnvironmentVariableValueErrors, GetResolvedEnvironmentVariableValueResponse, GetResolvedEnvironmentVariableValueResponses, GetResponse, GetRestoreCapabilitiesData, GetRestoreCapabilitiesError, GetRestoreCapabilitiesErrors, GetRestoreCapabilitiesResponse, GetRestoreCapabilitiesResponses, GetRestoreRunData, GetRestoreRunError, GetRestoreRunErrors, GetRestoreRunResponse, GetRestoreRunResponses, GetRouteData, GetRouteErrors, GetRouteResponse, GetRouteResponses, GetRunData, GetRunErrors, GetRunResponse, GetRunResponses, GetRunWithLogsData, GetRunWithLogsErrors, GetRunWithLogsResponse, GetRunWithLogsResponses, GetS3CredentialsData, GetS3CredentialsErrors, GetS3CredentialsResponse, GetS3CredentialsResponses, GetS3SourceData, GetS3SourceError, GetS3SourceErrors, GetS3SourceResponse, GetS3SourceResponses, GetSandboxData, GetSandboxErrors, GetSandboxResponse, GetSandboxResponses, GetSandboxStatusData, GetSandboxStatusErrors, GetSandboxStatusResponse, GetSandboxStatusResponses, GetScanByDeploymentData, GetScanByDeploymentError, GetScanByDeploymentErrors, GetScanByDeploymentResponse, GetScanByDeploymentResponses, GetScanData, GetScanError, GetScanErrors, GetScanResponse, GetScanResponses, GetScanVulnerabilitiesData, GetScanVulnerabilitiesError, GetScanVulnerabilitiesErrors, GetScanVulnerabilitiesResponse, GetScanVulnerabilitiesResponses, GetServiceBySlugData, GetServiceBySlugErrors, GetServiceBySlugResponse, GetServiceBySlugResponses, GetServiceData, GetServiceEnvironmentVariableData, GetServiceEnvironmentVariableErrors, GetServiceEnvironmentVariableResponse, GetServiceEnvironmentVariableResponses, GetServiceEnvironmentVariablesData, GetServiceEnvironmentVariablesErrors, GetServiceEnvironmentVariablesResponse, GetServiceEnvironmentVariablesResponses, GetServiceErrors, GetServiceHealthStatusData, GetServiceHealthStatusErrors, GetServiceHealthStatusResponse, GetServiceHealthStatusResponses, GetServicePreviewEnvironmentVariableNamesData, GetServicePreviewEnvironmentVariableNamesErrors, GetServicePreviewEnvironmentVariableNamesResponse, GetServicePreviewEnvironmentVariableNamesResponses, GetServicePreviewEnvironmentVariablesMaskedData, GetServicePreviewEnvironmentVariablesMaskedErrors, GetServicePreviewEnvironmentVariablesMaskedResponse, GetServicePreviewEnvironmentVariablesMaskedResponses, GetServiceResponse, GetServiceResponses, GetServiceRuntimeData, GetServiceRuntimeErrors, GetServiceRuntimeResponse, GetServiceRuntimeResponses, GetServiceStatsData, GetServiceStatsErrors, GetServiceStatsResponse, GetServiceStatsResponses, GetServiceTypeParametersData, GetServiceTypeParametersErrors, GetServiceTypeParametersResponses, GetServiceTypesData, GetServiceTypesErrors, GetServiceTypesResponse, GetServiceTypesResponses, GetSessionDetailsData, GetSessionDetailsErrors, GetSessionDetailsResponse, GetSessionDetailsResponses, GetSessionEventsData, GetSessionEventsErrors, GetSessionEventsResponse, GetSessionEventsResponses, GetSessionLogsData, GetSessionLogsErrors, GetSessionLogsResponse, GetSessionLogsResponses, GetSessionReplayData, GetSessionReplayError, GetSessionReplayErrors, GetSessionReplayEventsData, GetSessionReplayEventsError, GetSessionReplayEventsErrors, GetSessionReplayEventsResponse, GetSessionReplayEventsResponses, GetSessionReplayResponse, GetSessionReplayResponse2, GetSessionReplayResponses, GetSettingsData, GetSettingsErrors, GetSettingsResponse, GetSettingsResponses, GetSkillData, GetSkillErrors, GetSkillResponse, GetSkillResponses, GetSlowQueriesData, GetSlowQueriesErrors, GetSlowQueriesResponse, GetSlowQueriesResponses, GetStaticBundleData, GetStaticBundleErrors, GetStaticBundleResponse, GetStaticBundleResponses, GetStatusOverviewData, GetStatusOverviewErrors, GetStatusOverviewResponse, GetStatusOverviewResponses, GetTagsByRepositoryIdData, GetTagsByRepositoryIdErrors, GetTagsByRepositoryIdResponse, GetTagsByRepositoryIdResponses, GetTeamData, GetTeamErrors, GetTeamResponse, GetTeamResponses, GetTimeBucketStatsData, GetTimeBucketStatsError, GetTimeBucketStatsErrors, GetTimeBucketStatsResponse, GetTimeBucketStatsResponses, GetTodayStatsData, GetTodayStatsError, GetTodayStatsErrors, GetTodayStatsResponse, GetTodayStatsResponses, GetTraceData, GetTraceError, GetTraceErrors, GetTraceResponse, GetTraceResponses, GetUnifiedTraceData, GetUnifiedTraceError, GetUnifiedTraceErrors, GetUnifiedTraceResponse, GetUnifiedTraceResponses, GetUniqueCountsData, GetUniqueCountsErrors, GetUniqueCountsResponse, GetUniqueCountsResponses, GetUniqueEventsData, GetUniqueEventsErrors, GetUniqueEventsQuery, GetUniqueEventsResponse, GetUniqueEventsResponses, GetUpdateStatusData, GetUpdateStatusErrors, GetUpdateStatusResponse, GetUpdateStatusResponses, GetUptimeHistoryData, GetUptimeHistoryErrors, GetUptimeHistoryResponse, GetUptimeHistoryResponses, GetUsageByProviderData, GetUsageByProviderError, GetUsageByProviderErrors, GetUsageByProviderResponse, GetUsageByProviderResponses, GetUsageRecentData, GetUsageRecentError, GetUsageRecentErrors, GetUsageRecentResponse, GetUsageRecentResponses, GetUsageSummaryData, GetUsageSummaryError, GetUsageSummaryErrors, GetUsageSummaryResponse, GetUsageSummaryResponses, GetUsageTimeseriesData, GetUsageTimeseriesError, GetUsageTimeseriesErrors, GetUsageTimeseriesResponse, GetUsageTimeseriesResponses, GetUsageTopModelsData, GetUsageTopModelsError, GetUsageTopModelsErrors, GetUsageTopModelsResponse, GetUsageTopModelsResponses, GetVisitorByGuidData, GetVisitorByGuidErrors, GetVisitorByGuidResponse, GetVisitorByGuidResponses, GetVisitorByIdData, GetVisitorByIdErrors, GetVisitorByIdResponse, GetVisitorByIdResponses, GetVisitorDetailsData, GetVisitorDetailsErrors, GetVisitorDetailsResponse, GetVisitorDetailsResponses, GetVisitorFacetsData, GetVisitorFacetsErrors, GetVisitorFacetsResponse, GetVisitorFacetsResponses, GetVisitorInfoData, GetVisitorInfoErrors, GetVisitorInfoResponse, GetVisitorInfoResponses, GetVisitorJourneyData, GetVisitorJourneyErrors, GetVisitorJourneyResponse, GetVisitorJourneyResponses, GetVisitorsData, GetVisitorsErrors, GetVisitorSessionsData, GetVisitorSessionsError, GetVisitorSessionsErrors, GetVisitorSessionsQuery, GetVisitorSessionsResponse, GetVisitorSessionsResponse2, GetVisitorSessionsResponses, GetVisitorsResponse, GetVisitorsResponses, GetVisitorStatsData, GetVisitorStatsErrors, GetVisitorStatsResponse, GetVisitorStatsResponses, GetWebhookData, GetWebhookErrors, GetWebhookResponse, GetWebhookResponses, GitPushEvent, GitRefResponse, GitSourcePlan, GlobalConversationResponse, GlobalEventStatsResponse, GlobalMrrResponse, GlobalRecentEventResponse, GlobalRevenueSummaryResponse, GrantProjectAccessData, GrantProjectAccessErrors, GrantProjectAccessResponse, GrantProjectAccessResponses, GroupedPageMetric, GroupedPageMetricsQuery, GroupedPageMetricsResponse, HandleGitProviderOauthCallbackData, HandleGitProviderOauthCallbackErrors, HasAnalyticsEventsData, HasAnalyticsEventsErrors, HasAnalyticsEventsResponse, HasAnalyticsEventsResponse2, HasAnalyticsEventsResponses, HasErrorGroupsData, HasErrorGroupsErrors, HasErrorGroupsResponse, HasErrorGroupsResponse2, HasErrorGroupsResponses, HasEventsQuery, HasEventsResponse, HasMetricsQuery, HasMetricsResponse, HasPerformanceMetricsData, HasPerformanceMetricsError, HasPerformanceMetricsErrors, HasPerformanceMetricsResponse, HasPerformanceMetricsResponses, HealthCheckConfiguration, HealthCheckEntryResponse, HealthResponse, HealthStatus, HealthSummary, HeartbeatApiRequest, HeartbeatResponse, HierarchyLevel, HistogramSummary, HostnameChange, HostnamePreviewResponse, HourlyPageSessions, HourlyVisitsQuery, HttpChallengeDebugResponse, ImportCredentials, ImportExecutionStatus, ImportExternalServiceData, ImportExternalServiceErrors, ImportExternalServiceRequest, ImportExternalServiceResponse, ImportExternalServiceResponses, ImportOutcomeResponse, ImportPlan, ImportRowErrorResponse, ImportSelector, ImportSource, ImportSourceCapabilities, ImportSourceInfo, ImportStatusResponse, IncidentBucket, IncidentBucketedResponse, IncidentResponse, IncidentUpdateResponse, IncrRequest, IncrResponse, IngestLogsByPathData, IngestLogsByPathError, IngestLogsByPathErrors, IngestLogsByPathResponses, IngestLogsData, IngestLogsError, IngestLogsErrors, IngestLogsResponses, IngestMetricsByPathData, IngestMetricsByPathError, IngestMetricsByPathErrors, IngestMetricsByPathResponses, IngestMetricsData, IngestMetricsError, IngestMetricsErrors, IngestMetricsResponses, IngestSentryEnvelopeData, IngestSentryEnvelopeErrors, IngestSentryEnvelopeResponses, IngestSentryEventData, IngestSentryEventErrors, IngestSentryEventResponse, IngestSentryEventResponses, IngestTracesByPathData, IngestTracesByPathError, IngestTracesByPathErrors, IngestTracesByPathResponses, IngestTracesData, IngestTracesError, IngestTracesErrors, IngestTracesResponses, InitAuthResponse, InitSessionReplayData, InitSessionReplayError, InitSessionReplayErrors, InitSessionReplayResponse, InitSessionReplayResponses, Insight, InsightSeverity, InsightsResponse, InsightStatus, InspectDropArchiveData, InspectDropArchiveErrors, InspectDropArchiveResponse, InspectDropArchiveResponses, IntegrationResponse, IpAccessControlQuery, IpAccessControlResponse, JobLogsData, JobLogsErrors, JobLogsResponses, JobStatusData, JobStatusErrors, JobStatusResponse, JobStatusResponse2, JobStatusResponses, JobSummaryResponse, JoinTokenStatusResponse, JourneyEvent, JourneySession, KeysRequest, KeysResponse, KillJobBody, KillJobData, KillJobErrors, KillJobResponse, KillJobResponses, KnownAiAgentsResponse, KvDelData, KvDelErrors, KvDelResponse, KvDelResponses, KvDisableData, KvDisableErrors, KvDisableResponse, KvDisableResponses, KvEnableData, KvEnableErrors, KvEnableResponse, KvEnableResponses, KvExpireData, KvExpireErrors, KvExpireResponse, KvExpireResponses, KvGetData, KvGetErrors, KvGetResponse, KvGetResponses, KvIncrData, KvIncrErrors, KvIncrResponse, KvIncrResponses, KvKeysData, KvKeysErrors, KvKeysResponse, KvKeysResponses, KvSetData, KvSetErrors, KvSetResponse, KvSetResponses, KvStatusData, KvStatusErrors, KvStatusResponse, KvStatusResponse2, KvStatusResponses, KvTtlData, KvTtlErrors, KvTtlResponse, KvTtlResponses, KvUpdateData, KvUpdateErrors, KvUpdateResponse, KvUpdateResponses, LatestRunForSourceData, LatestRunForSourceErrors, LatestRunForSourceResponse, LatestRunForSourceResponses, LemonSqueezyConfig, LetsEncryptSettings, LineContext, LinkCustomDomainToCertificateData, LinkCustomDomainToCertificateErrors, LinkCustomDomainToCertificateResponse, LinkCustomDomainToCertificateResponses, LinkServiceRequest, LinkServiceToProjectData, LinkServiceToProjectErrors, LinkServiceToProjectResponse, LinkServiceToProjectResponses, ListAgentRunsData, ListAgentRunsErrors, ListAgentRunsResponse, ListAgentRunsResponses, ListAgentsData, ListAgentsErrors, ListAgentsResponse, ListAgentsResponse2, ListAgentsResponses, ListAiProvidersData, ListAiProvidersErrors, ListAiProvidersResponse, ListAiProvidersResponses, ListAlertRulesData, ListAlertRulesErrors, ListAlertRulesResponse, ListAlertRulesResponses, ListAlertsData, ListAlertsError, ListAlertsErrors, ListAlertsResponse, ListAlertsResponses, ListAllConversationsData, ListAllConversationsErrors, ListAllConversationsResponse, ListAllConversationsResponses, ListAllRunsData, ListAllRunsErrors, ListAllRunsResponse, ListAllRunsResponses, ListApiKeysData, ListApiKeysErrors, ListApiKeysQuery, ListApiKeysResponse, ListApiKeysResponses, ListAuditLogsData, ListAuditLogsErrors, ListAuditLogsQuery, ListAuditLogsResponse, ListAuditLogsResponses, ListAvailableContainersData, ListAvailableContainersErrors, ListAvailableContainersResponse, ListAvailableContainersResponses, ListBackupAlertsData, ListBackupAlertsError, ListBackupAlertsErrors, ListBackupAlertsResponse, ListBackupAlertsResponses, ListBackupChildrenData, ListBackupChildrenError, ListBackupChildrenErrors, ListBackupChildrenResponse, ListBackupChildrenResponses, ListBackupSchedulesData, ListBackupSchedulesError, ListBackupSchedulesErrors, ListBackupSchedulesResponse, ListBackupSchedulesResponses, ListBackupsForScheduleData, ListBackupsForScheduleErrors, ListBackupsForScheduleResponse, ListBackupsForScheduleResponses, ListBlobsQuery, ListBlobsResponse, ListCommitsByRepositoryIdData, ListCommitsByRepositoryIdErrors, ListCommitsByRepositoryIdResponse, ListCommitsByRepositoryIdResponses, ListConnectionsData, ListConnectionsErrors, ListConnectionsResponse, ListConnectionsResponses, ListContainersAtPathData, ListContainersAtPathErrors, ListContainersAtPathResponse, ListContainersAtPathResponses, ListContainersData, ListContainersErrors, ListContainersResponse, ListContainersResponses, ListConversationsData, ListConversationsErrors, ListConversationsResponse, ListConversationsResponses, ListCustomDomainsForProjectData, ListCustomDomainsForProjectErrors, ListCustomDomainsForProjectResponse, ListCustomDomainsForProjectResponses, ListCustomDomainsResponse, ListDashboardsData, ListDashboardsError, ListDashboardsErrors, ListDashboardsResponse, ListDashboardsResponses, ListDeliveriesData, ListDeliveriesErrors, ListDeliveriesResponse, ListDeliveriesResponses, ListDeploymentContainerLogsData, ListDeploymentContainerLogsErrors, ListDeploymentContainerLogsResponse, ListDeploymentContainerLogsResponses, ListDeploymentTokensData, ListDeploymentTokensErrors, ListDeploymentTokensQuery, ListDeploymentTokensResponse, ListDeploymentTokensResponses, ListDnsProvidersData, ListDnsProvidersErrors, ListDnsProvidersResponse, ListDnsProvidersResponses, ListDomainsData, ListDomainsErrors, ListDomainsResponse, ListDomainsResponse2, ListDomainsResponses, ListDsnsData, ListDsnsErrors, ListDsnsResponse, ListDsnsResponses, ListEmailDomainsData, ListEmailDomainsErrors, ListEmailDomainsResponse, ListEmailDomainsResponses, ListEmailProvidersData, ListEmailProvidersErrors, ListEmailProvidersResponse, ListEmailProvidersResponses, ListEmailsData, ListEmailsErrors, ListEmailsResponse, ListEmailsResponses, ListEnrollmentTokensData, ListEnrollmentTokensErrors, ListEnrollmentTokensResponse, ListEnrollmentTokensResponses, ListEntitiesData, ListEntitiesErrors, ListEntitiesQuery, ListEntitiesResponse, ListEntitiesResponses, ListErrorEventsData, ListErrorEventsErrors, ListErrorEventsQuery, ListErrorEventsResponse, ListErrorEventsResponses, ListErrorGroupsData, ListErrorGroupsErrors, ListErrorGroupsQuery, ListErrorGroupsResponse, ListErrorGroupsResponses, ListEventsData, ListEventsResponse, ListEventsResponses, ListEventTypesData, ListEventTypesResponse, ListEventTypesResponses, ListExternalImagesData, ListExternalImagesErrors, ListExternalImagesResponse, ListExternalImagesResponses, ListExternalPluginsData, ListExternalPluginsErrors, ListExternalPluginsResponse, ListExternalPluginsResponses, ListExternalServiceBackupsData, ListExternalServiceBackupsError, ListExternalServiceBackupsErrors, ListExternalServiceBackupsResponse, ListExternalServiceBackupsResponses, ListFlagsData, ListFlagsErrors, ListFlagsResponse, ListFlagsResponses, ListFunnelsData, ListFunnelsErrors, ListFunnelsResponse, ListFunnelsResponses, ListGitProvidersData, ListGitProvidersErrors, ListGitProvidersResponse, ListGitProvidersResponses, ListGlobalMcpsData, ListGlobalMcpsErrors, ListGlobalMcpsResponse, ListGlobalMcpsResponses, ListGlobalSkillsData, ListGlobalSkillsErrors, ListGlobalSkillsResponse, ListGlobalSkillsResponses, ListIncidentsData, ListIncidentsErrors, ListIncidentsResponses, ListInsightsData, ListInsightsError, ListInsightsErrors, ListInsightsResponse, ListInsightsResponses, ListIpAccessControlData, ListIpAccessControlError, ListIpAccessControlErrors, ListIpAccessControlResponse, ListIpAccessControlResponses, ListJobsData, ListJobsErrors, ListJobsResponse, ListJobsResponse2, ListJobsResponses, ListKnownAiAgentsData, ListKnownAiAgentsError, ListKnownAiAgentsErrors, ListKnownAiAgentsResponse, ListKnownAiAgentsResponses, ListManagedDomainsData, ListManagedDomainsErrors, ListManagedDomainsResponse, ListManagedDomainsResponses, ListMcpsData, ListMcpsErrors, ListMcpsResponse, ListMcpsResponse2, ListMcpsResponses, ListMetricLabelKeysData, ListMetricLabelKeysError, ListMetricLabelKeysErrors, ListMetricLabelKeysResponse, ListMetricLabelKeysResponses, ListMetricLabelValuesData, ListMetricLabelValuesError, ListMetricLabelValuesErrors, ListMetricLabelValuesResponse, ListMetricLabelValuesResponses, ListMetricNamesData, ListMetricNamesError, ListMetricNamesErrors, ListMetricNamesResponse, ListMetricNamesResponses, ListModelsData, ListModelsError, ListModelsErrors, ListModelsResponse, ListModelsResponses, ListMonitorsData, ListMonitorsErrors, ListMonitorsResponse, ListMonitorsResponses, ListNotificationProvidersData, ListNotificationProvidersErrors, ListNotificationProvidersResponse, ListNotificationProvidersResponses, ListOidcProvidersData, ListOidcProvidersResponse, ListOidcProvidersResponses, ListOidcProviderUsersData, ListOidcProviderUsersErrors, ListOidcProviderUsersResponse, ListOidcProviderUsersResponses, ListOidcRoleMappingsData, ListOidcRoleMappingsResponse, ListOidcRoleMappingsResponses, ListOnDemandCertsData, ListOnDemandCertsErrors, ListOnDemandCertsResponse, ListOnDemandCertsResponse2, ListOnDemandCertsResponses, ListOrdersData, ListOrdersErrors, ListOrdersResponse, ListOrdersResponse2, ListOrdersResponses, ListPeersData, ListPeersErrors, ListPeersResponse, ListPeersResponses, ListPendingActionsData, ListPendingActionsErrors, ListPendingActionsResponse, ListPendingActionsResponses, ListPgUpgradesData, ListPgUpgradesErrors, ListPgUpgradesResponse, ListPgUpgradesResponses, ListPresetsData, ListPresetsErrors, ListPresetsResponse, ListPresetsResponse2, ListPresetsResponses, ListProjectAccessData, ListProjectAccessErrors, ListProjectAccessResponse, ListProjectAccessResponses, ListProjectAlarmsData, ListProjectAlarmsErrors, ListProjectAlarmsResponse, ListProjectAlarmsResponses, ListProjectScansData, ListProjectScansError, ListProjectScansErrors, ListProjectScansResponse, ListProjectScansResponses, ListProjectSecretsData, ListProjectSecretsErrors, ListProjectSecretsResponse, ListProjectSecretsResponses, ListProjectServicesData, ListProjectServicesErrors, ListProjectServicesResponse, ListProjectServicesResponses, ListProjectTemplatesData, ListProjectTemplatesErrors, ListProjectTemplatesResponse, ListProjectTemplatesResponses, ListProjectTemplateTagsData, ListProjectTemplateTagsErrors, ListProjectTemplateTagsResponse, ListProjectTemplateTagsResponses, ListProviderKeysData, ListProviderKeysError, ListProviderKeysErrors, ListProviderKeysResponse, ListProviderKeysResponses, ListProviderZonesData, ListProviderZonesErrors, ListProviderZonesResponse, ListProviderZonesResponses, ListPublicProvidersData, ListPublicProvidersResponse, ListPublicProvidersResponses, ListReleaseFilesData, ListReleaseFilesErrors, ListReleaseFilesResponse, ListReleaseFilesResponses, ListReleasesData, ListReleasesErrors, ListReleasesResponse, ListReleasesResponses, ListRemoteExternalImagesData, ListRemoteExternalImagesErrors, ListRemoteExternalImagesResponse, ListRemoteExternalImagesResponses, ListRepositoriesByConnectionData, ListRepositoriesByConnectionErrors, ListRepositoriesByConnectionResponse, ListRepositoriesByConnectionResponses, ListRepositoriesByProviderData, ListRepositoriesByProviderErrors, ListRepositoriesByProviderResponse, ListRepositoriesByProviderResponses, ListRestoreRunsForServiceData, ListRestoreRunsForServiceResponse, ListRestoreRunsForServiceResponses, ListRootContainersData, ListRootContainersErrors, ListRootContainersResponse, ListRootContainersResponses, ListRoutesData, ListRoutesErrors, ListRoutesResponse, ListRoutesResponses, ListRunsResponse, ListS3SourcesData, ListS3SourcesError, ListS3SourcesErrors, ListS3SourcesResponse, ListS3SourcesResponses, ListSandboxesData, ListSandboxesErrors, ListSandboxesResponse, ListSandboxesResponse2, ListSandboxesResponses, ListScansQuery, ListScheduleRunJobsData, ListScheduleRunJobsError, ListScheduleRunJobsErrors, ListScheduleRunJobsResponse, ListScheduleRunJobsResponses, ListScheduleRunsData, ListScheduleRunsError, ListScheduleRunsErrors, ListScheduleRunsResponse, ListScheduleRunsResponses, ListScheduleServicesData, ListScheduleServicesError, ListScheduleServicesErrors, ListScheduleServicesResponse, ListScheduleServicesResponses, ListSecretsData, ListSecretsErrors, ListSecretsResponse, ListSecretsResponse2, ListSecretsResponses, ListServiceHealthStatusesData, ListServiceHealthStatusesErrors, ListServiceHealthStatusesResponse, ListServiceHealthStatusesResponses, ListServiceProjectsData, ListServiceProjectsErrors, ListServiceProjectsResponse, ListServiceProjectsResponses, ListServiceSchedulesData, ListServiceSchedulesError, ListServiceSchedulesErrors, ListServiceSchedulesResponse, ListServiceSchedulesResponses, ListServicesData, ListServicesErrors, ListServicesResponse, ListServicesResponses, ListSkillsData, ListSkillsErrors, ListSkillsResponse, ListSkillsResponse2, ListSkillsResponses, ListSourceBackupsData, ListSourceBackupsError, ListSourceBackupsErrors, ListSourceBackupsResponse, ListSourceBackupsResponses, ListSourceFilesData, ListSourceFilesErrors, ListSourceFilesResponse, ListSourceFilesResponses, ListSourceMapsData, ListSourceMapsErrors, ListSourceMapsResponse, ListSourceMapsResponses, ListSourcesData, ListSourcesErrors, ListSourcesResponse, ListSourcesResponses, ListStaticBundlesData, ListStaticBundlesErrors, ListStaticBundlesResponse, ListStaticBundlesResponses, ListSyncedRepositoriesData, ListSyncedRepositoriesErrors, ListSyncedRepositoriesResponse, ListSyncedRepositoriesResponses, ListTagsResponse, ListTeamMembersData, ListTeamMembersErrors, ListTeamMembersResponse, ListTeamMembersResponses, ListTeamProjectsData, ListTeamProjectsErrors, ListTeamProjectsResponse, ListTeamProjectsResponses, ListTeamsData, ListTeamsErrors, ListTeamsResponse, ListTeamsResponses, ListTemplatesQuery, ListTemplatesResponse, ListUsersData, ListUsersErrors, ListUsersResponse, ListUsersResponses, ListVulnerabilitiesQuery, ListWebhooksData, ListWebhooksErrors, ListWebhooksResponse, ListWebhooksResponses, LiveVisitorInfo, LiveVisitorsListResponse, LocationCount, LocationGranularity, LocationInfo, LoginData, LoginErrors, LoginRequest, LoginResponse, LoginResponses, LogLevel, LogoutData, LogoutErrors, LogoutResponses, LogRecord, LogSearchLine, LogSeverity, LogSource, LogsQuery, LogsResponse, LogStream, LookupDnsARecordsData, LookupDnsARecordsError, LookupDnsARecordsErrors, LookupDnsARecordsResponse, LookupDnsARecordsResponses, ManagedDomainResponse, ManualAction, ManualActionTiming, McpDefinitionResponse, MessageContent, MessagePart, MessageResponse, MeteredMode, MetricAggregation, MetricBucket, MetricDataPoint, MetricsOverTimeResponse, MetricsQuery, MetricsRangeQuery, MetricsStatusResponse, MetricsStoreKind, MetricsSummaryResponse, MetricType, MfaRequiredResponse, MfaSetupResponse, MfaVerificationRequest, MigrationStep, MigrationSummary, MintEnrollmentTokenData, MintEnrollmentTokenErrors, MintEnrollmentTokenRequest, MintEnrollmentTokenResponse, MintEnrollmentTokenResponse2, MintEnrollmentTokenResponses, MiscResult, MkdirBody, MkdirData, MkdirErrors, MkdirResponse, MkdirResponses, ModelInfo, ModelListResponse, ModelPricing, ModelUsage, MonitoringSettings, MonitoringSettingsMasked, MonitorResponse, MonitorStatus, MrrBucketResponse, MultiNodeSettings, MultiNodeSettingsMasked, MxResult, NavEntry, NavSection, NetworkConfiguration, NetworkMode, NixpacksPresetConfig, NixpacksProvider, NodeContainerListResponse, NodeContainerResponse, NodeCostInfo, NodeHeartbeatData, NodeHeartbeatErrors, NodeHeartbeatResponse, NodeHeartbeatResponses, NodeInfoResponse, NodeListResponse, NodeMetricsGetRangeData, NodeMetricsGetRangeErrors, NodeMetricsGetRangeResponse, NodeMetricsGetRangeResponses, NotificationPreferencesResponse, NotificationProviderResponse, ObservabilityCompressionSettings, ObservabilityEvent, ObservabilityFullEventData, ObservabilityFullEventError, ObservabilityFullEventErrors, ObservabilityFullEventResponse, ObservabilityFullEventResponses, ObservabilityListEventsData, ObservabilityListEventsError, ObservabilityListEventsErrors, ObservabilityListEventsResponse, ObservabilityListEventsResponses, ObservabilityRetentionSettings, OidcCallbackData, OidcProviderResponse, OidcProvidersListResponse, OidcProviderSummary, OidcProviderUserResponse, OidcRoleMappingResponse, OidcTestConnectionResponse, OnDemandCertAttemptResponse, OnDemandCertRow, OnDemandTlsSettings, OpenAiError, OpenAiErrorResponse, OperatingSystemCount, OperationResultResponse, OperationResultsResponse, OtelDashboardResponse, OtelDashboardsResponse, OtelMetricAlertRuleResponse, OtelMetricAlertsResponse, OtelMetricLabelKeysResponse, OtelMetricLabelValuesResponse, OtelMetricNamesResponse, OtelMetricsResponse, OutlierAlgorithm, OutlierParams, OverprovisioningAssessment, OverprovisioningVerdict, PageActivityBucket, PageCountryStats, PageFlowEntry, PageFlowQuery, PageFlowResponse, PageHourlySessionsQuery, PageHourlySessionsResponse, PagePathDetailQuery, PagePathDetailResponse, PagePathInfo, PagePathSparkline, PagePathSparklinePoint, PagePathsQuery, PagePathsResponse, PagePathsSparklineQuery, PagePathsSparklineResponse, PagePathVisitorsQuery, PagePathVisitorsResponse, PageReferrerStats, PagesComparisonResponse, PageSessionComparison, PageSessionStats, PageSessionStatsQuery, PageTransition, PageVisit, PageVisitorSession, PaginatedEmailsResponse, PaginatedEntitiesResponse, PaginatedErrorEventsResponse, PaginatedErrorGroupsResponse, PaginatedEventsResponse, PaginatedExternalImagesResponse, PaginatedProjectList, PaginatedStaticBundlesResponse, Pagination, PaginationMeta, PaginationParams, PasswordProtectionConfig, PatchAdminGateData, PatchAdminGateErrors, PatchAdminGateResponse, PatchAdminGateResponses, PatchPreviewGatewaySettingsData, PatchPreviewGatewaySettingsResponse, PatchPreviewGatewaySettingsResponses, PatchSettingsRequest, PathVisitors, PathVisitorsAnalyticsQuery, PathVisitorsResponse, PauseDeploymentData, PauseDeploymentErrors, PauseDeploymentResponse, PauseDeploymentResponses, PauseSandboxData, PauseSandboxErrors, PauseSandboxResponse, PauseSandboxResponses, PeerEntry, PeerListResponse, PendingActionResponse, PerformanceMetricsQuery, PerformanceMetricsResponse, PermissionInfo, PgUpgradeLogResponse, PgUpgradeResponse, PipelineStats, PipelineStatsResponse, PlanComplexity, PlanMetadata, PlanRestoreData, PlanRestoreError, PlanRestoreErrors, PlanRestoreResponse, PlanRestoreResponses, PlanSourceBackup, PlanTarget, PlatformInfo, PluginManifest, PortMapping, PostDnsAckData, PostDnsAckErrors, PostDnsAckResponse, PostDnsAckResponses, PostgresWalHealth, PresetConfigSchema, PresetInfo, PresetResponse, PreviewAlertData, PreviewAlertError, PreviewAlertErrors, PreviewAlertResponse, PreviewAlertResponses, PreviewFunnelMetricsData, PreviewFunnelMetricsErrors, PreviewFunnelMetricsResponse, PreviewFunnelMetricsResponses, PreviewGatewaySettings, PreviewGatewaySettingsMasked, PreviewGatewaySettingsResponse, PreviewHostnameModeData, PreviewHostnameModeErrors, PreviewHostnameModeResponse, PreviewHostnameModeResponses, PreviewShareLinkBody, PreviewShareLinkResponse, PricingResponse, ProblemDetails, ProjectAccessResponse, ProjectConfiguration, ProjectDashboardAnalytics, ProjectDsnResponse, ProjectHealthSummary, ProjectInfo, ProjectMonitorHealth, ProjectPresetResponse, ProjectQuery, ProjectRef, ProjectResponse, ProjectSecretEnvironmentInfo, ProjectSecretResponse, ProjectServiceInfo, ProjectsHealthResponse, ProjectsMonitorHealthResponse, ProjectStatisticsResponse, ProjectStatsBreakdown, ProjectType, ProjectUsageInfoResponse, PromoteClusterMemberData, PromoteClusterMemberErrors, PromoteClusterMemberResponses, PromoteDeploymentData, PromoteDeploymentErrors, PromoteDeploymentRequest, PromoteDeploymentResponse, PromoteDeploymentResponses, PropertyBreakdownItem, PropertyBreakdownQuery, PropertyBreakdownResponse, PropertyColumn, PropertyTimelineItem, PropertyTimelineQuery, PropertyTimelineResponse, Protocol, ProviderCatalogDto, ProviderCatalogResponse, ProviderConfig, ProviderConfigMasked, ProviderDeletionCheckResponse, ProviderDescriptor, ProviderKeyResponse, ProviderMetadata, ProviderResponse, ProviderUsage, ProvisionDomainData, ProvisionDomainErrors, ProvisionDomainResponse, ProvisionDomainResponses, ProvisionResponse, ProxyLogResponse, ProxyLogsPaginatedResponse, PublicHostnameStrategy, PublicPresetResponse, PublicRepositoryInfo, PurgeLogsRequest, PurgeProjectLogsData, PurgeProjectLogsError, PurgeProjectLogsErrors, PurgeProjectLogsResponses, PushedExternalImageResponse, PushExternalImageData, PushExternalImageErrors, PushExternalImageResponse, PushExternalImageResponses, PushImageRequest, QueryDataData, QueryDataErrors, QueryDataRequest, QueryDataResponse, QueryDataResponse2, QueryDataResponses, QueryGenaiTracesData, QueryGenaiTracesError, QueryGenaiTracesErrors, QueryGenaiTracesResponse, QueryGenaiTracesResponses, QueryLogsData, QueryLogsError, QueryLogsErrors, QueryLogsResponse, QueryLogsResponses, QueryMetricsData, QueryMetricsError, QueryMetricsErrors, QueryMetricsResponse, QueryMetricsResponses, QuerySpanStatsData, QuerySpanStatsError, QuerySpanStatsErrors, QuerySpanStatsResponse, QuerySpanStatsResponses, QueryTracesData, QueryTracesError, QueryTracesErrors, QueryTracesResponse, QueryTracesResponses, QueryTraceSummariesData, QueryTraceSummariesError, QueryTraceSummariesErrors, QueryTraceSummariesResponse, QueryTraceSummariesResponses, QuotaResponse, RateLimitConfig, RateLimitSettings, ReachabilityStatus, ReadEntityRowsData, ReadEntityRowsErrors, ReadEntityRowsResponse, ReadEntityRowsResponses, ReadFileData, ReadFileErrors, ReadFileResponse, ReadFileResponse2, ReadFileResponses, ReadRowsQuery, ReAnalyzeData, ReAnalyzeErrors, ReAnalyzeResponses, RecentActivityQuery, RecentActivityResponse, RecentEventResponse, RecentQueryParams, RecordConsoleEventData, RecordConsoleEventErrors, RecordConsoleEventResponses, RecordEventMetricsData, RecordEventMetricsErrors, RecordEventMetricsResponse, RecordEventMetricsResponses, RecordExposureRequest, RecordExposureResponse, RecordFlagExposureData, RecordFlagExposureErrors, RecordFlagExposureResponse, RecordFlagExposureResponses, RecordListResponse, RecordSpeedMetricsData, RecordSpeedMetricsError, RecordSpeedMetricsErrors, RecordSpeedMetricsResponse, RecordSpeedMetricsResponses, RecoveryTarget, ReferrerCount, ReferrersAnalyticsQuery, RefreshRouteTableData, RefreshRouteTableErrors, RefreshRouteTableResponse, RefreshRouteTableResponses, RegenerateDsnData, RegenerateDsnErrors, RegenerateDsnRequest, RegenerateDsnResponse, RegenerateDsnResponses, RegisterExternalImageData, RegisterExternalImageErrors, RegisterExternalImageResponse, RegisterExternalImageResponses, RegisterImageRequest, RegisterNodeApiRequest, RegisterNodeData, RegisterNodeErrors, RegisterNodeResponse, RegisterNodeResponse2, RegisterNodeResponses, RegisterRequest, ReinstallGitlabWebhookData, ReinstallGitlabWebhookErrors, ReinstallGitlabWebhookResponse, ReinstallGitlabWebhookResponses, ReinstallWebhookResponse, RejectPendingActionData, RejectPendingActionErrors, RejectPendingActionResponse, RejectPendingActionResponses, ReleaseListResponse, ReloadPluginsData, ReloadPluginsErrors, ReloadPluginsResponse, ReloadPluginsResponses, ReloadResponse, RemoteDeploymentResponse, RemoveClusterMemberData, RemoveClusterMemberErrors, RemoveClusterMemberResponse, RemoveClusterMemberResponses, RemoveManagedDomainData, RemoveManagedDomainErrors, RemoveManagedDomainResponse, RemoveManagedDomainResponses, RemoveNodeResponse, RemoveRoleData, RemoveRoleErrors, RemoveRoleResponse, RemoveRoleResponses, RemoveTeamMemberData, RemoveTeamMemberErrors, RemoveTeamMemberResponse, RemoveTeamMemberResponses, RenameConversationData, RenameConversationErrors, RenameConversationRequest, RenameConversationResponse, RenameConversationResponses, RenewDomainData, RenewDomainErrors, RenewDomainResponse, RenewDomainResponses, RepositoryListQuery, RepositoryListResponse, RepositoryPresetResponse, RepositoryResponse, RepositorySyncStartedResponse, RequestPasswordResetData, RequestPasswordResetErrors, RequestPasswordResetResponse, RequestPasswordResetResponses, RequestRow, RequiredPasswordChangeRequest, RequiredPasswordChangeResponse, ResetPasswordData, ResetPasswordErrors, ResetPasswordRequest, ResetPasswordResponse, ResetPasswordResponses, ResetPgStatStatementsRequest, ResetPgStatStatementsResponse, ResizeSandboxBody, ResizeSandboxData, ResizeSandboxErrors, ResizeSandboxResponse, ResizeSandboxResponses, ResolveAlarmData, ResolveAlarmErrors, ResolveAlarmResponses, ResolvedEnvVarResponse, ResolvedEnvVarSource, ResourceCounts, ResourceFootprint, ResourceInfo, ResourceLimitApplyResult, ResourceLimits, ResourceLimitsResponse, ResourceLimitsUpdateResponse, ResourcesBody, RestartContainerData, RestartContainerErrors, RestartContainerResponse, RestartContainerResponses, RestartPreviewGatewayData, RestartPreviewGatewayResponse, RestartPreviewGatewayResponses, RestartSandboxData, RestartSandboxErrors, RestartSandboxResponse, RestartSandboxResponses, RestoreCapabilities, RestoreCapabilitiesResponse, RestoreFlagData, RestoreFlagErrors, RestoreFlagResponse, RestoreFlagResponses, RestorePlan, RestoreRequestMode, RestoreRunView, RestoreUserData, RestoreUserErrors, RestoreUserResponse, RestoreUserResponses, ResumeDeploymentData, ResumeDeploymentErrors, ResumeDeploymentResponse, ResumeDeploymentResponses, ResumeSandboxData, ResumeSandboxErrors, ResumeSandboxResponse, ResumeSandboxResponses, RetentionCleanupFailure, RetentionCleanupReport, RetryClusterData, RetryClusterErrors, RetryClusterRequest, RetryClusterResponse, RetryClusterResponses, RetryDeliveryData, RetryDeliveryErrors, RetryDeliveryResponse, RetryDeliveryResponses, RetryPgUpgradeData, RetryPgUpgradeErrors, RetryPgUpgradeResponse, RetryPgUpgradeResponses, RetryRunData, RetryRunErrors, RetryRunResponse, RetryRunResponses, RevealGlobalMcpConfigData, RevealGlobalMcpConfigErrors, RevealGlobalMcpConfigResponse, RevealGlobalMcpConfigResponses, RevealMcpConfigData, RevealMcpConfigErrors, RevealMcpConfigResponse, RevealMcpConfigResponses, RevealNotificationProviderConfigData, RevealNotificationProviderConfigErrors, RevealNotificationProviderConfigResponse, RevealNotificationProviderConfigResponses, RevealServiceParameterData, RevealServiceParameterErrors, RevealServiceParameterResponse, RevealServiceParameterResponses, RevenueCreateIntegrationData, RevenueCreateIntegrationErrors, RevenueCreateIntegrationResponse, RevenueCreateIntegrationResponses, RevenueDeleteIntegrationData, RevenueDeleteIntegrationResponse, RevenueDeleteIntegrationResponses, RevenueGlobalEventsData, RevenueGlobalEventsResponse, RevenueGlobalEventsResponses, RevenueImportInvoicesCsvData, RevenueImportInvoicesCsvErrors, RevenueImportInvoicesCsvResponse, RevenueImportInvoicesCsvResponses, RevenueImportSubscriptionsCsvData, RevenueImportSubscriptionsCsvErrors, RevenueImportSubscriptionsCsvResponse, RevenueImportSubscriptionsCsvResponses, RevenueListIntegrationsData, RevenueListIntegrationsResponse, RevenueListIntegrationsResponses, RevenueListProvidersData, RevenueListProvidersResponse, RevenueListProvidersResponses, RevenueMetricsCustomersData, RevenueMetricsCustomersResponse, RevenueMetricsCustomersResponses, RevenueMetricsGlobalMrrData, RevenueMetricsGlobalMrrResponse, RevenueMetricsGlobalMrrResponses, RevenueMetricsGlobalSummaryData, RevenueMetricsGlobalSummaryResponse, RevenueMetricsGlobalSummaryResponses, RevenueMetricsMrrData, RevenueMetricsMrrResponse, RevenueMetricsMrrResponses, RevenueMetricsSummaryData, RevenueMetricsSummaryResponse, RevenueMetricsSummaryResponses, RevenueRecentEventsData, RevenueRecentEventsResponse, RevenueRecentEventsResponses, RevenueRotateTokenData, RevenueRotateTokenResponse, RevenueRotateTokenResponses, RevenueRow, RevenueUpdateConfigData, RevenueUpdateConfigErrors, RevenueUpdateConfigResponse, RevenueUpdateConfigResponses, RevenueUpdateSecretData, RevenueUpdateSecretErrors, RevenueUpdateSecretResponse, RevenueUpdateSecretResponses, RevokeDsnData, RevokeDsnErrors, RevokeDsnResponse, RevokeDsnResponses, RevokeEnrollmentTokenData, RevokeEnrollmentTokenErrors, RevokeEnrollmentTokenResponse, RevokeEnrollmentTokenResponses, RevokeJoinTokenData, RevokeJoinTokenErrors, RevokeJoinTokenResponse, RevokeJoinTokenResponses, RevokeProjectAccessData, RevokeProjectAccessErrors, RevokeProjectAccessResponse, RevokeProjectAccessResponses, RiskLevel, RoleInfo, RollbackPgUpgradeData, RollbackPgUpgradeErrors, RollbackPgUpgradeResponse, RollbackPgUpgradeResponses, RollbackToDeploymentData, RollbackToDeploymentErrors, RollbackToDeploymentResponse, RollbackToDeploymentResponses, RootfsCacheEntry, RootfsGcData, RootfsGcReport, RootfsGcResponses, RootfsReport, RootfsReportData, RootfsReportResponses, RootfsVmEntry, RotateApiKeyData, RotateApiKeyErrors, RotateApiKeyResponse, RotateApiKeyResponses, RotateDeploymentTokenData, RotateDeploymentTokenErrors, RotateDeploymentTokenResponse, RotateDeploymentTokenResponses, RouteRefreshResponse, RouteResponse, RouteRole, RouteUser, RouteUserWithRoles, RunBackupForSourceData, RunBackupForSourceError, RunBackupForSourceErrors, RunBackupForSourceResponse, RunBackupForSourceResponses, RunBackupRequest, RunConnectionHealthCheckData, RunConnectionHealthCheckErrors, RunConnectionHealthCheckResponse, RunConnectionHealthCheckResponses, RunExternalServiceBackupData, RunExternalServiceBackupError, RunExternalServiceBackupErrors, RunExternalServiceBackupRequest, RunExternalServiceBackupResponse, RunExternalServiceBackupResponses, RunScheduleNowData, RunScheduleNowError, RunScheduleNowErrors, RunScheduleNowResponse, RunScheduleNowResponses, S3ConnectionTestResponse, S3CredentialsResponse, S3SourceResponse, S3SourceResponseWritable, SandboxCreatePreviewLinkData, SandboxCreatePreviewLinkErrors, SandboxCreatePreviewLinkResponse, SandboxCreatePreviewLinkResponses, SandboxDomainResponse, SandboxEvent, SandboxEventsResponse, SandboxInner, SandboxResponse, SandboxRoute, SandboxStatusResponse, SaveAgentTokenData, SaveAgentTokenErrors, SaveAgentTokenRequest, SaveAgentTokenResponse, SaveAgentTokenResponse2, SaveAgentTokenResponses, SaveAiProviderCredentialData, SaveAiProviderCredentialErrors, SaveAiProviderCredentialResponse, SaveAiProviderCredentialResponses, SaveCredentialRequest, SaveCredentialResponse, ScalewayCredentialsRequest, ScanResponse, ScheduleRunEntry, ScheduleRunJobEntry, ScheduleRunListResponse, ScheduleRunResponse, ScheduleRunSummary, ScheduleRunSummaryList, ScreenshotSettings, SearchLogsData, SearchLogsError, SearchLogsErrors, SearchLogsRequest, SearchLogsResponse, SearchLogsResponse2, SearchLogsResponses, SearchMode, Seasonality, SecretResponse, SecurityConfig, SecurityHeadersConfig, SecurityHeadersSettings, SendEmailData, SendEmailErrors, SendEmailRequestBody, SendEmailResponse, SendEmailResponseBody, SendEmailResponses, SendMessageRequest, SensitiveConfigValueResponse, SensitiveMcpConfigValueResponse, SensitiveValueResponse, SentryChunkUploadResponse, SentryCreateReleaseRequest, SentryEventRequest, SentryEventResponse, SentryReleaseFileResponse, SentryReleaseProjectRef, SentryReleaseResponse, SeriesStateEntry, ServiceAccessInfo, ServiceAction, ServiceAlertRuleResponse, ServiceBackupEntryResponse, ServiceBackupListResponse, ServiceCreateAlertRuleRequest, ServiceHealthResponse, ServiceHealthStatusBatchResponse, ServiceHealthStatusEntryResponse, ServiceMemberInfo, ServiceParameter, ServicePlan, ServiceResourceLimits, ServiceRuntimeReport, ServiceStatsReport, ServiceTypeInfo, ServiceTypeRoute, ServiceUpdateAlertRuleRequest, SesCredentialsRequest, SessionDetails, SessionDetailsQuery, SessionEvent, SessionEventDto, SessionEventsQuery, SessionEventsResponse, SessionLogsQuery, SessionLogsResponse, SessionReplayEventsRequest, SessionReplayInfoDto, SessionReplayInitRequest, SessionReplayInitResponse, SessionReplayWithEventsDto, SessionReplayWithVisitorDto, SessionRequestLog, SessionSummary, SetAiDataAccessData, SetAiDataAccessErrors, SetAiDataAccessResponse, SetAiDataAccessResponses, SetDefaultS3SourceData, SetDefaultS3SourceError, SetDefaultS3SourceErrors, SetDefaultS3SourceResponse, SetDefaultS3SourceResponses, SetFlagEnvironmentData, SetFlagEnvironmentErrors, SetFlagEnvironmentRequest, SetFlagEnvironmentResponse, SetFlagEnvironmentResponses, SetPreviewPasswordBody, SetPreviewPasswordData, SetPreviewPasswordErrors, SetPreviewPasswordResponse, SetPreviewPasswordResponse2, SetPreviewPasswordResponses, SetRequest, SetResponse, SettingsUpdateResponse, SetupDnsChallengeData, SetupDnsChallengeErrors, SetupDnsChallengeRequest, SetupDnsChallengeResponse, SetupDnsChallengeResponse2, SetupDnsChallengeResponses, SetupDnsData, SetupDnsErrors, SetupDnsRequest, SetupDnsResponse, SetupDnsResponse2, SetupDnsResponses, SetupEmailTrackingData, SetupEmailTrackingErrors, SetupEmailTrackingResponse, SetupEmailTrackingResponses, SetupMfaData, SetupMfaErrors, SetupMfaResponse, SetupMfaResponses, SiblingRef, SkillDefinitionResponse, SlackConfig, SleepEnvironmentData, SleepEnvironmentErrors, SleepEnvironmentResponse, SleepEnvironmentResponses, SlowQueriesResponse, SlowQueryRow, SmartFilter, SmokeTestAgentData, SmokeTestAgentErrors, SmokeTestAgentResponse, SmokeTestAgentResponses, SmokeTestResponse, SmtpCredentialsRequest, SmtpEncryptionRoute, SmtpResult, SourceArchiveUpload, SourceBackupEntry, SourceBackupIndexResponse, SourceBody, SourceFileListResponse, SourceFileResponse, SourceMapListResponse, SourceMapResponse, SourceSandboxData, SourceSandboxErrors, SourceSandboxResponse, SourceSandboxResponses, SourceType, SpanEvent, SpanKind, SpanRecord, SpanRow, SpanStats, SpanStatsResponse, SpanStatusCode, SpeedMetricsPayload, SpeedSegmentFilters, StaleSlot, StartAnalysisData, StartAnalysisErrors, StartAnalysisRequest, StartAnalysisResponse, StartAnalysisResponses, StartContainerData, StartContainerErrors, StartContainerResponse, StartContainerResponses, StartFixData, StartFixErrors, StartFixResponses, StartGitProviderOauthData, StartGitProviderOauthErrors, StartOidcLoginBySlugData, StartOidcLoginBySlugErrors, StartPgUpgradeData, StartPgUpgradeErrors, StartPgUpgradeRequest, StartPgUpgradeResponse, StartPgUpgradeResponses, StartRestoreData, StartRestoreError, StartRestoreErrors, StartRestoreRequest, StartRestoreResponse, StartRestoreResponses, StartServiceData, StartServiceErrors, StartServiceResponse, StartServiceResponses, StaticBundleResponse, StaticParams, StaticPresetConfig, StatPathData, StatPathErrors, StatPathResponse, StatPathResponses, StatResponse, StatsFilters, StatusBucket, StatusBucketedResponse, StatusCodeCount, StatusCodesQuery, StatusPageOverview, StepConversionResponse, StepResourceType, StepResult, StepUpResponse, StopContainerData, StopContainerErrors, StopContainerResponse, StopContainerResponses, StopSandboxData, StopSandboxErrors, StopSandboxResponse, StopSandboxResponses, StopSequence, StopServiceData, StopServiceErrors, StopServiceResponse, StopServiceResponses, StorageQuota, StreamContainerMetricsData, StreamContainerMetricsErrors, StreamContainerMetricsResponses, StreamEventsData, StreamEventsErrors, StreamEventsResponses, StreamRunEventsData, StreamRunEventsErrors, StreamRunEventsResponses, StripeConfig, SyncedRepositoryListQuery, SyncRepositoriesData, SyncRepositoriesErrors, SyncRepositoriesResponse, SyncRepositoriesResponses, SyntaxResult, TagInfo, TagListResponse, TailDeploymentJobLogsData, TailDeploymentJobLogsErrors, TailLogsData, TailLogsError, TailLogsErrors, TailLogsRequest, TailLogsResponses, TargetRecommendation, TeamListResponse, TeamMemberResponse, TeamResponse, TeamRole, TeardownDeploymentData, TeardownDeploymentErrors, TeardownDeploymentResponse, TeardownDeploymentResponses, TeardownEnvironmentData, TeardownEnvironmentErrors, TeardownEnvironmentResponse, TeardownEnvironmentResponses, TemplateResponse, TerminalData, TerminalErrors, TestEmailRequest, TestEmailResponse, TestNotificationProviderData, TestNotificationProviderErrors, TestNotificationProviderResponse, TestNotificationProviderResponses, TestOidcProviderData, TestOidcProviderResponse, TestOidcProviderResponses, TestProviderConnectionData, TestProviderConnectionErrors, TestProviderConnectionResponse, TestProviderConnectionResponses, TestProviderData, TestProviderErrors, TestProviderKeyByIdData, TestProviderKeyByIdError, TestProviderKeyByIdErrors, TestProviderKeyByIdResponse, TestProviderKeyByIdResponses, TestProviderKeyInlineData, TestProviderKeyInlineError, TestProviderKeyInlineErrors, TestProviderKeyInlineResponse, TestProviderKeyInlineResponses, TestProviderKeyRequest, TestProviderKeyResponse, TestProviderResponse, TestProviderResponse2, TestProviderResponses, TestS3ConnectionPreviewData, TestS3ConnectionPreviewError, TestS3ConnectionPreviewErrors, TestS3ConnectionPreviewResponse, TestS3ConnectionPreviewResponses, TestS3SourceConnectionData, TestS3SourceConnectionError, TestS3SourceConnectionErrors, TestS3SourceConnectionResponse, TestS3SourceConnectionResponses, TimeBucketStats, TimeBucketStatsResponse, TimeseriesBucket, TimeseriesQueryParams, TlsMode, TodayStatsResponse, ToggleAiDataAccessRequest, ToggleDeploymentMetricsRequest, ToggleServiceMetricsRequest, TokenRenewalRequest, ToolCallEvent, ToolInfo, ToolResultEvent, TopModelsQueryParams, TraceProjectRef, TracesResponse, TraceSummariesResponse, TraceSummary, TrackClickData, TrackClickErrors, TrackedLinkResponse, TrackingEventResponse, TrackOpenData, TrackOpenErrors, TrackOpenResponses, TriggerAgentData, TriggerAgentErrors, TriggerAgentRequest, TriggerAgentResponse, TriggerAgentResponses, TriggerDigestResponse, TriggerPipelinePayload, TriggerPipelineResponse, TriggerProjectPipelineData, TriggerProjectPipelineErrors, TriggerProjectPipelineResponse, TriggerProjectPipelineResponses, TriggerScanData, TriggerScanError, TriggerScanErrors, TriggerScanRequest, TriggerScanResponse, TriggerScanResponse2, TriggerScanResponses, TriggerServiceHealthCheckData, TriggerServiceHealthCheckErrors, TriggerServiceHealthCheckResponse, TriggerServiceHealthCheckResponses, TriggerWeeklyDigestData, TriggerWeeklyDigestErrors, TriggerWeeklyDigestResponse, TriggerWeeklyDigestResponses, TtlRequest, TtlResponse, TxtRecord, UiManifest, UiRoute, UndrainNodeResponse, UnifiedTrace, UniqueCountsQuery, UniqueCountsResponse, UnlinkServiceFromProjectData, UnlinkServiceFromProjectErrors, UnlinkServiceFromProjectResponse, UnlinkServiceFromProjectResponses, UnsupportedFeature, UpdateAdminGateRequest, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponse, UpdateAgentResponses, UpdateAiProviderData, UpdateAiProviderErrors, UpdateAiProviderRequest, UpdateAiProviderResponse, UpdateAiProviderResponse2, UpdateAiProviderResponses, UpdateAlertData, UpdateAlertError, UpdateAlertErrors, UpdateAlertResponse, UpdateAlertResponses, UpdateAlertRuleData, UpdateAlertRuleErrors, UpdateAlertRuleRequest, UpdateAlertRuleResponse, UpdateAlertRuleResponses, UpdateApiKeyData, UpdateApiKeyErrors, UpdateApiKeyRequest, UpdateApiKeyResponse, UpdateApiKeyResponses, UpdateAutomaticDeployData, UpdateAutomaticDeployErrors, UpdateAutomaticDeployRequest, UpdateAutomaticDeployResponse, UpdateAutomaticDeployResponses, UpdateBackupScheduleData, UpdateBackupScheduleError, UpdateBackupScheduleErrors, UpdateBackupScheduleRequest, UpdateBackupScheduleResponse, UpdateBackupScheduleResponses, UpdateBlobRequest, UpdateBlobResponse, UpdateCloudflareProviderData, UpdateCloudflareProviderErrors, UpdateCloudflareProviderRequest, UpdateCloudflareProviderResponse, UpdateCloudflareProviderResponses, UpdateConfigBody, UpdateConnectionTokenData, UpdateConnectionTokenErrors, UpdateConnectionTokenResponse, UpdateConnectionTokenResponses, UpdateCustomDomainData, UpdateCustomDomainErrors, UpdateCustomDomainRequest, UpdateCustomDomainResponse, UpdateCustomDomainResponses, UpdateDashboardData, UpdateDashboardError, UpdateDashboardErrors, UpdateDashboardRequest, UpdateDashboardResponse, UpdateDashboardResponses, UpdateDeploymentConfigRequest, UpdateDeploymentTokenData, UpdateDeploymentTokenErrors, UpdateDeploymentTokenRequest, UpdateDeploymentTokenResponse, UpdateDeploymentTokenResponses, UpdateDnsProviderRequest, UpdateEmailProviderData, UpdateEmailProviderErrors, UpdateEmailProviderRequest, UpdateEmailProviderResponse, UpdateEmailProviderResponses, UpdateEnvironmentSettingsData, UpdateEnvironmentSettingsErrors, UpdateEnvironmentSettingsRequest, UpdateEnvironmentSettingsResponse, UpdateEnvironmentSettingsResponses, UpdateEnvironmentSubdomainData, UpdateEnvironmentSubdomainErrors, UpdateEnvironmentSubdomainRequest, UpdateEnvironmentSubdomainResponse, UpdateEnvironmentSubdomainResponses, UpdateEnvironmentVariableData, UpdateEnvironmentVariableErrors, UpdateEnvironmentVariableRequest, UpdateEnvironmentVariableResponse, UpdateEnvironmentVariableResponses, UpdateErrorGroupData, UpdateErrorGroupErrors, UpdateErrorGroupRequest, UpdateErrorGroupResponses, UpdateExternalServiceRequest, UpdateFlagData, UpdateFlagErrors, UpdateFlagRequest, UpdateFlagResponse, UpdateFlagResponses, UpdateFunnelData, UpdateFunnelErrors, UpdateFunnelResponses, UpdateGitProviderCredentialsData, UpdateGitProviderCredentialsErrors, UpdateGitProviderCredentialsResponse, UpdateGitProviderCredentialsResponses, UpdateGitSettingsData, UpdateGitSettingsErrors, UpdateGitSettingsRequest, UpdateGitSettingsResponse, UpdateGitSettingsResponses, UpdateGlobalMcpData, UpdateGlobalMcpErrors, UpdateGlobalMcpResponse, UpdateGlobalMcpResponses, UpdateGlobalSkillData, UpdateGlobalSkillErrors, UpdateGlobalSkillResponse, UpdateGlobalSkillResponses, UpdateIncidentStatusData, UpdateIncidentStatusErrors, UpdateIncidentStatusRequest, UpdateIncidentStatusResponse, UpdateIncidentStatusResponses, UpdateIpAccessControlData, UpdateIpAccessControlError, UpdateIpAccessControlErrors, UpdateIpAccessControlRequest, UpdateIpAccessControlResponse, UpdateIpAccessControlResponses, UpdateKvRequest, UpdateKvResponse, UpdateManagedDomainApiRequest, UpdateManagedDomainData, UpdateManagedDomainErrors, UpdateManagedDomainResponse, UpdateManagedDomainResponses, UpdateMcpData, UpdateMcpErrors, UpdateMcpRequest, UpdateMcpResponse, UpdateMcpResponses, UpdateMemberRoleRequest, UpdateMetricAlertRequest, UpdateNotificationEmailProviderData, UpdateNotificationEmailProviderErrors, UpdateNotificationEmailProviderRequest, UpdateNotificationEmailProviderResponse, UpdateNotificationEmailProviderResponses, UpdateNotificationProviderData, UpdateNotificationProviderErrors, UpdateNotificationProviderResponse, UpdateNotificationProviderResponses, UpdateOidcProviderData, UpdateOidcProviderRequest, UpdateOidcProviderResponse, UpdateOidcProviderResponses, UpdatePreferencesData, UpdatePreferencesErrors, UpdatePreferencesRequest, UpdatePreferencesResponse, UpdatePreferencesResponses, UpdateProjectData, UpdateProjectDeploymentConfigData, UpdateProjectDeploymentConfigErrors, UpdateProjectDeploymentConfigResponse, UpdateProjectDeploymentConfigResponses, UpdateProjectErrors, UpdateProjectResponse, UpdateProjectResponses, UpdateProjectSecretData, UpdateProjectSecretErrors, UpdateProjectSecretRequest, UpdateProjectSecretResponse, UpdateProjectSecretResponses, UpdateProjectSettingsData, UpdateProjectSettingsErrors, UpdateProjectSettingsRequest, UpdateProjectSettingsResponse, UpdateProjectSettingsResponses, UpdateProviderCredentialsRequest, UpdateProviderData, UpdateProviderErrors, UpdateProviderKeyData, UpdateProviderKeyError, UpdateProviderKeyErrors, UpdateProviderKeyRequest, UpdateProviderKeyResponse, UpdateProviderKeyResponses, UpdateProviderRequest, UpdateProviderResponse, UpdateProviderResponses, UpdateRouteData, UpdateRouteErrors, UpdateRouteRequest, UpdateRouteResponse, UpdateRouteResponses, UpdateS3SourceData, UpdateS3SourceError, UpdateS3SourceErrors, UpdateS3SourceRequest, UpdateS3SourceResponse, UpdateS3SourceResponses, UpdateSecretBody, UpdateSelfData, UpdateSelfErrors, UpdateSelfRequest, UpdateSelfResponse, UpdateSelfResponses, UpdateServiceData, UpdateServiceErrors, UpdateServiceResourcesData, UpdateServiceResourcesErrors, UpdateServiceResourcesResponse, UpdateServiceResourcesResponses, UpdateServiceResponse, UpdateServiceResponses, UpdateSessionDurationData, UpdateSessionDurationError, UpdateSessionDurationErrors, UpdateSessionDurationRequest, UpdateSessionDurationResponse, UpdateSessionDurationResponse2, UpdateSessionDurationResponses, UpdateSettingsData, UpdateSettingsErrors, UpdateSettingsResponse, UpdateSettingsResponses, UpdateSkillData, UpdateSkillErrors, UpdateSkillRequest, UpdateSkillResponse, UpdateSkillResponses, UpdateSlackProviderData, UpdateSlackProviderErrors, UpdateSlackProviderRequest, UpdateSlackProviderResponse, UpdateSlackProviderResponses, UpdateSpeedMetricsData, UpdateSpeedMetricsError, UpdateSpeedMetricsErrors, UpdateSpeedMetricsPayload, UpdateSpeedMetricsResponse, UpdateSpeedMetricsResponses, UpdateStatusResponse, UpdateTeamData, UpdateTeamErrors, UpdateTeamMemberRoleData, UpdateTeamMemberRoleErrors, UpdateTeamMemberRoleResponse, UpdateTeamMemberRoleResponses, UpdateTeamRequest, UpdateTeamResponse, UpdateTeamResponses, UpdateTokenRequest, UpdateTokenResponse, UpdateUserData, UpdateUserErrors, UpdateUserRequest, UpdateUserResponse, UpdateUserResponses, UpdateWebhookData, UpdateWebhookErrors, UpdateWebhookProviderData, UpdateWebhookProviderErrors, UpdateWebhookProviderRequest, UpdateWebhookProviderResponse, UpdateWebhookProviderResponses, UpdateWebhookRequestBody, UpdateWebhookResponse, UpdateWebhookResponses, UpgradeExternalServiceRequest, UpgradePreviewGatewayData, UpgradePreviewGatewayResponse, UpgradePreviewGatewayResponses, UpgradeRequest, UpgradeServiceData, UpgradeServiceErrors, UpgradeServiceResponse, UpgradeServiceResponses, UploadGlobalSkillData, UploadGlobalSkillErrors, UploadGlobalSkillResponse, UploadGlobalSkillResponses, UploadReleaseFileData, UploadReleaseFileErrors, UploadReleaseFileResponse, UploadReleaseFileResponses, UploadSkillData, UploadSkillErrors, UploadSkillResponse, UploadSkillResponses, UploadSourceFileData, UploadSourceFileErrors, UploadSourceFileResponse, UploadSourceFileResponses, UploadSourceMapData, UploadSourceMapErrors, UploadSourceMapResponse, UploadSourceMapResponses, UploadStaticBundleData, UploadStaticBundleErrors, UploadStaticBundleResponse, UploadStaticBundleResponses, UpsertAgentRequest, UpsertSecretData, UpsertSecretErrors, UpsertSecretRequest, UpsertSecretResponse, UpsertSecretResponses, UptimeDataPoint, UptimeHistoryResponse, UsageFilter, UsageInfo, UsageLogEntry, UsageLogPage, UsageQueryParams, UsageSource, UsageSummary, UserResponse, ValidateConnectionData, ValidateConnectionErrors, ValidateConnectionResponse, ValidateConnectionResponses, ValidateEmailData, ValidateEmailErrors, ValidateEmailRequest, ValidateEmailResponse, ValidateEmailResponse2, ValidateEmailResponses, ValidationLevel, ValidationReport, ValidationResponse, ValidationResult, ValidationStatus, ValidationSummary, VerifyAndEnableMfaData, VerifyAndEnableMfaErrors, VerifyAndEnableMfaResponse, VerifyAndEnableMfaResponses, VerifyDomainData, VerifyDomainErrors, VerifyDomainResponse, VerifyDomainResponses, VerifyEmailData, VerifyEmailErrors, VerifyEmailResponse, VerifyEmailResponses, VerifyManagedDomainData, VerifyManagedDomainErrors, VerifyManagedDomainResponse, VerifyManagedDomainResponses, VerifyMfaChallengeData, VerifyMfaChallengeErrors, VerifyMfaChallengeResponse, VerifyMfaChallengeResponses, VerifyMfaRequest, VerifyStepUpData, VerifyStepUpErrors, VerifyStepUpRequest, VerifyStepUpResponse, VerifyStepUpResponses, ViewItem, ViewsOverTime, ViewsOverTimeQuery, VisitorDetails, VisitorFacets, VisitorFacetsQuery, VisitorFacetValue, VisitorInfo, VisitorJourneyQuery, VisitorJourneyResponse, VisitorLocationsQuery, VisitorRecord, VisitorSegmentFilters, VisitorSessionsQuery, VisitorSessionsResponse, VisitorsListQuery, VisitorsResponse, VisitorStats, VisitorWithGeolocation, VolumeMount, VolumeType, VulnerabilityResponse, WakeEnvironmentData, WakeEnvironmentErrors, WakeEnvironmentResponse, WakeEnvironmentResponses, WalWarning, WalWarningSeverity, WebhookConfig, WebhookDeliveryResponse, WebhookResponse, WebhookTriggerData, WebhookTriggerErrors, WebhookTriggerRequest, WebhookTriggerResponse, WebhookTriggerResponse2, WebhookTriggerResponses, WorkflowDryRunData, WorkflowDryRunErrors, WorkflowDryRunRequest, WorkflowDryRunResponse, WorkflowDryRunResponses, WorkloadDescriptor, WorkloadId, WorkloadStatus, WorkloadType, WriteFileBody, WriteFileData, WriteFileErrors, WriteFileResponse, WriteFileResponses, WriteFilesBody, WriteFilesData, WriteFilesErrors, WriteFilesResponse, WriteFilesResponse2, WriteFilesResponses, ZoneListResponse } from './types.gen'; diff --git a/web/src/api/client/sdk.gen.ts b/web/src/api/client/sdk.gen.ts index ece762c63..abc5177ac 100644 --- a/web/src/api/client/sdk.gen.ts +++ b/web/src/api/client/sdk.gen.ts @@ -2,7 +2,7 @@ import { type Client, type ClientMeta, formDataBodySerializer, type Options as Options2, type RequestResult, type ServerSentEventsResult, type TDataShape } from './client'; import { client } from './client.gen'; -import type { AcknowledgeAlarmData, AcknowledgeAlarmErrors, AcknowledgeAlarmResponses, ActivateAiProviderData, ActivateAiProviderErrors, ActivateAiProviderResponses, ActivateApiKeyData, ActivateApiKeyErrors, ActivateApiKeyResponses, ActivateConnectionData, ActivateConnectionErrors, ActivateConnectionResponses, ActivateProviderData, ActivateProviderErrors, ActivateProviderResponses, AddClusterMemberData, AddClusterMemberErrors, AddClusterMemberResponses, AddContextData, AddContextErrors, AddContextResponses, AddEnvironmentDomainData, AddEnvironmentDomainErrors, AddEnvironmentDomainResponses, AddEventsData, AddEventsErrors, AddEventsResponses, AddManagedDomainData, AddManagedDomainErrors, AddManagedDomainResponses, AddSessionReplayEventsData, AddSessionReplayEventsErrors, AddSessionReplayEventsResponses, AddTeamMemberData, AddTeamMemberErrors, AddTeamMemberResponses, AdminDrainNodeData, AdminDrainNodeErrors, AdminDrainNodeResponses, AdminDrainStatusData, AdminDrainStatusErrors, AdminDrainStatusResponses, AdminGetNodeData, AdminGetNodeErrors, AdminGetNodeResponses, AdminListNodeContainersData, AdminListNodeContainersErrors, AdminListNodeContainersResponses, AdminListNodesData, AdminListNodesErrors, AdminListNodesResponses, AdminRemoveNodeData, AdminRemoveNodeErrors, AdminRemoveNodeResponses, AdminUndrainNodeData, AdminUndrainNodeErrors, AdminUndrainNodeResponses, ApplyHostnameModeData, ApplyHostnameModeErrors, ApplyHostnameModeResponses, ArchiveConversationData, ArchiveConversationErrors, ArchiveConversationResponses, ArchiveFlagData, ArchiveFlagErrors, ArchiveFlagResponses, AssignRoleData, AssignRoleErrors, AssignRoleResponses, AttachScheduleServicesData, AttachScheduleServicesErrors, AttachScheduleServicesResponses, BlobCopyData, BlobCopyErrors, BlobCopyResponses, BlobDeleteData, BlobDeleteErrors, BlobDeleteResponses, BlobDisableData, BlobDisableErrors, BlobDisableResponses, BlobDownloadData, BlobDownloadErrors, BlobDownloadResponses, BlobEnableData, BlobEnableErrors, BlobEnableResponses, BlobHeadData, BlobHeadErrors, BlobHeadResponses, BlobListData, BlobListErrors, BlobListResponses, BlobPutData, BlobPutErrors, BlobPutResponses, BlobStatusData, BlobStatusErrors, BlobStatusResponses, BlobUpdateData, BlobUpdateErrors, BlobUpdateResponses, CancelBackupData, CancelBackupErrors, CancelBackupResponses, CancelData, CancelDeploymentData, CancelDeploymentErrors, CancelDeploymentResponses, CancelDomainOrderData, CancelDomainOrderErrors, CancelDomainOrderResponses, CancelErrors, CancelPgUpgradeData, CancelPgUpgradeErrors, CancelPgUpgradeResponses, CancelResponses, CancelRunData, CancelRunErrors, CancelRunResponses, CancelScheduleRunData, CancelScheduleRunErrors, CancelScheduleRunResponses, ChangePasswordSelfData, ChangePasswordSelfErrors, ChangePasswordSelfResponses, ChangeProjectSourceData, ChangeProjectSourceErrors, ChangeProjectSourceResponses, ChangeRequiredPasswordData, ChangeRequiredPasswordErrors, ChangeRequiredPasswordResponses, ChatCompletionsData, ChatCompletionsErrors, ChatCompletionsResponses, CheckAnalyticsHasEventsData, CheckAnalyticsHasEventsErrors, CheckAnalyticsHasEventsResponses, CheckCommitExistsData, CheckCommitExistsErrors, CheckCommitExistsResponses, CheckDomainStatusData, CheckDomainStatusErrors, CheckDomainStatusResponses, CheckExplorerSupportData, CheckExplorerSupportErrors, CheckExplorerSupportResponses, CheckIpBlockedData, CheckIpBlockedErrors, CheckIpBlockedResponses, CheckProviderDeletionSafetyData, CheckProviderDeletionSafetyErrors, CheckProviderDeletionSafetyResponses, ChunkUploadOptionsData, ChunkUploadOptionsResponses, CleanupExpiredBackupsData, CleanupExpiredBackupsErrors, CleanupExpiredBackupsResponses, ClearPreviewPasswordData, ClearPreviewPasswordErrors, ClearPreviewPasswordResponses, CliDeviceApproveData, CliDeviceApproveErrors, CliDeviceApproveResponses, CliDeviceDenyData, CliDeviceDenyErrors, CliDeviceDenyResponses, CliDeviceLookupData, CliDeviceLookupErrors, CliDeviceLookupResponses, CliDevicePollData, CliDevicePollErrors, CliDevicePollResponses, CliDeviceStartData, CliDeviceStartErrors, CliDeviceStartResponses, CliLogoutData, CliLogoutErrors, CliLogoutResponses, CmdData, CmdErrors, CmdKillData, CmdKillErrors, CmdKillResponses, CmdLogsData, CmdLogsErrors, CmdLogsResponses, CmdResponses, ConfirmPendingActionData, ConfirmPendingActionErrors, ConfirmPendingActionResponses, ContainerMetricsGetHistoryData, ContainerMetricsGetHistoryErrors, ContainerMetricsGetHistoryResponses, CreateAgentData, CreateAgentErrors, CreateAgentResponses, CreateAlertData, CreateAlertErrors, CreateAlertResponses, CreateAlertRuleData, CreateAlertRuleErrors, CreateAlertRuleResponses, CreateApiKeyData, CreateApiKeyErrors, CreateApiKeyResponses, CreateBackupScheduleData, CreateBackupScheduleErrors, CreateBackupScheduleResponses, CreateBitbucketProviderData, CreateBitbucketProviderErrors, CreateBitbucketProviderResponses, CreateCloudflareProviderData, CreateCloudflareProviderErrors, CreateCloudflareProviderResponses, CreateConversationData, CreateConversationErrors, CreateConversationResponses, CreateCustomDomainData, CreateCustomDomainErrors, CreateCustomDomainResponses, CreateDashboardData, CreateDashboardErrors, CreateDashboardResponses, CreateDeploymentTokenData, CreateDeploymentTokenErrors, CreateDeploymentTokenResponses, CreateDnsProviderData, CreateDnsProviderErrors, CreateDnsProviderResponses, CreateDomainData, CreateDomainErrors, CreateDomainResponses, CreateDsnData, CreateDsnErrors, CreateDsnResponses, CreateEmailDomainData, CreateEmailDomainErrors, CreateEmailDomainResponses, CreateEmailProviderData, CreateEmailProviderErrors, CreateEmailProviderResponses, CreateEnvironmentData, CreateEnvironmentErrors, CreateEnvironmentResponses, CreateEnvironmentVariableData, CreateEnvironmentVariableErrors, CreateEnvironmentVariableResponses, CreateFlagData, CreateFlagErrors, CreateFlagResponses, CreateFunnelData, CreateFunnelErrors, CreateFunnelResponses, CreateGenericProviderData, CreateGenericProviderErrors, CreateGenericProviderResponses, CreateGiteaPatProviderData, CreateGiteaPatProviderErrors, CreateGiteaPatProviderResponses, CreateGithubPatProviderData, CreateGithubPatProviderErrors, CreateGithubPatProviderResponses, CreateGitlabOauthProviderData, CreateGitlabOauthProviderErrors, CreateGitlabOauthProviderResponses, CreateGitlabPatProviderData, CreateGitlabPatProviderErrors, CreateGitlabPatProviderResponses, CreateGitProviderData, CreateGitProviderErrors, CreateGitProviderResponses, CreateGlobalMcpData, CreateGlobalMcpErrors, CreateGlobalMcpResponses, CreateGlobalSkillData, CreateGlobalSkillErrors, CreateGlobalSkillResponses, CreateIncidentData, CreateIncidentErrors, CreateIncidentResponses, CreateIpAccessControlData, CreateIpAccessControlErrors, CreateIpAccessControlResponses, CreateMcpData, CreateMcpErrors, CreateMcpResponses, CreateMonitorData, CreateMonitorErrors, CreateMonitorResponses, CreateNotificationEmailProviderData, CreateNotificationEmailProviderErrors, CreateNotificationEmailProviderResponses, CreateNotificationProviderData, CreateNotificationProviderErrors, CreateNotificationProviderResponses, CreateOidcProviderData, CreateOidcProviderErrors, CreateOidcProviderResponses, CreateOidcRoleMappingData, CreateOidcRoleMappingResponses, CreateOrRecreateOrderData, CreateOrRecreateOrderErrors, CreateOrRecreateOrderResponses, CreatePlanData, CreatePlanErrors, CreatePlanResponses, CreatePrData, CreatePrErrors, CreateProjectData, CreateProjectErrors, CreateProjectFromTemplateData, CreateProjectFromTemplateErrors, CreateProjectFromTemplateResponses, CreateProjectReleaseData, CreateProjectReleaseErrors, CreateProjectReleaseResponses, CreateProjectResponses, CreateProjectSecretData, CreateProjectSecretErrors, CreateProjectSecretResponses, CreateProviderKeyData, CreateProviderKeyErrors, CreateProviderKeyResponses, CreatePrResponses, CreateReleaseData, CreateReleaseErrors, CreateReleaseResponses, CreateRouteData, CreateRouteErrors, CreateRouteResponses, CreateS3SourceData, CreateS3SourceErrors, CreateS3SourceResponses, CreateSandboxData, CreateSandboxErrors, CreateSandboxResponses, CreateServiceData, CreateServiceErrors, CreateServiceResponses, CreateSkillData, CreateSkillErrors, CreateSkillResponses, CreateSlackProviderData, CreateSlackProviderErrors, CreateSlackProviderResponses, CreateTeamData, CreateTeamErrors, CreateTeamResponses, CreateUserData, CreateUserErrors, CreateUserResponses, CreateWebhookData, CreateWebhookErrors, CreateWebhookProviderData, CreateWebhookProviderErrors, CreateWebhookProviderResponses, CreateWebhookResponses, DeactivateApiKeyData, DeactivateApiKeyErrors, DeactivateApiKeyResponses, DeactivateConnectionData, DeactivateConnectionErrors, DeactivateConnectionResponses, DeactivateProviderData, DeactivateProviderErrors, DeactivateProviderResponses, DeleteAgentData, DeleteAgentErrors, DeleteAgentResponses, DeleteAlertData, DeleteAlertErrors, DeleteAlertResponses, DeleteAlertRuleData, DeleteAlertRuleErrors, DeleteAlertRuleResponses, DeleteApiKeyData, DeleteApiKeyErrors, DeleteApiKeyResponses, DeleteBackupData, DeleteBackupErrors, DeleteBackupResponses, DeleteBackupScheduleData, DeleteBackupScheduleErrors, DeleteBackupScheduleResponses, DeleteConnectionData, DeleteConnectionErrors, DeleteConnectionResponses, DeleteCustomDomainData, DeleteCustomDomainErrors, DeleteCustomDomainResponses, DeleteDashboardData, DeleteDashboardErrors, DeleteDashboardResponses, DeleteDeploymentTokenData, DeleteDeploymentTokenErrors, DeleteDeploymentTokenResponses, DeleteDnsProviderData, DeleteDnsProviderErrors, DeleteDnsProviderResponses, DeleteDomainData, DeleteDomainErrors, DeleteDomainResponses, DeleteEmailDomainData, DeleteEmailDomainErrors, DeleteEmailDomainResponses, DeleteEmailProviderData, DeleteEmailProviderErrors, DeleteEmailProviderResponses, DeleteEnvironmentData, DeleteEnvironmentDomainData, DeleteEnvironmentDomainErrors, DeleteEnvironmentDomainResponses, DeleteEnvironmentErrors, DeleteEnvironmentResponses, DeleteEnvironmentVariableData, DeleteEnvironmentVariableErrors, DeleteEnvironmentVariableResponses, DeleteExternalImageData, DeleteExternalImageErrors, DeleteExternalImageResponses, DeleteFunnelData, DeleteFunnelErrors, DeleteFunnelResponses, DeleteGitProviderData, DeleteGitProviderErrors, DeleteGitProviderResponses, DeleteGlobalMcpData, DeleteGlobalMcpErrors, DeleteGlobalMcpResponses, DeleteGlobalSkillData, DeleteGlobalSkillErrors, DeleteGlobalSkillResponses, DeleteIpAccessControlData, DeleteIpAccessControlErrors, DeleteIpAccessControlResponses, DeleteMcpData, DeleteMcpErrors, DeleteMcpResponses, DeleteMonitorData, DeleteMonitorErrors, DeleteMonitorResponses, DeleteNotificationProviderData, DeleteNotificationProviderErrors, DeleteNotificationProviderResponses, DeleteOidcProviderData, DeleteOidcProviderResponses, DeleteOidcRoleMappingData, DeleteOidcRoleMappingResponses, DeletePreferencesData, DeletePreferencesErrors, DeletePreferencesResponses, DeleteProjectData, DeleteProjectErrors, DeleteProjectResponses, DeleteProjectSecretData, DeleteProjectSecretErrors, DeleteProjectSecretResponses, DeleteProviderKeyData, DeleteProviderKeyErrors, DeleteProviderKeyResponses, DeleteProviderSafelyData, DeleteProviderSafelyErrors, DeleteProviderSafelyResponses, DeleteReleaseSourceFilesData, DeleteReleaseSourceFilesErrors, DeleteReleaseSourceFilesResponses, DeleteReleaseSourceMapsData, DeleteReleaseSourceMapsErrors, DeleteReleaseSourceMapsResponses, DeleteRouteData, DeleteRouteErrors, DeleteRouteResponses, DeleteS3SourceData, DeleteS3SourceErrors, DeleteS3SourceResponses, DeleteScanData, DeleteScanErrors, DeleteScanResponses, DeleteSecretData, DeleteSecretErrors, DeleteSecretResponses, DeleteServiceData, DeleteServiceErrors, DeleteServiceResponses, DeleteSessionReplayData, DeleteSessionReplayErrors, DeleteSessionReplayResponses, DeleteSkillData, DeleteSkillErrors, DeleteSkillResponses, DeleteSourceMapData, DeleteSourceMapErrors, DeleteSourceMapResponses, DeleteStaticBundleData, DeleteStaticBundleErrors, DeleteStaticBundleResponses, DeleteTeamData, DeleteTeamErrors, DeleteTeamResponses, DeleteUserData, DeleteUserErrors, DeleteUserResponses, DeleteWebhookData, DeleteWebhookErrors, DeleteWebhookResponses, DeployFromImageData, DeployFromImageErrors, DeployFromImageResponses, DeployFromImageUploadData, DeployFromImageUploadErrors, DeployFromImageUploadResponses, DeployFromStaticData, DeployFromStaticErrors, DeployFromStaticResponses, DeployFromUploadedSourceData, DeployFromUploadedSourceErrors, DeployFromUploadedSourceResponses, DeploymentMetricsGetLatestData, DeploymentMetricsGetLatestErrors, DeploymentMetricsGetLatestResponses, DeploymentMetricsGetRangeData, DeploymentMetricsGetRangeErrors, DeploymentMetricsGetRangeResponses, DeploymentMetricsToggleData, DeploymentMetricsToggleErrors, DeploymentMetricsToggleResponses, DestroySandboxData, DestroySandboxErrors, DestroySandboxResponses, DetachScheduleServiceData, DetachScheduleServiceErrors, DetachScheduleServiceResponses, DetectPublicPresetsData, DetectPublicPresetsErrors, DetectPublicPresetsResponses, DisableBackupScheduleData, DisableBackupScheduleErrors, DisableBackupScheduleResponses, DisableMfaData, DisableMfaErrors, DisableMfaResponses, DiscoverWorkloadsData, DiscoverWorkloadsErrors, DiscoverWorkloadsResponses, DomainData, DomainErrors, DomainResponses, DownloadGlobalSkillArchiveData, DownloadGlobalSkillArchiveErrors, DownloadGlobalSkillArchiveResponses, DownloadObjectData, DownloadObjectErrors, DownloadObjectResponses, DownloadSkillArchiveData, DownloadSkillArchiveErrors, DownloadSkillArchiveResponses, EmailStatusData, EmailStatusErrors, EmailStatusResponses, EmbeddingsData, EmbeddingsErrors, EmbeddingsResponses, EnableBackupScheduleData, EnableBackupScheduleErrors, EnableBackupScheduleResponses, EnrichVisitorData, EnrichVisitorErrors, EnrichVisitorResponses, ExecData, ExecDetachedData, ExecDetachedErrors, ExecDetachedResponses, ExecErrors, ExecResponses, ExecuteDeploymentOperationData, ExecuteDeploymentOperationErrors, ExecuteDeploymentOperationResponses, ExecuteImportData, ExecuteImportErrors, ExecuteImportResponses, ExtendTimeoutData, ExtendTimeoutErrors, ExtendTimeoutResponses, ExternalServiceEnablePgStatStatementsData, ExternalServiceEnablePgStatStatementsErrors, ExternalServiceEnablePgStatStatementsResponses, ExternalServiceMetricsByDatabaseData, ExternalServiceMetricsByDatabaseErrors, ExternalServiceMetricsByDatabaseResponses, ExternalServiceMetricsCreateAlertRuleData, ExternalServiceMetricsCreateAlertRuleErrors, ExternalServiceMetricsCreateAlertRuleResponses, ExternalServiceMetricsDeleteAlertRuleData, ExternalServiceMetricsDeleteAlertRuleErrors, ExternalServiceMetricsDeleteAlertRuleResponses, ExternalServiceMetricsGetAlertRulesData, ExternalServiceMetricsGetAlertRulesErrors, ExternalServiceMetricsGetAlertRulesResponses, ExternalServiceMetricsGetLatestData, ExternalServiceMetricsGetLatestErrors, ExternalServiceMetricsGetLatestResponses, ExternalServiceMetricsGetRangeData, ExternalServiceMetricsGetRangeErrors, ExternalServiceMetricsGetRangeResponses, ExternalServiceMetricsStatusData, ExternalServiceMetricsStatusErrors, ExternalServiceMetricsStatusResponses, ExternalServiceMetricsToggleData, ExternalServiceMetricsToggleErrors, ExternalServiceMetricsToggleResponses, ExternalServiceMetricsUpdateAlertRuleData, ExternalServiceMetricsUpdateAlertRuleErrors, ExternalServiceMetricsUpdateAlertRuleResponses, ExternalServiceResetPgStatStatementsData, ExternalServiceResetPgStatStatementsErrors, ExternalServiceResetPgStatStatementsResponses, FinalizeOrderData, FinalizeOrderErrors, FinalizeOrderResponses, FinalizeProjectReleaseData, FinalizeProjectReleaseErrors, FinalizeProjectReleaseResponses, FindConversationData, FindConversationErrors, FindConversationResponses, GenerateJoinTokenData, GenerateJoinTokenErrors, GenerateJoinTokenResponses, GeneratePresetDockerfileData, GeneratePresetDockerfileErrors, GeneratePresetDockerfileResponses, GetAccessInfoData, GetAccessInfoErrors, GetAccessInfoResponses, GetActiveVisitorsData, GetActiveVisitorsErrors, GetActiveVisitorsResponses, GetActivityGraphData, GetActivityGraphErrors, GetActivityGraphResponses, GetAdminGateData, GetAdminGateErrors, GetAdminGateResponses, GetAgentData, GetAgentErrors, GetAgentResponses, GetAggregatedBucketsData, GetAggregatedBucketsErrors, GetAggregatedBucketsResponses, GetAiAgentBreakdownData, GetAiAgentBreakdownErrors, GetAiAgentBreakdownResponses, GetAiAgentPagesData, GetAiAgentPagesErrors, GetAiAgentPagesResponses, GetAiAgentTimelineData, GetAiAgentTimelineErrors, GetAiAgentTimelineResponses, GetAiDataAccessData, GetAiDataAccessErrors, GetAiDataAccessResponses, GetAiPageBreakdownData, GetAiPageBreakdownErrors, GetAiPageBreakdownResponses, GetAiStatusBreakdownData, GetAiStatusBreakdownErrors, GetAiStatusBreakdownResponses, GetAlertData, GetAlertErrors, GetAlertResponses, GetAlertRuleData, GetAlertRuleErrors, GetAlertRuleResponses, GetAllRepositoriesByNameData, GetAllRepositoriesByNameErrors, GetAllRepositoriesByNameResponses, GetAnalyticsActiveVisitorsData, GetAnalyticsActiveVisitorsErrors, GetAnalyticsActiveVisitorsResponses, GetAnalyticsEventsCountData, GetAnalyticsEventsCountErrors, GetAnalyticsEventsCountResponses, GetAnalyticsSessionEventsData, GetAnalyticsSessionEventsErrors, GetAnalyticsSessionEventsResponses, GetAnalyticsVisitorSessionsData, GetAnalyticsVisitorSessionsErrors, GetAnalyticsVisitorSessionsResponses, GetApiKeyData, GetApiKeyErrors, GetApiKeyPermissionsData, GetApiKeyPermissionsErrors, GetApiKeyPermissionsResponses, GetApiKeyResponses, GetAuditLogData, GetAuditLogErrors, GetAuditLogResponses, GetBackupData, GetBackupErrors, GetBackupResponses, GetBackupScheduleData, GetBackupScheduleErrors, GetBackupScheduleResponses, GetBranchesByRepositoryIdData, GetBranchesByRepositoryIdErrors, GetBranchesByRepositoryIdResponses, GetBucketedIncidentsData, GetBucketedIncidentsErrors, GetBucketedIncidentsResponses, GetBucketedStatusData, GetBucketedStatusErrors, GetBucketedStatusResponses, GetChallengeTokenData, GetChallengeTokenErrors, GetChallengeTokenResponses, GetChatReadinessData, GetChatReadinessErrors, GetChatReadinessResponses, GetCliStatusData, GetCliStatusErrors, GetCliStatusResponses, GetClusterHealthData, GetClusterHealthErrors, GetClusterHealthResponses, GetClusterMemberData, GetClusterMemberErrors, GetClusterMemberResponses, GetCmdData, GetCmdErrors, GetCmdResponses, GetContainerDetailData, GetContainerDetailErrors, GetContainerDetailResponses, GetContainerEnvironmentVariableData, GetContainerEnvironmentVariableErrors, GetContainerEnvironmentVariableResponses, GetContainerLogsByIdData, GetContainerLogsByIdErrors, GetContainerLogsData, GetContainerLogsErrors, GetContainerMetricsData, GetContainerMetricsErrors, GetContainerMetricsResponses, GetConversationData, GetConversationDetailData, GetConversationDetailErrors, GetConversationDetailResponses, GetConversationErrors, GetConversationResponses, GetConversationsData, GetConversationsErrors, GetConversationsResponses, GetCronByIdData, GetCronByIdErrors, GetCronByIdResponses, GetCronExecutionsData, GetCronExecutionsErrors, GetCronExecutionsResponses, GetCrossProjectTraceSiblingsData, GetCrossProjectTraceSiblingsErrors, GetCrossProjectTraceSiblingsResponses, GetCurrentMonitorStatusData, GetCurrentMonitorStatusErrors, GetCurrentMonitorStatusResponses, GetCurrentUserData, GetCurrentUserErrors, GetCurrentUserResponses, GetCustomDomainData, GetCustomDomainErrors, GetCustomDomainResponses, GetDashboardData, GetDashboardErrors, GetDashboardProjectsAnalyticsData, GetDashboardProjectsAnalyticsErrors, GetDashboardProjectsAnalyticsResponses, GetDashboardResponses, GetDeliveryData, GetDeliveryErrors, GetDeliveryResponses, GetDeploymentContainerLogContentData, GetDeploymentContainerLogContentErrors, GetDeploymentContainerLogContentResponses, GetDeploymentData, GetDeploymentErrors, GetDeploymentJobLogsData, GetDeploymentJobLogsErrors, GetDeploymentJobLogsResponses, GetDeploymentJobsData, GetDeploymentJobsErrors, GetDeploymentJobsResponses, GetDeploymentOperationsData, GetDeploymentOperationsErrors, GetDeploymentOperationsResponses, GetDeploymentOperationStatusData, GetDeploymentOperationStatusErrors, GetDeploymentOperationStatusResponses, GetDeploymentResponses, GetDeploymentTokenData, GetDeploymentTokenErrors, GetDeploymentTokenResponses, GetDiskStatusData, GetDiskStatusErrors, GetDiskStatusResponses, GetDnsChangesData, GetDnsChangesErrors, GetDnsChangesResponses, GetDnsProviderData, GetDnsProviderErrors, GetDnsProviderResponses, GetDomainByHostData, GetDomainByHostErrors, GetDomainByHostResponses, GetDomainByIdData, GetDomainByIdErrors, GetDomainByIdResponses, GetDomainByNameData, GetDomainByNameErrors, GetDomainByNameResponses, GetDomainData, GetDomainDnsRecordsData, GetDomainDnsRecordsErrors, GetDomainDnsRecordsResponses, GetDomainErrors, GetDomainOrderData, GetDomainOrderErrors, GetDomainOrderResponses, GetDomainResponses, GetEmailData, GetEmailErrors, GetEmailEventsData, GetEmailEventsErrors, GetEmailEventsResponses, GetEmailLinksData, GetEmailLinksErrors, GetEmailLinksResponses, GetEmailProviderData, GetEmailProviderErrors, GetEmailProviderResponses, GetEmailResponses, GetEmailStatsData, GetEmailStatsErrors, GetEmailStatsResponses, GetEmailTrackingData, GetEmailTrackingErrors, GetEmailTrackingResponses, GetEmailTrackingStatusData, GetEmailTrackingStatusErrors, GetEmailTrackingStatusResponses, GetEntityInfoData, GetEntityInfoErrors, GetEntityInfoResponses, GetEnvironmentCronsData, GetEnvironmentCronsErrors, GetEnvironmentCronsResponses, GetEnvironmentData, GetEnvironmentDomainsData, GetEnvironmentDomainsErrors, GetEnvironmentDomainsResponses, GetEnvironmentErrors, GetEnvironmentResponses, GetEnvironmentsData, GetEnvironmentsErrors, GetEnvironmentsResponses, GetEnvironmentVariablesData, GetEnvironmentVariablesErrors, GetEnvironmentVariablesResponses, GetEnvironmentVariableValueData, GetEnvironmentVariableValueErrors, GetEnvironmentVariableValueResponses, GetErrorDashboardStatsData, GetErrorDashboardStatsErrors, GetErrorDashboardStatsResponses, GetErrorEventData, GetErrorEventErrors, GetErrorEventResponses, GetErrorGroupData, GetErrorGroupErrors, GetErrorGroupResponses, GetErrorStatsData, GetErrorStatsErrors, GetErrorStatsResponses, GetErrorTimeSeriesData, GetErrorTimeSeriesErrors, GetErrorTimeSeriesResponses, GetEventDetailData, GetEventDetailErrors, GetEventDetailResponses, GetEventEntriesData, GetEventEntriesErrors, GetEventEntriesResponses, GetEventsCountData, GetEventsCountErrors, GetEventsCountResponses, GetEventsTimelineData, GetEventsTimelineErrors, GetEventsTimelineResponses, GetEventTypeBreakdownData, GetEventTypeBreakdownErrors, GetEventTypeBreakdownResponses, GetEventVisitorsData, GetEventVisitorsErrors, GetEventVisitorsResponses, GetExternalImageData, GetExternalImageErrors, GetExternalImageResponses, GetFileData, GetFileErrors, GetFileResponses, GetFlagData, GetFlagErrors, GetFlagResponses, GetFlagSnapshotData, GetFlagSnapshotErrors, GetFlagSnapshotResponses, GetFunnelMetricsData, GetFunnelMetricsErrors, GetFunnelMetricsResponses, GetGenaiTraceData, GetGenaiTraceErrors, GetGenaiTraceResponses, GetGeneralStatsData, GetGeneralStatsErrors, GetGeneralStatsResponses, GetGitProviderData, GetGitProviderErrors, GetGitProviderResponses, GetGlobalEventsData, GetGlobalEventsErrors, GetGlobalEventsResponses, GetGlobalEventStatsData, GetGlobalEventStatsErrors, GetGlobalEventStatsResponses, GetGlobalMcpData, GetGlobalMcpErrors, GetGlobalMcpResponses, GetGlobalSandboxStatusData, GetGlobalSandboxStatusErrors, GetGlobalSandboxStatusResponses, GetGlobalSkillData, GetGlobalSkillErrors, GetGlobalSkillResponses, GetGroupedPageMetricsData, GetGroupedPageMetricsErrors, GetGroupedPageMetricsResponses, GetHealthData, GetHealthErrors, GetHealthResponses, GetHourlyVisitsData, GetHourlyVisitsErrors, GetHourlyVisitsResponses, GetHttpChallengeDebugData, GetHttpChallengeDebugErrors, GetHttpChallengeDebugResponses, GetImportStatusData, GetImportStatusErrors, GetImportStatusResponses, GetIncidentData, GetIncidentErrors, GetIncidentResponses, GetIncidentUpdatesData, GetIncidentUpdatesErrors, GetIncidentUpdatesResponses, GetIpAccessControlData, GetIpAccessControlErrors, GetIpAccessControlResponses, GetIpGeolocationData, GetIpGeolocationErrors, GetIpGeolocationResponses, GetJoinTokenStatusData, GetJoinTokenStatusErrors, GetJoinTokenStatusResponses, GetLastDeploymentData, GetLastDeploymentErrors, GetLastDeploymentResponses, GetLatestScanData, GetLatestScanErrors, GetLatestScanResponses, GetLatestScansPerEnvironmentData, GetLatestScansPerEnvironmentErrors, GetLatestScansPerEnvironmentResponses, GetLiveVisitorsListData, GetLiveVisitorsListErrors, GetLiveVisitorsListResponses, GetLogContextData, GetLogContextErrors, GetLogContextResponses, GetMcpData, GetMcpErrors, GetMcpResponses, GetMetricsOverTimeData, GetMetricsOverTimeErrors, GetMetricsOverTimeResponses, GetMonitorData, GetMonitorErrors, GetMonitorResponses, GetNotificationProviderData, GetNotificationProviderErrors, GetNotificationProviderResponses, GetOnDemandCertStatusData, GetOnDemandCertStatusErrors, GetOnDemandCertStatusResponses, GetOrCreateDsnData, GetOrCreateDsnErrors, GetOrCreateDsnResponses, GetPageFlowData, GetPageFlowErrors, GetPageFlowResponses, GetPageHourlySessionsData, GetPageHourlySessionsErrors, GetPageHourlySessionsResponses, GetPagePathDetailData, GetPagePathDetailErrors, GetPagePathDetailResponses, GetPagePathsData, GetPagePathsErrors, GetPagePathsResponses, GetPagePathsSparklinesData, GetPagePathsSparklinesErrors, GetPagePathsSparklinesResponses, GetPagePathVisitorsData, GetPagePathVisitorsErrors, GetPagePathVisitorsResponses, GetPendingActionData, GetPendingActionErrors, GetPendingActionResponses, GetPerformanceMetricsData, GetPerformanceMetricsErrors, GetPerformanceMetricsResponses, GetPgUpgradeData, GetPgUpgradeErrors, GetPgUpgradeLogsData, GetPgUpgradeLogsErrors, GetPgUpgradeLogsResponses, GetPgUpgradeResponses, GetPipelineStatsData, GetPipelineStatsErrors, GetPipelineStatsResponses, GetPlatformInfoData, GetPlatformInfoErrors, GetPlatformInfoResponses, GetPostgresWalHealthData, GetPostgresWalHealthErrors, GetPostgresWalHealthResponses, GetPreferencesData, GetPreferencesErrors, GetPreferencesResponses, GetPreviewGatewayLogsData, GetPreviewGatewayLogsResponses, GetPreviewGatewaySettingsData, GetPreviewGatewaySettingsResponses, GetPreviewGatewayStatusData, GetPreviewGatewayStatusResponses, GetPricingData, GetPricingErrors, GetPricingResponses, GetPrivateIpData, GetPrivateIpErrors, GetPrivateIpResponses, GetProjectAlarmsSummaryData, GetProjectAlarmsSummaryErrors, GetProjectAlarmsSummaryResponses, GetProjectBySlugData, GetProjectBySlugErrors, GetProjectBySlugResponses, GetProjectData, GetProjectDeploymentsData, GetProjectDeploymentsErrors, GetProjectDeploymentsResponses, GetProjectErrors, GetProjectResponses, GetProjectsData, GetProjectsErrors, GetProjectServiceEnvironmentVariablesData, GetProjectServiceEnvironmentVariablesErrors, GetProjectServiceEnvironmentVariablesResponses, GetProjectSessionReplaysData, GetProjectSessionReplaysErrors, GetProjectSessionReplaysResponses, GetProjectsHealthData, GetProjectsHealthErrors, GetProjectsHealthResponses, GetProjectsMonitorHealthData, GetProjectsMonitorHealthErrors, GetProjectsMonitorHealthResponses, GetProjectsResponses, GetProjectStatisticsData, GetProjectStatisticsErrors, GetProjectStatisticsResponses, GetProjectTemplateData, GetProjectTemplateErrors, GetProjectTemplateResponses, GetPropertyBreakdownData, GetPropertyBreakdownErrors, GetPropertyBreakdownResponses, GetPropertyTimelineData, GetPropertyTimelineErrors, GetPropertyTimelineResponses, GetProviderConnectionsData, GetProviderConnectionsErrors, GetProviderConnectionsResponses, GetProviderMetadataData, GetProviderMetadataErrors, GetProviderMetadataResponses, GetProvidersMetadataData, GetProvidersMetadataErrors, GetProvidersMetadataResponses, GetProxyLogByIdData, GetProxyLogByIdErrors, GetProxyLogByIdResponses, GetProxyLogByRequestIdData, GetProxyLogByRequestIdErrors, GetProxyLogByRequestIdResponses, GetProxyLogsData, GetProxyLogsErrors, GetProxyLogsResponses, GetPublicBranchesData, GetPublicBranchesErrors, GetPublicBranchesResponses, GetPublicIpData, GetPublicIpErrors, GetPublicIpResponses, GetPublicRepositoryData, GetPublicRepositoryErrors, GetPublicRepositoryResponses, GetQueryContainerInfoData, GetQueryContainerInfoErrors, GetQueryContainerInfoResponses, GetQuotaData, GetQuotaErrors, GetQuotaResponses, GetRecentActivityData, GetRecentActivityErrors, GetRecentActivityResponses, GetRemoteExternalImageData, GetRemoteExternalImageErrors, GetRemoteExternalImageResponses, GetRepositoryBranchesData, GetRepositoryBranchesErrors, GetRepositoryBranchesResponses, GetRepositoryByIdData, GetRepositoryByIdErrors, GetRepositoryByIdResponses, GetRepositoryByNameData, GetRepositoryByNameErrors, GetRepositoryByNameResponses, GetRepositoryPresetByNameData, GetRepositoryPresetByNameErrors, GetRepositoryPresetByNameResponses, GetRepositoryPresetLiveData, GetRepositoryPresetLiveErrors, GetRepositoryPresetLiveResponses, GetRepositoryTagsData, GetRepositoryTagsErrors, GetRepositoryTagsResponses, GetResolvedEnvironmentVariablesData, GetResolvedEnvironmentVariablesErrors, GetResolvedEnvironmentVariablesResponses, GetResolvedEnvironmentVariableValueData, GetResolvedEnvironmentVariableValueErrors, GetResolvedEnvironmentVariableValueResponses, GetRestoreCapabilitiesData, GetRestoreCapabilitiesErrors, GetRestoreCapabilitiesResponses, GetRestoreRunData, GetRestoreRunErrors, GetRestoreRunResponses, GetRouteData, GetRouteErrors, GetRouteResponses, GetRunData, GetRunErrors, GetRunResponses, GetRunWithLogsData, GetRunWithLogsErrors, GetRunWithLogsResponses, GetS3CredentialsData, GetS3CredentialsErrors, GetS3CredentialsResponses, GetS3SourceData, GetS3SourceErrors, GetS3SourceResponses, GetSandboxData, GetSandboxErrors, GetSandboxResponses, GetSandboxStatusData, GetSandboxStatusErrors, GetSandboxStatusResponses, GetScanByDeploymentData, GetScanByDeploymentErrors, GetScanByDeploymentResponses, GetScanData, GetScanErrors, GetScanResponses, GetScanVulnerabilitiesData, GetScanVulnerabilitiesErrors, GetScanVulnerabilitiesResponses, GetServiceBySlugData, GetServiceBySlugErrors, GetServiceBySlugResponses, GetServiceData, GetServiceEnvironmentVariableData, GetServiceEnvironmentVariableErrors, GetServiceEnvironmentVariableResponses, GetServiceEnvironmentVariablesData, GetServiceEnvironmentVariablesErrors, GetServiceEnvironmentVariablesResponses, GetServiceErrors, GetServiceHealthStatusData, GetServiceHealthStatusErrors, GetServiceHealthStatusResponses, GetServicePreviewEnvironmentVariableNamesData, GetServicePreviewEnvironmentVariableNamesErrors, GetServicePreviewEnvironmentVariableNamesResponses, GetServicePreviewEnvironmentVariablesMaskedData, GetServicePreviewEnvironmentVariablesMaskedErrors, GetServicePreviewEnvironmentVariablesMaskedResponses, GetServiceResponses, GetServiceRuntimeData, GetServiceRuntimeErrors, GetServiceRuntimeResponses, GetServiceStatsData, GetServiceStatsErrors, GetServiceStatsResponses, GetServiceTypeParametersData, GetServiceTypeParametersErrors, GetServiceTypeParametersResponses, GetServiceTypesData, GetServiceTypesErrors, GetServiceTypesResponses, GetSessionDetailsData, GetSessionDetailsErrors, GetSessionDetailsResponses, GetSessionEventsData, GetSessionEventsErrors, GetSessionEventsResponses, GetSessionLogsData, GetSessionLogsErrors, GetSessionLogsResponses, GetSessionReplayData, GetSessionReplayErrors, GetSessionReplayEventsData, GetSessionReplayEventsErrors, GetSessionReplayEventsResponses, GetSessionReplayResponses, GetSettingsData, GetSettingsErrors, GetSettingsResponses, GetSkillData, GetSkillErrors, GetSkillResponses, GetSlowQueriesData, GetSlowQueriesErrors, GetSlowQueriesResponses, GetStaticBundleData, GetStaticBundleErrors, GetStaticBundleResponses, GetStatusOverviewData, GetStatusOverviewErrors, GetStatusOverviewResponses, GetTagsByRepositoryIdData, GetTagsByRepositoryIdErrors, GetTagsByRepositoryIdResponses, GetTeamData, GetTeamErrors, GetTeamResponses, GetTimeBucketStatsData, GetTimeBucketStatsErrors, GetTimeBucketStatsResponses, GetTodayStatsData, GetTodayStatsErrors, GetTodayStatsResponses, GetTraceData, GetTraceErrors, GetTraceResponses, GetUnifiedTraceData, GetUnifiedTraceErrors, GetUnifiedTraceResponses, GetUniqueCountsData, GetUniqueCountsErrors, GetUniqueCountsResponses, GetUniqueEventsData, GetUniqueEventsErrors, GetUniqueEventsResponses, GetUpdateStatusData, GetUpdateStatusErrors, GetUpdateStatusResponses, GetUptimeHistoryData, GetUptimeHistoryErrors, GetUptimeHistoryResponses, GetUsageByProviderData, GetUsageByProviderErrors, GetUsageByProviderResponses, GetUsageRecentData, GetUsageRecentErrors, GetUsageRecentResponses, GetUsageSummaryData, GetUsageSummaryErrors, GetUsageSummaryResponses, GetUsageTimeseriesData, GetUsageTimeseriesErrors, GetUsageTimeseriesResponses, GetUsageTopModelsData, GetUsageTopModelsErrors, GetUsageTopModelsResponses, GetVisitorByGuidData, GetVisitorByGuidErrors, GetVisitorByGuidResponses, GetVisitorByIdData, GetVisitorByIdErrors, GetVisitorByIdResponses, GetVisitorDetailsData, GetVisitorDetailsErrors, GetVisitorDetailsResponses, GetVisitorFacetsData, GetVisitorFacetsErrors, GetVisitorFacetsResponses, GetVisitorInfoData, GetVisitorInfoErrors, GetVisitorInfoResponses, GetVisitorJourneyData, GetVisitorJourneyErrors, GetVisitorJourneyResponses, GetVisitorsData, GetVisitorsErrors, GetVisitorSessionsData, GetVisitorSessionsErrors, GetVisitorSessionsResponses, GetVisitorsResponses, GetVisitorStatsData, GetVisitorStatsErrors, GetVisitorStatsResponses, GetWebhookData, GetWebhookErrors, GetWebhookResponses, GrantProjectAccessData, GrantProjectAccessErrors, GrantProjectAccessResponses, HandleGitProviderOauthCallbackData, HandleGitProviderOauthCallbackErrors, HasAnalyticsEventsData, HasAnalyticsEventsErrors, HasAnalyticsEventsResponses, HasErrorGroupsData, HasErrorGroupsErrors, HasErrorGroupsResponses, HasPerformanceMetricsData, HasPerformanceMetricsErrors, HasPerformanceMetricsResponses, ImportExternalServiceData, ImportExternalServiceErrors, ImportExternalServiceResponses, IngestLogsByPathData, IngestLogsByPathErrors, IngestLogsByPathResponses, IngestLogsData, IngestLogsErrors, IngestLogsResponses, IngestMetricsByPathData, IngestMetricsByPathErrors, IngestMetricsByPathResponses, IngestMetricsData, IngestMetricsErrors, IngestMetricsResponses, IngestSentryEnvelopeData, IngestSentryEnvelopeErrors, IngestSentryEnvelopeResponses, IngestSentryEventData, IngestSentryEventErrors, IngestSentryEventResponses, IngestTracesByPathData, IngestTracesByPathErrors, IngestTracesByPathResponses, IngestTracesData, IngestTracesErrors, IngestTracesResponses, InitSessionReplayData, InitSessionReplayErrors, InitSessionReplayResponses, InspectDropArchiveData, InspectDropArchiveErrors, InspectDropArchiveResponses, JobLogsData, JobLogsErrors, JobLogsResponses, JobStatusData, JobStatusErrors, JobStatusResponses, KillJobData, KillJobErrors, KillJobResponses, KvDelData, KvDelErrors, KvDelResponses, KvDisableData, KvDisableErrors, KvDisableResponses, KvEnableData, KvEnableErrors, KvEnableResponses, KvExpireData, KvExpireErrors, KvExpireResponses, KvGetData, KvGetErrors, KvGetResponses, KvIncrData, KvIncrErrors, KvIncrResponses, KvKeysData, KvKeysErrors, KvKeysResponses, KvSetData, KvSetErrors, KvSetResponses, KvStatusData, KvStatusErrors, KvStatusResponses, KvTtlData, KvTtlErrors, KvTtlResponses, KvUpdateData, KvUpdateErrors, KvUpdateResponses, LatestRunForSourceData, LatestRunForSourceErrors, LatestRunForSourceResponses, LinkCustomDomainToCertificateData, LinkCustomDomainToCertificateErrors, LinkCustomDomainToCertificateResponses, LinkServiceToProjectData, LinkServiceToProjectErrors, LinkServiceToProjectResponses, ListAgentRunsData, ListAgentRunsErrors, ListAgentRunsResponses, ListAgentsData, ListAgentsErrors, ListAgentsResponses, ListAiProvidersData, ListAiProvidersErrors, ListAiProvidersResponses, ListAlertRulesData, ListAlertRulesErrors, ListAlertRulesResponses, ListAlertsData, ListAlertsErrors, ListAlertsResponses, ListAllConversationsData, ListAllConversationsErrors, ListAllConversationsResponses, ListAllRunsData, ListAllRunsErrors, ListAllRunsResponses, ListApiKeysData, ListApiKeysErrors, ListApiKeysResponses, ListAuditLogsData, ListAuditLogsErrors, ListAuditLogsResponses, ListAvailableContainersData, ListAvailableContainersErrors, ListAvailableContainersResponses, ListBackupAlertsData, ListBackupAlertsErrors, ListBackupAlertsResponses, ListBackupChildrenData, ListBackupChildrenErrors, ListBackupChildrenResponses, ListBackupSchedulesData, ListBackupSchedulesErrors, ListBackupSchedulesResponses, ListBackupsForScheduleData, ListBackupsForScheduleErrors, ListBackupsForScheduleResponses, ListCommitsByRepositoryIdData, ListCommitsByRepositoryIdErrors, ListCommitsByRepositoryIdResponses, ListConnectionsData, ListConnectionsErrors, ListConnectionsResponses, ListContainersAtPathData, ListContainersAtPathErrors, ListContainersAtPathResponses, ListContainersData, ListContainersErrors, ListContainersResponses, ListConversationsData, ListConversationsErrors, ListConversationsResponses, ListCustomDomainsForProjectData, ListCustomDomainsForProjectErrors, ListCustomDomainsForProjectResponses, ListDashboardsData, ListDashboardsErrors, ListDashboardsResponses, ListDeliveriesData, ListDeliveriesErrors, ListDeliveriesResponses, ListDeploymentContainerLogsData, ListDeploymentContainerLogsErrors, ListDeploymentContainerLogsResponses, ListDeploymentTokensData, ListDeploymentTokensErrors, ListDeploymentTokensResponses, ListDnsProvidersData, ListDnsProvidersErrors, ListDnsProvidersResponses, ListDomainsData, ListDomainsErrors, ListDomainsResponses, ListDsnsData, ListDsnsErrors, ListDsnsResponses, ListEmailDomainsData, ListEmailDomainsErrors, ListEmailDomainsResponses, ListEmailProvidersData, ListEmailProvidersErrors, ListEmailProvidersResponses, ListEmailsData, ListEmailsErrors, ListEmailsResponses, ListEnrollmentTokensData, ListEnrollmentTokensErrors, ListEnrollmentTokensResponses, ListEntitiesData, ListEntitiesErrors, ListEntitiesResponses, ListErrorEventsData, ListErrorEventsErrors, ListErrorEventsResponses, ListErrorGroupsData, ListErrorGroupsErrors, ListErrorGroupsResponses, ListEventsData, ListEventsResponses, ListEventTypesData, ListEventTypesResponses, ListExternalImagesData, ListExternalImagesErrors, ListExternalImagesResponses, ListExternalPluginsData, ListExternalPluginsErrors, ListExternalPluginsResponses, ListExternalServiceBackupsData, ListExternalServiceBackupsErrors, ListExternalServiceBackupsResponses, ListFlagsData, ListFlagsErrors, ListFlagsResponses, ListFunnelsData, ListFunnelsErrors, ListFunnelsResponses, ListGitProvidersData, ListGitProvidersErrors, ListGitProvidersResponses, ListGlobalMcpsData, ListGlobalMcpsErrors, ListGlobalMcpsResponses, ListGlobalSkillsData, ListGlobalSkillsErrors, ListGlobalSkillsResponses, ListIncidentsData, ListIncidentsErrors, ListIncidentsResponses, ListInsightsData, ListInsightsErrors, ListInsightsResponses, ListIpAccessControlData, ListIpAccessControlErrors, ListIpAccessControlResponses, ListJobsData, ListJobsErrors, ListJobsResponses, ListKnownAiAgentsData, ListKnownAiAgentsErrors, ListKnownAiAgentsResponses, ListManagedDomainsData, ListManagedDomainsErrors, ListManagedDomainsResponses, ListMcpsData, ListMcpsErrors, ListMcpsResponses, ListMetricLabelKeysData, ListMetricLabelKeysErrors, ListMetricLabelKeysResponses, ListMetricLabelValuesData, ListMetricLabelValuesErrors, ListMetricLabelValuesResponses, ListMetricNamesData, ListMetricNamesErrors, ListMetricNamesResponses, ListModelsData, ListModelsErrors, ListModelsResponses, ListMonitorsData, ListMonitorsErrors, ListMonitorsResponses, ListNotificationProvidersData, ListNotificationProvidersErrors, ListNotificationProvidersResponses, ListOidcProvidersData, ListOidcProvidersResponses, ListOidcProviderUsersData, ListOidcProviderUsersErrors, ListOidcProviderUsersResponses, ListOidcRoleMappingsData, ListOidcRoleMappingsResponses, ListOnDemandCertsData, ListOnDemandCertsErrors, ListOnDemandCertsResponses, ListOrdersData, ListOrdersErrors, ListOrdersResponses, ListPeersData, ListPeersErrors, ListPeersResponses, ListPendingActionsData, ListPendingActionsErrors, ListPendingActionsResponses, ListPgUpgradesData, ListPgUpgradesErrors, ListPgUpgradesResponses, ListPresetsData, ListPresetsErrors, ListPresetsResponses, ListProjectAccessData, ListProjectAccessErrors, ListProjectAccessResponses, ListProjectAlarmsData, ListProjectAlarmsErrors, ListProjectAlarmsResponses, ListProjectScansData, ListProjectScansErrors, ListProjectScansResponses, ListProjectSecretsData, ListProjectSecretsErrors, ListProjectSecretsResponses, ListProjectServicesData, ListProjectServicesErrors, ListProjectServicesResponses, ListProjectTemplatesData, ListProjectTemplatesErrors, ListProjectTemplatesResponses, ListProjectTemplateTagsData, ListProjectTemplateTagsErrors, ListProjectTemplateTagsResponses, ListProviderKeysData, ListProviderKeysErrors, ListProviderKeysResponses, ListProviderZonesData, ListProviderZonesErrors, ListProviderZonesResponses, ListPublicProvidersData, ListPublicProvidersResponses, ListReleaseFilesData, ListReleaseFilesErrors, ListReleaseFilesResponses, ListReleasesData, ListReleasesErrors, ListReleasesResponses, ListRemoteExternalImagesData, ListRemoteExternalImagesErrors, ListRemoteExternalImagesResponses, ListRepositoriesByConnectionData, ListRepositoriesByConnectionErrors, ListRepositoriesByConnectionResponses, ListRepositoriesByProviderData, ListRepositoriesByProviderErrors, ListRepositoriesByProviderResponses, ListRestoreRunsForServiceData, ListRestoreRunsForServiceResponses, ListRootContainersData, ListRootContainersErrors, ListRootContainersResponses, ListRoutesData, ListRoutesErrors, ListRoutesResponses, ListS3SourcesData, ListS3SourcesErrors, ListS3SourcesResponses, ListSandboxesData, ListSandboxesResponses, ListScheduleRunJobsData, ListScheduleRunJobsErrors, ListScheduleRunJobsResponses, ListScheduleRunsData, ListScheduleRunsErrors, ListScheduleRunsResponses, ListScheduleServicesData, ListScheduleServicesErrors, ListScheduleServicesResponses, ListSecretsData, ListSecretsErrors, ListSecretsResponses, ListServiceHealthStatusesData, ListServiceHealthStatusesErrors, ListServiceHealthStatusesResponses, ListServiceProjectsData, ListServiceProjectsErrors, ListServiceProjectsResponses, ListServiceSchedulesData, ListServiceSchedulesErrors, ListServiceSchedulesResponses, ListServicesData, ListServicesErrors, ListServicesResponses, ListSkillsData, ListSkillsErrors, ListSkillsResponses, ListSourceBackupsData, ListSourceBackupsErrors, ListSourceBackupsResponses, ListSourceFilesData, ListSourceFilesErrors, ListSourceFilesResponses, ListSourceMapsData, ListSourceMapsErrors, ListSourceMapsResponses, ListSourcesData, ListSourcesErrors, ListSourcesResponses, ListStaticBundlesData, ListStaticBundlesErrors, ListStaticBundlesResponses, ListSyncedRepositoriesData, ListSyncedRepositoriesErrors, ListSyncedRepositoriesResponses, ListTeamMembersData, ListTeamMembersErrors, ListTeamMembersResponses, ListTeamProjectsData, ListTeamProjectsErrors, ListTeamProjectsResponses, ListTeamsData, ListTeamsErrors, ListTeamsResponses, ListUsersData, ListUsersErrors, ListUsersResponses, ListWebhooksData, ListWebhooksErrors, ListWebhooksResponses, LoginData, LoginErrors, LoginResponses, LogoutData, LogoutErrors, LogoutResponses, LookupDnsARecordsData, LookupDnsARecordsErrors, LookupDnsARecordsResponses, MintEnrollmentTokenData, MintEnrollmentTokenErrors, MintEnrollmentTokenResponses, MkdirData, MkdirErrors, MkdirResponses, NodeHeartbeatData, NodeHeartbeatErrors, NodeHeartbeatResponses, NodeMetricsGetRangeData, NodeMetricsGetRangeErrors, NodeMetricsGetRangeResponses, ObservabilityFullEventData, ObservabilityFullEventErrors, ObservabilityFullEventResponses, ObservabilityListEventsData, ObservabilityListEventsErrors, ObservabilityListEventsResponses, OidcCallbackData, PatchAdminGateData, PatchAdminGateErrors, PatchAdminGateResponses, PatchPreviewGatewaySettingsData, PatchPreviewGatewaySettingsResponses, PauseDeploymentData, PauseDeploymentErrors, PauseDeploymentResponses, PauseSandboxData, PauseSandboxErrors, PauseSandboxResponses, PlanRestoreData, PlanRestoreErrors, PlanRestoreResponses, PostDnsAckData, PostDnsAckErrors, PostDnsAckResponses, PreviewAlertData, PreviewAlertErrors, PreviewAlertResponses, PreviewFunnelMetricsData, PreviewFunnelMetricsErrors, PreviewFunnelMetricsResponses, PreviewHostnameModeData, PreviewHostnameModeErrors, PreviewHostnameModeResponses, PromoteClusterMemberData, PromoteClusterMemberErrors, PromoteClusterMemberResponses, PromoteDeploymentData, PromoteDeploymentErrors, PromoteDeploymentResponses, ProvisionDomainData, ProvisionDomainErrors, ProvisionDomainResponses, PurgeProjectLogsData, PurgeProjectLogsErrors, PurgeProjectLogsResponses, PushExternalImageData, PushExternalImageErrors, PushExternalImageResponses, QueryDataData, QueryDataErrors, QueryDataResponses, QueryGenaiTracesData, QueryGenaiTracesErrors, QueryGenaiTracesResponses, QueryLogsData, QueryLogsErrors, QueryLogsResponses, QueryMetricsData, QueryMetricsErrors, QueryMetricsResponses, QuerySpanStatsData, QuerySpanStatsErrors, QuerySpanStatsResponses, QueryTracesData, QueryTracesErrors, QueryTracesResponses, QueryTraceSummariesData, QueryTraceSummariesErrors, QueryTraceSummariesResponses, ReadEntityRowsData, ReadEntityRowsErrors, ReadEntityRowsResponses, ReadFileData, ReadFileErrors, ReadFileResponses, ReAnalyzeData, ReAnalyzeErrors, ReAnalyzeResponses, RecordConsoleEventData, RecordConsoleEventErrors, RecordConsoleEventResponses, RecordEventMetricsData, RecordEventMetricsErrors, RecordEventMetricsResponses, RecordFlagExposureData, RecordFlagExposureErrors, RecordFlagExposureResponses, RecordSpeedMetricsData, RecordSpeedMetricsErrors, RecordSpeedMetricsResponses, RefreshRouteTableData, RefreshRouteTableErrors, RefreshRouteTableResponses, RegenerateDsnData, RegenerateDsnErrors, RegenerateDsnResponses, RegisterExternalImageData, RegisterExternalImageErrors, RegisterExternalImageResponses, RegisterNodeData, RegisterNodeErrors, RegisterNodeResponses, ReinstallGitlabWebhookData, ReinstallGitlabWebhookErrors, ReinstallGitlabWebhookResponses, RejectPendingActionData, RejectPendingActionErrors, RejectPendingActionResponses, ReloadPluginsData, ReloadPluginsErrors, ReloadPluginsResponses, RemoveClusterMemberData, RemoveClusterMemberErrors, RemoveClusterMemberResponses, RemoveManagedDomainData, RemoveManagedDomainErrors, RemoveManagedDomainResponses, RemoveRoleData, RemoveRoleErrors, RemoveRoleResponses, RemoveTeamMemberData, RemoveTeamMemberErrors, RemoveTeamMemberResponses, RenameConversationData, RenameConversationErrors, RenameConversationResponses, RenewDomainData, RenewDomainErrors, RenewDomainResponses, RequestPasswordResetData, RequestPasswordResetErrors, RequestPasswordResetResponses, ResetPasswordData, ResetPasswordErrors, ResetPasswordResponses, ResizeSandboxData, ResizeSandboxErrors, ResizeSandboxResponses, ResolveAlarmData, ResolveAlarmErrors, ResolveAlarmResponses, RestartContainerData, RestartContainerErrors, RestartContainerResponses, RestartPreviewGatewayData, RestartPreviewGatewayResponses, RestartSandboxData, RestartSandboxErrors, RestartSandboxResponses, RestoreFlagData, RestoreFlagErrors, RestoreFlagResponses, RestoreUserData, RestoreUserErrors, RestoreUserResponses, ResumeDeploymentData, ResumeDeploymentErrors, ResumeDeploymentResponses, ResumeSandboxData, ResumeSandboxErrors, ResumeSandboxResponses, RetryClusterData, RetryClusterErrors, RetryClusterResponses, RetryDeliveryData, RetryDeliveryErrors, RetryDeliveryResponses, RetryPgUpgradeData, RetryPgUpgradeErrors, RetryPgUpgradeResponses, RetryRunData, RetryRunErrors, RetryRunResponses, RevealGlobalMcpConfigData, RevealGlobalMcpConfigErrors, RevealGlobalMcpConfigResponses, RevealMcpConfigData, RevealMcpConfigErrors, RevealMcpConfigResponses, RevealNotificationProviderConfigData, RevealNotificationProviderConfigErrors, RevealNotificationProviderConfigResponses, RevealServiceParameterData, RevealServiceParameterErrors, RevealServiceParameterResponses, RevenueCreateIntegrationData, RevenueCreateIntegrationErrors, RevenueCreateIntegrationResponses, RevenueDeleteIntegrationData, RevenueDeleteIntegrationResponses, RevenueGlobalEventsData, RevenueGlobalEventsResponses, RevenueImportInvoicesCsvData, RevenueImportInvoicesCsvErrors, RevenueImportInvoicesCsvResponses, RevenueImportSubscriptionsCsvData, RevenueImportSubscriptionsCsvErrors, RevenueImportSubscriptionsCsvResponses, RevenueListIntegrationsData, RevenueListIntegrationsResponses, RevenueListProvidersData, RevenueListProvidersResponses, RevenueMetricsCustomersData, RevenueMetricsCustomersResponses, RevenueMetricsGlobalMrrData, RevenueMetricsGlobalMrrResponses, RevenueMetricsGlobalSummaryData, RevenueMetricsGlobalSummaryResponses, RevenueMetricsMrrData, RevenueMetricsMrrResponses, RevenueMetricsSummaryData, RevenueMetricsSummaryResponses, RevenueRecentEventsData, RevenueRecentEventsResponses, RevenueRotateTokenData, RevenueRotateTokenResponses, RevenueUpdateConfigData, RevenueUpdateConfigErrors, RevenueUpdateConfigResponses, RevenueUpdateSecretData, RevenueUpdateSecretErrors, RevenueUpdateSecretResponses, RevokeDsnData, RevokeDsnErrors, RevokeDsnResponses, RevokeEnrollmentTokenData, RevokeEnrollmentTokenErrors, RevokeEnrollmentTokenResponses, RevokeJoinTokenData, RevokeJoinTokenErrors, RevokeJoinTokenResponses, RevokeProjectAccessData, RevokeProjectAccessErrors, RevokeProjectAccessResponses, RollbackPgUpgradeData, RollbackPgUpgradeErrors, RollbackPgUpgradeResponses, RollbackToDeploymentData, RollbackToDeploymentErrors, RollbackToDeploymentResponses, RootfsGcData, RootfsGcResponses, RootfsReportData, RootfsReportResponses, RotateApiKeyData, RotateApiKeyErrors, RotateApiKeyResponses, RotateDeploymentTokenData, RotateDeploymentTokenErrors, RotateDeploymentTokenResponses, RunBackupForSourceData, RunBackupForSourceErrors, RunBackupForSourceResponses, RunConnectionHealthCheckData, RunConnectionHealthCheckErrors, RunConnectionHealthCheckResponses, RunExternalServiceBackupData, RunExternalServiceBackupErrors, RunExternalServiceBackupResponses, RunScheduleNowData, RunScheduleNowErrors, RunScheduleNowResponses, SandboxCreatePreviewLinkData, SandboxCreatePreviewLinkErrors, SandboxCreatePreviewLinkResponses, SaveAgentTokenData, SaveAgentTokenErrors, SaveAgentTokenResponses, SaveAiProviderCredentialData, SaveAiProviderCredentialErrors, SaveAiProviderCredentialResponses, SearchLogsData, SearchLogsErrors, SearchLogsResponses, SendEmailData, SendEmailErrors, SendEmailResponses, SetAiDataAccessData, SetAiDataAccessErrors, SetAiDataAccessResponses, SetDefaultS3SourceData, SetDefaultS3SourceErrors, SetDefaultS3SourceResponses, SetFlagEnvironmentData, SetFlagEnvironmentErrors, SetFlagEnvironmentResponses, SetPreviewPasswordData, SetPreviewPasswordErrors, SetPreviewPasswordResponses, SetupDnsChallengeData, SetupDnsChallengeErrors, SetupDnsChallengeResponses, SetupDnsData, SetupDnsErrors, SetupDnsResponses, SetupEmailTrackingData, SetupEmailTrackingErrors, SetupEmailTrackingResponses, SetupMfaData, SetupMfaErrors, SetupMfaResponses, SleepEnvironmentData, SleepEnvironmentErrors, SleepEnvironmentResponses, SmokeTestAgentData, SmokeTestAgentErrors, SmokeTestAgentResponses, SourceSandboxData, SourceSandboxErrors, SourceSandboxResponses, StartAnalysisData, StartAnalysisErrors, StartAnalysisResponses, StartContainerData, StartContainerErrors, StartContainerResponses, StartFixData, StartFixErrors, StartFixResponses, StartGitProviderOauthData, StartGitProviderOauthErrors, StartOidcLoginBySlugData, StartOidcLoginBySlugErrors, StartPgUpgradeData, StartPgUpgradeErrors, StartPgUpgradeResponses, StartRestoreData, StartRestoreErrors, StartRestoreResponses, StartServiceData, StartServiceErrors, StartServiceResponses, StatPathData, StatPathErrors, StatPathResponses, StopContainerData, StopContainerErrors, StopContainerResponses, StopSandboxData, StopSandboxErrors, StopSandboxResponses, StopServiceData, StopServiceErrors, StopServiceResponses, StreamContainerMetricsData, StreamContainerMetricsErrors, StreamContainerMetricsResponses, StreamEventsData, StreamEventsErrors, StreamEventsResponses, StreamRunEventsData, StreamRunEventsErrors, StreamRunEventsResponses, SyncRepositoriesData, SyncRepositoriesErrors, SyncRepositoriesResponses, TailDeploymentJobLogsData, TailDeploymentJobLogsErrors, TailLogsData, TailLogsErrors, TailLogsResponses, TeardownDeploymentData, TeardownDeploymentErrors, TeardownDeploymentResponses, TeardownEnvironmentData, TeardownEnvironmentErrors, TeardownEnvironmentResponses, TestNotificationProviderData, TestNotificationProviderErrors, TestNotificationProviderResponses, TestOidcProviderData, TestOidcProviderResponses, TestProviderConnectionData, TestProviderConnectionErrors, TestProviderConnectionResponses, TestProviderData, TestProviderErrors, TestProviderKeyByIdData, TestProviderKeyByIdErrors, TestProviderKeyByIdResponses, TestProviderKeyInlineData, TestProviderKeyInlineErrors, TestProviderKeyInlineResponses, TestProviderResponses, TestS3ConnectionPreviewData, TestS3ConnectionPreviewErrors, TestS3ConnectionPreviewResponses, TestS3SourceConnectionData, TestS3SourceConnectionErrors, TestS3SourceConnectionResponses, TrackClickData, TrackClickErrors, TrackOpenData, TrackOpenErrors, TrackOpenResponses, TriggerAgentData, TriggerAgentErrors, TriggerAgentResponses, TriggerProjectPipelineData, TriggerProjectPipelineErrors, TriggerProjectPipelineResponses, TriggerScanData, TriggerScanErrors, TriggerScanResponses, TriggerServiceHealthCheckData, TriggerServiceHealthCheckErrors, TriggerServiceHealthCheckResponses, TriggerWeeklyDigestData, TriggerWeeklyDigestErrors, TriggerWeeklyDigestResponses, UnlinkServiceFromProjectData, UnlinkServiceFromProjectErrors, UnlinkServiceFromProjectResponses, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponses, UpdateAiProviderData, UpdateAiProviderErrors, UpdateAiProviderResponses, UpdateAlertData, UpdateAlertErrors, UpdateAlertResponses, UpdateAlertRuleData, UpdateAlertRuleErrors, UpdateAlertRuleResponses, UpdateApiKeyData, UpdateApiKeyErrors, UpdateApiKeyResponses, UpdateAutomaticDeployData, UpdateAutomaticDeployErrors, UpdateAutomaticDeployResponses, UpdateBackupScheduleData, UpdateBackupScheduleErrors, UpdateBackupScheduleResponses, UpdateCloudflareProviderData, UpdateCloudflareProviderErrors, UpdateCloudflareProviderResponses, UpdateConnectionTokenData, UpdateConnectionTokenErrors, UpdateConnectionTokenResponses, UpdateCustomDomainData, UpdateCustomDomainErrors, UpdateCustomDomainResponses, UpdateDashboardData, UpdateDashboardErrors, UpdateDashboardResponses, UpdateDeploymentTokenData, UpdateDeploymentTokenErrors, UpdateDeploymentTokenResponses, UpdateEmailProviderData, UpdateEmailProviderErrors, UpdateEmailProviderResponses, UpdateEnvironmentSettingsData, UpdateEnvironmentSettingsErrors, UpdateEnvironmentSettingsResponses, UpdateEnvironmentSubdomainData, UpdateEnvironmentSubdomainErrors, UpdateEnvironmentSubdomainResponses, UpdateEnvironmentVariableData, UpdateEnvironmentVariableErrors, UpdateEnvironmentVariableResponses, UpdateErrorGroupData, UpdateErrorGroupErrors, UpdateErrorGroupResponses, UpdateFlagData, UpdateFlagErrors, UpdateFlagResponses, UpdateFunnelData, UpdateFunnelErrors, UpdateFunnelResponses, UpdateGitProviderCredentialsData, UpdateGitProviderCredentialsErrors, UpdateGitProviderCredentialsResponses, UpdateGitSettingsData, UpdateGitSettingsErrors, UpdateGitSettingsResponses, UpdateGlobalMcpData, UpdateGlobalMcpErrors, UpdateGlobalMcpResponses, UpdateGlobalSkillData, UpdateGlobalSkillErrors, UpdateGlobalSkillResponses, UpdateIncidentStatusData, UpdateIncidentStatusErrors, UpdateIncidentStatusResponses, UpdateIpAccessControlData, UpdateIpAccessControlErrors, UpdateIpAccessControlResponses, UpdateManagedDomainData, UpdateManagedDomainErrors, UpdateManagedDomainResponses, UpdateMcpData, UpdateMcpErrors, UpdateMcpResponses, UpdateNotificationEmailProviderData, UpdateNotificationEmailProviderErrors, UpdateNotificationEmailProviderResponses, UpdateNotificationProviderData, UpdateNotificationProviderErrors, UpdateNotificationProviderResponses, UpdateOidcProviderData, UpdateOidcProviderResponses, UpdatePreferencesData, UpdatePreferencesErrors, UpdatePreferencesResponses, UpdateProjectData, UpdateProjectDeploymentConfigData, UpdateProjectDeploymentConfigErrors, UpdateProjectDeploymentConfigResponses, UpdateProjectErrors, UpdateProjectResponses, UpdateProjectSecretData, UpdateProjectSecretErrors, UpdateProjectSecretResponses, UpdateProjectSettingsData, UpdateProjectSettingsErrors, UpdateProjectSettingsResponses, UpdateProviderData, UpdateProviderErrors, UpdateProviderKeyData, UpdateProviderKeyErrors, UpdateProviderKeyResponses, UpdateProviderResponses, UpdateRouteData, UpdateRouteErrors, UpdateRouteResponses, UpdateS3SourceData, UpdateS3SourceErrors, UpdateS3SourceResponses, UpdateSelfData, UpdateSelfErrors, UpdateSelfResponses, UpdateServiceData, UpdateServiceErrors, UpdateServiceResourcesData, UpdateServiceResourcesErrors, UpdateServiceResourcesResponses, UpdateServiceResponses, UpdateSessionDurationData, UpdateSessionDurationErrors, UpdateSessionDurationResponses, UpdateSettingsData, UpdateSettingsErrors, UpdateSettingsResponses, UpdateSkillData, UpdateSkillErrors, UpdateSkillResponses, UpdateSlackProviderData, UpdateSlackProviderErrors, UpdateSlackProviderResponses, UpdateSpeedMetricsData, UpdateSpeedMetricsErrors, UpdateSpeedMetricsResponses, UpdateTeamData, UpdateTeamErrors, UpdateTeamMemberRoleData, UpdateTeamMemberRoleErrors, UpdateTeamMemberRoleResponses, UpdateTeamResponses, UpdateUserData, UpdateUserErrors, UpdateUserResponses, UpdateWebhookData, UpdateWebhookErrors, UpdateWebhookProviderData, UpdateWebhookProviderErrors, UpdateWebhookProviderResponses, UpdateWebhookResponses, UpgradePreviewGatewayData, UpgradePreviewGatewayResponses, UpgradeServiceData, UpgradeServiceErrors, UpgradeServiceResponses, UploadGlobalSkillData, UploadGlobalSkillErrors, UploadGlobalSkillResponses, UploadReleaseFileData, UploadReleaseFileErrors, UploadReleaseFileResponses, UploadSkillData, UploadSkillErrors, UploadSkillResponses, UploadSourceFileData, UploadSourceFileErrors, UploadSourceFileResponses, UploadSourceMapData, UploadSourceMapErrors, UploadSourceMapResponses, UploadStaticBundleData, UploadStaticBundleErrors, UploadStaticBundleResponses, UpsertSecretData, UpsertSecretErrors, UpsertSecretResponses, ValidateConnectionData, ValidateConnectionErrors, ValidateConnectionResponses, ValidateEmailData, ValidateEmailErrors, ValidateEmailResponses, VerifyAndEnableMfaData, VerifyAndEnableMfaErrors, VerifyAndEnableMfaResponses, VerifyDomainData, VerifyDomainErrors, VerifyDomainResponses, VerifyEmailData, VerifyEmailErrors, VerifyEmailResponses, VerifyManagedDomainData, VerifyManagedDomainErrors, VerifyManagedDomainResponses, VerifyMfaChallengeData, VerifyMfaChallengeErrors, VerifyMfaChallengeResponses, VerifyStepUpData, VerifyStepUpErrors, VerifyStepUpResponses, WakeEnvironmentData, WakeEnvironmentErrors, WakeEnvironmentResponses, WebhookTriggerData, WebhookTriggerErrors, WebhookTriggerResponses, WorkflowDryRunData, WorkflowDryRunErrors, WorkflowDryRunResponses, WriteFileData, WriteFileErrors, WriteFileResponses, WriteFilesData, WriteFilesErrors, WriteFilesResponses } from './types.gen'; +import type { AcknowledgeAlarmData, AcknowledgeAlarmErrors, AcknowledgeAlarmResponses, ActivateAiProviderData, ActivateAiProviderErrors, ActivateAiProviderResponses, ActivateApiKeyData, ActivateApiKeyErrors, ActivateApiKeyResponses, ActivateConnectionData, ActivateConnectionErrors, ActivateConnectionResponses, ActivateProviderData, ActivateProviderErrors, ActivateProviderResponses, AddClusterMemberData, AddClusterMemberErrors, AddClusterMemberResponses, AddContextData, AddContextErrors, AddContextResponses, AddEnvironmentDomainData, AddEnvironmentDomainErrors, AddEnvironmentDomainResponses, AddEventsData, AddEventsErrors, AddEventsResponses, AddManagedDomainData, AddManagedDomainErrors, AddManagedDomainResponses, AddSessionReplayEventsData, AddSessionReplayEventsErrors, AddSessionReplayEventsResponses, AddTeamMemberData, AddTeamMemberErrors, AddTeamMemberResponses, AdminDrainNodeData, AdminDrainNodeErrors, AdminDrainNodeResponses, AdminDrainStatusData, AdminDrainStatusErrors, AdminDrainStatusResponses, AdminGetNodeData, AdminGetNodeErrors, AdminGetNodeResponses, AdminListNodeContainersData, AdminListNodeContainersErrors, AdminListNodeContainersResponses, AdminListNodesData, AdminListNodesErrors, AdminListNodesResponses, AdminRemoveNodeData, AdminRemoveNodeErrors, AdminRemoveNodeResponses, AdminUndrainNodeData, AdminUndrainNodeErrors, AdminUndrainNodeResponses, ApplyHostnameModeData, ApplyHostnameModeErrors, ApplyHostnameModeResponses, ArchiveConversationData, ArchiveConversationErrors, ArchiveConversationResponses, ArchiveFlagData, ArchiveFlagErrors, ArchiveFlagResponses, AssignRoleData, AssignRoleErrors, AssignRoleResponses, AttachScheduleServicesData, AttachScheduleServicesErrors, AttachScheduleServicesResponses, BlobCopyData, BlobCopyErrors, BlobCopyResponses, BlobDeleteData, BlobDeleteErrors, BlobDeleteResponses, BlobDisableData, BlobDisableErrors, BlobDisableResponses, BlobDownloadData, BlobDownloadErrors, BlobDownloadResponses, BlobEnableData, BlobEnableErrors, BlobEnableResponses, BlobHeadData, BlobHeadErrors, BlobHeadResponses, BlobListData, BlobListErrors, BlobListResponses, BlobPutData, BlobPutErrors, BlobPutResponses, BlobStatusData, BlobStatusErrors, BlobStatusResponses, BlobUpdateData, BlobUpdateErrors, BlobUpdateResponses, CancelBackupData, CancelBackupErrors, CancelBackupResponses, CancelData, CancelDeploymentData, CancelDeploymentErrors, CancelDeploymentResponses, CancelDomainOrderData, CancelDomainOrderErrors, CancelDomainOrderResponses, CancelErrors, CancelPgUpgradeData, CancelPgUpgradeErrors, CancelPgUpgradeResponses, CancelResponses, CancelRunData, CancelRunErrors, CancelRunResponses, CancelScheduleRunData, CancelScheduleRunErrors, CancelScheduleRunResponses, ChangePasswordSelfData, ChangePasswordSelfErrors, ChangePasswordSelfResponses, ChangeProjectSourceData, ChangeProjectSourceErrors, ChangeProjectSourceResponses, ChangeRequiredPasswordData, ChangeRequiredPasswordErrors, ChangeRequiredPasswordResponses, ChatCompletionsData, ChatCompletionsErrors, ChatCompletionsResponses, CheckAnalyticsHasEventsData, CheckAnalyticsHasEventsErrors, CheckAnalyticsHasEventsResponses, CheckCommitExistsData, CheckCommitExistsErrors, CheckCommitExistsResponses, CheckDomainStatusData, CheckDomainStatusErrors, CheckDomainStatusResponses, CheckExplorerSupportData, CheckExplorerSupportErrors, CheckExplorerSupportResponses, CheckIpBlockedData, CheckIpBlockedErrors, CheckIpBlockedResponses, CheckProviderDeletionSafetyData, CheckProviderDeletionSafetyErrors, CheckProviderDeletionSafetyResponses, ChunkUploadOptionsData, ChunkUploadOptionsResponses, CleanupExpiredBackupsData, CleanupExpiredBackupsErrors, CleanupExpiredBackupsResponses, ClearPreviewPasswordData, ClearPreviewPasswordErrors, ClearPreviewPasswordResponses, CliDeviceApproveData, CliDeviceApproveErrors, CliDeviceApproveResponses, CliDeviceDenyData, CliDeviceDenyErrors, CliDeviceDenyResponses, CliDeviceLookupData, CliDeviceLookupErrors, CliDeviceLookupResponses, CliDevicePollData, CliDevicePollErrors, CliDevicePollResponses, CliDeviceStartData, CliDeviceStartErrors, CliDeviceStartResponses, CliLogoutData, CliLogoutErrors, CliLogoutResponses, CmdData, CmdErrors, CmdKillData, CmdKillErrors, CmdKillResponses, CmdLogsData, CmdLogsErrors, CmdLogsResponses, CmdResponses, ConfirmPendingActionData, ConfirmPendingActionErrors, ConfirmPendingActionResponses, ContainerMetricsGetHistoryData, ContainerMetricsGetHistoryErrors, ContainerMetricsGetHistoryResponses, CreateAgentData, CreateAgentErrors, CreateAgentResponses, CreateAlertData, CreateAlertErrors, CreateAlertResponses, CreateAlertRuleData, CreateAlertRuleErrors, CreateAlertRuleResponses, CreateApiKeyData, CreateApiKeyErrors, CreateApiKeyResponses, CreateBackupScheduleData, CreateBackupScheduleErrors, CreateBackupScheduleResponses, CreateBitbucketProviderData, CreateBitbucketProviderErrors, CreateBitbucketProviderResponses, CreateCloudflareProviderData, CreateCloudflareProviderErrors, CreateCloudflareProviderResponses, CreateConversationData, CreateConversationErrors, CreateConversationResponses, CreateCustomDomainData, CreateCustomDomainErrors, CreateCustomDomainResponses, CreateDashboardData, CreateDashboardErrors, CreateDashboardResponses, CreateDeploymentTokenData, CreateDeploymentTokenErrors, CreateDeploymentTokenResponses, CreateDnsProviderData, CreateDnsProviderErrors, CreateDnsProviderResponses, CreateDomainData, CreateDomainErrors, CreateDomainResponses, CreateDsnData, CreateDsnErrors, CreateDsnResponses, CreateEmailDomainData, CreateEmailDomainErrors, CreateEmailDomainResponses, CreateEmailProviderData, CreateEmailProviderErrors, CreateEmailProviderResponses, CreateEnvironmentData, CreateEnvironmentErrors, CreateEnvironmentResponses, CreateEnvironmentVariableData, CreateEnvironmentVariableErrors, CreateEnvironmentVariableResponses, CreateFlagData, CreateFlagErrors, CreateFlagResponses, CreateFunnelData, CreateFunnelErrors, CreateFunnelResponses, CreateGenericProviderData, CreateGenericProviderErrors, CreateGenericProviderResponses, CreateGiteaPatProviderData, CreateGiteaPatProviderErrors, CreateGiteaPatProviderResponses, CreateGithubPatProviderData, CreateGithubPatProviderErrors, CreateGithubPatProviderResponses, CreateGitlabOauthProviderData, CreateGitlabOauthProviderErrors, CreateGitlabOauthProviderResponses, CreateGitlabPatProviderData, CreateGitlabPatProviderErrors, CreateGitlabPatProviderResponses, CreateGitProviderData, CreateGitProviderErrors, CreateGitProviderResponses, CreateGlobalMcpData, CreateGlobalMcpErrors, CreateGlobalMcpResponses, CreateGlobalSkillData, CreateGlobalSkillErrors, CreateGlobalSkillResponses, CreateIncidentData, CreateIncidentErrors, CreateIncidentResponses, CreateIpAccessControlData, CreateIpAccessControlErrors, CreateIpAccessControlResponses, CreateMcpData, CreateMcpErrors, CreateMcpResponses, CreateMonitorData, CreateMonitorErrors, CreateMonitorResponses, CreateNotificationEmailProviderData, CreateNotificationEmailProviderErrors, CreateNotificationEmailProviderResponses, CreateNotificationProviderData, CreateNotificationProviderErrors, CreateNotificationProviderResponses, CreateOidcProviderData, CreateOidcProviderErrors, CreateOidcProviderResponses, CreateOidcRoleMappingData, CreateOidcRoleMappingResponses, CreateOrRecreateOrderData, CreateOrRecreateOrderErrors, CreateOrRecreateOrderResponses, CreatePlanData, CreatePlanErrors, CreatePlanResponses, CreatePrData, CreatePrErrors, CreateProjectData, CreateProjectErrors, CreateProjectFromTemplateData, CreateProjectFromTemplateErrors, CreateProjectFromTemplateResponses, CreateProjectReleaseData, CreateProjectReleaseErrors, CreateProjectReleaseResponses, CreateProjectResponses, CreateProjectSecretData, CreateProjectSecretErrors, CreateProjectSecretResponses, CreateProviderKeyData, CreateProviderKeyErrors, CreateProviderKeyResponses, CreatePrResponses, CreateReleaseData, CreateReleaseErrors, CreateReleaseResponses, CreateRouteData, CreateRouteErrors, CreateRouteResponses, CreateS3SourceData, CreateS3SourceErrors, CreateS3SourceResponses, CreateSandboxData, CreateSandboxErrors, CreateSandboxResponses, CreateServiceData, CreateServiceErrors, CreateServiceResponses, CreateSkillData, CreateSkillErrors, CreateSkillResponses, CreateSlackProviderData, CreateSlackProviderErrors, CreateSlackProviderResponses, CreateTeamData, CreateTeamErrors, CreateTeamResponses, CreateUserData, CreateUserErrors, CreateUserResponses, CreateWebhookData, CreateWebhookErrors, CreateWebhookProviderData, CreateWebhookProviderErrors, CreateWebhookProviderResponses, CreateWebhookResponses, DeactivateApiKeyData, DeactivateApiKeyErrors, DeactivateApiKeyResponses, DeactivateConnectionData, DeactivateConnectionErrors, DeactivateConnectionResponses, DeactivateProviderData, DeactivateProviderErrors, DeactivateProviderResponses, DeleteAgentData, DeleteAgentErrors, DeleteAgentResponses, DeleteAlertData, DeleteAlertErrors, DeleteAlertResponses, DeleteAlertRuleData, DeleteAlertRuleErrors, DeleteAlertRuleResponses, DeleteApiKeyData, DeleteApiKeyErrors, DeleteApiKeyResponses, DeleteBackupData, DeleteBackupErrors, DeleteBackupResponses, DeleteBackupScheduleData, DeleteBackupScheduleErrors, DeleteBackupScheduleResponses, DeleteConnectionData, DeleteConnectionErrors, DeleteConnectionResponses, DeleteCustomDomainData, DeleteCustomDomainErrors, DeleteCustomDomainResponses, DeleteDashboardData, DeleteDashboardErrors, DeleteDashboardResponses, DeleteDeploymentTokenData, DeleteDeploymentTokenErrors, DeleteDeploymentTokenResponses, DeleteDnsProviderData, DeleteDnsProviderErrors, DeleteDnsProviderResponses, DeleteDomainData, DeleteDomainErrors, DeleteDomainResponses, DeleteEmailDomainData, DeleteEmailDomainErrors, DeleteEmailDomainResponses, DeleteEmailProviderData, DeleteEmailProviderErrors, DeleteEmailProviderResponses, DeleteEnvironmentData, DeleteEnvironmentDomainData, DeleteEnvironmentDomainErrors, DeleteEnvironmentDomainResponses, DeleteEnvironmentErrors, DeleteEnvironmentResponses, DeleteEnvironmentVariableData, DeleteEnvironmentVariableErrors, DeleteEnvironmentVariableResponses, DeleteExternalImageData, DeleteExternalImageErrors, DeleteExternalImageResponses, DeleteFunnelData, DeleteFunnelErrors, DeleteFunnelResponses, DeleteGitProviderData, DeleteGitProviderErrors, DeleteGitProviderResponses, DeleteGlobalMcpData, DeleteGlobalMcpErrors, DeleteGlobalMcpResponses, DeleteGlobalSkillData, DeleteGlobalSkillErrors, DeleteGlobalSkillResponses, DeleteIpAccessControlData, DeleteIpAccessControlErrors, DeleteIpAccessControlResponses, DeleteMcpData, DeleteMcpErrors, DeleteMcpResponses, DeleteMonitorData, DeleteMonitorErrors, DeleteMonitorResponses, DeleteNotificationProviderData, DeleteNotificationProviderErrors, DeleteNotificationProviderResponses, DeleteOidcProviderData, DeleteOidcProviderResponses, DeleteOidcRoleMappingData, DeleteOidcRoleMappingResponses, DeletePreferencesData, DeletePreferencesErrors, DeletePreferencesResponses, DeleteProjectData, DeleteProjectErrors, DeleteProjectResponses, DeleteProjectSecretData, DeleteProjectSecretErrors, DeleteProjectSecretResponses, DeleteProviderKeyData, DeleteProviderKeyErrors, DeleteProviderKeyResponses, DeleteProviderSafelyData, DeleteProviderSafelyErrors, DeleteProviderSafelyResponses, DeleteReleaseSourceFilesData, DeleteReleaseSourceFilesErrors, DeleteReleaseSourceFilesResponses, DeleteReleaseSourceMapsData, DeleteReleaseSourceMapsErrors, DeleteReleaseSourceMapsResponses, DeleteRouteData, DeleteRouteErrors, DeleteRouteResponses, DeleteS3SourceData, DeleteS3SourceErrors, DeleteS3SourceResponses, DeleteScanData, DeleteScanErrors, DeleteScanResponses, DeleteSecretData, DeleteSecretErrors, DeleteSecretResponses, DeleteServiceData, DeleteServiceErrors, DeleteServiceResponses, DeleteSessionReplayData, DeleteSessionReplayErrors, DeleteSessionReplayResponses, DeleteSkillData, DeleteSkillErrors, DeleteSkillResponses, DeleteSourceMapData, DeleteSourceMapErrors, DeleteSourceMapResponses, DeleteStaticBundleData, DeleteStaticBundleErrors, DeleteStaticBundleResponses, DeleteTeamData, DeleteTeamErrors, DeleteTeamResponses, DeleteUserData, DeleteUserErrors, DeleteUserResponses, DeleteWebhookData, DeleteWebhookErrors, DeleteWebhookResponses, DeployFromImageData, DeployFromImageErrors, DeployFromImageResponses, DeployFromImageUploadData, DeployFromImageUploadErrors, DeployFromImageUploadResponses, DeployFromStaticData, DeployFromStaticErrors, DeployFromStaticResponses, DeployFromUploadedSourceData, DeployFromUploadedSourceErrors, DeployFromUploadedSourceResponses, DeploymentMetricsGetLatestData, DeploymentMetricsGetLatestErrors, DeploymentMetricsGetLatestResponses, DeploymentMetricsGetRangeData, DeploymentMetricsGetRangeErrors, DeploymentMetricsGetRangeResponses, DeploymentMetricsToggleData, DeploymentMetricsToggleErrors, DeploymentMetricsToggleResponses, DestroySandboxData, DestroySandboxErrors, DestroySandboxResponses, DetachScheduleServiceData, DetachScheduleServiceErrors, DetachScheduleServiceResponses, DetectPublicPresetsData, DetectPublicPresetsErrors, DetectPublicPresetsResponses, DisableBackupScheduleData, DisableBackupScheduleErrors, DisableBackupScheduleResponses, DisableMfaData, DisableMfaErrors, DisableMfaResponses, DiscoverWorkloadsData, DiscoverWorkloadsErrors, DiscoverWorkloadsResponses, DomainData, DomainErrors, DomainResponses, DownloadGlobalSkillArchiveData, DownloadGlobalSkillArchiveErrors, DownloadGlobalSkillArchiveResponses, DownloadObjectData, DownloadObjectErrors, DownloadObjectResponses, DownloadSkillArchiveData, DownloadSkillArchiveErrors, DownloadSkillArchiveResponses, EmailStatusData, EmailStatusErrors, EmailStatusResponses, EmbeddingsData, EmbeddingsErrors, EmbeddingsResponses, EnableBackupScheduleData, EnableBackupScheduleErrors, EnableBackupScheduleResponses, EnrichVisitorData, EnrichVisitorErrors, EnrichVisitorResponses, ExecData, ExecDetachedData, ExecDetachedErrors, ExecDetachedResponses, ExecErrors, ExecResponses, ExecuteDeploymentOperationData, ExecuteDeploymentOperationErrors, ExecuteDeploymentOperationResponses, ExecuteImportData, ExecuteImportErrors, ExecuteImportResponses, ExtendTimeoutData, ExtendTimeoutErrors, ExtendTimeoutResponses, ExternalServiceEnablePgStatStatementsData, ExternalServiceEnablePgStatStatementsErrors, ExternalServiceEnablePgStatStatementsResponses, ExternalServiceMetricsByDatabaseData, ExternalServiceMetricsByDatabaseErrors, ExternalServiceMetricsByDatabaseResponses, ExternalServiceMetricsCreateAlertRuleData, ExternalServiceMetricsCreateAlertRuleErrors, ExternalServiceMetricsCreateAlertRuleResponses, ExternalServiceMetricsDeleteAlertRuleData, ExternalServiceMetricsDeleteAlertRuleErrors, ExternalServiceMetricsDeleteAlertRuleResponses, ExternalServiceMetricsGetAlertRulesData, ExternalServiceMetricsGetAlertRulesErrors, ExternalServiceMetricsGetAlertRulesResponses, ExternalServiceMetricsGetLatestData, ExternalServiceMetricsGetLatestErrors, ExternalServiceMetricsGetLatestResponses, ExternalServiceMetricsGetRangeData, ExternalServiceMetricsGetRangeErrors, ExternalServiceMetricsGetRangeResponses, ExternalServiceMetricsStatusData, ExternalServiceMetricsStatusErrors, ExternalServiceMetricsStatusResponses, ExternalServiceMetricsToggleData, ExternalServiceMetricsToggleErrors, ExternalServiceMetricsToggleResponses, ExternalServiceMetricsUpdateAlertRuleData, ExternalServiceMetricsUpdateAlertRuleErrors, ExternalServiceMetricsUpdateAlertRuleResponses, ExternalServiceResetPgStatStatementsData, ExternalServiceResetPgStatStatementsErrors, ExternalServiceResetPgStatStatementsResponses, FinalizeOrderData, FinalizeOrderErrors, FinalizeOrderResponses, FinalizeProjectReleaseData, FinalizeProjectReleaseErrors, FinalizeProjectReleaseResponses, FindConversationData, FindConversationErrors, FindConversationResponses, GenerateJoinTokenData, GenerateJoinTokenErrors, GenerateJoinTokenResponses, GeneratePresetDockerfileData, GeneratePresetDockerfileErrors, GeneratePresetDockerfileResponses, GetAccessInfoData, GetAccessInfoErrors, GetAccessInfoResponses, GetActiveVisitorsData, GetActiveVisitorsErrors, GetActiveVisitorsResponses, GetActivityGraphData, GetActivityGraphErrors, GetActivityGraphResponses, GetAdminGateData, GetAdminGateErrors, GetAdminGateResponses, GetAgentData, GetAgentErrors, GetAgentResponses, GetAggregatedBucketsData, GetAggregatedBucketsErrors, GetAggregatedBucketsResponses, GetAiAgentBreakdownData, GetAiAgentBreakdownErrors, GetAiAgentBreakdownResponses, GetAiAgentPagesData, GetAiAgentPagesErrors, GetAiAgentPagesResponses, GetAiAgentTimelineData, GetAiAgentTimelineErrors, GetAiAgentTimelineResponses, GetAiDataAccessData, GetAiDataAccessErrors, GetAiDataAccessResponses, GetAiPageBreakdownData, GetAiPageBreakdownErrors, GetAiPageBreakdownResponses, GetAiStatusBreakdownData, GetAiStatusBreakdownErrors, GetAiStatusBreakdownResponses, GetAlertData, GetAlertErrors, GetAlertResponses, GetAlertRuleData, GetAlertRuleErrors, GetAlertRuleResponses, GetAllRepositoriesByNameData, GetAllRepositoriesByNameErrors, GetAllRepositoriesByNameResponses, GetAnalyticsActiveVisitorsData, GetAnalyticsActiveVisitorsErrors, GetAnalyticsActiveVisitorsResponses, GetAnalyticsEventsCountData, GetAnalyticsEventsCountErrors, GetAnalyticsEventsCountResponses, GetAnalyticsSessionEventsData, GetAnalyticsSessionEventsErrors, GetAnalyticsSessionEventsResponses, GetAnalyticsVisitorSessionsData, GetAnalyticsVisitorSessionsErrors, GetAnalyticsVisitorSessionsResponses, GetApiKeyData, GetApiKeyErrors, GetApiKeyPermissionsData, GetApiKeyPermissionsErrors, GetApiKeyPermissionsResponses, GetApiKeyResponses, GetAuditLogData, GetAuditLogErrors, GetAuditLogResponses, GetBackupData, GetBackupErrors, GetBackupResponses, GetBackupScheduleData, GetBackupScheduleErrors, GetBackupScheduleResponses, GetBranchesByRepositoryIdData, GetBranchesByRepositoryIdErrors, GetBranchesByRepositoryIdResponses, GetBucketedIncidentsData, GetBucketedIncidentsErrors, GetBucketedIncidentsResponses, GetBucketedStatusData, GetBucketedStatusErrors, GetBucketedStatusResponses, GetChallengeTokenData, GetChallengeTokenErrors, GetChallengeTokenResponses, GetChatReadinessData, GetChatReadinessErrors, GetChatReadinessResponses, GetCliStatusData, GetCliStatusErrors, GetCliStatusResponses, GetClusterHealthData, GetClusterHealthErrors, GetClusterHealthResponses, GetClusterMemberData, GetClusterMemberErrors, GetClusterMemberResponses, GetCmdData, GetCmdErrors, GetCmdResponses, GetContainerDetailData, GetContainerDetailErrors, GetContainerDetailResponses, GetContainerEnvironmentVariableData, GetContainerEnvironmentVariableErrors, GetContainerEnvironmentVariableResponses, GetContainerLogsByIdData, GetContainerLogsByIdErrors, GetContainerLogsData, GetContainerLogsErrors, GetContainerMetricsData, GetContainerMetricsErrors, GetContainerMetricsResponses, GetConversationData, GetConversationDetailData, GetConversationDetailErrors, GetConversationDetailResponses, GetConversationErrors, GetConversationResponses, GetConversationsData, GetConversationsErrors, GetConversationsResponses, GetCronByIdData, GetCronByIdErrors, GetCronByIdResponses, GetCronExecutionsData, GetCronExecutionsErrors, GetCronExecutionsResponses, GetCrossProjectTraceSiblingsData, GetCrossProjectTraceSiblingsErrors, GetCrossProjectTraceSiblingsResponses, GetCurrentMonitorStatusData, GetCurrentMonitorStatusErrors, GetCurrentMonitorStatusResponses, GetCurrentUserData, GetCurrentUserErrors, GetCurrentUserResponses, GetCustomDomainData, GetCustomDomainErrors, GetCustomDomainResponses, GetDashboardData, GetDashboardErrors, GetDashboardProjectsAnalyticsData, GetDashboardProjectsAnalyticsErrors, GetDashboardProjectsAnalyticsResponses, GetDashboardResponses, GetDeliveryData, GetDeliveryErrors, GetDeliveryResponses, GetDeploymentContainerLogContentData, GetDeploymentContainerLogContentErrors, GetDeploymentContainerLogContentResponses, GetDeploymentData, GetDeploymentErrors, GetDeploymentJobLogsData, GetDeploymentJobLogsErrors, GetDeploymentJobLogsResponses, GetDeploymentJobsData, GetDeploymentJobsErrors, GetDeploymentJobsResponses, GetDeploymentOperationsData, GetDeploymentOperationsErrors, GetDeploymentOperationsResponses, GetDeploymentOperationStatusData, GetDeploymentOperationStatusErrors, GetDeploymentOperationStatusResponses, GetDeploymentResponses, GetDeploymentTokenData, GetDeploymentTokenErrors, GetDeploymentTokenResponses, GetDiskStatusData, GetDiskStatusErrors, GetDiskStatusResponses, GetDnsChangesData, GetDnsChangesErrors, GetDnsChangesResponses, GetDnsProviderData, GetDnsProviderErrors, GetDnsProviderResponses, GetDomainByHostData, GetDomainByHostErrors, GetDomainByHostResponses, GetDomainByIdData, GetDomainByIdErrors, GetDomainByIdResponses, GetDomainByNameData, GetDomainByNameErrors, GetDomainByNameResponses, GetDomainData, GetDomainDnsRecordsData, GetDomainDnsRecordsErrors, GetDomainDnsRecordsResponses, GetDomainErrors, GetDomainOrderData, GetDomainOrderErrors, GetDomainOrderResponses, GetDomainResponses, GetEmailData, GetEmailErrors, GetEmailEventsData, GetEmailEventsErrors, GetEmailEventsResponses, GetEmailLinksData, GetEmailLinksErrors, GetEmailLinksResponses, GetEmailProviderData, GetEmailProviderErrors, GetEmailProviderResponses, GetEmailResponses, GetEmailStatsData, GetEmailStatsErrors, GetEmailStatsResponses, GetEmailTrackingData, GetEmailTrackingErrors, GetEmailTrackingResponses, GetEmailTrackingStatusData, GetEmailTrackingStatusErrors, GetEmailTrackingStatusResponses, GetEntityInfoData, GetEntityInfoErrors, GetEntityInfoResponses, GetEnvironmentCronsData, GetEnvironmentCronsErrors, GetEnvironmentCronsResponses, GetEnvironmentData, GetEnvironmentDomainsData, GetEnvironmentDomainsErrors, GetEnvironmentDomainsResponses, GetEnvironmentErrors, GetEnvironmentResponses, GetEnvironmentsData, GetEnvironmentsErrors, GetEnvironmentsResponses, GetEnvironmentVariablesData, GetEnvironmentVariablesErrors, GetEnvironmentVariablesResponses, GetEnvironmentVariableValueData, GetEnvironmentVariableValueErrors, GetEnvironmentVariableValueResponses, GetErrorDashboardStatsData, GetErrorDashboardStatsErrors, GetErrorDashboardStatsResponses, GetErrorEventData, GetErrorEventErrors, GetErrorEventResponses, GetErrorGroupData, GetErrorGroupErrors, GetErrorGroupResponses, GetErrorStatsData, GetErrorStatsErrors, GetErrorStatsResponses, GetErrorTimeSeriesData, GetErrorTimeSeriesErrors, GetErrorTimeSeriesResponses, GetEventDetailData, GetEventDetailErrors, GetEventDetailResponses, GetEventEntriesData, GetEventEntriesErrors, GetEventEntriesResponses, GetEventsCountData, GetEventsCountErrors, GetEventsCountResponses, GetEventsTimelineData, GetEventsTimelineErrors, GetEventsTimelineResponses, GetEventTypeBreakdownData, GetEventTypeBreakdownErrors, GetEventTypeBreakdownResponses, GetEventVisitorsData, GetEventVisitorsErrors, GetEventVisitorsResponses, GetExternalImageData, GetExternalImageErrors, GetExternalImageResponses, GetFileData, GetFileErrors, GetFileResponses, GetFlagData, GetFlagErrors, GetFlagResponses, GetFlagSnapshotData, GetFlagSnapshotErrors, GetFlagSnapshotResponses, GetFunnelMetricsData, GetFunnelMetricsErrors, GetFunnelMetricsResponses, GetGenaiTraceData, GetGenaiTraceErrors, GetGenaiTraceResponses, GetGeneralStatsData, GetGeneralStatsErrors, GetGeneralStatsResponses, GetGitProviderData, GetGitProviderErrors, GetGitProviderResponses, GetGlobalEventsData, GetGlobalEventsErrors, GetGlobalEventsResponses, GetGlobalEventStatsData, GetGlobalEventStatsErrors, GetGlobalEventStatsResponses, GetGlobalMcpData, GetGlobalMcpErrors, GetGlobalMcpResponses, GetGlobalSandboxStatusData, GetGlobalSandboxStatusErrors, GetGlobalSandboxStatusResponses, GetGlobalSkillData, GetGlobalSkillErrors, GetGlobalSkillResponses, GetGroupedPageMetricsData, GetGroupedPageMetricsErrors, GetGroupedPageMetricsResponses, GetHealthData, GetHealthErrors, GetHealthResponses, GetHourlyVisitsData, GetHourlyVisitsErrors, GetHourlyVisitsResponses, GetHttpChallengeDebugData, GetHttpChallengeDebugErrors, GetHttpChallengeDebugResponses, GetImportStatusData, GetImportStatusErrors, GetImportStatusResponses, GetIncidentData, GetIncidentErrors, GetIncidentResponses, GetIncidentUpdatesData, GetIncidentUpdatesErrors, GetIncidentUpdatesResponses, GetIpAccessControlData, GetIpAccessControlErrors, GetIpAccessControlResponses, GetIpGeolocationData, GetIpGeolocationErrors, GetIpGeolocationResponses, GetJoinTokenStatusData, GetJoinTokenStatusErrors, GetJoinTokenStatusResponses, GetLastDeploymentData, GetLastDeploymentErrors, GetLastDeploymentResponses, GetLatestScanData, GetLatestScanErrors, GetLatestScanResponses, GetLatestScansPerEnvironmentData, GetLatestScansPerEnvironmentErrors, GetLatestScansPerEnvironmentResponses, GetLiveVisitorsListData, GetLiveVisitorsListErrors, GetLiveVisitorsListResponses, GetLogContextData, GetLogContextErrors, GetLogContextResponses, GetMcpData, GetMcpErrors, GetMcpResponses, GetMetricsOverTimeData, GetMetricsOverTimeErrors, GetMetricsOverTimeResponses, GetMonitorData, GetMonitorErrors, GetMonitorResponses, GetNotificationProviderData, GetNotificationProviderErrors, GetNotificationProviderResponses, GetOnDemandCertStatusData, GetOnDemandCertStatusErrors, GetOnDemandCertStatusResponses, GetOrCreateDsnData, GetOrCreateDsnErrors, GetOrCreateDsnResponses, GetPageFlowData, GetPageFlowErrors, GetPageFlowResponses, GetPageHourlySessionsData, GetPageHourlySessionsErrors, GetPageHourlySessionsResponses, GetPagePathDetailData, GetPagePathDetailErrors, GetPagePathDetailResponses, GetPagePathsData, GetPagePathsErrors, GetPagePathsResponses, GetPagePathsSparklinesData, GetPagePathsSparklinesErrors, GetPagePathsSparklinesResponses, GetPagePathVisitorsData, GetPagePathVisitorsErrors, GetPagePathVisitorsResponses, GetPendingActionData, GetPendingActionErrors, GetPendingActionResponses, GetPerformanceMetricsData, GetPerformanceMetricsErrors, GetPerformanceMetricsResponses, GetPgUpgradeData, GetPgUpgradeErrors, GetPgUpgradeLogsData, GetPgUpgradeLogsErrors, GetPgUpgradeLogsResponses, GetPgUpgradeResponses, GetPipelineStatsData, GetPipelineStatsErrors, GetPipelineStatsResponses, GetPlatformInfoData, GetPlatformInfoErrors, GetPlatformInfoResponses, GetPostgresWalHealthData, GetPostgresWalHealthErrors, GetPostgresWalHealthResponses, GetPreferencesData, GetPreferencesErrors, GetPreferencesResponses, GetPreviewGatewayLogsData, GetPreviewGatewayLogsResponses, GetPreviewGatewaySettingsData, GetPreviewGatewaySettingsResponses, GetPreviewGatewayStatusData, GetPreviewGatewayStatusResponses, GetPricingData, GetPricingErrors, GetPricingResponses, GetPrivateIpData, GetPrivateIpErrors, GetPrivateIpResponses, GetProjectAlarmsSummaryData, GetProjectAlarmsSummaryErrors, GetProjectAlarmsSummaryResponses, GetProjectBySlugData, GetProjectBySlugErrors, GetProjectBySlugResponses, GetProjectData, GetProjectDeploymentsData, GetProjectDeploymentsErrors, GetProjectDeploymentsResponses, GetProjectErrors, GetProjectResponses, GetProjectsData, GetProjectsErrors, GetProjectServiceEnvironmentVariablesData, GetProjectServiceEnvironmentVariablesErrors, GetProjectServiceEnvironmentVariablesResponses, GetProjectSessionReplaysData, GetProjectSessionReplaysErrors, GetProjectSessionReplaysResponses, GetProjectsHealthData, GetProjectsHealthErrors, GetProjectsHealthResponses, GetProjectsMonitorHealthData, GetProjectsMonitorHealthErrors, GetProjectsMonitorHealthResponses, GetProjectsResponses, GetProjectStatisticsData, GetProjectStatisticsErrors, GetProjectStatisticsResponses, GetProjectTemplateData, GetProjectTemplateErrors, GetProjectTemplateResponses, GetPropertyBreakdownData, GetPropertyBreakdownErrors, GetPropertyBreakdownResponses, GetPropertyTimelineData, GetPropertyTimelineErrors, GetPropertyTimelineResponses, GetProviderConnectionsData, GetProviderConnectionsErrors, GetProviderConnectionsResponses, GetProviderMetadataData, GetProviderMetadataErrors, GetProviderMetadataResponses, GetProvidersMetadataData, GetProvidersMetadataErrors, GetProvidersMetadataResponses, GetProxyLogByIdData, GetProxyLogByIdErrors, GetProxyLogByIdResponses, GetProxyLogByRequestIdData, GetProxyLogByRequestIdErrors, GetProxyLogByRequestIdResponses, GetProxyLogsData, GetProxyLogsErrors, GetProxyLogsResponses, GetPublicBranchesData, GetPublicBranchesErrors, GetPublicBranchesResponses, GetPublicIpData, GetPublicIpErrors, GetPublicIpResponses, GetPublicRepositoryData, GetPublicRepositoryErrors, GetPublicRepositoryResponses, GetQueryContainerInfoData, GetQueryContainerInfoErrors, GetQueryContainerInfoResponses, GetQuotaData, GetQuotaErrors, GetQuotaResponses, GetRecentActivityData, GetRecentActivityErrors, GetRecentActivityResponses, GetRemoteExternalImageData, GetRemoteExternalImageErrors, GetRemoteExternalImageResponses, GetRepositoryBranchesData, GetRepositoryBranchesErrors, GetRepositoryBranchesResponses, GetRepositoryByIdData, GetRepositoryByIdErrors, GetRepositoryByIdResponses, GetRepositoryByNameData, GetRepositoryByNameErrors, GetRepositoryByNameResponses, GetRepositoryPresetByNameData, GetRepositoryPresetByNameErrors, GetRepositoryPresetByNameResponses, GetRepositoryPresetLiveData, GetRepositoryPresetLiveErrors, GetRepositoryPresetLiveResponses, GetRepositoryTagsData, GetRepositoryTagsErrors, GetRepositoryTagsResponses, GetResolvedEnvironmentVariablesData, GetResolvedEnvironmentVariablesErrors, GetResolvedEnvironmentVariablesResponses, GetResolvedEnvironmentVariableValueData, GetResolvedEnvironmentVariableValueErrors, GetResolvedEnvironmentVariableValueResponses, GetRestoreCapabilitiesData, GetRestoreCapabilitiesErrors, GetRestoreCapabilitiesResponses, GetRestoreRunData, GetRestoreRunErrors, GetRestoreRunResponses, GetRouteData, GetRouteErrors, GetRouteResponses, GetRunData, GetRunErrors, GetRunResponses, GetRunWithLogsData, GetRunWithLogsErrors, GetRunWithLogsResponses, GetS3CredentialsData, GetS3CredentialsErrors, GetS3CredentialsResponses, GetS3SourceData, GetS3SourceErrors, GetS3SourceResponses, GetSandboxData, GetSandboxErrors, GetSandboxResponses, GetSandboxStatusData, GetSandboxStatusErrors, GetSandboxStatusResponses, GetScanByDeploymentData, GetScanByDeploymentErrors, GetScanByDeploymentResponses, GetScanData, GetScanErrors, GetScanResponses, GetScanVulnerabilitiesData, GetScanVulnerabilitiesErrors, GetScanVulnerabilitiesResponses, GetServiceBySlugData, GetServiceBySlugErrors, GetServiceBySlugResponses, GetServiceData, GetServiceEnvironmentVariableData, GetServiceEnvironmentVariableErrors, GetServiceEnvironmentVariableResponses, GetServiceEnvironmentVariablesData, GetServiceEnvironmentVariablesErrors, GetServiceEnvironmentVariablesResponses, GetServiceErrors, GetServiceHealthStatusData, GetServiceHealthStatusErrors, GetServiceHealthStatusResponses, GetServicePreviewEnvironmentVariableNamesData, GetServicePreviewEnvironmentVariableNamesErrors, GetServicePreviewEnvironmentVariableNamesResponses, GetServicePreviewEnvironmentVariablesMaskedData, GetServicePreviewEnvironmentVariablesMaskedErrors, GetServicePreviewEnvironmentVariablesMaskedResponses, GetServiceResponses, GetServiceRuntimeData, GetServiceRuntimeErrors, GetServiceRuntimeResponses, GetServiceStatsData, GetServiceStatsErrors, GetServiceStatsResponses, GetServiceTypeParametersData, GetServiceTypeParametersErrors, GetServiceTypeParametersResponses, GetServiceTypesData, GetServiceTypesErrors, GetServiceTypesResponses, GetSessionDetailsData, GetSessionDetailsErrors, GetSessionDetailsResponses, GetSessionEventsData, GetSessionEventsErrors, GetSessionEventsResponses, GetSessionLogsData, GetSessionLogsErrors, GetSessionLogsResponses, GetSessionReplayData, GetSessionReplayErrors, GetSessionReplayEventsData, GetSessionReplayEventsErrors, GetSessionReplayEventsResponses, GetSessionReplayResponses, GetSettingsData, GetSettingsErrors, GetSettingsResponses, GetSkillData, GetSkillErrors, GetSkillResponses, GetSlowQueriesData, GetSlowQueriesErrors, GetSlowQueriesResponses, GetStaticBundleData, GetStaticBundleErrors, GetStaticBundleResponses, GetStatusOverviewData, GetStatusOverviewErrors, GetStatusOverviewResponses, GetTagsByRepositoryIdData, GetTagsByRepositoryIdErrors, GetTagsByRepositoryIdResponses, GetTeamData, GetTeamErrors, GetTeamResponses, GetTimeBucketStatsData, GetTimeBucketStatsErrors, GetTimeBucketStatsResponses, GetTodayStatsData, GetTodayStatsErrors, GetTodayStatsResponses, GetTraceData, GetTraceErrors, GetTraceResponses, GetUnifiedTraceData, GetUnifiedTraceErrors, GetUnifiedTraceResponses, GetUniqueCountsData, GetUniqueCountsErrors, GetUniqueCountsResponses, GetUniqueEventsData, GetUniqueEventsErrors, GetUniqueEventsResponses, GetUpdateStatusData, GetUpdateStatusErrors, GetUpdateStatusResponses, GetUptimeHistoryData, GetUptimeHistoryErrors, GetUptimeHistoryResponses, GetUsageByProviderData, GetUsageByProviderErrors, GetUsageByProviderResponses, GetUsageRecentData, GetUsageRecentErrors, GetUsageRecentResponses, GetUsageSummaryData, GetUsageSummaryErrors, GetUsageSummaryResponses, GetUsageTimeseriesData, GetUsageTimeseriesErrors, GetUsageTimeseriesResponses, GetUsageTopModelsData, GetUsageTopModelsErrors, GetUsageTopModelsResponses, GetVisitorByGuidData, GetVisitorByGuidErrors, GetVisitorByGuidResponses, GetVisitorByIdData, GetVisitorByIdErrors, GetVisitorByIdResponses, GetVisitorDetailsData, GetVisitorDetailsErrors, GetVisitorDetailsResponses, GetVisitorFacetsData, GetVisitorFacetsErrors, GetVisitorFacetsResponses, GetVisitorInfoData, GetVisitorInfoErrors, GetVisitorInfoResponses, GetVisitorJourneyData, GetVisitorJourneyErrors, GetVisitorJourneyResponses, GetVisitorsData, GetVisitorsErrors, GetVisitorSessionsData, GetVisitorSessionsErrors, GetVisitorSessionsResponses, GetVisitorsResponses, GetVisitorStatsData, GetVisitorStatsErrors, GetVisitorStatsResponses, GetWebhookData, GetWebhookErrors, GetWebhookResponses, GrantProjectAccessData, GrantProjectAccessErrors, GrantProjectAccessResponses, HandleGitProviderOauthCallbackData, HandleGitProviderOauthCallbackErrors, HasAnalyticsEventsData, HasAnalyticsEventsErrors, HasAnalyticsEventsResponses, HasErrorGroupsData, HasErrorGroupsErrors, HasErrorGroupsResponses, HasPerformanceMetricsData, HasPerformanceMetricsErrors, HasPerformanceMetricsResponses, ImportExternalServiceData, ImportExternalServiceErrors, ImportExternalServiceResponses, IngestLogsByPathData, IngestLogsByPathErrors, IngestLogsByPathResponses, IngestLogsData, IngestLogsErrors, IngestLogsResponses, IngestMetricsByPathData, IngestMetricsByPathErrors, IngestMetricsByPathResponses, IngestMetricsData, IngestMetricsErrors, IngestMetricsResponses, IngestSentryEnvelopeData, IngestSentryEnvelopeErrors, IngestSentryEnvelopeResponses, IngestSentryEventData, IngestSentryEventErrors, IngestSentryEventResponses, IngestTracesByPathData, IngestTracesByPathErrors, IngestTracesByPathResponses, IngestTracesData, IngestTracesErrors, IngestTracesResponses, InitSessionReplayData, InitSessionReplayErrors, InitSessionReplayResponses, InspectDropArchiveData, InspectDropArchiveErrors, InspectDropArchiveResponses, JobLogsData, JobLogsErrors, JobLogsResponses, JobStatusData, JobStatusErrors, JobStatusResponses, KillJobData, KillJobErrors, KillJobResponses, KvDelData, KvDelErrors, KvDelResponses, KvDisableData, KvDisableErrors, KvDisableResponses, KvEnableData, KvEnableErrors, KvEnableResponses, KvExpireData, KvExpireErrors, KvExpireResponses, KvGetData, KvGetErrors, KvGetResponses, KvIncrData, KvIncrErrors, KvIncrResponses, KvKeysData, KvKeysErrors, KvKeysResponses, KvSetData, KvSetErrors, KvSetResponses, KvStatusData, KvStatusErrors, KvStatusResponses, KvTtlData, KvTtlErrors, KvTtlResponses, KvUpdateData, KvUpdateErrors, KvUpdateResponses, LatestRunForSourceData, LatestRunForSourceErrors, LatestRunForSourceResponses, LinkCustomDomainToCertificateData, LinkCustomDomainToCertificateErrors, LinkCustomDomainToCertificateResponses, LinkServiceToProjectData, LinkServiceToProjectErrors, LinkServiceToProjectResponses, ListAgentRunsData, ListAgentRunsErrors, ListAgentRunsResponses, ListAgentsData, ListAgentsErrors, ListAgentsResponses, ListAiProvidersData, ListAiProvidersErrors, ListAiProvidersResponses, ListAlertRulesData, ListAlertRulesErrors, ListAlertRulesResponses, ListAlertsData, ListAlertsErrors, ListAlertsResponses, ListAllConversationsData, ListAllConversationsErrors, ListAllConversationsResponses, ListAllRunsData, ListAllRunsErrors, ListAllRunsResponses, ListApiKeysData, ListApiKeysErrors, ListApiKeysResponses, ListAuditLogsData, ListAuditLogsErrors, ListAuditLogsResponses, ListAvailableContainersData, ListAvailableContainersErrors, ListAvailableContainersResponses, ListBackupAlertsData, ListBackupAlertsErrors, ListBackupAlertsResponses, ListBackupChildrenData, ListBackupChildrenErrors, ListBackupChildrenResponses, ListBackupSchedulesData, ListBackupSchedulesErrors, ListBackupSchedulesResponses, ListBackupsForScheduleData, ListBackupsForScheduleErrors, ListBackupsForScheduleResponses, ListCommitsByRepositoryIdData, ListCommitsByRepositoryIdErrors, ListCommitsByRepositoryIdResponses, ListConnectionsData, ListConnectionsErrors, ListConnectionsResponses, ListContainersAtPathData, ListContainersAtPathErrors, ListContainersAtPathResponses, ListContainersData, ListContainersErrors, ListContainersResponses, ListConversationsData, ListConversationsErrors, ListConversationsResponses, ListCustomDomainsForProjectData, ListCustomDomainsForProjectErrors, ListCustomDomainsForProjectResponses, ListDashboardsData, ListDashboardsErrors, ListDashboardsResponses, ListDeliveriesData, ListDeliveriesErrors, ListDeliveriesResponses, ListDeploymentContainerLogsData, ListDeploymentContainerLogsErrors, ListDeploymentContainerLogsResponses, ListDeploymentTokensData, ListDeploymentTokensErrors, ListDeploymentTokensResponses, ListDnsProvidersData, ListDnsProvidersErrors, ListDnsProvidersResponses, ListDomainsData, ListDomainsErrors, ListDomainsResponses, ListDsnsData, ListDsnsErrors, ListDsnsResponses, ListEmailDomainsData, ListEmailDomainsErrors, ListEmailDomainsResponses, ListEmailProvidersData, ListEmailProvidersErrors, ListEmailProvidersResponses, ListEmailsData, ListEmailsErrors, ListEmailsResponses, ListEnrollmentTokensData, ListEnrollmentTokensErrors, ListEnrollmentTokensResponses, ListEntitiesData, ListEntitiesErrors, ListEntitiesResponses, ListErrorEventsData, ListErrorEventsErrors, ListErrorEventsResponses, ListErrorGroupsData, ListErrorGroupsErrors, ListErrorGroupsResponses, ListEventsData, ListEventsResponses, ListEventTypesData, ListEventTypesResponses, ListExternalImagesData, ListExternalImagesErrors, ListExternalImagesResponses, ListExternalPluginsData, ListExternalPluginsErrors, ListExternalPluginsResponses, ListExternalServiceBackupsData, ListExternalServiceBackupsErrors, ListExternalServiceBackupsResponses, ListFlagsData, ListFlagsErrors, ListFlagsResponses, ListFunnelsData, ListFunnelsErrors, ListFunnelsResponses, ListGitProvidersData, ListGitProvidersErrors, ListGitProvidersResponses, ListGlobalMcpsData, ListGlobalMcpsErrors, ListGlobalMcpsResponses, ListGlobalSkillsData, ListGlobalSkillsErrors, ListGlobalSkillsResponses, ListIncidentsData, ListIncidentsErrors, ListIncidentsResponses, ListInsightsData, ListInsightsErrors, ListInsightsResponses, ListIpAccessControlData, ListIpAccessControlErrors, ListIpAccessControlResponses, ListJobsData, ListJobsErrors, ListJobsResponses, ListKnownAiAgentsData, ListKnownAiAgentsErrors, ListKnownAiAgentsResponses, ListManagedDomainsData, ListManagedDomainsErrors, ListManagedDomainsResponses, ListMcpsData, ListMcpsErrors, ListMcpsResponses, ListMetricLabelKeysData, ListMetricLabelKeysErrors, ListMetricLabelKeysResponses, ListMetricLabelValuesData, ListMetricLabelValuesErrors, ListMetricLabelValuesResponses, ListMetricNamesData, ListMetricNamesErrors, ListMetricNamesResponses, ListModelsData, ListModelsErrors, ListModelsResponses, ListMonitorsData, ListMonitorsErrors, ListMonitorsResponses, ListNotificationProvidersData, ListNotificationProvidersErrors, ListNotificationProvidersResponses, ListOidcProvidersData, ListOidcProvidersResponses, ListOidcProviderUsersData, ListOidcProviderUsersErrors, ListOidcProviderUsersResponses, ListOidcRoleMappingsData, ListOidcRoleMappingsResponses, ListOnDemandCertsData, ListOnDemandCertsErrors, ListOnDemandCertsResponses, ListOrdersData, ListOrdersErrors, ListOrdersResponses, ListPeersData, ListPeersErrors, ListPeersResponses, ListPendingActionsData, ListPendingActionsErrors, ListPendingActionsResponses, ListPgUpgradesData, ListPgUpgradesErrors, ListPgUpgradesResponses, ListPresetsData, ListPresetsErrors, ListPresetsResponses, ListProjectAccessData, ListProjectAccessErrors, ListProjectAccessResponses, ListProjectAlarmsData, ListProjectAlarmsErrors, ListProjectAlarmsResponses, ListProjectScansData, ListProjectScansErrors, ListProjectScansResponses, ListProjectSecretsData, ListProjectSecretsErrors, ListProjectSecretsResponses, ListProjectServicesData, ListProjectServicesErrors, ListProjectServicesResponses, ListProjectTemplatesData, ListProjectTemplatesErrors, ListProjectTemplatesResponses, ListProjectTemplateTagsData, ListProjectTemplateTagsErrors, ListProjectTemplateTagsResponses, ListProviderKeysData, ListProviderKeysErrors, ListProviderKeysResponses, ListProviderZonesData, ListProviderZonesErrors, ListProviderZonesResponses, ListPublicProvidersData, ListPublicProvidersResponses, ListReleaseFilesData, ListReleaseFilesErrors, ListReleaseFilesResponses, ListReleasesData, ListReleasesErrors, ListReleasesResponses, ListRemoteExternalImagesData, ListRemoteExternalImagesErrors, ListRemoteExternalImagesResponses, ListRepositoriesByConnectionData, ListRepositoriesByConnectionErrors, ListRepositoriesByConnectionResponses, ListRepositoriesByProviderData, ListRepositoriesByProviderErrors, ListRepositoriesByProviderResponses, ListRestoreRunsForServiceData, ListRestoreRunsForServiceResponses, ListRootContainersData, ListRootContainersErrors, ListRootContainersResponses, ListRoutesData, ListRoutesErrors, ListRoutesResponses, ListS3SourcesData, ListS3SourcesErrors, ListS3SourcesResponses, ListSandboxesData, ListSandboxesErrors, ListSandboxesResponses, ListScheduleRunJobsData, ListScheduleRunJobsErrors, ListScheduleRunJobsResponses, ListScheduleRunsData, ListScheduleRunsErrors, ListScheduleRunsResponses, ListScheduleServicesData, ListScheduleServicesErrors, ListScheduleServicesResponses, ListSecretsData, ListSecretsErrors, ListSecretsResponses, ListServiceHealthStatusesData, ListServiceHealthStatusesErrors, ListServiceHealthStatusesResponses, ListServiceProjectsData, ListServiceProjectsErrors, ListServiceProjectsResponses, ListServiceSchedulesData, ListServiceSchedulesErrors, ListServiceSchedulesResponses, ListServicesData, ListServicesErrors, ListServicesResponses, ListSkillsData, ListSkillsErrors, ListSkillsResponses, ListSourceBackupsData, ListSourceBackupsErrors, ListSourceBackupsResponses, ListSourceFilesData, ListSourceFilesErrors, ListSourceFilesResponses, ListSourceMapsData, ListSourceMapsErrors, ListSourceMapsResponses, ListSourcesData, ListSourcesErrors, ListSourcesResponses, ListStaticBundlesData, ListStaticBundlesErrors, ListStaticBundlesResponses, ListSyncedRepositoriesData, ListSyncedRepositoriesErrors, ListSyncedRepositoriesResponses, ListTeamMembersData, ListTeamMembersErrors, ListTeamMembersResponses, ListTeamProjectsData, ListTeamProjectsErrors, ListTeamProjectsResponses, ListTeamsData, ListTeamsErrors, ListTeamsResponses, ListUsersData, ListUsersErrors, ListUsersResponses, ListWebhooksData, ListWebhooksErrors, ListWebhooksResponses, LoginData, LoginErrors, LoginResponses, LogoutData, LogoutErrors, LogoutResponses, LookupDnsARecordsData, LookupDnsARecordsErrors, LookupDnsARecordsResponses, MintEnrollmentTokenData, MintEnrollmentTokenErrors, MintEnrollmentTokenResponses, MkdirData, MkdirErrors, MkdirResponses, NodeHeartbeatData, NodeHeartbeatErrors, NodeHeartbeatResponses, NodeMetricsGetRangeData, NodeMetricsGetRangeErrors, NodeMetricsGetRangeResponses, ObservabilityFullEventData, ObservabilityFullEventErrors, ObservabilityFullEventResponses, ObservabilityListEventsData, ObservabilityListEventsErrors, ObservabilityListEventsResponses, OidcCallbackData, PatchAdminGateData, PatchAdminGateErrors, PatchAdminGateResponses, PatchPreviewGatewaySettingsData, PatchPreviewGatewaySettingsResponses, PauseDeploymentData, PauseDeploymentErrors, PauseDeploymentResponses, PauseSandboxData, PauseSandboxErrors, PauseSandboxResponses, PlanRestoreData, PlanRestoreErrors, PlanRestoreResponses, PostDnsAckData, PostDnsAckErrors, PostDnsAckResponses, PreviewAlertData, PreviewAlertErrors, PreviewAlertResponses, PreviewFunnelMetricsData, PreviewFunnelMetricsErrors, PreviewFunnelMetricsResponses, PreviewHostnameModeData, PreviewHostnameModeErrors, PreviewHostnameModeResponses, PromoteClusterMemberData, PromoteClusterMemberErrors, PromoteClusterMemberResponses, PromoteDeploymentData, PromoteDeploymentErrors, PromoteDeploymentResponses, ProvisionDomainData, ProvisionDomainErrors, ProvisionDomainResponses, PurgeProjectLogsData, PurgeProjectLogsErrors, PurgeProjectLogsResponses, PushExternalImageData, PushExternalImageErrors, PushExternalImageResponses, QueryDataData, QueryDataErrors, QueryDataResponses, QueryGenaiTracesData, QueryGenaiTracesErrors, QueryGenaiTracesResponses, QueryLogsData, QueryLogsErrors, QueryLogsResponses, QueryMetricsData, QueryMetricsErrors, QueryMetricsResponses, QuerySpanStatsData, QuerySpanStatsErrors, QuerySpanStatsResponses, QueryTracesData, QueryTracesErrors, QueryTracesResponses, QueryTraceSummariesData, QueryTraceSummariesErrors, QueryTraceSummariesResponses, ReadEntityRowsData, ReadEntityRowsErrors, ReadEntityRowsResponses, ReadFileData, ReadFileErrors, ReadFileResponses, ReAnalyzeData, ReAnalyzeErrors, ReAnalyzeResponses, RecordConsoleEventData, RecordConsoleEventErrors, RecordConsoleEventResponses, RecordEventMetricsData, RecordEventMetricsErrors, RecordEventMetricsResponses, RecordFlagExposureData, RecordFlagExposureErrors, RecordFlagExposureResponses, RecordSpeedMetricsData, RecordSpeedMetricsErrors, RecordSpeedMetricsResponses, RefreshRouteTableData, RefreshRouteTableErrors, RefreshRouteTableResponses, RegenerateDsnData, RegenerateDsnErrors, RegenerateDsnResponses, RegisterExternalImageData, RegisterExternalImageErrors, RegisterExternalImageResponses, RegisterNodeData, RegisterNodeErrors, RegisterNodeResponses, ReinstallGitlabWebhookData, ReinstallGitlabWebhookErrors, ReinstallGitlabWebhookResponses, RejectPendingActionData, RejectPendingActionErrors, RejectPendingActionResponses, ReloadPluginsData, ReloadPluginsErrors, ReloadPluginsResponses, RemoveClusterMemberData, RemoveClusterMemberErrors, RemoveClusterMemberResponses, RemoveManagedDomainData, RemoveManagedDomainErrors, RemoveManagedDomainResponses, RemoveRoleData, RemoveRoleErrors, RemoveRoleResponses, RemoveTeamMemberData, RemoveTeamMemberErrors, RemoveTeamMemberResponses, RenameConversationData, RenameConversationErrors, RenameConversationResponses, RenewDomainData, RenewDomainErrors, RenewDomainResponses, RequestPasswordResetData, RequestPasswordResetErrors, RequestPasswordResetResponses, ResetPasswordData, ResetPasswordErrors, ResetPasswordResponses, ResizeSandboxData, ResizeSandboxErrors, ResizeSandboxResponses, ResolveAlarmData, ResolveAlarmErrors, ResolveAlarmResponses, RestartContainerData, RestartContainerErrors, RestartContainerResponses, RestartPreviewGatewayData, RestartPreviewGatewayResponses, RestartSandboxData, RestartSandboxErrors, RestartSandboxResponses, RestoreFlagData, RestoreFlagErrors, RestoreFlagResponses, RestoreUserData, RestoreUserErrors, RestoreUserResponses, ResumeDeploymentData, ResumeDeploymentErrors, ResumeDeploymentResponses, ResumeSandboxData, ResumeSandboxErrors, ResumeSandboxResponses, RetryClusterData, RetryClusterErrors, RetryClusterResponses, RetryDeliveryData, RetryDeliveryErrors, RetryDeliveryResponses, RetryPgUpgradeData, RetryPgUpgradeErrors, RetryPgUpgradeResponses, RetryRunData, RetryRunErrors, RetryRunResponses, RevealGlobalMcpConfigData, RevealGlobalMcpConfigErrors, RevealGlobalMcpConfigResponses, RevealMcpConfigData, RevealMcpConfigErrors, RevealMcpConfigResponses, RevealNotificationProviderConfigData, RevealNotificationProviderConfigErrors, RevealNotificationProviderConfigResponses, RevealServiceParameterData, RevealServiceParameterErrors, RevealServiceParameterResponses, RevenueCreateIntegrationData, RevenueCreateIntegrationErrors, RevenueCreateIntegrationResponses, RevenueDeleteIntegrationData, RevenueDeleteIntegrationResponses, RevenueGlobalEventsData, RevenueGlobalEventsResponses, RevenueImportInvoicesCsvData, RevenueImportInvoicesCsvErrors, RevenueImportInvoicesCsvResponses, RevenueImportSubscriptionsCsvData, RevenueImportSubscriptionsCsvErrors, RevenueImportSubscriptionsCsvResponses, RevenueListIntegrationsData, RevenueListIntegrationsResponses, RevenueListProvidersData, RevenueListProvidersResponses, RevenueMetricsCustomersData, RevenueMetricsCustomersResponses, RevenueMetricsGlobalMrrData, RevenueMetricsGlobalMrrResponses, RevenueMetricsGlobalSummaryData, RevenueMetricsGlobalSummaryResponses, RevenueMetricsMrrData, RevenueMetricsMrrResponses, RevenueMetricsSummaryData, RevenueMetricsSummaryResponses, RevenueRecentEventsData, RevenueRecentEventsResponses, RevenueRotateTokenData, RevenueRotateTokenResponses, RevenueUpdateConfigData, RevenueUpdateConfigErrors, RevenueUpdateConfigResponses, RevenueUpdateSecretData, RevenueUpdateSecretErrors, RevenueUpdateSecretResponses, RevokeDsnData, RevokeDsnErrors, RevokeDsnResponses, RevokeEnrollmentTokenData, RevokeEnrollmentTokenErrors, RevokeEnrollmentTokenResponses, RevokeJoinTokenData, RevokeJoinTokenErrors, RevokeJoinTokenResponses, RevokeProjectAccessData, RevokeProjectAccessErrors, RevokeProjectAccessResponses, RollbackPgUpgradeData, RollbackPgUpgradeErrors, RollbackPgUpgradeResponses, RollbackToDeploymentData, RollbackToDeploymentErrors, RollbackToDeploymentResponses, RootfsGcData, RootfsGcResponses, RootfsReportData, RootfsReportResponses, RotateApiKeyData, RotateApiKeyErrors, RotateApiKeyResponses, RotateDeploymentTokenData, RotateDeploymentTokenErrors, RotateDeploymentTokenResponses, RunBackupForSourceData, RunBackupForSourceErrors, RunBackupForSourceResponses, RunConnectionHealthCheckData, RunConnectionHealthCheckErrors, RunConnectionHealthCheckResponses, RunExternalServiceBackupData, RunExternalServiceBackupErrors, RunExternalServiceBackupResponses, RunScheduleNowData, RunScheduleNowErrors, RunScheduleNowResponses, SandboxCreatePreviewLinkData, SandboxCreatePreviewLinkErrors, SandboxCreatePreviewLinkResponses, SaveAgentTokenData, SaveAgentTokenErrors, SaveAgentTokenResponses, SaveAiProviderCredentialData, SaveAiProviderCredentialErrors, SaveAiProviderCredentialResponses, SearchLogsData, SearchLogsErrors, SearchLogsResponses, SendEmailData, SendEmailErrors, SendEmailResponses, SetAiDataAccessData, SetAiDataAccessErrors, SetAiDataAccessResponses, SetDefaultS3SourceData, SetDefaultS3SourceErrors, SetDefaultS3SourceResponses, SetFlagEnvironmentData, SetFlagEnvironmentErrors, SetFlagEnvironmentResponses, SetPreviewPasswordData, SetPreviewPasswordErrors, SetPreviewPasswordResponses, SetupDnsChallengeData, SetupDnsChallengeErrors, SetupDnsChallengeResponses, SetupDnsData, SetupDnsErrors, SetupDnsResponses, SetupEmailTrackingData, SetupEmailTrackingErrors, SetupEmailTrackingResponses, SetupMfaData, SetupMfaErrors, SetupMfaResponses, SleepEnvironmentData, SleepEnvironmentErrors, SleepEnvironmentResponses, SmokeTestAgentData, SmokeTestAgentErrors, SmokeTestAgentResponses, SourceSandboxData, SourceSandboxErrors, SourceSandboxResponses, StartAnalysisData, StartAnalysisErrors, StartAnalysisResponses, StartContainerData, StartContainerErrors, StartContainerResponses, StartFixData, StartFixErrors, StartFixResponses, StartGitProviderOauthData, StartGitProviderOauthErrors, StartOidcLoginBySlugData, StartOidcLoginBySlugErrors, StartPgUpgradeData, StartPgUpgradeErrors, StartPgUpgradeResponses, StartRestoreData, StartRestoreErrors, StartRestoreResponses, StartServiceData, StartServiceErrors, StartServiceResponses, StatPathData, StatPathErrors, StatPathResponses, StopContainerData, StopContainerErrors, StopContainerResponses, StopSandboxData, StopSandboxErrors, StopSandboxResponses, StopServiceData, StopServiceErrors, StopServiceResponses, StreamContainerMetricsData, StreamContainerMetricsErrors, StreamContainerMetricsResponses, StreamEventsData, StreamEventsErrors, StreamEventsResponses, StreamRunEventsData, StreamRunEventsErrors, StreamRunEventsResponses, SyncRepositoriesData, SyncRepositoriesErrors, SyncRepositoriesResponses, TailDeploymentJobLogsData, TailDeploymentJobLogsErrors, TailLogsData, TailLogsErrors, TailLogsResponses, TeardownDeploymentData, TeardownDeploymentErrors, TeardownDeploymentResponses, TeardownEnvironmentData, TeardownEnvironmentErrors, TeardownEnvironmentResponses, TerminalData, TerminalErrors, TestNotificationProviderData, TestNotificationProviderErrors, TestNotificationProviderResponses, TestOidcProviderData, TestOidcProviderResponses, TestProviderConnectionData, TestProviderConnectionErrors, TestProviderConnectionResponses, TestProviderData, TestProviderErrors, TestProviderKeyByIdData, TestProviderKeyByIdErrors, TestProviderKeyByIdResponses, TestProviderKeyInlineData, TestProviderKeyInlineErrors, TestProviderKeyInlineResponses, TestProviderResponses, TestS3ConnectionPreviewData, TestS3ConnectionPreviewErrors, TestS3ConnectionPreviewResponses, TestS3SourceConnectionData, TestS3SourceConnectionErrors, TestS3SourceConnectionResponses, TrackClickData, TrackClickErrors, TrackOpenData, TrackOpenErrors, TrackOpenResponses, TriggerAgentData, TriggerAgentErrors, TriggerAgentResponses, TriggerProjectPipelineData, TriggerProjectPipelineErrors, TriggerProjectPipelineResponses, TriggerScanData, TriggerScanErrors, TriggerScanResponses, TriggerServiceHealthCheckData, TriggerServiceHealthCheckErrors, TriggerServiceHealthCheckResponses, TriggerWeeklyDigestData, TriggerWeeklyDigestErrors, TriggerWeeklyDigestResponses, UnlinkServiceFromProjectData, UnlinkServiceFromProjectErrors, UnlinkServiceFromProjectResponses, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponses, UpdateAiProviderData, UpdateAiProviderErrors, UpdateAiProviderResponses, UpdateAlertData, UpdateAlertErrors, UpdateAlertResponses, UpdateAlertRuleData, UpdateAlertRuleErrors, UpdateAlertRuleResponses, UpdateApiKeyData, UpdateApiKeyErrors, UpdateApiKeyResponses, UpdateAutomaticDeployData, UpdateAutomaticDeployErrors, UpdateAutomaticDeployResponses, UpdateBackupScheduleData, UpdateBackupScheduleErrors, UpdateBackupScheduleResponses, UpdateCloudflareProviderData, UpdateCloudflareProviderErrors, UpdateCloudflareProviderResponses, UpdateConnectionTokenData, UpdateConnectionTokenErrors, UpdateConnectionTokenResponses, UpdateCustomDomainData, UpdateCustomDomainErrors, UpdateCustomDomainResponses, UpdateDashboardData, UpdateDashboardErrors, UpdateDashboardResponses, UpdateDeploymentTokenData, UpdateDeploymentTokenErrors, UpdateDeploymentTokenResponses, UpdateEmailProviderData, UpdateEmailProviderErrors, UpdateEmailProviderResponses, UpdateEnvironmentSettingsData, UpdateEnvironmentSettingsErrors, UpdateEnvironmentSettingsResponses, UpdateEnvironmentSubdomainData, UpdateEnvironmentSubdomainErrors, UpdateEnvironmentSubdomainResponses, UpdateEnvironmentVariableData, UpdateEnvironmentVariableErrors, UpdateEnvironmentVariableResponses, UpdateErrorGroupData, UpdateErrorGroupErrors, UpdateErrorGroupResponses, UpdateFlagData, UpdateFlagErrors, UpdateFlagResponses, UpdateFunnelData, UpdateFunnelErrors, UpdateFunnelResponses, UpdateGitProviderCredentialsData, UpdateGitProviderCredentialsErrors, UpdateGitProviderCredentialsResponses, UpdateGitSettingsData, UpdateGitSettingsErrors, UpdateGitSettingsResponses, UpdateGlobalMcpData, UpdateGlobalMcpErrors, UpdateGlobalMcpResponses, UpdateGlobalSkillData, UpdateGlobalSkillErrors, UpdateGlobalSkillResponses, UpdateIncidentStatusData, UpdateIncidentStatusErrors, UpdateIncidentStatusResponses, UpdateIpAccessControlData, UpdateIpAccessControlErrors, UpdateIpAccessControlResponses, UpdateManagedDomainData, UpdateManagedDomainErrors, UpdateManagedDomainResponses, UpdateMcpData, UpdateMcpErrors, UpdateMcpResponses, UpdateNotificationEmailProviderData, UpdateNotificationEmailProviderErrors, UpdateNotificationEmailProviderResponses, UpdateNotificationProviderData, UpdateNotificationProviderErrors, UpdateNotificationProviderResponses, UpdateOidcProviderData, UpdateOidcProviderResponses, UpdatePreferencesData, UpdatePreferencesErrors, UpdatePreferencesResponses, UpdateProjectData, UpdateProjectDeploymentConfigData, UpdateProjectDeploymentConfigErrors, UpdateProjectDeploymentConfigResponses, UpdateProjectErrors, UpdateProjectResponses, UpdateProjectSecretData, UpdateProjectSecretErrors, UpdateProjectSecretResponses, UpdateProjectSettingsData, UpdateProjectSettingsErrors, UpdateProjectSettingsResponses, UpdateProviderData, UpdateProviderErrors, UpdateProviderKeyData, UpdateProviderKeyErrors, UpdateProviderKeyResponses, UpdateProviderResponses, UpdateRouteData, UpdateRouteErrors, UpdateRouteResponses, UpdateS3SourceData, UpdateS3SourceErrors, UpdateS3SourceResponses, UpdateSelfData, UpdateSelfErrors, UpdateSelfResponses, UpdateServiceData, UpdateServiceErrors, UpdateServiceResourcesData, UpdateServiceResourcesErrors, UpdateServiceResourcesResponses, UpdateServiceResponses, UpdateSessionDurationData, UpdateSessionDurationErrors, UpdateSessionDurationResponses, UpdateSettingsData, UpdateSettingsErrors, UpdateSettingsResponses, UpdateSkillData, UpdateSkillErrors, UpdateSkillResponses, UpdateSlackProviderData, UpdateSlackProviderErrors, UpdateSlackProviderResponses, UpdateSpeedMetricsData, UpdateSpeedMetricsErrors, UpdateSpeedMetricsResponses, UpdateTeamData, UpdateTeamErrors, UpdateTeamMemberRoleData, UpdateTeamMemberRoleErrors, UpdateTeamMemberRoleResponses, UpdateTeamResponses, UpdateUserData, UpdateUserErrors, UpdateUserResponses, UpdateWebhookData, UpdateWebhookErrors, UpdateWebhookProviderData, UpdateWebhookProviderErrors, UpdateWebhookProviderResponses, UpdateWebhookResponses, UpgradePreviewGatewayData, UpgradePreviewGatewayResponses, UpgradeServiceData, UpgradeServiceErrors, UpgradeServiceResponses, UploadGlobalSkillData, UploadGlobalSkillErrors, UploadGlobalSkillResponses, UploadReleaseFileData, UploadReleaseFileErrors, UploadReleaseFileResponses, UploadSkillData, UploadSkillErrors, UploadSkillResponses, UploadSourceFileData, UploadSourceFileErrors, UploadSourceFileResponses, UploadSourceMapData, UploadSourceMapErrors, UploadSourceMapResponses, UploadStaticBundleData, UploadStaticBundleErrors, UploadStaticBundleResponses, UpsertSecretData, UpsertSecretErrors, UpsertSecretResponses, ValidateConnectionData, ValidateConnectionErrors, ValidateConnectionResponses, ValidateEmailData, ValidateEmailErrors, ValidateEmailResponses, VerifyAndEnableMfaData, VerifyAndEnableMfaErrors, VerifyAndEnableMfaResponses, VerifyDomainData, VerifyDomainErrors, VerifyDomainResponses, VerifyEmailData, VerifyEmailErrors, VerifyEmailResponses, VerifyManagedDomainData, VerifyManagedDomainErrors, VerifyManagedDomainResponses, VerifyMfaChallengeData, VerifyMfaChallengeErrors, VerifyMfaChallengeResponses, VerifyStepUpData, VerifyStepUpErrors, VerifyStepUpResponses, WakeEnvironmentData, WakeEnvironmentErrors, WakeEnvironmentResponses, WebhookTriggerData, WebhookTriggerErrors, WebhookTriggerResponses, WorkflowDryRunData, WorkflowDryRunErrors, WorkflowDryRunResponses, WriteFileData, WriteFileErrors, WriteFileResponses, WriteFilesData, WriteFilesErrors, WriteFilesResponses } from './types.gen'; export type Options = Options2 & { /** @@ -7515,7 +7515,7 @@ export const removeRole = (options: Option ...options }); -export const listSandboxes = (options?: Options): RequestResult => (options?.client ?? client).get({ +export const listSandboxes = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ scheme: 'bearer', type: 'http' }], url: '/v1/sandboxes', ...options @@ -7847,6 +7847,15 @@ export const stopSandbox = (options: Optio ...options }); +/** + * Attach an interactive terminal to a sandbox. + */ +export const terminal = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ scheme: 'bearer', type: 'http' }], + url: '/v1/sandboxes/{id}/terminal', + ...options +}); + /** * Kill a running command (`@vercel/sandbox`-compatible). The SDK * calls `POST /v1/sandboxes/{id}/{cmdId}/kill` — note the path has the diff --git a/web/src/api/client/types.gen.ts b/web/src/api/client/types.gen.ts index f19a3a3db..594cf2eb9 100644 --- a/web/src/api/client/types.gen.ts +++ b/web/src/api/client/types.gen.ts @@ -3882,6 +3882,17 @@ export type CreateSandboxBody = { * Docker image override. `null` uses the platform default. */ image?: string | null; + /** + * Lifecycle class (ADR-036, temps-native): `"ephemeral"` (default) or + * `"workspace"`. + * + * A workspace is a long-lived development environment: it is still + * suspended after `timeout_secs` of inactivity, but the next exec or + * filesystem call wakes it transparently instead of returning 409, and + * nothing ever destroys it automatically. Use it for "give me a place + * to work on this repo"; leave it unset for throwaway sandboxes. + */ + lifecycle?: string | null; memory_limit_mb?: number | null; name?: string | null; networkPolicy?: unknown; @@ -3902,6 +3913,16 @@ export type CreateSandboxBody = { */ preview_password?: string | null; projectId?: string | null; + /** + * Create the sandbox against a temps project (temps-native). The + * project's connected repo and git credential seed the work dir when + * no explicit `source` is given, and the sandbox is attributed to the + * project so it can be listed alongside it. + * + * Requires access to the project — the same team/scope rules that + * gate every other project-scoped endpoint apply. + */ + project_id?: number | null; resources?: null | ResourcesBody; source?: null | SourceBody; /** @@ -14003,16 +14024,30 @@ export type SandboxInner = { disk_size_mb?: number | null; id: string; image?: string | null; + /** + * Lifecycle class (ADR-036): `"ephemeral"` or `"workspace"`. Always + * present — a client that doesn't know about workspaces sees + * `"ephemeral"` and behaves exactly as before. + */ + lifecycle: string; memory: number; name: string; preview_password_hint?: string | null; preview_url_template: string; + /** + * Project this sandbox was created from, when created from one. + */ + project_id?: number | null; region: string; /** * Creation time as Unix epoch milliseconds. */ requestedAt: number; runtime: string; + /** + * Repo the work dir was seeded from. Never carries credentials. + */ + source_repo_url?: string | null; status: string; /** * Idle timeout in milliseconds (SDK convention). @@ -48411,10 +48446,25 @@ export type ListSandboxesData = { * Items per page (default 20, max 100) */ page_size?: number; + /** + * Filter by lifecycle class: "ephemeral" or "workspace" + */ + lifecycle?: string; + /** + * Filter to sandboxes created from a project + */ + project_id?: number; }; url: '/v1/sandboxes'; }; +export type ListSandboxesErrors = { + /** + * Unknown lifecycle value + */ + 400: unknown; +}; + export type ListSandboxesResponses = { /** * List sandboxes @@ -49264,6 +49314,54 @@ export type StopSandboxResponses = { export type StopSandboxResponse = StopSandboxResponses[keyof StopSandboxResponses]; +export type TerminalData = { + body?: never; + path: { + /** + * Sandbox public ID + */ + id: string; + }; + query?: { + /** + * Tab to attach to (default "main"); reusing an id reattaches to the running program + */ + tab?: string; + /** + * Program to launch when the tab is created (default: login shell) + */ + cmd?: string; + /** + * Initial columns (default 80) + */ + cols?: number; + /** + * Initial rows (default 24) + */ + rows?: number; + }; + url: '/v1/sandboxes/{id}/terminal'; +}; + +export type TerminalErrors = { + /** + * Unauthorized + */ + 401: unknown; + /** + * Insufficient permissions + */ + 403: unknown; + /** + * Sandbox not found + */ + 404: unknown; + /** + * Sandbox is not in a state that can be attached to + */ + 409: unknown; +}; + export type CmdKillData = { body?: CmdKillBody; path: { diff --git a/web/src/components/sandboxes/helpers.ts b/web/src/components/sandboxes/helpers.ts index b63f4836f..0bf8ddbfe 100644 --- a/web/src/components/sandboxes/helpers.ts +++ b/web/src/components/sandboxes/helpers.ts @@ -16,6 +16,19 @@ export type SandboxView = { expires_at: string preview_url_template: string preview_password_hint?: string | null + /** + * `'ephemeral'` or `'workspace'` (ADR-036). A workspace suspends on idle + * like an ephemeral sandbox but wakes on the next access instead of + * erroring, so `expires_at` means "suspends at" rather than "dies at". + */ + lifecycle?: string + project_id?: number | null + source_repo_url?: string | null +} + +/** Is this sandbox a persistent workspace? Absent lifecycle = ephemeral. */ +export function isWorkspace(s: Pick): boolean { + return s.lifecycle === 'workspace' } export type JobSummary = JobSummaryResponse @@ -39,6 +52,9 @@ export function toSandboxView(inner: SandboxInner): SandboxView { expires_at: new Date(expiresMs).toISOString(), preview_url_template: inner.preview_url_template, preview_password_hint: inner.preview_password_hint ?? undefined, + lifecycle: inner.lifecycle, + project_id: inner.project_id ?? null, + source_repo_url: inner.source_repo_url ?? null, } } diff --git a/web/src/pages/Sandboxes.tsx b/web/src/pages/Sandboxes.tsx index d491d7b2c..12dd1c552 100644 --- a/web/src/pages/Sandboxes.tsx +++ b/web/src/pages/Sandboxes.tsx @@ -46,7 +46,11 @@ import { resumeSandboxMutation, stopSandboxMutation, } from '@/api/client/@tanstack/react-query.gen' -import { toSandboxView, type SandboxView } from '@/components/sandboxes/helpers' +import { + toSandboxView, + isWorkspace, + type SandboxView, +} from '@/components/sandboxes/helpers' import { CreateSandboxDocs } from '@/components/sandboxes/CreateSandboxDocs' function statusVariant( @@ -472,6 +476,7 @@ function SandboxRow({ const timeLeft = !destroyed ? formatCountdown(sandbox.expires_at, now) : '—' const expired = !destroyed && new Date(sandbox.expires_at).getTime() <= now + const workspace = isWorkspace(sandbox) const openPort = (port: number) => { if (!sandbox.preview_url_template || port < 1 || port > 65535) return @@ -513,6 +518,14 @@ function SandboxRow({ {sandbox.status} + {/* A workspace behaves differently from an ephemeral sandbox — + it wakes on access instead of erroring — so it has to look + different, or "stopped" reads as broken rather than idle. */} + {isWorkspace(sandbox) && ( + + workspace + + )} {sandbox.image && ( {sandbox.image} @@ -656,18 +669,27 @@ function SandboxRow({ >
+ {/* For a workspace this clock counts down to *suspension*, + not destruction, and a suspended one wakes on the next + command — so it is never shown in destructive red. */}
- {expired ? 'expired' : `${timeLeft} left`} + {expired + ? workspace + ? 'suspended — wakes on next use' + : 'expired' + : `${timeLeft} ${workspace ? 'to suspend' : 'left'}`}
created {formatAge(sandbox.created_at, now)} From 5ed480e53bc6fbf0597f4c1310ed8ab965921aed Mon Sep 17 00:00:00 2001 From: David Viejo Date: Fri, 7 Aug 2026 09:07:21 +0200 Subject: [PATCH 09/12] fix(sandbox): address review findings on workspaces and the terminal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to the /review-pr + security-auditor pass on this branch. touch() was cancelling extendTimeout() ------------------------------------- `extend_timeout` pushes `expires_at` past the idle window and deliberately leaves `timeout_secs` alone. `touch` then assigned `now + timeout_secs` unconditionally — and `touch` runs on every exec, every fs op, and every terminal heartbeat. So the first thing the long-running operation did was silently cancel the extension bought for it: extend by an hour at t0+10, exec at t0+20, deadline back to t0+3620. The deadline now only moves forward, guarded in SQL (`CASE WHEN expires_at < $1`) so `touch` stays one statement with no read-modify-write on the exec hot path. `last_activity_at` is still bumped unconditionally — it records activity, not a deadline. Regression test included. Terminal bounds --------------- - WebSocket messages were unbounded. axum defaults to 64 MiB, and the agent's 4 MiB frame check only runs *after* the message is buffered, so 32 sessions meant ~2 GiB of attacker-controlled buffering on the 4 GB reference host. Capped at 64 KiB, which is generous for keystrokes. The `MAX_FRAME_BYTES` doc comment claimed this cap already existed; it did not, and it now says what it actually bounds. - A half-open socket pinned a sandbox forever: with no keepalive the heartbeat was the only firing branch, so it kept calling `touch` indefinitely and never returned its slot — defeating the very idle timeout this branch set out to fix. Sessions now ping, close after 3 unanswered pings, and time out a blocked write instead of wedging the whole select! loop. - The global 32-slot cap was instance-wide, so one account could lock everyone else out with a 429. Added a per-user sub-cap of 4, released via RAII. - Authorization is evaluated once at upgrade and never revalidated, so a logout or revoked key left the shell working. Full revalidation needs an auth dependency the sandbox state does not carry; a 12h ceiling bounds the window in the meantime and is documented as such. - An oversized paste killed the terminal with no explanation; it now gets an error frame first. - Agent frames that fail to decode no longer fall back to defaults silently. Read-only endpoints no longer boot containers --------------------------------------------- `resolve_id` wakes a suspended workspace, and five call sites used it purely as an ownership check: `domain()`, `preview_link()`, `job_status`, `subscribe_job_logs`, `list_jobs`. A `GET` that starts a container is a surprise that costs real memory, and for the job endpoints it is pure waste — the in-memory job table was emptied when the container stopped, so waking it cannot change the answer. Added `resolve_id_no_wake` for those. Also ---- - The migration now backfills `work_dir` from the hardcoded `/workspace` to `/home/temps/workspace`. Fixing the code without the data left every pre-existing sandbox reporting a `cwd` that has never existed in the image. - `wake_workspace` bounds the container start at 120s; a wedged daemon was an indefinitely hung request. - Consolidated the two URL-credential checks on the correct one. The handler's copy scanned for the first `@` after the scheme, so it false-positived on a URL with an explicit port and an `@` in the path. - Dropped the unused `bytes` dependency; corrected the `list_for_user` index claim (the partial index only serves the non-ephemeral side). - ADR-036 said `project_id` carries `ON DELETE SET NULL`; there is no FK, on purpose, and the ADR now explains why. It also now states that the project-derived clone uses the caller's own git connection. - Recorded, on the step-up authorizer, *why* the unenrolled-user change is not the loss it looks like — enrolment itself is not re-auth protected, so the old gate was never a control for those users — and that this reasoning is load-bearing: fixing enrolment means revisiting this policy. --- Cargo.lock | 1 - crates/temps-auth/src/sensitive_action.rs | 19 ++ ...0806_000001_sandbox_workspace_lifecycle.rs | 14 ++ crates/temps-pty-agent/src/protocol.rs | 11 +- crates/temps-sandbox/Cargo.toml | 1 - .../temps-sandbox/src/handlers/sandboxes.rs | 22 +- crates/temps-sandbox/src/handlers/terminal.rs | 229 ++++++++++++++++-- crates/temps-sandbox/src/services/exec.rs | 8 +- .../src/services/sandbox_service.rs | 161 ++++++++++-- .../adr/036-persistent-workspace-sandboxes.md | 4 +- 10 files changed, 395 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc1b08a82..3e6c59ebc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12438,7 +12438,6 @@ dependencies = [ "async-trait", "axum", "base64 0.23.0", - "bytes", "chrono", "flate2", "futures", diff --git a/crates/temps-auth/src/sensitive_action.rs b/crates/temps-auth/src/sensitive_action.rs index db62d5610..343fee648 100644 --- a/crates/temps-auth/src/sensitive_action.rs +++ b/crates/temps-auth/src/sensitive_action.rs @@ -39,6 +39,25 @@ pub const STEP_UP_TTL_MINUTES: i64 = 5; /// What it is *not* weakened by: a stolen session cannot unenrol to escape the /// challenge, because disabling MFA itself requires a valid TOTP code. /// +/// # Why this is not the loss it looks like — and what would change that +/// +/// The gate this replaces was never a control for unenrolled users. Enrolment +/// itself is guarded only by `permission_guard!(auth, UsersWrite)`: +/// `POST /users/me/mfa/setup` and `/users/me/mfa/verify` ask for no password +/// and no step-up. An attacker holding a stolen session for an unenrolled +/// account could therefore enrol *their own* authenticator and satisfy the old +/// challenge in two calls — while leaving their TOTP secret on the victim's +/// account, which is both a persistence mechanism and a permanent lockout for +/// the real owner. Removing the challenge for those users removes that +/// incentive; it does not remove a barrier the attacker could not already +/// cross. +/// +/// **That reasoning is load-bearing.** If enrolment is ever put behind +/// re-authentication (current password, or a step-up for re-enrolment), the +/// pre-existing behaviour *would* become a real control, and this policy must +/// be revisited at the same time — otherwise the fix to enrolment silently +/// leaves this hole open behind it. +/// /// # Operators who want the stricter posture /// /// `AppSettings::require_mfa_for_admins` is **not** sufficient on its own: it diff --git a/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs b/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs index 2cf222e52..b2055375a 100644 --- a/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs +++ b/crates/temps-migrations/src/migration/m20260806_000001_sandbox_workspace_lifecycle.rs @@ -50,6 +50,20 @@ impl MigrationTrait for Migration { "CREATE INDEX IF NOT EXISTS idx_sandboxes_project_id ON sandboxes (project_id) WHERE project_id IS NOT NULL", ) .await?; + + // Backfill the work dir that `create_sandbox` used to hardcode. + // + // Rows created before the fix carry '/workspace', which does not exist + // in the sandbox image — the real directory is '/home/temps/workspace'. + // That column is handed to API clients as `cwd`, so an SDK caller + // using it as an exec working directory gets a path that has never + // existed. Correcting the code without correcting the rows leaves + // every pre-existing sandbox broken in exactly the way this PR set out + // to fix. Scoped to the wrong value so a custom work dir is untouched. + conn.execute_unprepared( + "UPDATE sandboxes SET work_dir = '/home/temps/workspace' WHERE work_dir = '/workspace'", + ) + .await?; Ok(()) } diff --git a/crates/temps-pty-agent/src/protocol.rs b/crates/temps-pty-agent/src/protocol.rs index 928253d74..c06adeebb 100644 --- a/crates/temps-pty-agent/src/protocol.rs +++ b/crates/temps-pty-agent/src/protocol.rs @@ -11,9 +11,14 @@ use serde::{Deserialize, Serialize}; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; -/// Hard cap on a single frame, matches the websocket frame cap in the -/// terminal handler. Prevents a malicious or buggy client from asking the -/// agent to allocate gigabytes before we know what's in the frame. +/// Hard cap on a single frame. Prevents a malicious or buggy peer from asking +/// the agent to allocate gigabytes before we know what's in the frame. +/// +/// This bounds the *agent* side only, and it is checked after the length +/// header rather than after buffering. It is deliberately **not** the bound on +/// what a browser can send: the terminal handler caps WebSocket messages +/// separately and far lower (`MAX_WS_MESSAGE_BYTES`), because a message is +/// fully buffered before any agent-side check can see it. pub const MAX_FRAME_BYTES: usize = 4 * 1024 * 1024; // Client → Agent diff --git a/crates/temps-sandbox/Cargo.toml b/crates/temps-sandbox/Cargo.toml index dcc066b6f..69117aa5b 100644 --- a/crates/temps-sandbox/Cargo.toml +++ b/crates/temps-sandbox/Cargo.toml @@ -35,7 +35,6 @@ hex = "0.4" url = { workspace = true } tokio-stream = { version = "0.1.17", features = ["sync"] } tokio-util = { workspace = true, features = ["io"] } -bytes = { workspace = true } futures = { workspace = true } async-stream = { workspace = true } flate2 = { workspace = true } diff --git a/crates/temps-sandbox/src/handlers/sandboxes.rs b/crates/temps-sandbox/src/handlers/sandboxes.rs index 2c56e998c..46813074e 100644 --- a/crates/temps-sandbox/src/handlers/sandboxes.rs +++ b/crates/temps-sandbox/src/handlers/sandboxes.rs @@ -195,26 +195,6 @@ pub enum SourceBody { }, } -/// Reject credentials baked into the URL (`https://user:pass@host/...`). -/// We want credentials to flow through the `username`/`password` or -/// `git_connection_id` channels so the token goes through the safe -/// `GIT_ASKPASS` path and never lands in `.git/config` or logs. -fn url_contains_credentials(url: &str) -> bool { - // Look for `://@` where `` contains `:` — that's - // the `user:password` form. A plain `@` without `:` is fine (user-only, - // which git treats as "prompt for password"). - if let Some(scheme_end) = url.find("://") { - let rest = &url[scheme_end + 3..]; - if let Some(at_idx) = rest.find('@') { - let userinfo = &rest[..at_idx]; - if userinfo.contains(':') { - return true; - } - } - } - false -} - /// Reject URLs that point at private/loopback/metadata IPs or use /// non-HTTP schemes. Without this, an authenticated user can drive the /// sandbox to fetch from internal Docker network services (control @@ -305,7 +285,7 @@ impl SourceBody { message: "git source: url must not be empty".into(), }); } - if url_contains_credentials(url) { + if crate::services::sandbox_service::url_has_embedded_credentials(url) { return Err(SandboxError::Validation { message: "git source: url must not contain embedded credentials — use username/password or git_connection_id".into(), }); diff --git a/crates/temps-sandbox/src/handlers/terminal.rs b/crates/temps-sandbox/src/handlers/terminal.rs index 616be2e8d..068073752 100644 --- a/crates/temps-sandbox/src/handlers/terminal.rs +++ b/crates/temps-sandbox/src/handlers/terminal.rs @@ -32,6 +32,7 @@ //! every PTY with it (`/run/temps-pty` is tmpfs). An attached terminal is //! activity; this is what makes that true. +use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; @@ -81,6 +82,85 @@ const MAX_CONCURRENT_TERMINALS: usize = 32; static TERMINAL_SLOTS: tokio::sync::Semaphore = tokio::sync::Semaphore::const_new(MAX_CONCURRENT_TERMINALS); +/// Concurrent terminals a *single* account may hold. +/// +/// [`MAX_CONCURRENT_TERMINALS`] alone bounds the host, but it is global: one +/// account opening 32 sessions locks every other user out of the feature with +/// a 429. Nobody drives more than a handful of terminals by hand, so a small +/// per-user sub-cap turns an instance-wide denial of service into a limit the +/// offending account hits by itself. +const MAX_TERMINALS_PER_USER: usize = 4; + +/// Live attachment count per user id, guarding [`MAX_TERMINALS_PER_USER`]. +/// A plain `Mutex` is fine here: it is taken twice per *session*, never on a +/// data path. +static TERMINALS_PER_USER: std::sync::Mutex>> = + std::sync::Mutex::new(None); + +/// RAII counter for [`TERMINALS_PER_USER`]. Decrements on drop, so every exit +/// path — clean close, error, panic in the session future — returns the slot. +struct UserSlot(i32); + +impl UserSlot { + /// Returns `None` when this user is already at their cap. + fn acquire(user_id: i32) -> Option { + let mut guard = TERMINALS_PER_USER.lock().ok()?; + let counts = guard.get_or_insert_with(HashMap::new); + let entry = counts.entry(user_id).or_insert(0); + if *entry >= MAX_TERMINALS_PER_USER { + return None; + } + *entry += 1; + Some(UserSlot(user_id)) + } +} + +impl Drop for UserSlot { + fn drop(&mut self) { + if let Ok(mut guard) = TERMINALS_PER_USER.lock() { + if let Some(counts) = guard.as_mut() { + if let Some(entry) = counts.get_mut(&self.0) { + *entry = entry.saturating_sub(1); + // Don't let the map grow one entry per user id forever. + if *entry == 0 { + counts.remove(&self.0); + } + } + } + } + } +} + +/// Largest WebSocket message accepted from a terminal client. +/// +/// A terminal client sends keystrokes and small JSON control frames; 64 KiB is +/// already generous for a paste. axum's default is 64 MiB, which times +/// [`MAX_CONCURRENT_TERMINALS`] is ~2 GiB of attacker-controlled buffering on +/// the 3 vCPU / 4 GB reference host — and the agent-side +/// `MAX_FRAME_BYTES` check only runs *after* the whole message is buffered, +/// so it does not bound this. +const MAX_WS_MESSAGE_BYTES: usize = 64 * 1024; + +/// How long a session may sit with no traffic from the client before we close +/// it, and how many unanswered pings that allows. +/// +/// Without this a half-open connection (closed laptop, NAT drop, dead Wi-Fi) +/// leaves the heartbeat as the only firing branch, so the session keeps +/// calling `touch` forever: the sandbox is never swept, the `docker exec` +/// stays open, and a global slot is never returned. A live terminal answers +/// pings; a dead one does not. +const MISSED_PONGS_BEFORE_CLOSE: u32 = 3; + +/// Hard ceiling on a single attachment. +/// +/// Authorization is evaluated once, at upgrade, and never revalidated — so a +/// logout, an account deactivation, a password change with +/// `revoke_other_sessions`, or a deleted API key leave this shell working. +/// (The container-exec terminal has the same shape.) Bounding the session +/// bounds that window: the client reconnects transparently and is +/// re-authorized when it does. +const MAX_SESSION_DURATION: Duration = Duration::from_secs(12 * 60 * 60); + /// Longest accepted `tab` identifier, and the character set. /// /// The agent keys tabs by this string and allocates a PTY plus a 64 KiB @@ -198,6 +278,18 @@ pub async fn terminal( )) })?; + // Per-user sub-cap, so one account cannot take every global slot and lock + // the whole instance out of the feature. + let user_slot = UserSlot::acquire(auth.user_id()).ok_or_else(|| { + problemdetails::new(StatusCode::TOO_MANY_REQUESTS) + .with_title("Too Many Terminals") + .with_detail(format!( + "You already have {} terminal sessions open. \ + Close one and retry.", + MAX_TERMINALS_PER_USER + )) + })?; + // Resolve *before* the upgrade so ownership failures, a missing sandbox, // or a stopped ephemeral one surface as a real HTTP status instead of a // WebSocket that opens and immediately dies. This also wakes a suspended @@ -250,25 +342,29 @@ pub async fn terminal( // "spawn_failed: No such file or directory". let work_dir = handle.work_dir.to_string_lossy().to_string(); - Ok(ws.on_upgrade(move |socket| async move { - // Held for the session's lifetime; released when this future ends, - // however it ends. - let _permit = permit; - let session = TerminalSession { - socket, - attachment, - service, - sandbox_id: id, - internal_id, - timeout_secs, - tab, - cmd, - cols, - rows, - work_dir, - }; - session.run().await; - })) + Ok(ws + .max_message_size(MAX_WS_MESSAGE_BYTES) + .max_frame_size(MAX_WS_MESSAGE_BYTES) + .on_upgrade(move |socket| async move { + // Held for the session's lifetime; released when this future ends, + // however it ends. + let _permit = permit; + let _user_slot = user_slot; + let session = TerminalSession { + socket, + attachment, + service, + sandbox_id: id, + internal_id, + timeout_secs, + tab, + cmd, + cols, + rows, + work_dir, + }; + session.run().await; + })) } struct TerminalSession { @@ -348,11 +444,53 @@ impl TerminalSession { // it means a sandbox seconds from expiry is rescued on connect. heartbeat.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + // Liveness. `touch` on a tick keeps the sweeper off a sandbox someone + // is using — but only a *live* client should get that. Each tick pings + // and counts; any frame from the client (including the pong) clears + // the count. After MISSED_PONGS_BEFORE_CLOSE unanswered pings we treat + // the peer as gone, stop touching, and let the sandbox suspend + // normally. Without this a half-open socket pins the container + // forever, which is exactly the idle timeout this PR set out to fix. + let mut unanswered_pings: u32 = 0; + let deadline = tokio::time::sleep(MAX_SESSION_DURATION); + tokio::pin!(deadline); + loop { tokio::select! { + // Bounded session: the client reconnects and is re-authorized. + _ = &mut deadline => { + send_error( + &mut ws_tx, + "terminal session reached its maximum duration; reconnect to continue" + .to_string(), + ) + .await; + break; + } + // Keep the sweeper honest while someone is attached. _ = heartbeat.tick() => { + if unanswered_pings >= MISSED_PONGS_BEFORE_CLOSE { + tracing::debug!( + "Terminal on sandbox {} tab '{}' stopped answering pings; closing", + sandbox_id, + tab + ); + break; + } service.touch(internal_id, timeout_secs).await; + // A closed receive window must not wedge the whole select! + // loop (no more heartbeats, no more reads). Time it out + // and drop the session instead. + match tokio::time::timeout( + ACTIVITY_HEARTBEAT, + ws_tx.send(Message::Ping(Vec::new().into())), + ) + .await + { + Ok(Ok(())) => unanswered_pings += 1, + _ => break, + } } // Agent → client. Cancellation-safe: see the codec above. @@ -375,10 +513,23 @@ impl TerminalSession { // Client → agent. msg = ws_rx.next() => { + // Anything at all from the peer proves it is alive. + unanswered_pings = 0; match msg { Some(Ok(Message::Binary(data))) => { - if pty::write_frame(&mut agent_in, pty::OP_INPUT, &data).await.is_err() { - break; + match pty::write_frame(&mut agent_in, pty::OP_INPUT, &data).await { + Ok(()) => {} + Err(e) => { + // Most likely an oversized paste. Say so + // instead of letting the terminal vanish + // with no explanation. + send_error( + &mut ws_tx, + format!("could not forward input: {}", e), + ) + .await; + break; + } } } Some(Ok(Message::Text(text))) => { @@ -423,7 +574,17 @@ async fn forward_agent_frame( match op { pty::OP_OUTPUT => ws_tx.send(Message::Binary(payload.into())).await.is_ok(), pty::OP_OPENED => { - let opened: Option = serde_json::from_slice(&payload).ok(); + let opened: Option = serde_json::from_slice(&payload) + .inspect_err(|e| { + // Falling back to a default silently makes a + // protocol-version mismatch look like normal + // operation. Say which frame failed. + tracing::warn!( + "terminal: could not decode OPENED frame from the pty agent: {}", + e + ); + }) + .ok(); let (tab_id, existed) = opened .as_ref() .map(|o| (o.tab_id.as_str(), o.existed)) @@ -431,14 +592,34 @@ async fn forward_agent_frame( send_event(ws_tx, ServerEvent::Ready { tab_id, existed }).await } pty::OP_EXIT => { - let exit: Option = serde_json::from_slice(&payload).ok(); + let exit: Option = serde_json::from_slice(&payload) + .inspect_err(|e| { + // Falling back to a default silently makes a + // protocol-version mismatch look like normal + // operation. Say which frame failed. + tracing::warn!( + "terminal: could not decode EXIT frame from the pty agent: {}", + e + ); + }) + .ok(); let (code, signal) = exit.map(|e| (e.code, e.signal)).unwrap_or((None, None)); send_event(ws_tx, ServerEvent::Exit { code, signal }).await; // The program is gone; nothing left to relay. false } pty::OP_ERROR => { - let err: Option = serde_json::from_slice(&payload).ok(); + let err: Option = serde_json::from_slice(&payload) + .inspect_err(|e| { + // Falling back to a default silently makes a + // protocol-version mismatch look like normal + // operation. Say which frame failed. + tracing::warn!( + "terminal: could not decode ERROR frame from the pty agent: {}", + e + ); + }) + .ok(); let message = err .map(|e| format!("{}: {}", e.code, e.message)) .unwrap_or_else(|| "terminal agent reported an error".to_string()); diff --git a/crates/temps-sandbox/src/services/exec.rs b/crates/temps-sandbox/src/services/exec.rs index c01ce03ef..167d8b0fd 100644 --- a/crates/temps-sandbox/src/services/exec.rs +++ b/crates/temps-sandbox/src/services/exec.rs @@ -287,7 +287,9 @@ impl SandboxService { user_id: i32, job_id: &str, ) -> Result, SandboxError> { - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; + // Ownership only, no wake: job state lives in the in-process tracker, + // and a suspended container's jobs are already gone. + let (_row, internal_id) = self.resolve_id_no_wake(public_id, user_id).await?; self.jobs().subscribe(public_id, internal_id, job_id).await } @@ -298,7 +300,7 @@ impl SandboxService { user_id: i32, job_id: &str, ) -> Result { - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; + let (_row, internal_id) = self.resolve_id_no_wake(public_id, user_id).await?; self.jobs().status(public_id, internal_id, job_id).await } @@ -310,7 +312,7 @@ impl SandboxService { public_id: &str, user_id: i32, ) -> Result, SandboxError> { - let (_row, internal_id) = self.resolve_id(public_id, user_id).await?; + let (_row, internal_id) = self.resolve_id_no_wake(public_id, user_id).await?; Ok(self.jobs().list(internal_id).await) } } diff --git a/crates/temps-sandbox/src/services/sandbox_service.rs b/crates/temps-sandbox/src/services/sandbox_service.rs index 68d3bdadd..04bbdcf06 100644 --- a/crates/temps-sandbox/src/services/sandbox_service.rs +++ b/crates/temps-sandbox/src/services/sandbox_service.rs @@ -17,8 +17,8 @@ use std::time::{Duration, SystemTime}; use chrono::Utc; use sea_orm::{ - ActiveModelTrait, ActiveValue::Set, ColumnTrait, DatabaseConnection, EntityTrait, - PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, + sea_query::Expr, ActiveModelTrait, ActiveValue::Set, ColumnTrait, DatabaseConnection, + EntityTrait, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, }; use temps_agents::sandbox::SandboxCreateConfig; @@ -331,7 +331,14 @@ async fn validate_resolved_source(source: &SandboxSource) -> Result<(), SandboxE /// /// A bare `user@` is fine — git reads that as "prompt for a password" and it /// carries no secret. Only the colon form is a credential. -fn url_has_embedded_credentials(url: &str) -> bool { +/// +/// Shared with the handler so both entry points agree. The naive version — +/// scanning for the first `@` anywhere after the scheme — false-positives on a +/// URL that has an explicit port and an `@` later in the path +/// (`https://host:8080/org/repo@v1.git`), because it reads the whole +/// `host:8080/org/repo` as userinfo. Stopping at the first `/` is what makes +/// that correct. +pub(crate) fn url_has_embedded_credentials(url: &str) -> bool { let Some(scheme_end) = url.find("://") else { return false; }; @@ -407,6 +414,12 @@ fn work_dir_to_remove(data_root: &Path, public_id_value: &str) -> Option 'ephemeral'`, + /// so `?lifecycle=workspace` avoids the ephemeral rows (the overwhelming + /// majority) while `?lifecycle=ephemeral` — an equally valid call — gets + /// no index and falls back to the `user_id` scan, which is the right + /// trade: one user's sandboxes are few, and indexing the common value + /// would cost writes on every row for no gain. pub async fn list_for_user( &self, user_id: i32, @@ -1676,18 +1693,35 @@ TEMPS_ASKPASS_EOF\n\ /// single UPDATE with no read-modify-write. `timeout_secs` is taken /// from the caller (who already has the row) to avoid a SELECT here. /// + /// **The deadline only ever moves forward.** `extend_timeout` (the SDK's + /// `extendTimeout()`) pushes `expires_at` past `now + timeout_secs` + /// precisely so a long operation can outlive the idle window — and the + /// first thing that operation does is exec, which lands here. Assigning + /// the idle deadline unconditionally would silently undo the extension + /// the caller just paid for, so the write is `CASE WHEN`-guarded in SQL: + /// still one statement, still no read-modify-write, but never a + /// regression. `last_activity_at` is always bumped — it records activity, + /// not a deadline. + /// /// Swallows DB errors: activity bumps are best-effort, and failing a /// user's exec because a bookkeeping write lost a race would be worse /// than a sandbox expiring slightly early. pub async fn touch(&self, sandbox_id: i32, timeout_secs: i32) { let now = Utc::now(); - let active = sandboxes::ActiveModel { - id: Set(sandbox_id), - last_activity_at: Set(now), - expires_at: Set(idle_deadline(now, timeout_secs)), - ..Default::default() - }; - if let Err(e) = active.update(self.db.as_ref()).await { + let deadline = idle_deadline(now, timeout_secs); + let result = sandboxes::Entity::update_many() + .col_expr(sandboxes::Column::LastActivityAt, Expr::value(now)) + .col_expr( + sandboxes::Column::ExpiresAt, + Expr::cust_with_values( + "CASE WHEN expires_at < $1 THEN $2 ELSE expires_at END", + [deadline, deadline], + ), + ) + .filter(sandboxes::Column::Id.eq(sandbox_id)) + .exec(self.db.as_ref()) + .await; + if let Err(e) = result { tracing::debug!( "touch: failed to bump last_activity_at for {}: {}", sandbox_id, @@ -1859,10 +1893,35 @@ TEMPS_ASKPASS_EOF\n\ // ── Helpers shared with the exec/fs modules ────────────────────────── + /// Load + authorize + return the internal ID **without** waking a + /// suspended workspace. + /// + /// For endpoints that only need to prove ownership and then answer from + /// the row or from in-memory state — preview URLs, job listings, job + /// status. Those are reads; booting a container as a side effect of a + /// `GET` is a surprise that costs real memory on a 3 vCPU / 4 GB host, and + /// in the job cases it is pure waste: the in-memory job table was emptied + /// when the container stopped, so waking it cannot change the answer. + /// + /// Use [`Self::resolve_id`] on paths that genuinely need the container + /// running (exec, filesystem, terminal). + pub async fn resolve_id_no_wake( + &self, + public_id_value: &str, + user_id: i32, + ) -> Result<(sandboxes::Model, i32), SandboxError> { + let row = self.find_by_public_id(public_id_value, user_id).await?; + let id = row.id; + Ok((row, id)) + } + /// Load + authorize + return the internal ID, or a typed error that /// already includes the public ID. Exec/fs modules call this first. /// Rejects stopped sandboxes with `InvalidState` (→ HTTP 409) — the /// user must call `/resume` before running commands. + /// + /// **Wakes a suspended workspace as a side effect** (ADR-036), so only + /// call it where the container must actually be running. pub async fn resolve_id( &self, public_id_value: &str, @@ -1913,10 +1972,28 @@ TEMPS_ASKPASS_EOF\n\ public_id_value, sandbox_id ); - self.registry - .start(sandbox_id, &public_id_value) - .await - .map_err(|e| from_agent_error(&public_id_value, e))?; + // Bounded: a wake happens inline on a user's request, and a wedged + // container runtime would otherwise hang that request forever with no + // way for the caller to tell a slow start from a dead daemon. + match tokio::time::timeout( + WAKE_TIMEOUT, + self.registry.start(sandbox_id, &public_id_value), + ) + .await + { + Ok(result) => result.map_err(|e| from_agent_error(&public_id_value, e))?, + Err(_) => { + return Err(SandboxError::InvalidState { + sandbox_id: public_id_value.clone(), + state: "stopped".to_string(), + operation: format!( + "wake timed out after {}s; the container runtime did not \ + start the workspace. Check the daemon, then retry", + WAKE_TIMEOUT.as_secs() + ), + }); + } + } let now = Utc::now(); let new_expires = idle_deadline(now, row.timeout_secs); @@ -1960,8 +2037,9 @@ TEMPS_ASKPASS_EOF\n\ }); } // Ownership + validity check. The numeric id is intentionally - // discarded — the preview URL never embeds it. - let _ = self.resolve_id(public_id_value, user_id).await?; + // discarded — the preview URL never embeds it. No wake: building a + // URL string does not need the container running. + let _ = self.resolve_id_no_wake(public_id_value, user_id).await?; let parts = self.preview_parts().await; Ok(parts.url_for(public_id_value, port)) } @@ -1990,7 +2068,8 @@ TEMPS_ASKPASS_EOF\n\ message: "port must be between 1 and 65535".into(), }); } - let (row, _) = self.resolve_id(public_id_value, user_id).await?; + // No wake: minting a share link reads the row's password hash. + let (row, _) = self.resolve_id_no_wake(public_id_value, user_id).await?; let password_hash = row.preview_password_hash .as_deref() @@ -2474,6 +2553,46 @@ mod tests { assert_eq!(s.image.as_deref(), Some("node:20")); assert_eq!(s.agent_run_id, Some(42)); } + + /// `extend_timeout` deliberately pushes `expires_at` past the idle window + /// and leaves `timeout_secs` alone. `touch` then runs on the very next + /// exec — the long operation the extension was bought for — so if it + /// assigned the idle deadline unconditionally it would silently cancel the + /// extension the caller just paid for. The guard has to live in the SQL, + /// because `touch` must stay a single statement with no read-modify-write + /// on the exec hot path. + #[tokio::test] + async fn touch_never_moves_the_deadline_backwards() { + let db = Arc::new( + MockDatabase::new(DatabaseBackend::Postgres) + .append_exec_results(vec![sea_orm::MockExecResult { + last_insert_id: 0, + rows_affected: 1, + }]) + .into_connection(), + ); + let service = preview_test_service_with_db(db.clone()); + + service.touch(42, 3600).await; + + drop(service); + let log = Arc::try_unwrap(db) + .expect("service owns no database references after drop") + .into_transaction_log(); + let statements = format!("{log:?}"); + + assert!( + statements.contains("CASE WHEN"), + "touch must guard the deadline in SQL so an extendTimeout() is \ + never silently undone; log: {statements}" + ); + assert!(statements.contains("expires_at"), "log: {statements}"); + assert!( + statements.contains("last_activity_at"), + "activity is always recorded, only the deadline is guarded; \ + log: {statements}" + ); + } } /// Service-level tests for the storage-cleanup paths. diff --git a/docs/adr/036-persistent-workspace-sandboxes.md b/docs/adr/036-persistent-workspace-sandboxes.md index 21a4b2908..51f8346cb 100644 --- a/docs/adr/036-persistent-workspace-sandboxes.md +++ b/docs/adr/036-persistent-workspace-sandboxes.md @@ -69,10 +69,12 @@ Wake latency is a container start, not a create: the image is local, the volumes ### 5. Create a workspace from a project -`POST /v1/sandboxes` accepts `lifecycle` and an optional `project_id`. When `project_id` is present and no explicit `source` was given, the repo URL and git connection are resolved from the project row, so "give me a workspace on this project's code" needs no copy-pasted clone URL. `project_id` is persisted (nullable, `ON DELETE SET NULL`) so workspaces can be listed per project. +`POST /v1/sandboxes` accepts `lifecycle` and an optional `project_id`. When `project_id` is present and no explicit `source` was given, the repo URL and git connection are resolved from the project row, so "give me a workspace on this project's code" needs no copy-pasted clone URL. `project_id` is persisted nullable, with **no foreign key** — deliberately. The column is only ever read as a list filter inside an already `user_id`-scoped query, and at create time behind the project access guard, so a dangling id grants nothing; leaving the FK off keeps project deletion from taking a lock on `sandboxes` and avoids a cascade that would silently rewrite sandbox rows. Explicit `source` always wins over the project-derived one — the project is a convenience default, not an override. +The project-derived path clones with **the caller's own git connection**. A private repo therefore resolves only for the user who owns the connection the project was set up with — lending one user's token to another is exactly the vulnerability we are not going to build. A teammate with project access but no connection of their own must pass an explicit `source`, or connect their own provider. + ### 6. Interactive terminal, and why it must heartbeat `GET /v1/sandboxes/{id}/terminal` upgrades to a WebSocket bridged to the in-sandbox PTY agent (ADR-008), via a new `SandboxProvider::attach_pty` — a trait method rather than direct Docker access, because `temps-sandbox` must not depend on `bollard` (ADR-010, enforced by `scripts/check-provider-boundary.sh`). `temps sandbox shell ` is the client. From 53c02a220f4984ee91168b3e3a42529fa7af87b6 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Fri, 7 Aug 2026 10:05:03 +0200 Subject: [PATCH 10/12] fix(sandbox): normalise the PTY from the host so terminals echo on any image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The agent's `cfmakeraw()` removal fixed the blind-typing bug at the source, but the agent binary is compiled into the sandbox image — so the fix reaches a sandbox only after an operator rebuilds that image. Every existing sandbox, and every new one from an existing image, still started its PTY with ECHO off. In practice the bug was still fully present for anyone using the feature, and the workaround was to type `stty sane` blind into a shell that appeared broken. Rebuilding the image is not a step the person trying to open a terminal should have to perform first, so the host now normalises the line discipline itself: the requested program is wrapped as `stty sane 2>/dev/null; exec `. One `stty` per tab, works on every image, and `exec` keeps the wrapper shell from lingering as a parent. Safe in front of anything: full-screen programs set their own termios on startup regardless, and a sane state is what a real terminal would hand them. `stty` failure is swallowed so a minimal image without it still gets a shell. Verified against a sandbox created from an image predating the agent fix, on a fresh tab, with no `stty sane` sent: all five characters of `ls -l` echoed back and the command ran. The wrapper can be dropped once no supported image ships the old agent; until then removing it silently reintroduces a shell you cannot type into, so it is covered by tests. --- crates/temps-sandbox/src/handlers/terminal.rs | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/crates/temps-sandbox/src/handlers/terminal.rs b/crates/temps-sandbox/src/handlers/terminal.rs index 068073752..7e5ee810d 100644 --- a/crates/temps-sandbox/src/handlers/terminal.rs +++ b/crates/temps-sandbox/src/handlers/terminal.rs @@ -233,6 +233,32 @@ fn default_shell_cmd() -> String { "/bin/bash -l".to_string() } +/// Wrap the requested program so the PTY is in a sane line discipline before +/// it starts. +/// +/// The in-sandbox agent used to call `cfmakeraw()` when creating the PTY, +/// which clears `ECHO`. Bash's readline assumes something else is echoing, so +/// the user typed completely blind: commands ran, output appeared, keystrokes +/// were invisible. +/// +/// That is fixed in the agent, **but the agent binary is compiled into the +/// sandbox image**. Every sandbox built from an image that predates the fix +/// carries the old behaviour, and rebuilding the image is an operator action +/// the person trying to use a terminal should not have to perform first. So +/// the host normalises the terminal itself, which costs one `stty` per tab and +/// works on every image. +/// +/// `stty sane` is safe in front of anything: full-screen programs (claude, +/// vim) set their own termios on startup regardless, and starting them from a +/// sane state is what a normal terminal would give them anyway. Failures are +/// swallowed — a sandbox image without `stty` should still get a shell. +/// +/// Once no supported image ships the old agent this wrapper can go; until +/// then, removing it silently reintroduces a shell you cannot type into. +fn wrap_with_sane_termios(cmd: &str) -> String { + format!("stty sane 2>/dev/null; exec {cmd}") +} + /// Attach an interactive terminal to a sandbox. #[utoipa::path( tag = "Sandboxes", @@ -332,7 +358,7 @@ pub async fn terminal( let service = state.sandbox_service.clone(); let timeout_secs = row.timeout_secs; - let cmd = params.cmd.unwrap_or_else(default_shell_cmd); + let cmd = wrap_with_sane_termios(¶ms.cmd.unwrap_or_else(default_shell_cmd)); let cols = params.cols.unwrap_or(80); let rows = params.rows.unwrap_or(24); // Take the working directory from the provider handle, not the DB row. @@ -721,6 +747,38 @@ mod tests { assert!(exit.contains(r#""type":"exit""#), "{}", exit); } + #[test] + fn shell_command_is_wrapped_so_the_pty_echoes() { + // The regression guard for a terminal you cannot type into. Images + // predating the agent's `cfmakeraw` removal start the PTY with ECHO + // off; without this wrapper the user types blind on every one of + // them, and rebuilding the image is not something they can do from + // inside a shell that does not work. + let wrapped = wrap_with_sane_termios(&default_shell_cmd()); + assert!(wrapped.starts_with("stty sane"), "{wrapped}"); + assert!(wrapped.contains("exec /bin/bash -l"), "{wrapped}"); + } + + #[test] + fn wrapping_preserves_a_custom_command_verbatim() { + // `--cmd claude` must still start claude, arguments intact. + let wrapped = wrap_with_sane_termios("claude --resume"); + assert!(wrapped.ends_with("exec claude --resume"), "{wrapped}"); + // `exec` matters: the wrapper shell must be replaced, not left as a + // parent, or signals and exit codes get an extra hop. + assert!(wrapped.contains("; exec "), "{wrapped}"); + } + + #[test] + fn wrapping_tolerates_images_without_stty() { + // A minimal image with no `stty` must still get a shell, not a tab + // that dies on the first command. + assert!( + wrap_with_sane_termios("sh").contains("2>/dev/null"), + "stty failure must be swallowed" + ); + } + #[test] fn tab_accepts_ordinary_names() { for ok in ["main", "claude", "tab-2", "my_work_1", &"a".repeat(64)] { From 731ebb386e1c23304f3f0fe1f7a619c686a5dc7d Mon Sep 17 00:00:00 2001 From: David Viejo Date: Fri, 7 Aug 2026 10:16:53 +0200 Subject: [PATCH 11/12] fix(web): raise the js-yaml override past the advisory, and make detach honest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two unrelated fixes batched to avoid a third CI cycle. bun audit (GHSA-5p4m-2wfm-xmqj) ------------------------------ `@hey-api/openapi-ts › @hey-api/json-schema-ref-parser` pins js-yaml at exactly 4.2.0, so `bun update` cannot move it. An override already existed and was working — it just sat at `^4.3.0`, one patch short: the advisory's affected range is `>=4.0.0 <4.3.1`. Raised to `^4.3.1`. This check has been red on main on every scheduled run since at least 2026-07-06, so it is not a regression from this branch — but it is one line to fix and leaving it red trains everyone to ignore a security gate. Verified the override does not break the tool it forces: regenerating the SDK against the same server produced byte-identical output. `sandbox shell` told the user the opposite of what happened ---------------------------------------------------------- On close it always printed "Anything running in it keeps running". After `exit` that is false — the program ended, so the agent drops the tab, and the next attach correctly gets a fresh shell. The message made that look like reattach was broken rather than the expected result of typing `exit`. - `exit` now reports the session ended and that the tab is gone. - A deliberate detach says "Detached"; a dropped socket says "Disconnected". - Attaching prints one line saying whether it reattached to an existing tab or started a new one. Both previously rendered just a prompt, so there was no way to tell a restored session from a fresh one. Implements the detach escape the new message advises: Ctrl-P Ctrl-Q, the same sequence `docker attach` uses. Without it there was no way to leave a session running from inside it — `exit` kills the tab and every other key is forwarded by design. A lone Ctrl-P is still forwarded, so readline's history binding keeps working; only the pair detaches. Verified against a live sandbox: detached with the escape, reattached to the same tab, got `existed: true`, full scrollback replay, and a background job still Running with the same pid. --- apps/temps-cli/src/commands/sandbox/index.ts | 2 +- apps/temps-cli/src/commands/sandbox/shell.ts | 92 ++++++++++++++++++-- web/bun.lock | 4 +- web/package.json | 2 +- 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/apps/temps-cli/src/commands/sandbox/index.ts b/apps/temps-cli/src/commands/sandbox/index.ts index 733152e1b..19d4c2cc6 100644 --- a/apps/temps-cli/src/commands/sandbox/index.ts +++ b/apps/temps-cli/src/commands/sandbox/index.ts @@ -382,7 +382,7 @@ export function registerSandboxCommands(program: Command): void { .command('shell ') .alias('attach') .description( - 'Open an interactive terminal in a sandbox. Detaching leaves the program running — reattach with the same --tab', + 'Open an interactive terminal in a sandbox. Detach with Ctrl-P Ctrl-Q to leave the program running; `exit` ends it. Reattach with the same --tab', ) .option( '--tab ', diff --git a/apps/temps-cli/src/commands/sandbox/shell.ts b/apps/temps-cli/src/commands/sandbox/shell.ts index 30dd66313..5a8009c49 100644 --- a/apps/temps-cli/src/commands/sandbox/shell.ts +++ b/apps/temps-cli/src/commands/sandbox/shell.ts @@ -104,6 +104,17 @@ function runSession( let rawModeEngaged = false let exitCode = 0 let settled = false + // Did the *program* end, or did we just disconnect? The closing message + // is a different fact in each case, and getting it wrong tells the user + // their session survived when it did not. + let programExited = false + // Set when the user detached deliberately with the escape sequence, so + // the closing message can confirm it rather than read like a dropout. + let detachRequested = false + // Whether this attach landed in an existing tab. Reported on exit so a + // reattach is distinguishable from a fresh spawn without printing over + // the replayed screen at connect time. + let reattached = false // Every exit path goes through here. Leaving the terminal in raw mode // is the classic failure of this kind of tool — the user's shell is @@ -126,9 +137,40 @@ function runSession( else resolve() } + // Detach escape: Ctrl-P Ctrl-Q, the same sequence `docker attach` uses. + // + // Without it there is no way to leave a session alive from inside it — + // `exit` ends the program (killing the tab), and every other key is + // forwarded to the remote shell by design. Closing the window works but + // is not something to have to reach for. + const CTRL_P = 0x10 + const CTRL_Q = 0x11 + let sawCtrlP = false + const onStdin = (chunk: Buffer) => { - if (socket.readyState === WebSocket.OPEN) { - socket.send(chunk) + if (socket.readyState !== WebSocket.OPEN) return + + // Handle the escape without swallowing a legitimate Ctrl-P: only the + // *pair* detaches. A lone Ctrl-P is held back one keystroke and then + // forwarded, so readline's "previous history" still works — it just + // arrives with the following key. + for (let i = 0; i < chunk.length; i++) { + const byte = chunk[i]! + if (sawCtrlP) { + sawCtrlP = false + if (byte === CTRL_Q) { + detachRequested = true + socket.close() + return + } + socket.send(Buffer.from([CTRL_P, byte])) + continue + } + if (byte === CTRL_P) { + sawCtrlP = true + continue + } + socket.send(Buffer.from([byte])) } } @@ -153,14 +195,31 @@ function runSession( } // Text frames are control events, not terminal output — writing them // to stdout would splatter JSON into the user's session. - let event: { type?: string; code?: number; message?: string } + let event: { + type?: string + code?: number + message?: string + existed?: boolean + } try { event = JSON.parse(data.toString()) } catch { return } - if (event.type === 'exit') { + if (event.type === 'ready') { + reattached = event.existed === true + // Say which one this is, once, before the replay arrives. Without it + // there is no way to tell a restored session from a brand-new shell: + // both just render a prompt, so a tab that legitimately ended looks + // identical to reattach being broken. + process.stdout.write( + reattached + ? `${colors.muted(`— reattached to tab '${options.tab ?? 'main'}', restoring recent output —`)}\r\n` + : `${colors.muted(`— new session in tab '${options.tab ?? 'main'}' —`)}\r\n`, + ) + } else if (event.type === 'exit') { exitCode = event.code ?? 0 + programExited = true socket.close() } else if (event.type === 'error') { restore() @@ -195,11 +254,28 @@ function runSession( ) return } + const tab = options.tab ?? 'main' newline() - info( - `Detached from ${colors.primary(id)} (tab ${options.tab ?? 'main'}). ` + - 'Anything running in it keeps running — reattach with the same command.', - ) + if (programExited) { + // The program ended, so the agent dropped the tab with it. Saying + // "anything running keeps running" here would be plainly false, and + // it is what made a fresh shell on the next attach look like lost + // history rather than the expected result of typing `exit`. + info( + `Session ended in ${colors.primary(id)} (tab ${tab}${ + exitCode !== 0 ? `, exit ${exitCode}` : '' + }). ` + + 'That tab is gone — reattaching starts a fresh shell. To keep a ' + + 'session alive, detach with Ctrl-P Ctrl-Q or just close the ' + + 'window instead of exiting.', + ) + } else { + info( + `${detachRequested ? 'Detached' : 'Disconnected'} from ${colors.primary(id)} (tab ${tab}). ` + + 'Anything running in it keeps running — reattach with the same ' + + 'command to pick up where you left off.', + ) + } if (exitCode !== 0) { process.exitCode = exitCode } diff --git a/web/bun.lock b/web/bun.lock index b4927a02a..99de264fe 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -108,7 +108,7 @@ "defu": "^6.1.5", "flatted": "^3.4.2", "handlebars": "^4.7.9", - "js-yaml": "^4.3.0", + "js-yaml": "^4.3.1", "lodash": "^4.17.24", "minimatch": "^10.2.5", "picomatch": "^2.3.2", @@ -1054,7 +1054,7 @@ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="], + "js-yaml": ["js-yaml@4.3.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ=="], "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], diff --git a/web/package.json b/web/package.json index e4615dd6e..4e04f9224 100644 --- a/web/package.json +++ b/web/package.json @@ -135,7 +135,7 @@ "defu": "^6.1.5", "flatted": "^3.4.2", "handlebars": "^4.7.9", - "js-yaml": "^4.3.0", + "js-yaml": "^4.3.1", "lodash": "^4.17.24", "minimatch": "^10.2.5", "picomatch": "^2.3.2", From d719852427f97da5d9924e671ed667fc2ad819d2 Mon Sep 17 00:00:00 2001 From: David Viejo Date: Fri, 7 Aug 2026 10:54:06 +0200 Subject: [PATCH 12/12] fix(sandbox): repair compound --cmd, bound agent writes, surface oversized input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second security-auditor pass on this branch. Verdict was mergeable with no blocking or major findings; these are the three worth doing before it ships plus the cheap nits. Compound `--cmd` was broken by my own wrapper --------------------------------------------- `stty sane; exec {cmd}` splices at *statement* level, so shell operators inside the caller's command bound to the wrapper instead of their program. `--cmd "cd /app && npm start"` became `exec cd /app && npm start`: `exec cd` fails because `cd` is a builtin rather than a program, a non-interactive shell exits 127, and `npm start` never ran. Reproduced against the real image (`sh: 1: exec: cd: not found`). The command is now nested in an inner `sh -c` with the standard `'\''` escaping, so it parses exactly as written. Verified over the live endpoint with a compound command and with embedded quotes. A blocked write to the agent outlived every ceiling --------------------------------------------------- `write_frame` sits in a `select!` handler body, which tokio does not cancel, so while it blocked the deadline and heartbeat branches were never polled — defeating MAX_SESSION_DURATION and the ping timeout at once while holding a global permit, a per-user slot and a docker exec. Reachable without malice: a tab whose program never reads stdin (`?cmd=sleep 3600`) fills the PTY buffer until the agent stops draining its socket. Writes are now bounded by AGENT_WRITE_TIMEOUT and report why they gave up. Oversized input closed the terminal silently -------------------------------------------- The 64 KiB WebSocket cap is enforced by the *reader*, so an oversized paste never reaches the frame writer's size check — it surfaced as `Some(Err(_))` and broke with no event sent. The error branch that was supposed to explain this was dead for that case. The real path now names the limit before closing. Nits: recover from mutex poisoning in the per-user cap rather than turning every future attach into a permanent instance-wide 429 blaming the user's own session count (and, in `Drop`, rather than leaking the slot); stop `url_has_embedded_credentials` reading a query string as userinfo (`?ref=a:b@c` was rejected as carrying a password) by ending the authority at `/`, `?` or `#`. --- crates/temps-sandbox/src/handlers/terminal.rs | 138 +++++++++++++++--- .../src/services/sandbox_service.rs | 20 ++- 2 files changed, 136 insertions(+), 22 deletions(-) diff --git a/crates/temps-sandbox/src/handlers/terminal.rs b/crates/temps-sandbox/src/handlers/terminal.rs index 7e5ee810d..2392ca17e 100644 --- a/crates/temps-sandbox/src/handlers/terminal.rs +++ b/crates/temps-sandbox/src/handlers/terminal.rs @@ -104,7 +104,13 @@ struct UserSlot(i32); impl UserSlot { /// Returns `None` when this user is already at their cap. fn acquire(user_id: i32) -> Option { - let mut guard = TERMINALS_PER_USER.lock().ok()?; + // A poisoned `HashMap` is not logically corrupt — the + // critical section is one entry update — so recover rather than turn + // every future attach into a permanent instance-wide 429 that blames + // the user's own session count. + let mut guard = TERMINALS_PER_USER + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); let counts = guard.get_or_insert_with(HashMap::new); let entry = counts.entry(user_id).or_insert(0); if *entry >= MAX_TERMINALS_PER_USER { @@ -117,14 +123,17 @@ impl UserSlot { impl Drop for UserSlot { fn drop(&mut self) { - if let Ok(mut guard) = TERMINALS_PER_USER.lock() { - if let Some(counts) = guard.as_mut() { - if let Some(entry) = counts.get_mut(&self.0) { - *entry = entry.saturating_sub(1); - // Don't let the map grow one entry per user id forever. - if *entry == 0 { - counts.remove(&self.0); - } + // Recover from poisoning here too: bailing out would leak the slot + // permanently, which is the one outcome worse than a poisoned map. + let mut guard = TERMINALS_PER_USER + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner); + if let Some(counts) = guard.as_mut() { + if let Some(entry) = counts.get_mut(&self.0) { + *entry = entry.saturating_sub(1); + // Don't let the map grow one entry per user id forever. + if *entry == 0 { + counts.remove(&self.0); } } } @@ -151,6 +160,14 @@ const MAX_WS_MESSAGE_BYTES: usize = 64 * 1024; /// pings; a dead one does not. const MISSED_PONGS_BEFORE_CLOSE: u32 = 3; +/// How long a single write to the agent may block before the session gives up. +/// +/// Writes happen in a `select!` handler body, which tokio does not cancel, so +/// an agent that has stopped draining its socket blocks every other branch +/// with it. Bounding the write is what keeps the session ceiling and the ping +/// timeout meaningful. +const AGENT_WRITE_TIMEOUT: Duration = Duration::from_secs(10); + /// Hard ceiling on a single attachment. /// /// Authorization is evaluated once, at upgrade, and never revalidated — so a @@ -255,8 +272,21 @@ fn default_shell_cmd() -> String { /// /// Once no supported image ships the old agent this wrapper can go; until /// then, removing it silently reintroduces a shell you cannot type into. +/// +/// # Why the command is nested rather than spliced +/// +/// The obvious form — `stty sane; exec {cmd}` — splices at *statement* level, +/// so any shell operator inside `cmd` binds to the wrapper instead of to the +/// user's program. `--cmd "cd /app && npm start"` became +/// `exec cd /app && npm start`: `exec cd` fails (`cd` is a builtin, not a +/// program), and `npm start` never ran. Nesting in an inner `sh -c` hands the +/// original string to a shell verbatim, so it parses exactly as the caller +/// wrote it. fn wrap_with_sane_termios(cmd: &str) -> String { - format!("stty sane 2>/dev/null; exec {cmd}") + // Single-quote the whole command and escape any embedded single quote by + // the standard `'\''` dance: close, emit an escaped quote, reopen. + let quoted = cmd.replace('\'', r"'\''"); + format!("stty sane 2>/dev/null; exec /bin/sh -c '{quoted}'") } /// Attach an interactive terminal to a sandbox. @@ -543,12 +573,24 @@ impl TerminalSession { unanswered_pings = 0; match msg { Some(Ok(Message::Binary(data))) => { - match pty::write_frame(&mut agent_in, pty::OP_INPUT, &data).await { - Ok(()) => {} - Err(e) => { - // Most likely an oversized paste. Say so - // instead of letting the terminal vanish - // with no explanation. + // Bounded: this write is in a handler body, which + // `select!` does not cancel, so an agent that has + // stopped draining its socket would otherwise wedge + // the whole loop — the deadline and heartbeat + // branches stop being polled, defeating both + // MAX_SESSION_DURATION and the ping timeout while + // still holding a global permit and a docker exec. + // A tab whose program never reads stdin (say + // `?cmd=sleep 3600`) fills the PTY buffer and does + // exactly that. + match tokio::time::timeout( + AGENT_WRITE_TIMEOUT, + pty::write_frame(&mut agent_in, pty::OP_INPUT, &data), + ) + .await + { + Ok(Ok(())) => {} + Ok(Err(e)) => { send_error( &mut ws_tx, format!("could not forward input: {}", e), @@ -556,6 +598,16 @@ impl TerminalSession { .await; break; } + Err(_) => { + send_error( + &mut ws_tx, + "the program in this tab stopped reading input; \ + detaching. Reattach to try again." + .to_string(), + ) + .await; + break; + } } } Some(Ok(Message::Text(text))) => { @@ -565,7 +617,24 @@ impl TerminalSession { } Some(Ok(Message::Close(_))) | None => break, Some(Ok(Message::Ping(_) | Message::Pong(_))) => {} - Some(Err(_)) => break, + Some(Err(e)) => { + // Where an oversized paste actually lands: the + // WebSocket cap (MAX_WS_MESSAGE_BYTES) is enforced + // by the *reader*, so the message never reaches the + // frame writer's size check. Without this the + // terminal simply vanished, which is the behaviour + // the message cap was supposed to replace. + send_error( + &mut ws_tx, + format!( + "connection closed: {} (input is limited to {} KiB per message)", + e, + MAX_WS_MESSAGE_BYTES / 1024 + ), + ) + .await; + break; + } } } } @@ -756,14 +825,45 @@ mod tests { // inside a shell that does not work. let wrapped = wrap_with_sane_termios(&default_shell_cmd()); assert!(wrapped.starts_with("stty sane"), "{wrapped}"); - assert!(wrapped.contains("exec /bin/bash -l"), "{wrapped}"); + assert!(wrapped.contains("'/bin/bash -l'"), "{wrapped}"); + } + + #[test] + fn wrapping_preserves_shell_operators_in_a_custom_command() { + // The regression this nesting exists to prevent. Splicing at + // statement level bound the caller's operators to the *wrapper*: + // `exec cd /app && npm start` ran `exec cd` (which fails — `cd` is a + // builtin, not a program) and never reached `npm start`. + let wrapped = wrap_with_sane_termios("cd /app && npm start"); + assert!( + wrapped.contains("'cd /app && npm start'"), + "the command must reach an inner shell intact: {wrapped}" + ); + assert!( + !wrapped.contains("exec cd /app"), + "must not splice the command at statement level: {wrapped}" + ); + } + + #[test] + fn wrapping_escapes_embedded_single_quotes() { + // Otherwise a quote in the command closes our quoting early and the + // rest is reinterpreted by the outer shell. + let wrapped = wrap_with_sane_termios("echo 'hi there'"); + assert!(wrapped.contains(r"'\''hi there'\''"), "{wrapped}"); + // The wrapper's own quoting must still be balanced. + assert_eq!( + wrapped.matches('\'').count() % 2, + 0, + "unbalanced quoting: {wrapped}" + ); } #[test] fn wrapping_preserves_a_custom_command_verbatim() { // `--cmd claude` must still start claude, arguments intact. let wrapped = wrap_with_sane_termios("claude --resume"); - assert!(wrapped.ends_with("exec claude --resume"), "{wrapped}"); + assert!(wrapped.ends_with("'claude --resume'"), "{wrapped}"); // `exec` matters: the wrapper shell must be replaced, not left as a // parent, or signals and exit codes get an extra hop. assert!(wrapped.contains("; exec "), "{wrapped}"); diff --git a/crates/temps-sandbox/src/services/sandbox_service.rs b/crates/temps-sandbox/src/services/sandbox_service.rs index 04bbdcf06..3d1cb43b5 100644 --- a/crates/temps-sandbox/src/services/sandbox_service.rs +++ b/crates/temps-sandbox/src/services/sandbox_service.rs @@ -343,9 +343,11 @@ pub(crate) fn url_has_embedded_credentials(url: &str) -> bool { return false; }; let rest = &url[scheme_end + 3..]; - // Stop at the path: an `@` after the first `/` belongs to the path, not - // to userinfo (e.g. `https://host/org/repo@v1.git`). - let authority = rest.split('/').next().unwrap_or(rest); + // Stop at the end of the authority. Userinfo always precedes the first + // `/`, `?` or `#`, so anything past them is path/query/fragment — an `@` + // there is not a credential (`https://host/org/repo@v1.git`, or a query + // like `?ref=a:b@c`, which a `/`-only split misread as userinfo). + let authority = rest.split(['/', '?', '#']).next().unwrap_or(rest); match authority.find('@') { Some(at) => authority[..at].contains(':'), None => false, @@ -3233,6 +3235,18 @@ mod storage_cleanup_tests { "https://github.com/org/repo@v1.git" )); assert!(!url_has_embedded_credentials("git@github.com:org/repo.git")); + // A `:` and `@` in the query or fragment are not userinfo either — + // userinfo always precedes the first `/`, `?` or `#`. Splitting on + // `/` alone read this as `user:password` and rejected a valid URL. + assert!(!url_has_embedded_credentials( + "https://github.com/org/repo.git?ref=a:b@c" + )); + assert!(!url_has_embedded_credentials("https://host?ref=a:b@c")); + assert!(!url_has_embedded_credentials("https://host#frag=a:b@c")); + // ...but real userinfo before a query is still caught. + assert!(url_has_embedded_credentials( + "https://user:pw@github.com/org/repo.git?ref=main" + )); } #[tokio::test]