diff --git a/api-reference/app-releases/activate.mdx b/api-reference/app-releases/activate.mdx new file mode 100644 index 0000000..bf107e4 --- /dev/null +++ b/api-reference/app-releases/activate.mdx @@ -0,0 +1,11 @@ +--- +title: Activate or Roll Back an App Release +openapi: POST /api/v1/workspaces/{id}/app-releases/{release_id}/activate +description: Activate a ready candidate or restore a retained successful app release. +--- + +This endpoint does not require a request body. New activation work returns **202 Accepted**; selecting the already-current artifact can return **200 OK**. Poll the returned release ID, which may identify a new activation of a retained artifact. + +Activation briefly restarts affected services on their original ports and verifies readiness. The workspace, SSH sessions, unrelated apps, and persistent data remain in place. Code rollback does not undo database migrations or restore runtime data. + +An expired artifact, conflicting operation, or incompatible ownership cannot be activated. See [release and rollback guidance](/guides/releases-and-rollback). diff --git a/api-reference/app-releases/get.mdx b/api-reference/app-releases/get.mdx new file mode 100644 index 0000000..146f772 --- /dev/null +++ b/api-reference/app-releases/get.mdx @@ -0,0 +1,9 @@ +--- +title: Get an App Release +openapi: GET /api/v1/workspaces/{id}/app-releases/{release_id} +description: Retrieve the status and retained metadata of one workspace app release. +--- + +Statuses include `staging`, `ready`, `activating`, `succeeded`, `failed`, and `expired`. A ready candidate has finished staging but is not serving traffic until activated. + +Release metadata excludes the encrypted deployment payload. Use the logs endpoint for progress and errors. diff --git a/api-reference/app-releases/list.mdx b/api-reference/app-releases/list.mdx new file mode 100644 index 0000000..fcb4712 --- /dev/null +++ b/api-reference/app-releases/list.mdx @@ -0,0 +1,9 @@ +--- +title: List App Releases +openapi: GET /api/v1/workspaces/{id}/app-releases +description: List retained app releases and activation history for a workspace. +--- + +The response identifies current releases with `is_current` and available rollback targets with `can_rollback`. Use these fields instead of inferring the active version from creation time. + +See [app releases and rollback](/guides/releases-and-rollback) for retention and persistent-data behavior. diff --git a/api-reference/app-releases/logs.mdx b/api-reference/app-releases/logs.mdx new file mode 100644 index 0000000..bffc207 --- /dev/null +++ b/api-reference/app-releases/logs.mdx @@ -0,0 +1,7 @@ +--- +title: Get App Release Logs +openapi: GET /api/v1/workspaces/{id}/app-releases/{release_id}/logs +description: Read staging and activation progress for an app release. +--- + +The response contains log lines for the selected release. Poll while an operation is running, and use the release status to determine completion. The CLI provides the same view with `rig app-release logs --workspace --release `. diff --git a/api-reference/app-releases/stage.mdx b/api-reference/app-releases/stage.mdx new file mode 100644 index 0000000..8785313 --- /dev/null +++ b/api-reference/app-releases/stage.mdx @@ -0,0 +1,11 @@ +--- +title: Stage an App Release +openapi: POST /api/v1/workspaces/{id}/app-releases +description: Prepare app source and dependencies inside an existing running workspace. +--- + +Returns **202 Accepted** while staging runs. Staging preserves the workspace and does not activate the candidate. Poll the release and its logs, then activate it when its status is `ready`. + +Reuse the same `idempotency_key` only for the same request. Duplicate submissions return the existing attempt; a changed request with the same key is rejected. Failed or interrupted installation is not silently replayed. + +For normal deployments, [use the CLI](/guides/deploying) to collect source files and validate the manifest. Runtime secrets belong in the request’s protected runtime configuration, not in Git or source archives. diff --git a/docs.json b/docs.json index 320ebef..b518dd7 100644 --- a/docs.json +++ b/docs.json @@ -141,6 +141,16 @@ "api-reference/apps/verify-domain" ] }, + { + "group": "App Releases", + "pages": [ + "api-reference/app-releases/list", + "api-reference/app-releases/stage", + "api-reference/app-releases/get", + "api-reference/app-releases/activate", + "api-reference/app-releases/logs" + ] + }, { "group": "App Logs", "pages": [ diff --git a/guides/deploy-button.mdx b/guides/deploy-button.mdx index 500aa08..34871f0 100644 --- a/guides/deploy-button.mdx +++ b/guides/deploy-button.mdx @@ -11,8 +11,8 @@ A **Deploy to Rigbox** button opens workspace creation with a repository, branch 2. Connect GitHub. Select an existing fork, including a renamed fork, or choose **Fork on GitHub**. Forking opens a separate tab. Return to Rigbox and select **Refresh after forking**, then **Continue with my fork**. 3. If the fork is missing, grant the Rigbox GitHub App access to it and refresh the connection. Choose the correct GitHub account when you have several connected accounts. 4. Choose **New workspace**, or select a workspace you already own. Previous deployments of the same example are marked in the destination list. -5. Review the apps and resource allocation. Choose **Deploy with defaults**, or **Customize** to edit resources, app settings, and YAML. Required settings and secrets must be supplied; invalid manifests and insufficient capacity block deployment. -6. Rigbox starts the workspace, queues deployment, and opens its detail page. Follow the build and deployment progress there. HTTP services get app links; CLI tools are available from the workspace terminal or SSH. +5. Review the apps, deployment strategy, and resource allocation. Choose **Deploy with defaults**, or **Customize** to edit resources, app settings, and YAML. Required settings and secrets must be supplied; invalid manifests and insufficient capacity block deployment. +6. Rigbox starts the workspace, queues deployment, and opens its detail page. Follow app-release progress and logs there (or image-build logs for an image deployment). HTTP services get app links; CLI tools are available from the workspace terminal or SSH. The badge source must be a public GitHub repository. Your fork is checked using GitHub repository identity and ancestry, so renaming a fork is supported. The GitHub App needs access to the selected fork; the flow does not expand its permissions or retain a GitHub user token. @@ -26,9 +26,19 @@ Redeploying the same target reuses its branch. Existing connections keep their c ## Existing workspaces -Rigbox imports the workspace's actual vCPU, RAM, disk, and base image into the configuration preview. Confirm **root-filesystem and app replacement** before deploying. Persistent volumes are retained; changes stored only on the root filesystem are replaced. +Rigbox imports the workspace's actual vCPU, RAM, disk, and base image into the configuration preview. New connections default to **app releases** unless the manifest explicitly selects image mode. App deployment preserves workspace identity, root files, development tools, and SSH sessions. It stages code separately from your development checkout, then briefly restarts affected services on their existing ports. -If the workspace already has a different automatic deployment connection, review and explicitly confirm replacing it. Rigbox keeps one active automatic deployment connection per workspace. Adding apps without replacing the root filesystem is a separate planned capability. +**Image replacement** is an explicit advanced strategy. Confirm root-filesystem replacement before using it on an existing workspace. Persistent volumes are retained; arbitrary root-filesystem changes are replaced. Some catalog examples retain image mode because their installers change system packages or global tool configuration. + +Existing image-based connections keep their strategy until you explicitly review a change. Changing strategy does not automatically adopt existing apps: conflicting app ownership requires a separate import and cannot be bypassed by matching an app name. Never delete an app or enable reimaging merely to work around that conflict. + +If the workspace already has another automatic deployment connection, explicitly review replacement. Rigbox keeps one active automatic deployment connection per workspace. Resource changes and volume provisioning are separate workspace operations; incremental deployment requires declared volumes to exist already. + +## App releases and rollback + +The workspace detail page shows app-release history and deployment logs. Restore a retained release to return affected apps to its code and configuration. Services briefly restart; the workspace and SSH sessions stay in place. Database migrations, uploads, and other persistent data are not rolled back. Your Git branch stays unchanged, so its next push can deploy newer code again. + +No preview workspace, alternate port, promotion, or blue-green stage is part of this flow. See [Releases and rollback](/guides/releases-and-rollback) for the separate app and image operations. ## Secrets and retries diff --git a/guides/deploying.mdx b/guides/deploying.mdx index 6832041..50fe703 100644 --- a/guides/deploying.mdx +++ b/guides/deploying.mdx @@ -1,11 +1,11 @@ --- title: Deploying with rig deploy -description: Ship a project to a workspace from a single rig.yaml — the standard rsync deploy, reproducible frozen-image builds, multi-app graphs, and blue-green promotion. +description: Deploy app releases inside a persistent workspace, with explicit image replacement available for environment rebuilds. --- `rig deploy` is the one command that takes a project on your machine and runs it as a live app in a Rigbox workspace. It reads a `rig.yaml` in the project directory, resolves a target workspace, syncs your code, and brings the service up behind a public subdomain. -For push-to-deploy workflows, use the [GitHub Actions guide](/guides/github-actions). It deploys to a bound workspace with a short-lived credential. +For push-to-deploy workflows, connect the GitHub App in workspace creation or settings, use a [Deploy button](/guides/deploy-button), or configure [GitHub Actions](/guides/github-actions). ```bash cd my-app @@ -179,31 +179,73 @@ health: ## Deploy modes -`rig deploy` picks its mode from `rig.yaml`. There is **no `--reproducible` flag** — the app-level `reproducible: true` key is the only signal. +Choose `--strategy incremental|image` or declare `workspace.deployment.strategy` in `rig.yaml`. The explicit CLI option takes precedence over the manifest. Without an explicit strategy, the legacy `reproducible: true` setting retains image behavior; otherwise source apps default to incremental. New GitHub connections use the reviewed explicit strategy, and existing bindings retain their previous behavior. -### Standard deploy +### Incremental app releases -With `reproducible` unset (or `false`) and local source, `rig deploy`: - -1. Rsyncs the app directory into the workspace. -2. Runs `install:` on the VM. -3. (Re)starts the service. - -This is the default and fits most apps with fast installs. +An incremental deployment keeps the workspace running and installs app files in a managed release directory, separate from your development checkout. It stages source, installs dependencies when needed, builds the app, then briefly restarts affected services on their original ports and checks health. Your SSH session, tools, unrelated apps, and development files remain in place. ```yaml name: my-app +workspace: + deployment: + strategy: incremental port: 8080 +install: npm ci +dependencyInputs: [package.json, package-lock.json] +build: npm run build start: node server.js -install: npm ci && npm run build health: { path: /healthz, timeoutSeconds: 30 } ``` +`dependencyInputs` lists exact files relative to the app source directory. Use it only when those files describe all installation inputs. Matching inputs and runtime allow safe reuse; missing or empty inputs run installation conservatively. Source-dependent work belongs in `build`, not a dependency-only installation step. Avoid mutable shared environments and globally installed dependencies; Python apps should use a release-local virtual environment. + +For an installation whose dependencies can remain read-only, declare the generated directories with `dependencyOutputs`. Rigbox retains these immutable outputs separately, so source-only updates reuse the same dependency environment instead of copying its entire file tree: + +```yaml +install: npm ci --omit=dev +dependencyInputs: [package.json, package-lock.json] +dependencyOutputs: [node_modules] +start: node server.js +``` + +This optional mode requires nonempty `install` and `dependencyInputs`, and currently cannot be combined with `build`, `configure`, or `reconfigure` hooks. Output paths must be safe, non-overlapping relative directories; they cannot overlap source files or dependency inputs. Runtime writes belong in `RIGBOX_APP_DATA_DIR`, not in cached dependencies. Omit `dependencyOutputs` to retain ordinary release-local copying. Each release keeps its dependency version for rollback; changing installation inputs can require another full installation and additional storage. + +Install/build commands run under an unprivileged app identity inside the guest. They cannot use sudo or modify arbitrary workspace paths. Services use that identity and receive `RIGBOX_APP_DATA_DIR`, a persistent app-owned directory outside release files. This data survives app updates and app rollback, but it is not a substitute for backups or a promise about workspace deletion. Declared workspace volumes must already exist; provisioning volumes and changing workspace resources are separate operations. + +CLI apps declare controlled entrypoints rather than writing global symlinks themselves: + +```yaml +name: tools +kind: cli +workspace: + deployment: + strategy: incremental +executables: + workspace-info: bin/workspace-info +``` + +Each executable path is relative to the release. Rigbox registers the command, preserving the SSH user's arguments, terminal input, and working directory. A CLI health command is optional when executables are declared; otherwise provide an explicit `health.command`. Activation changes subsequent invocations, not already-running CLI processes. + +Source transfer excludes environment files, version-control metadata, dependency directories, and generated build output. It rejects symlinks and oversized payloads. Keep runtime secrets in Rigbox secret inputs, never in source files. Custom working directories are not supported by the managed release layout. + +To resume a specific attempt explicitly, keep the deployment identifier stable: + +```bash +rig deploy --strategy incremental --deployment-id release-2026-09-08 +``` + +Identifiers contain 1–128 letters, numbers, dots, underscores, or hyphens. Duplicate submissions use persisted deployment state; a failed attempt is not implicitly replayed. Inspect its app-release logs before explicitly retrying with the same identifier; do not create another workspace as a retry mechanism. Installation scripts with external side effects must still be written defensively. + +Use `rig app-release ls --workspace ` and `rig app-release rollback --workspace --release ` for app history and rollback. Restoring a release briefly restarts its apps, without restoring database contents or undoing migrations. Existing unmanaged apps require explicit ownership import; a matching name is not enough to adopt them. No fallback reimage occurs after an incremental failure. + +Managed app runtime configuration remains in `rig.yaml`. To change commands, parameters, or environment, update the manifest and deploy a new release. Direct parameter/environment edits and source-refresh shortcuts are rejected for release-managed apps so retained configuration stays accurate. Display name, access controls, and ordinary service start/stop/restart remain separate controls when no deployment operation is active. + ### Reproducible deploy -> **`reproducible: true` in `rig.yaml` makes the deploy reproducible — the same `install:` script, frozen once.** +> **Image mode is an explicit environment rebuild. It replaces the workspace root filesystem; it is separate from an app release.** -When an app sets `reproducible: true`, `rig deploy` runs its `install:` script in an isolated builder workspace and freezes the result into a content-addressed image. It boots the target from that image digest. With `source.kind: local`, app code is then synced from your machine. With `source.kind: git`, the builder fetches the resolved commit and the CLI does not overlay the local checkout. +With `workspace.deployment.strategy: image` (or legacy `reproducible: true` when no explicit strategy is set), `rig deploy` runs its `install:` script in an isolated builder workspace and freezes the result into a content-addressed image. It boots the target from that image digest. With `source.kind: local`, app code is then synced from your machine. With `source.kind: git`, the builder fetches the resolved commit and the CLI does not overlay the local checkout. ```yaml name: ai-chat @@ -216,7 +258,7 @@ start: uvicorn chat:app --host 0.0.0.0 --port 8080 health: { path: /healthz, timeoutSeconds: 30 } ``` -Nothing about the manifest changes except the flag: the same `install:` you would run on every standard deploy is what gets frozen. The image is always built on top of the platform base image (`workspace.image`, default `base`), so the agent and systemd are present and you keep the platform's opinions while layering your own dependencies on top. +In image mode: the same `install:` you would run on every standard deploy is what gets frozen. The image is always built on top of the platform base image (`workspace.image`, default `base`), so the agent and systemd are present and you keep the platform's opinions while layering your own dependencies on top. Install dependencies to system paths, such as pip `--break-system-packages`, so deployed code can find them. Git source is fetched into the build at its resolved commit; local source is synced after the image is ready. @@ -286,8 +328,8 @@ Every reproducible deploy also auto-records a **release** (an image digest + run #### When to use which -- **`install:` alone** — simple apps with fast installs. The default. -- **`reproducible: true`** — heavier or slower installs you want frozen and byte-identical across deploys and rollbacks. `rig deploy` freezes and mounts the image for you, and only rebuilds when the build inputs change. +- **Incremental strategy** — normal app updates in a persistent development workspace, with retained app releases. +- **Image strategy** — reviewed environment rebuilds and installers that require system-level changes. Existing image connections retain their behavior until an explicitly reviewed migration. --- @@ -314,6 +356,8 @@ Application environment values are stored in plaintext metadata and are readable ## Blue-green deploys and promotion +These are separate advanced operations. Incremental app releases do not create preview workspaces, move your SSH connection, change ports, or promise uninterrupted service. + For zero-downtime rollouts, stage a change, verify it, then swap production over atomically — either a whole-workspace clone (`rig deploy --bluegreen preview`) or an in-VM sibling (`rig deploy --bluegreen `), each cut over with `--promote`. See **[Blue-green deploys & promotion](/guides/bluegreen)** for both flows, the service-host-vs-live-environment boundary, and rollback. --- diff --git a/guides/releases-and-rollback.mdx b/guides/releases-and-rollback.mdx index bc4bf2e..650702c 100644 --- a/guides/releases-and-rollback.mdx +++ b/guides/releases-and-rollback.mdx @@ -1,15 +1,51 @@ --- title: Releases & Rollback -description: Every reproducible deploy records an immutable release. List history, roll back to a known-good image, or pin a release manually. +description: Restore app releases inside a persistent workspace, or explicitly activate an older workspace image. --- -A **release** is an immutable record of what ran: an image digest plus its run-config. Every reproducible `rig deploy` (one whose `rig.yaml` sets `reproducible: true`) auto-records a release, giving you a linear history you can roll back to at any time. +## App releases: preserve the workspace + +Incremental deployments record app releases inside the existing workspace. They retain app code, dependency environments, and service configuration needed for a compatible rollback. The VM identity, SSH sessions, development checkout, unrelated tools, and persistent data stay in place. + +```bash +rig app-release ls --workspace my-project +rig app-release logs --workspace my-project --release +rig app-release rollback --workspace my-project --release +``` + +Rollback streams its progress and briefly restarts affected services on the same ports. It does not restore database contents, undo migrations, or revert arbitrary system changes. A retained artifact must still be available and compatible. The workspace detail page also provides release history, logs, and a reviewed rollback action. + +Rollback records another activation; it does not reset your Git branch. The next push can deploy newer code again. Blue-green, preview workspaces, and workspace promotion are separate advanced workflows, not prerequisites for app releases. + +Managed app runtime configuration remains in `rig.yaml`. To change commands, parameters, or environment, update the manifest and deploy a new release. Direct parameter/environment edits and source-refresh shortcuts are rejected for release-managed apps so retained configuration stays accurate. Display name, access controls, and ordinary service start/stop/restart remain separate controls when no deployment operation is active. + +### Activate a staged release + +`rig deploy --sync-only` prepares a ready app release without activating it. Activate that ready release explicitly: + +```bash +rig app-release activate --workspace my-project --release +``` + +`activate` requires a ready release; `rollback` selects a previously successful release. Neither command creates a preview workspace or an alternate listening port. + +### Retention and retries + +Rigbox retains three distinct successful app artifacts for each deployment owner, preserving artifacts still referenced by active apps. Repeated activation of the same artifact does not consume another artifact slot. Plan disk space for retained dependencies, a staged candidate, caches, and persistent app data. + +Rollback restores retained code and configuration; it leaves runtime data untouched. Failed attempts keep their deployment IDs. Retrying the same ID returns the existing attempt and status instead of creating duplicate resources; it does not silently repeat an interrupted installation. To run a reviewed new attempt, provide a new deployment ID. An expired artifact cannot be activated. + +## Image releases: replace the root filesystem + +The commands below operate on **workspace image releases**, not app releases. Their behavior is deliberately unchanged. Activating one replaces the workspace root filesystem and can disconnect SSH sessions. Use `rig app-release` when you intend to restore only deployed apps. + +An **image release** records an image digest and its run configuration. Deployments using the image strategy record this history. Legacy `reproducible: true` selects that strategy only when no explicit strategy overrides it: `workspace.deployment.strategy: incremental` still produces an app release, even if an older `reproducible: true` field remains. Because the image is content-addressed and frozen, activating an old release boots the workspace from the exact environment that release captured — not an approximate rebuild. ## How releases are recorded -When `rig deploy` takes the [reproducible path](/guides/deploying#reproducible-deploy), it freezes the `install:` result into a content-addressed image and records a release pointing at that digest. Standard (rsync-only) deploys do not produce releases — there is no frozen image to pin. +When `rig deploy` takes the [reproducible path](/guides/deploying#reproducible-deploy), it freezes the `install:` result into a content-addressed image and records a release pointing at that digest. Incremental app deployments produce app-release history through `rig app-release`, rather than an image release. ```text $ rig deploy @@ -65,7 +101,7 @@ This is useful for promoting an image you built and tested separately, or for co ## rig build: the explicit image build -`rig build image` is the explicit, standalone image build. It runs an install script once in an ephemeral builder VM on top of a base image (the same content-addressed mechanism `rig deploy` uses for `reproducible: true`) and returns a digest and cache key: +`rig build image` is the explicit, standalone image build. It runs an install script once in an ephemeral builder VM on top of a base image (the same content-addressed mechanism `rig deploy` uses with the image strategy) and returns a digest and cache key: ```bash rig build image --workspace my-project --base-image base \ @@ -95,7 +131,7 @@ A typical reproducible workflow: `rig release ls` shows the linear history and which release is active. -`rig rollback --release ` boots the previous release's frozen image — instant, no rebuild. +`rig rollback --release ` boots the previous release's frozen image — without rebuilding the image. Build separately with `rig build image`, then `rig release create --image-digest ` to capture it as a release before activating. diff --git a/openapi/auth-api.json b/openapi/auth-api.json index dfd5083..341af12 100644 --- a/openapi/auth-api.json +++ b/openapi/auth-api.json @@ -1474,6 +1474,99 @@ ] } }, + "/api/v1/apps/{id}/refresh-source": { + "post": { + "tags": [ + "Apps" + ], + "description": "Fetch and check out an exact Git commit in the app's existing working directory. Does not install dependencies or restart the service. Poll the returned job for completion.", + "operationId": "refresh_app_source", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "App ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSourceRequest" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Source refresh queued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSourceResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/apps/{id}/refresh-source/{job_id}": { + "get": { + "tags": [ + "Apps" + ], + "description": "Poll this app's latest source refresh. Success requires status done and exit_code 0. Jobs are ephemeral and disappear when the workspace restarts.", + "operationId": "get_source_refresh_status", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "App ID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "job_id", + "in": "path", + "description": "Source refresh job ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Source refresh status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSourceStatusResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, "/api/v1/apps/{id}/restart": { "post": { "tags": [ @@ -1759,43 +1852,70 @@ ] } }, - "/api/v1/catalog": { + "/api/v1/auth/github/app": { "get": { "tags": [ - "App Catalog" + "GitHub Deployments" ], - "summary": "Cursor-paginated list of exact deployable catalog refs for the current\nuser. Same offset-under-opaque-cursor approach as `list_recipes`.", - "description": "List paginated deployable catalog refs available to the current user.", - "operationId": "list_versioned_catalog", - "parameters": [ - { - "name": "max_results", - "in": "query", - "description": "Maximum items to return. Clamped to `[1, MAX_LIMIT]`. Default 50.\n\nDeserialized leniently from a string: axum's `Query` (serde_urlencoded)\ncannot coerce a *flattened* numeric field, so a struct that\n`#[serde(flatten)]`s `PageParams` (e.g. `ListAppsQuery`) would otherwise\nfail with \"invalid type: string, expected u32\" on `?max_results=50`.", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "minimum": 0 + "operationId": "status", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionStatus" + } + } } - }, + } + }, + "security": [ { - "name": "cursor", - "in": "query", - "description": "Opaque cursor returned by a prior call's `next_cursor`. Omit on the\nfirst page.", - "required": false, - "schema": { - "type": "string" - } + "bearer": [] + } + ] + }, + "delete": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "disconnect", + "responses": { + "204": { + "description": "GitHub disconnected from this account" + } + }, + "security": [ + { + "bearer": [] } + ] + } + }, + "/api/v1/auth/github/app/attempts": { + "post": { + "tags": [ + "GitHub Deployments" ], + "operationId": "create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttemptRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Catalog page", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Page_DeployPreviewResponse" + "$ref": "#/components/schemas/AttemptResponse" } } } @@ -1808,32 +1928,30 @@ ] } }, - "/api/v1/catalog/detail": { + "/api/v1/auth/github/app/attempts/{id}": { "get": { "tags": [ - "App Catalog" + "GitHub Deployments" ], - "summary": "Get one exact deployable catalog ref for the current user.", - "description": "Get full details for one exact deployable catalog ref.", - "operationId": "get_versioned_catalog_detail", + "operationId": "get", "parameters": [ { - "name": "ref", - "in": "query", - "description": "Exact deploy ref, e.g. @rigbox/filebrowser@builtin or @alice/pgweb@1.2.3", + "name": "id", + "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], "responses": { "200": { - "description": "Versioned catalog item detail", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CommunityCatalogDetailResponse" + "$ref": "#/components/schemas/AttemptResponse" } } } @@ -1846,30 +1964,39 @@ ] } }, - "/api/v1/community/app-recipes": { - "get": { + "/api/v1/auth/github/app/attempts/{id}/deploy": { + "post": { "tags": [ - "Community" + "GitHub Deployments" ], - "summary": "List all published v1 app recipes (latest version of each).", - "description": "List all visible community app recipes, latest version of each.", - "operationId": "list_app_recipes", - "responses": { - "200": { - "description": "List of app recipe manifests (latest version each)", - "content": { - "application/json": { - "schema": {} + "operationId": "deploy", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployRequest" } } }, - "403": { - "description": "Feature not enabled", + "required": true + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorBody" - } + "schema": {} } } } @@ -1879,47 +2006,66 @@ "bearer": [] } ] - }, + } + }, + "/api/v1/auth/github/app/badge-fork": { "post": { "tags": [ - "Community" + "GitHub Deployments" ], - "summary": "Publish a v1 App Recipe version.", - "description": "Publish a new version of a community app recipe.", - "operationId": "publish_app_recipe", + "operationId": "fork", "requestBody": { "content": { "application/json": { - "schema": {} + "schema": { + "$ref": "#/components/schemas/ForkRequest" + } } }, "required": true }, "responses": { - "201": { - "description": "Recipe published", - "content": { - "application/json": { - "schema": {} - } - } - }, - "400": { - "description": "Invalid recipe", + "200": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiErrorBody" + "$ref": "#/components/schemas/Inspection" } } } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/badge-source": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "source", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceRequest" + } + } }, - "403": { - "description": "Feature not enabled", + "required": true + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiErrorBody" + "$ref": "#/components/schemas/BadgeSource" } } } @@ -1932,27 +2078,773 @@ ] } }, - "/api/v1/community/app-recipes/{vendor}/{slug}": { - "delete": { + "/api/v1/auth/github/app/branches": { + "get": { "tags": [ - "Community" + "GitHub Deployments" ], - "summary": "Delete an entire v1 App Recipe (all versions) owned by the caller.", - "description": "Delete a community app recipe and all of its published versions.", - "operationId": "delete_app_recipe_all", + "operationId": "branches", "parameters": [ { - "name": "vendor", - "in": "path", - "description": "Vendor (lowercase)", + "name": "installation_id", + "in": "query", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int64" } }, { - "name": "slug", - "in": "path", + "name": "repository_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BranchList" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/callback": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "callback", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Callback" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionStatus" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/connect": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "connect", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectUrl" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/generate": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "generate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/inspect": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "inspect", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Inspection" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/manifest-paths": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "manifest_paths", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PathsRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ManifestPaths" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/projects": { + "get": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "list", + "parameters": [ + { + "name": "workspace_id", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectList" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "save", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/projects/{id}": { + "delete": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "disconnect", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "Disconnected" + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/projects/{id}/retry": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "retry", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/repositories": { + "get": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "repos", + "parameters": [ + { + "name": "installation_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepoList" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/webhook": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "webhook", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Event accepted" + } + } + } + }, + "/api/v1/auth/github/bindings": { + "get": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "list_bindings", + "responses": { + "200": { + "description": "Account repository bindings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GithubBindingsResponse" + } + } + } + }, + "403": { + "description": "Full-account credential required" + }, + "404": { + "description": "Feature disabled" + } + }, + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "create_binding", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateGithubBindingRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Repository binding", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GithubBindingResponse" + } + } + } + }, + "400": { + "description": "Invalid repository name" + }, + "403": { + "description": "Full-account credential required" + }, + "404": { + "description": "Workspace unavailable or feature disabled" + }, + "409": { + "description": "Repository already bound" + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/bindings/{binding_id}": { + "delete": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "delete_binding", + "parameters": [ + { + "name": "binding_id", + "in": "path", + "description": "Binding ID", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "workspace_id", + "in": "query", + "description": "Required target when a repository has several workspace bindings", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Binding deleted and deploy tokens revoked" + }, + "403": { + "description": "Full-account credential required" + }, + "404": { + "description": "Binding unavailable or feature disabled" + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/token": { + "post": { + "tags": [ + "Auth" + ], + "operationId": "exchange_token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExchangeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExchangeResponse" + } + } + } + }, + "401": { + "description": "Invalid or replayed GitHub token" + }, + "403": { + "description": "No permitted repository binding" + } + } + } + }, + "/api/v1/catalog": { + "get": { + "tags": [ + "App Catalog" + ], + "summary": "Cursor-paginated list of exact deployable catalog refs for the current\nuser. Same offset-under-opaque-cursor approach as `list_recipes`.", + "description": "List paginated deployable catalog refs available to the current user.", + "operationId": "list_versioned_catalog", + "parameters": [ + { + "name": "max_results", + "in": "query", + "description": "Maximum items to return. Clamped to `[1, MAX_LIMIT]`. Default 50.\n\nDeserialized leniently from a string: axum's `Query` (serde_urlencoded)\ncannot coerce a *flattened* numeric field, so a struct that\n`#[serde(flatten)]`s `PageParams` (e.g. `ListAppsQuery`) would otherwise\nfail with \"invalid type: string, expected u32\" on `?max_results=50`.", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor returned by a prior call's `next_cursor`. Omit on the\nfirst page.", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Catalog page", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Page_DeployPreviewResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/catalog/detail": { + "get": { + "tags": [ + "App Catalog" + ], + "summary": "Get one exact deployable catalog ref for the current user.", + "description": "Get full details for one exact deployable catalog ref.", + "operationId": "get_versioned_catalog_detail", + "parameters": [ + { + "name": "ref", + "in": "query", + "description": "Exact deploy ref, e.g. @rigbox/filebrowser@builtin or @alice/pgweb@1.2.3", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Versioned catalog item detail", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommunityCatalogDetailResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/community/app-recipes": { + "get": { + "tags": [ + "Community" + ], + "summary": "List all published v1 app recipes (latest version of each).", + "description": "List all visible community app recipes, latest version of each.", + "operationId": "list_app_recipes", + "responses": { + "200": { + "description": "List of app recipe manifests (latest version each)", + "content": { + "application/json": { + "schema": {} + } + } + }, + "403": { + "description": "Feature not enabled", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "tags": [ + "Community" + ], + "summary": "Publish a v1 App Recipe version.", + "description": "Publish a new version of a community app recipe.", + "operationId": "publish_app_recipe", + "requestBody": { + "content": { + "application/json": { + "schema": {} + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Recipe published", + "content": { + "application/json": { + "schema": {} + } + } + }, + "400": { + "description": "Invalid recipe", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorBody" + } + } + } + }, + "403": { + "description": "Feature not enabled", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/community/app-recipes/{vendor}/{slug}": { + "delete": { + "tags": [ + "Community" + ], + "summary": "Delete an entire v1 App Recipe (all versions) owned by the caller.", + "description": "Delete a community app recipe and all of its published versions.", + "operationId": "delete_app_recipe_all", + "parameters": [ + { + "name": "vendor", + "in": "path", + "description": "Vendor (lowercase)", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "slug", + "in": "path", "description": "Recipe slug", "required": true, "schema": { @@ -4622,6 +5514,231 @@ ] } }, + "/api/v1/workspaces/{id}/app-releases": { + "get": { + "tags": [ + "App releases" + ], + "operationId": "list", + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + } + ] + }, + "post": { + "tags": [ + "App releases" + ], + "operationId": "create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAppRelease" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "App release accepted for asynchronous processing.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + } + ] + } + }, + "/api/v1/workspaces/{id}/app-releases/{release_id}": { + "get": { + "tags": [ + "App releases" + ], + "operationId": "read", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + }, + { + "name": "release_id", + "in": "path", + "required": true, + "description": "App release ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/workspaces/{id}/app-releases/{release_id}/activate": { + "post": { + "tags": [ + "App releases" + ], + "operationId": "activate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + }, + { + "name": "release_id", + "in": "path", + "required": true, + "description": "App release ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + }, + "202": { + "description": "App release accepted for asynchronous processing.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/workspaces/{id}/app-releases/{release_id}/logs": { + "get": { + "tags": [ + "App releases" + ], + "operationId": "logs", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + }, + { + "name": "release_id", + "in": "path", + "required": true, + "description": "App release ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LogsResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, "/api/v1/workspaces/{id}/cancel": { "post": { "tags": [ @@ -7432,15 +8549,88 @@ }, "description": "The parameter schema (snapshotted at creation time)." }, - "values": { - "type": "object", - "description": "Current values (from metadata.config). Sensitive values are masked.", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - } + "values": { + "type": "object", + "description": "Current values (from metadata.config). Sensitive values are masked.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + } + }, + "AppRelease": { + "type": "object", + "required": [ + "id", + "is_current", + "can_rollback", + "workspace_id", + "user_id", + "owner_key", + "idempotency_key", + "status", + "artifact_release_id", + "apps", + "created_at", + "updated_at" + ], + "properties": { + "apps": {}, + "artifact_release_id": { + "type": "string" + }, + "can_rollback": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string" + }, + "idempotency_key": { + "type": "string" + }, + "is_current": { + "type": "boolean" + }, + "owner_key": { + "type": "string" + }, + "previous_release_id": { + "type": [ + "string", + "null" + ] + }, + "source_commit": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" } } }, @@ -7492,6 +8682,100 @@ } } }, + "AttemptRequest": { + "type": "object", + "required": [ + "id", + "source", + "installation_id", + "repository_id", + "repository_name", + "commit", + "branch", + "name", + "content" + ], + "properties": { + "branch": { + "type": "string" + }, + "commit": { + "type": "string" + }, + "content": { + "type": "string" + }, + "deployment_strategy": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "replace_binding_id": { + "type": [ + "string", + "null" + ], + "format": "uuid" + }, + "repository_id": { + "type": "integer", + "format": "int64" + }, + "repository_name": { + "type": "string" + }, + "source": { + "$ref": "#/components/schemas/SourceRequest" + }, + "workspace_id": { + "type": [ + "string", + "null" + ] + } + } + }, + "AttemptResponse": { + "type": "object", + "required": [ + "id", + "workspace_id", + "existing_workspace", + "branch", + "draft" + ], + "properties": { + "branch": { + "type": "string" + }, + "draft": { + "$ref": "#/components/schemas/AttemptRequest" + }, + "existing_workspace": { + "type": "boolean" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "result": {}, + "workspace_id": { + "type": "string" + } + } + }, "AuthMessageResponse": { "type": "object", "required": [ @@ -7521,6 +8805,25 @@ } } }, + "BadgeSource": { + "type": "object", + "required": [ + "repository", + "commit", + "fork_url" + ], + "properties": { + "commit": { + "type": "string" + }, + "fork_url": { + "type": "string" + }, + "repository": { + "$ref": "#/components/schemas/Repository" + } + } + }, "BindingsResponse": { "type": "object", "required": [ @@ -7535,6 +8838,120 @@ } } }, + "Branch": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + } + }, + "BranchList": { + "type": "object", + "required": [ + "branches" + ], + "properties": { + "branches": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Branch" + } + }, + "next_page": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + } + }, + "Build": { + "type": "object", + "description": "Index row for one image build. NOT the build log \u2014\nthe log text stays in host journald under `rigbox-build-`; this row\njust lets a user enumerate their recent builds (incl. failures) and resolve\neach `build_id` to open its journald log. Owner-scoped.", + "required": [ + "build_id", + "owner_user_id", + "status", + "created_at", + "updated_at" + ], + "properties": { + "build_id": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": [ + "string", + "null" + ], + "description": "Short failure summary \u2014 set on failure." + }, + "image_digest": { + "type": [ + "string", + "null" + ], + "description": "Content digest of the produced image \u2014 set on success." + }, + "label": { + "type": [ + "string", + "null" + ], + "description": "Best-effort app/project label from the deploy (the CLI's `rig.yaml` name)." + }, + "owner_user_id": { + "type": "string" + }, + "source_commit": { + "type": [ + "string", + "null" + ], + "description": "Full git object ID requested for this build; retained on failure." + }, + "source_kind": { + "type": [ + "string", + "null" + ], + "description": "`recipe` for every build since Dockerfile/image sources were removed;\nhistorical rows may still read `dockerfile` or `image`." + }, + "status": { + "type": "string", + "description": "`building` while in flight, then `succeeded` | `failed`." + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "Callback": { + "type": "object", + "required": [ + "code", + "state" + ], + "properties": { + "code": { + "type": "string" + }, + "state": { + "type": "string" + } + } + }, "CatalogResponse": { "type": "object", "required": [ @@ -7891,6 +9308,41 @@ } } }, + "ConnectUrl": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string" + } + } + }, + "ConnectionStatus": { + "type": "object", + "required": [ + "configured", + "connections" + ], + "properties": { + "configured": { + "type": "boolean" + }, + "connections": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubConnection" + } + }, + "install_url": { + "type": [ + "string", + "null" + ] + } + } + }, "CreateApiKeyRequest": { "type": "object", "properties": { @@ -7937,19 +9389,53 @@ "null" ] }, - "is_primary": { + "is_primary": { + "type": [ + "boolean", + "null" + ] + }, + "source_ref": { + "type": "string" + }, + "source_type": { + "type": "string" + } + } + }, + "CreateAppRelease": { + "type": "object", + "required": [ + "idempotency_key", + "apps" + ], + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReleaseApp" + } + }, + "deployment_scope": { + "type": [ + "string", + "null" + ] + }, + "idempotency_key": { + "type": "string" + }, + "replace_app_set": { + "type": "boolean" + }, + "source_commit": { "type": [ - "boolean", + "string", "null" ] - }, - "source_ref": { - "type": "string" - }, - "source_type": { - "type": "string" } - } + }, + "additionalProperties": false }, "CreateAppRequest": { "type": "object", @@ -8031,6 +9517,21 @@ } } }, + "CreateGithubBindingRequest": { + "type": "object", + "required": [ + "repository_name", + "workspace_id" + ], + "properties": { + "repository_name": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, "CreateServiceSpecRequest": { "type": "object", "required": [ @@ -8554,6 +10055,42 @@ } } }, + "DeployRequest": { + "type": "object", + "required": [ + "content", + "allow_reimage" + ], + "properties": { + "allow_reimage": { + "type": "boolean" + }, + "confirm_strategy_change": { + "type": "boolean" + }, + "content": { + "type": "string" + }, + "deployment_strategy": { + "type": [ + "string", + "null" + ] + }, + "secrets": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + } + }, "DeployResourceRequirements": { "type": "object", "required": [ @@ -8842,6 +10379,57 @@ } } }, + "ExchangeRequest": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "ExchangeResponse": { + "type": "object", + "required": [ + "token", + "expires_at", + "workspace_id", + "repository", + "source_ref", + "source_commit", + "ci_run_url", + "repository_private" + ], + "properties": { + "ci_run_url": { + "type": "string" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "repository": { + "type": "string" + }, + "repository_private": { + "type": "boolean" + }, + "source_commit": { + "type": "string" + }, + "source_ref": { + "type": "string" + }, + "token": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, "ExposePortRequest": { "type": "object", "required": [ @@ -8957,6 +10545,77 @@ } } }, + "ForkRequest": { + "type": "object", + "required": [ + "source_repository_id", + "installation_id", + "repository_id", + "branch", + "manifest_path" + ], + "properties": { + "branch": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "repository_id": { + "type": "integer", + "format": "int64" + }, + "source_repository_id": { + "type": "integer", + "format": "int64" + } + } + }, + "GenerateRequest": { + "type": "object", + "required": [ + "repository", + "branch", + "settings" + ], + "properties": { + "branch": { + "type": "string" + }, + "existing": { + "type": [ + "string", + "null" + ] + }, + "repository": { + "type": "string" + }, + "settings": { + "$ref": "#/components/schemas/Settings" + } + } + }, + "GeneratedCredential": { + "type": "object", + "required": [ + "key", + "env_var" + ], + "properties": { + "env_var": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "additionalProperties": false + }, "GetAiDefaultsResponse": { "type": "object", "required": [ @@ -9125,105 +10784,380 @@ } } }, - "GetServiceSpecResponse": { + "GetServiceSpecResponse": { + "type": "object", + "required": [ + "spec" + ], + "properties": { + "spec": { + "$ref": "#/components/schemas/ServiceSpec" + } + } + }, + "GetSetupScriptResponse": { + "type": "object", + "required": [ + "script" + ], + "properties": { + "script": { + "$ref": "#/components/schemas/SetupScript" + } + } + }, + "GetUserLimitsResponse": { + "type": "object", + "required": [ + "plan", + "custom", + "limits", + "usage" + ], + "properties": { + "custom": { + "type": "boolean" + }, + "limits": { + "$ref": "#/components/schemas/EffectiveLimits" + }, + "plan": { + "type": "string" + }, + "usage": { + "$ref": "#/components/schemas/LimitsUsage" + } + } + }, + "GetUserSettingsResponse": { + "type": "object", + "required": [ + "settings" + ], + "properties": { + "settings": { + "$ref": "#/components/schemas/UserSettings" + } + } + }, + "GetWorkspaceLogsResponse": { + "type": "object", + "required": [ + "lines", + "has_more" + ], + "properties": { + "cursor": { + "type": [ + "string", + "null" + ] + }, + "has_more": { + "type": "boolean" + }, + "lines": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LogLine" + } + } + } + }, + "GetWorkspaceResponse": { + "type": "object", + "required": [ + "vm" + ], + "properties": { + "failure": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/WorkspaceFailure", + "description": "Structured failure info when `vm.status == Failed`. `None` otherwise.\nComputed from the workspace's `failure_code`, `failure_reason`, and\n`creation_attempts` fields plus the retryable allowlist policy." + } + ] + }, + "vm": { + "$ref": "#/components/schemas/Vm" + } + } + }, + "GithubBindingResponse": { + "type": "object", + "required": [ + "binding" + ], + "properties": { + "binding": { + "$ref": "#/components/schemas/GithubRepoBinding" + } + } + }, + "GithubBindingsResponse": { "type": "object", "required": [ - "spec" + "bindings" ], "properties": { - "spec": { - "$ref": "#/components/schemas/ServiceSpec" + "bindings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubRepoBinding" + } } } }, - "GetSetupScriptResponse": { + "GithubConnection": { "type": "object", "required": [ - "script" + "user_id", + "installation_id", + "github_user_id", + "github_login", + "account_login" ], "properties": { - "script": { - "$ref": "#/components/schemas/SetupScript" + "account_login": { + "type": "string" + }, + "github_login": { + "type": "string" + }, + "github_user_id": { + "type": "integer", + "format": "int64" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "user_id": { + "type": "string" } } }, - "GetUserLimitsResponse": { + "GithubJob": { "type": "object", "required": [ - "plan", - "custom", - "limits", - "usage" + "builds", + "id", + "binding_id", + "source_commit", + "source_ref", + "status", + "created_at" ], "properties": { - "custom": { - "type": "boolean" + "binding_id": { + "type": "string", + "format": "uuid" }, - "limits": { - "$ref": "#/components/schemas/EffectiveLimits" + "builds": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Build" + } }, - "plan": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "message": { + "type": [ + "string", + "null" + ] + }, + "source_commit": { "type": "string" }, - "usage": { - "$ref": "#/components/schemas/LimitsUsage" + "source_ref": { + "type": "string" + }, + "status": { + "type": "string" } } }, - "GetUserSettingsResponse": { + "GithubProject": { "type": "object", "required": [ - "settings" + "id", + "user_id", + "workspace_id", + "repository_name", + "deployment_mode", + "deployment_strategy", + "production_branch", + "manifest_path", + "allow_reimage" ], "properties": { - "settings": { - "$ref": "#/components/schemas/UserSettings" + "allow_reimage": { + "type": "boolean" + }, + "deployment_mode": { + "type": "string" + }, + "deployment_strategy": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "installation_id": { + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "production_branch": { + "type": "string" + }, + "repository_id": { + "type": [ + "string", + "null" + ] + }, + "repository_name": { + "type": "string" + }, + "repository_owner_id": { + "type": [ + "string", + "null" + ] + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" } } }, - "GetWorkspaceLogsResponse": { + "GithubRepoBinding": { "type": "object", "required": [ - "lines", - "has_more" + "id", + "user_id", + "workspace_id", + "repository_name", + "status", + "claim_expires_at", + "created_at" ], "properties": { - "cursor": { + "claim_expires_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "repository_id": { "type": [ "string", "null" ] }, - "has_more": { - "type": "boolean" + "repository_name": { + "type": "string" }, - "lines": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogLine" - } + "repository_owner_id": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" } } }, - "GetWorkspaceResponse": { + "InspectRequest": { "type": "object", "required": [ - "vm" + "installation_id", + "repository_id", + "branch", + "manifest_path" ], "properties": { - "failure": { - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "#/components/schemas/WorkspaceFailure", - "description": "Structured failure info when `vm.status == Failed`. `None` otherwise.\nComputed from the workspace's `failure_code`, `failure_reason`, and\n`creation_attempts` fields plus the retryable allowlist policy." - } + "branch": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "repository_id": { + "type": "integer", + "format": "int64" + } + } + }, + "Inspection": { + "type": "object", + "required": [ + "repository", + "commit", + "settings", + "requires_pull_request", + "manifest_paths" + ], + "properties": { + "commit": { + "type": "string" + }, + "content": { + "type": [ + "string", + "null" ] }, - "vm": { - "$ref": "#/components/schemas/Vm" + "manifest_paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "repository": { + "$ref": "#/components/schemas/Repository" + }, + "requires_pull_request": { + "type": "boolean" + }, + "settings": { + "$ref": "#/components/schemas/Settings" } } }, @@ -9314,7 +11248,7 @@ }, "status": { "type": "string", - "description": "Job execution status: \"running\", \"done\", \"failed\", \"cancelled\", \"unknown\"" + "description": "Job execution status: \"running\", \"finalizing\" (script finished, app\nstatus pending), \"done\", \"failed\", \"cancelled\", \"unknown\"" }, "stderr": { "type": [ @@ -9364,6 +11298,13 @@ "manifest" ], "properties": { + "deploy_config_digest": { + "type": [ + "string", + "null" + ], + "description": "SHA-256 of the versioned CLI deployment configuration, lowercase hexadecimal." + }, "manifest": { "description": "Inline `AppManifest` (the same canonical JSON shape recipes\nstore under `manifest`). Validation runs server-side via\n`validate_app_recipe` with the caller's publish context." }, @@ -9482,6 +11423,20 @@ } } }, + "ListResponse": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppRelease" + } + } + } + }, "ListServiceSpecsResponse": { "type": "object", "required": [ @@ -9612,6 +11567,20 @@ } } }, + "LogsResponse": { + "type": "object", + "required": [ + "lines" + ], + "properties": { + "lines": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "LookupByEmailRequest": { "type": "object", "required": [ @@ -9649,6 +11618,20 @@ } } }, + "ManifestPaths": { + "type": "object", + "required": [ + "paths" + ], + "properties": { + "paths": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "MarkKeyUsedRequest": { "type": "object", "required": [ @@ -9693,6 +11676,18 @@ } } }, + "Owner": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, "Page_ApiKeyResponse": { "type": "object", "description": "Paginated response envelope. `next_cursor: None` \u21d2 last page.", @@ -10290,6 +12285,27 @@ "textarea" ] }, + "PathsRequest": { + "type": "object", + "required": [ + "installation_id", + "repository_id", + "branch" + ], + "properties": { + "branch": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "repository_id": { + "type": "integer", + "format": "int64" + } + } + }, "PollCliSessionResponse": { "type": "object", "required": [ @@ -10363,6 +12379,27 @@ } } }, + "ProjectList": { + "type": "object", + "required": [ + "projects", + "jobs" + ], + "properties": { + "jobs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubJob" + } + }, + "projects": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubProject" + } + } + } + }, "QuickDeployRequest": { "type": "object", "required": [ @@ -10445,100 +12482,395 @@ "type": "string" } }, - "template_id": { + "template_id": { + "type": "string" + }, + "vcpu_count": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + } + }, + "QuickDeployResponse": { + "type": "object", + "required": [ + "workspace", + "message" + ], + "properties": { + "expected_apps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/App" + } + }, + "installed_apps": { + "type": "array", + "items": { + "type": "string" + } + }, + "message": { + "type": "string" + }, + "workspace": { + "$ref": "#/components/schemas/Vm" + } + } + }, + "ReconcileAppsResponse": { + "type": "object", + "required": [ + "created", + "existing", + "install_jobs" + ], + "properties": { + "created": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppView" + } + }, + "existing": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppView" + } + }, + "install_jobs": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + } + }, + "RefreshSourceRequest": { + "type": "object", + "required": [ + "source_commit", + "source_repo" + ], + "properties": { + "source_commit": { + "type": "string", + "description": "Exact, lowercase 40- or 64-character Git commit object ID." + }, + "source_repo": { + "type": "string", + "description": "Expected credential-free HTTPS origin. GitHub URL spelling is normalized." + } + }, + "additionalProperties": false + }, + "RefreshSourceResponse": { + "type": "object", + "required": [ + "job_id", + "workspace_id", + "source_commit" + ], + "properties": { + "job_id": { + "type": "string" + }, + "source_commit": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, + "RefreshSourceStatusResponse": { + "type": "object", + "required": [ + "job_id", + "status", + "stdout", + "stderr" + ], + "properties": { + "exit_code": { + "type": [ + "integer", + "null" + ], + "format": "int32" + }, + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "stderr": { + "type": "string" + }, + "stdout": { + "type": "string" + } + } + }, + "RegisterPendingKeyRequest": { + "type": "object", + "required": [ + "email", + "public_key" + ], + "properties": { + "email": { + "type": "string" + }, + "public_key": { + "type": "string" + } + } + }, + "RegisterPendingKeyResponse": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "ReleaseApp": { + "type": "object", + "required": [ + "name", + "kind", + "start_command", + "source_files" + ], + "properties": { + "allowed_emails": { + "type": "array", + "items": { + "type": "string" + } + }, + "build_command": { + "type": [ + "string", + "null" + ] + }, + "configure_command": { + "type": [ + "string", + "null" + ] + }, + "custom_domain": { + "type": [ + "string", + "null" + ] + }, + "dependency_input_paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "dependency_output_paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "depends_on": { + "type": "array", + "items": { + "type": "string" + } + }, + "environment": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "executables": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "generated_credentials": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GeneratedCredential" + } + }, + "health_command": { + "type": [ + "string", + "null" + ] + }, + "health_path": { + "type": [ + "string", + "null" + ] + }, + "health_timeout_seconds": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "install_command": { + "type": [ + "string", + "null" + ] + }, + "kind": { + "type": "string" + }, + "limits": { + "$ref": "#/components/schemas/ResourceLimits" + }, + "name": { "type": "string" }, - "vcpu_count": { + "port": { "type": [ "integer", "null" ], "format": "int32", "minimum": 0 - } - } - }, - "QuickDeployResponse": { - "type": "object", - "required": [ - "workspace", - "message" - ], - "properties": { - "expected_apps": { - "type": "array", - "items": { - "$ref": "#/components/schemas/App" - } }, - "installed_apps": { + "reconfigure_command": { + "type": [ + "string", + "null" + ] + }, + "restart_policy": { + "type": "string" + }, + "source_files": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/SourceFile" } }, - "message": { + "start_command": { "type": "string" }, - "workspace": { - "$ref": "#/components/schemas/Vm" + "visibility": { + "type": "string" + }, + "volumes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReleaseVolume" + } } - } + }, + "additionalProperties": false }, - "ReconcileAppsResponse": { + "ReleaseResponse": { "type": "object", "required": [ - "created", - "existing", - "install_jobs" + "release" ], "properties": { - "created": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AppView" - } - }, - "existing": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AppView" - } - }, - "install_jobs": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - } + "release": { + "$ref": "#/components/schemas/AppRelease" } } }, - "RegisterPendingKeyRequest": { + "ReleaseVolume": { "type": "object", "required": [ - "email", - "public_key" + "name", + "mount_path", + "size_mb" ], "properties": { - "email": { + "mount_path": { "type": "string" }, - "public_key": { + "name": { "type": "string" + }, + "size_mb": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "RepoList": { + "type": "object", + "required": [ + "repositories" + ], + "properties": { + "next_page": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Repository" + } } } }, - "RegisterPendingKeyResponse": { + "Repository": { "type": "object", "required": [ - "token" + "id", + "full_name", + "default_branch", + "private", + "owner" ], "properties": { - "token": { + "default_branch": { + "type": "string" + }, + "full_name": { "type": "string" + }, + "id": { + "type": "integer", + "format": "int64" + }, + "owner": { + "$ref": "#/components/schemas/Owner" + }, + "private": { + "type": "boolean" } } }, @@ -10599,6 +12931,36 @@ } } }, + "ResourceLimits": { + "type": "object", + "properties": { + "cpu_percent": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "memory_max_mb": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "tasks_max": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + }, + "additionalProperties": false + }, "RestoreSnapshotResponse": { "type": "object", "required": [ @@ -10676,6 +13038,83 @@ } } }, + "SaveRequest": { + "type": "object", + "required": [ + "installation_id", + "repository_id", + "workspace_id", + "branch", + "manifest_path", + "expected_commit", + "content", + "pull_request", + "deployment_mode", + "allow_reimage" + ], + "properties": { + "allow_reimage": { + "type": "boolean" + }, + "branch": { + "type": "string" + }, + "confirm_strategy_change": { + "type": "boolean" + }, + "content": { + "type": "string" + }, + "deployment_mode": { + "type": "string" + }, + "deployment_strategy": { + "type": [ + "string", + "null" + ] + }, + "expected_commit": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "pull_request": { + "type": "boolean" + }, + "replace_binding_id": { + "type": [ + "string", + "null" + ], + "format": "uuid" + }, + "repository_id": { + "type": "integer", + "format": "int64" + }, + "secrets": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "workspace_id": { + "type": "string" + } + } + }, "ServiceActionResponse": { "type": "object", "required": [ @@ -10885,6 +13324,45 @@ } } }, + "Settings": { + "type": "object", + "required": [ + "name", + "port", + "start", + "install" + ], + "properties": { + "build": { + "type": [ + "string", + "null" + ] + }, + "install": { + "type": "string" + }, + "memory_mb": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + }, + "port": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "start": { + "type": "string" + } + } + }, "SetupScript": { "type": "object", "description": "Account-level setup script for reproducible workspace environments.\nScripts run once on first boot or on every start.", @@ -11102,6 +13580,44 @@ } } }, + "SourceFile": { + "type": "object", + "required": [ + "path", + "content_base64" + ], + "properties": { + "content_base64": { + "type": "string" + }, + "executable": { + "type": "boolean" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false + }, + "SourceRequest": { + "type": "object", + "required": [ + "repository", + "branch", + "manifest_path" + ], + "properties": { + "branch": { + "type": "string" + }, + "manifest_path": { + "type": "string" + }, + "repository": { + "type": "string" + } + } + }, "SpanNode": { "type": "object", "required": [ @@ -13730,6 +16246,9 @@ { "name": "Auth" }, + { + "name": "GitHub Deployments" + }, { "name": "API Keys" }, @@ -13782,4 +16301,4 @@ "name": "System" } ] -} \ No newline at end of file +} diff --git a/openapi/rigbox-api.json b/openapi/rigbox-api.json index dfd5083..341af12 100644 --- a/openapi/rigbox-api.json +++ b/openapi/rigbox-api.json @@ -1474,6 +1474,99 @@ ] } }, + "/api/v1/apps/{id}/refresh-source": { + "post": { + "tags": [ + "Apps" + ], + "description": "Fetch and check out an exact Git commit in the app's existing working directory. Does not install dependencies or restart the service. Poll the returned job for completion.", + "operationId": "refresh_app_source", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "App ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSourceRequest" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Source refresh queued", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSourceResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/apps/{id}/refresh-source/{job_id}": { + "get": { + "tags": [ + "Apps" + ], + "description": "Poll this app's latest source refresh. Success requires status done and exit_code 0. Jobs are ephemeral and disappear when the workspace restarts.", + "operationId": "get_source_refresh_status", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "App ID", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "job_id", + "in": "path", + "description": "Source refresh job ID", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Source refresh status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RefreshSourceStatusResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, "/api/v1/apps/{id}/restart": { "post": { "tags": [ @@ -1759,43 +1852,70 @@ ] } }, - "/api/v1/catalog": { + "/api/v1/auth/github/app": { "get": { "tags": [ - "App Catalog" + "GitHub Deployments" ], - "summary": "Cursor-paginated list of exact deployable catalog refs for the current\nuser. Same offset-under-opaque-cursor approach as `list_recipes`.", - "description": "List paginated deployable catalog refs available to the current user.", - "operationId": "list_versioned_catalog", - "parameters": [ - { - "name": "max_results", - "in": "query", - "description": "Maximum items to return. Clamped to `[1, MAX_LIMIT]`. Default 50.\n\nDeserialized leniently from a string: axum's `Query` (serde_urlencoded)\ncannot coerce a *flattened* numeric field, so a struct that\n`#[serde(flatten)]`s `PageParams` (e.g. `ListAppsQuery`) would otherwise\nfail with \"invalid type: string, expected u32\" on `?max_results=50`.", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "minimum": 0 + "operationId": "status", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionStatus" + } + } } - }, + } + }, + "security": [ { - "name": "cursor", - "in": "query", - "description": "Opaque cursor returned by a prior call's `next_cursor`. Omit on the\nfirst page.", - "required": false, - "schema": { - "type": "string" - } + "bearer": [] + } + ] + }, + "delete": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "disconnect", + "responses": { + "204": { + "description": "GitHub disconnected from this account" + } + }, + "security": [ + { + "bearer": [] } + ] + } + }, + "/api/v1/auth/github/app/attempts": { + "post": { + "tags": [ + "GitHub Deployments" ], + "operationId": "create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttemptRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Catalog page", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Page_DeployPreviewResponse" + "$ref": "#/components/schemas/AttemptResponse" } } } @@ -1808,32 +1928,30 @@ ] } }, - "/api/v1/catalog/detail": { + "/api/v1/auth/github/app/attempts/{id}": { "get": { "tags": [ - "App Catalog" + "GitHub Deployments" ], - "summary": "Get one exact deployable catalog ref for the current user.", - "description": "Get full details for one exact deployable catalog ref.", - "operationId": "get_versioned_catalog_detail", + "operationId": "get", "parameters": [ { - "name": "ref", - "in": "query", - "description": "Exact deploy ref, e.g. @rigbox/filebrowser@builtin or @alice/pgweb@1.2.3", + "name": "id", + "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], "responses": { "200": { - "description": "Versioned catalog item detail", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CommunityCatalogDetailResponse" + "$ref": "#/components/schemas/AttemptResponse" } } } @@ -1846,30 +1964,39 @@ ] } }, - "/api/v1/community/app-recipes": { - "get": { + "/api/v1/auth/github/app/attempts/{id}/deploy": { + "post": { "tags": [ - "Community" + "GitHub Deployments" ], - "summary": "List all published v1 app recipes (latest version of each).", - "description": "List all visible community app recipes, latest version of each.", - "operationId": "list_app_recipes", - "responses": { - "200": { - "description": "List of app recipe manifests (latest version each)", - "content": { - "application/json": { - "schema": {} + "operationId": "deploy", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployRequest" } } }, - "403": { - "description": "Feature not enabled", + "required": true + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorBody" - } + "schema": {} } } } @@ -1879,47 +2006,66 @@ "bearer": [] } ] - }, + } + }, + "/api/v1/auth/github/app/badge-fork": { "post": { "tags": [ - "Community" + "GitHub Deployments" ], - "summary": "Publish a v1 App Recipe version.", - "description": "Publish a new version of a community app recipe.", - "operationId": "publish_app_recipe", + "operationId": "fork", "requestBody": { "content": { "application/json": { - "schema": {} + "schema": { + "$ref": "#/components/schemas/ForkRequest" + } } }, "required": true }, "responses": { - "201": { - "description": "Recipe published", - "content": { - "application/json": { - "schema": {} - } - } - }, - "400": { - "description": "Invalid recipe", + "200": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiErrorBody" + "$ref": "#/components/schemas/Inspection" } } } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/badge-source": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "source", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceRequest" + } + } }, - "403": { - "description": "Feature not enabled", + "required": true + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiErrorBody" + "$ref": "#/components/schemas/BadgeSource" } } } @@ -1932,27 +2078,773 @@ ] } }, - "/api/v1/community/app-recipes/{vendor}/{slug}": { - "delete": { + "/api/v1/auth/github/app/branches": { + "get": { "tags": [ - "Community" + "GitHub Deployments" ], - "summary": "Delete an entire v1 App Recipe (all versions) owned by the caller.", - "description": "Delete a community app recipe and all of its published versions.", - "operationId": "delete_app_recipe_all", + "operationId": "branches", "parameters": [ { - "name": "vendor", - "in": "path", - "description": "Vendor (lowercase)", + "name": "installation_id", + "in": "query", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int64" } }, { - "name": "slug", - "in": "path", + "name": "repository_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BranchList" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/callback": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "callback", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Callback" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionStatus" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/connect": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "connect", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectUrl" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/generate": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "generate", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/inspect": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "inspect", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Inspection" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/manifest-paths": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "manifest_paths", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PathsRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ManifestPaths" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/projects": { + "get": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "list", + "parameters": [ + { + "name": "workspace_id", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectList" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "save", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/projects/{id}": { + "delete": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "disconnect", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "204": { + "description": "Disconnected" + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/projects/{id}/retry": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "retry", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/repositories": { + "get": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "repos", + "parameters": [ + { + "name": "installation_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepoList" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/app/webhook": { + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "webhook", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Event accepted" + } + } + } + }, + "/api/v1/auth/github/bindings": { + "get": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "list_bindings", + "responses": { + "200": { + "description": "Account repository bindings", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GithubBindingsResponse" + } + } + } + }, + "403": { + "description": "Full-account credential required" + }, + "404": { + "description": "Feature disabled" + } + }, + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "create_binding", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateGithubBindingRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Repository binding", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GithubBindingResponse" + } + } + } + }, + "400": { + "description": "Invalid repository name" + }, + "403": { + "description": "Full-account credential required" + }, + "404": { + "description": "Workspace unavailable or feature disabled" + }, + "409": { + "description": "Repository already bound" + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/bindings/{binding_id}": { + "delete": { + "tags": [ + "GitHub Deployments" + ], + "operationId": "delete_binding", + "parameters": [ + { + "name": "binding_id", + "in": "path", + "description": "Binding ID", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "workspace_id", + "in": "query", + "description": "Required target when a repository has several workspace bindings", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Binding deleted and deploy tokens revoked" + }, + "403": { + "description": "Full-account credential required" + }, + "404": { + "description": "Binding unavailable or feature disabled" + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/auth/github/token": { + "post": { + "tags": [ + "Auth" + ], + "operationId": "exchange_token", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExchangeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExchangeResponse" + } + } + } + }, + "401": { + "description": "Invalid or replayed GitHub token" + }, + "403": { + "description": "No permitted repository binding" + } + } + } + }, + "/api/v1/catalog": { + "get": { + "tags": [ + "App Catalog" + ], + "summary": "Cursor-paginated list of exact deployable catalog refs for the current\nuser. Same offset-under-opaque-cursor approach as `list_recipes`.", + "description": "List paginated deployable catalog refs available to the current user.", + "operationId": "list_versioned_catalog", + "parameters": [ + { + "name": "max_results", + "in": "query", + "description": "Maximum items to return. Clamped to `[1, MAX_LIMIT]`. Default 50.\n\nDeserialized leniently from a string: axum's `Query` (serde_urlencoded)\ncannot coerce a *flattened* numeric field, so a struct that\n`#[serde(flatten)]`s `PageParams` (e.g. `ListAppsQuery`) would otherwise\nfail with \"invalid type: string, expected u32\" on `?max_results=50`.", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor returned by a prior call's `next_cursor`. Omit on the\nfirst page.", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Catalog page", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Page_DeployPreviewResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/catalog/detail": { + "get": { + "tags": [ + "App Catalog" + ], + "summary": "Get one exact deployable catalog ref for the current user.", + "description": "Get full details for one exact deployable catalog ref.", + "operationId": "get_versioned_catalog_detail", + "parameters": [ + { + "name": "ref", + "in": "query", + "description": "Exact deploy ref, e.g. @rigbox/filebrowser@builtin or @alice/pgweb@1.2.3", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Versioned catalog item detail", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CommunityCatalogDetailResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/community/app-recipes": { + "get": { + "tags": [ + "Community" + ], + "summary": "List all published v1 app recipes (latest version of each).", + "description": "List all visible community app recipes, latest version of each.", + "operationId": "list_app_recipes", + "responses": { + "200": { + "description": "List of app recipe manifests (latest version each)", + "content": { + "application/json": { + "schema": {} + } + } + }, + "403": { + "description": "Feature not enabled", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "tags": [ + "Community" + ], + "summary": "Publish a v1 App Recipe version.", + "description": "Publish a new version of a community app recipe.", + "operationId": "publish_app_recipe", + "requestBody": { + "content": { + "application/json": { + "schema": {} + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Recipe published", + "content": { + "application/json": { + "schema": {} + } + } + }, + "400": { + "description": "Invalid recipe", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorBody" + } + } + } + }, + "403": { + "description": "Feature not enabled", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorBody" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/community/app-recipes/{vendor}/{slug}": { + "delete": { + "tags": [ + "Community" + ], + "summary": "Delete an entire v1 App Recipe (all versions) owned by the caller.", + "description": "Delete a community app recipe and all of its published versions.", + "operationId": "delete_app_recipe_all", + "parameters": [ + { + "name": "vendor", + "in": "path", + "description": "Vendor (lowercase)", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "slug", + "in": "path", "description": "Recipe slug", "required": true, "schema": { @@ -4622,6 +5514,231 @@ ] } }, + "/api/v1/workspaces/{id}/app-releases": { + "get": { + "tags": [ + "App releases" + ], + "operationId": "list", + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + } + ] + }, + "post": { + "tags": [ + "App releases" + ], + "operationId": "create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAppRelease" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "App release accepted for asynchronous processing.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + } + ] + } + }, + "/api/v1/workspaces/{id}/app-releases/{release_id}": { + "get": { + "tags": [ + "App releases" + ], + "operationId": "read", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + }, + { + "name": "release_id", + "in": "path", + "required": true, + "description": "App release ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/workspaces/{id}/app-releases/{release_id}/activate": { + "post": { + "tags": [ + "App releases" + ], + "operationId": "activate", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + }, + { + "name": "release_id", + "in": "path", + "required": true, + "description": "App release ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + }, + "202": { + "description": "App release accepted for asynchronous processing.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReleaseResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, + "/api/v1/workspaces/{id}/app-releases/{release_id}/logs": { + "get": { + "tags": [ + "App releases" + ], + "operationId": "logs", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Workspace ID.", + "schema": { + "type": "string" + } + }, + { + "name": "release_id", + "in": "path", + "required": true, + "description": "App release ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "App release result", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LogsResponse" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ] + } + }, "/api/v1/workspaces/{id}/cancel": { "post": { "tags": [ @@ -7432,15 +8549,88 @@ }, "description": "The parameter schema (snapshotted at creation time)." }, - "values": { - "type": "object", - "description": "Current values (from metadata.config). Sensitive values are masked.", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - } + "values": { + "type": "object", + "description": "Current values (from metadata.config). Sensitive values are masked.", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + } + }, + "AppRelease": { + "type": "object", + "required": [ + "id", + "is_current", + "can_rollback", + "workspace_id", + "user_id", + "owner_key", + "idempotency_key", + "status", + "artifact_release_id", + "apps", + "created_at", + "updated_at" + ], + "properties": { + "apps": {}, + "artifact_release_id": { + "type": "string" + }, + "can_rollback": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string" + }, + "idempotency_key": { + "type": "string" + }, + "is_current": { + "type": "boolean" + }, + "owner_key": { + "type": "string" + }, + "previous_release_id": { + "type": [ + "string", + "null" + ] + }, + "source_commit": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" } } }, @@ -7492,6 +8682,100 @@ } } }, + "AttemptRequest": { + "type": "object", + "required": [ + "id", + "source", + "installation_id", + "repository_id", + "repository_name", + "commit", + "branch", + "name", + "content" + ], + "properties": { + "branch": { + "type": "string" + }, + "commit": { + "type": "string" + }, + "content": { + "type": "string" + }, + "deployment_strategy": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "replace_binding_id": { + "type": [ + "string", + "null" + ], + "format": "uuid" + }, + "repository_id": { + "type": "integer", + "format": "int64" + }, + "repository_name": { + "type": "string" + }, + "source": { + "$ref": "#/components/schemas/SourceRequest" + }, + "workspace_id": { + "type": [ + "string", + "null" + ] + } + } + }, + "AttemptResponse": { + "type": "object", + "required": [ + "id", + "workspace_id", + "existing_workspace", + "branch", + "draft" + ], + "properties": { + "branch": { + "type": "string" + }, + "draft": { + "$ref": "#/components/schemas/AttemptRequest" + }, + "existing_workspace": { + "type": "boolean" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "result": {}, + "workspace_id": { + "type": "string" + } + } + }, "AuthMessageResponse": { "type": "object", "required": [ @@ -7521,6 +8805,25 @@ } } }, + "BadgeSource": { + "type": "object", + "required": [ + "repository", + "commit", + "fork_url" + ], + "properties": { + "commit": { + "type": "string" + }, + "fork_url": { + "type": "string" + }, + "repository": { + "$ref": "#/components/schemas/Repository" + } + } + }, "BindingsResponse": { "type": "object", "required": [ @@ -7535,6 +8838,120 @@ } } }, + "Branch": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + } + }, + "BranchList": { + "type": "object", + "required": [ + "branches" + ], + "properties": { + "branches": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Branch" + } + }, + "next_page": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + } + }, + "Build": { + "type": "object", + "description": "Index row for one image build. NOT the build log \u2014\nthe log text stays in host journald under `rigbox-build-`; this row\njust lets a user enumerate their recent builds (incl. failures) and resolve\neach `build_id` to open its journald log. Owner-scoped.", + "required": [ + "build_id", + "owner_user_id", + "status", + "created_at", + "updated_at" + ], + "properties": { + "build_id": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": [ + "string", + "null" + ], + "description": "Short failure summary \u2014 set on failure." + }, + "image_digest": { + "type": [ + "string", + "null" + ], + "description": "Content digest of the produced image \u2014 set on success." + }, + "label": { + "type": [ + "string", + "null" + ], + "description": "Best-effort app/project label from the deploy (the CLI's `rig.yaml` name)." + }, + "owner_user_id": { + "type": "string" + }, + "source_commit": { + "type": [ + "string", + "null" + ], + "description": "Full git object ID requested for this build; retained on failure." + }, + "source_kind": { + "type": [ + "string", + "null" + ], + "description": "`recipe` for every build since Dockerfile/image sources were removed;\nhistorical rows may still read `dockerfile` or `image`." + }, + "status": { + "type": "string", + "description": "`building` while in flight, then `succeeded` | `failed`." + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "Callback": { + "type": "object", + "required": [ + "code", + "state" + ], + "properties": { + "code": { + "type": "string" + }, + "state": { + "type": "string" + } + } + }, "CatalogResponse": { "type": "object", "required": [ @@ -7891,6 +9308,41 @@ } } }, + "ConnectUrl": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string" + } + } + }, + "ConnectionStatus": { + "type": "object", + "required": [ + "configured", + "connections" + ], + "properties": { + "configured": { + "type": "boolean" + }, + "connections": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubConnection" + } + }, + "install_url": { + "type": [ + "string", + "null" + ] + } + } + }, "CreateApiKeyRequest": { "type": "object", "properties": { @@ -7937,19 +9389,53 @@ "null" ] }, - "is_primary": { + "is_primary": { + "type": [ + "boolean", + "null" + ] + }, + "source_ref": { + "type": "string" + }, + "source_type": { + "type": "string" + } + } + }, + "CreateAppRelease": { + "type": "object", + "required": [ + "idempotency_key", + "apps" + ], + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReleaseApp" + } + }, + "deployment_scope": { + "type": [ + "string", + "null" + ] + }, + "idempotency_key": { + "type": "string" + }, + "replace_app_set": { + "type": "boolean" + }, + "source_commit": { "type": [ - "boolean", + "string", "null" ] - }, - "source_ref": { - "type": "string" - }, - "source_type": { - "type": "string" } - } + }, + "additionalProperties": false }, "CreateAppRequest": { "type": "object", @@ -8031,6 +9517,21 @@ } } }, + "CreateGithubBindingRequest": { + "type": "object", + "required": [ + "repository_name", + "workspace_id" + ], + "properties": { + "repository_name": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, "CreateServiceSpecRequest": { "type": "object", "required": [ @@ -8554,6 +10055,42 @@ } } }, + "DeployRequest": { + "type": "object", + "required": [ + "content", + "allow_reimage" + ], + "properties": { + "allow_reimage": { + "type": "boolean" + }, + "confirm_strategy_change": { + "type": "boolean" + }, + "content": { + "type": "string" + }, + "deployment_strategy": { + "type": [ + "string", + "null" + ] + }, + "secrets": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + } + }, "DeployResourceRequirements": { "type": "object", "required": [ @@ -8842,6 +10379,57 @@ } } }, + "ExchangeRequest": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "ExchangeResponse": { + "type": "object", + "required": [ + "token", + "expires_at", + "workspace_id", + "repository", + "source_ref", + "source_commit", + "ci_run_url", + "repository_private" + ], + "properties": { + "ci_run_url": { + "type": "string" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "repository": { + "type": "string" + }, + "repository_private": { + "type": "boolean" + }, + "source_commit": { + "type": "string" + }, + "source_ref": { + "type": "string" + }, + "token": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, "ExposePortRequest": { "type": "object", "required": [ @@ -8957,6 +10545,77 @@ } } }, + "ForkRequest": { + "type": "object", + "required": [ + "source_repository_id", + "installation_id", + "repository_id", + "branch", + "manifest_path" + ], + "properties": { + "branch": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "repository_id": { + "type": "integer", + "format": "int64" + }, + "source_repository_id": { + "type": "integer", + "format": "int64" + } + } + }, + "GenerateRequest": { + "type": "object", + "required": [ + "repository", + "branch", + "settings" + ], + "properties": { + "branch": { + "type": "string" + }, + "existing": { + "type": [ + "string", + "null" + ] + }, + "repository": { + "type": "string" + }, + "settings": { + "$ref": "#/components/schemas/Settings" + } + } + }, + "GeneratedCredential": { + "type": "object", + "required": [ + "key", + "env_var" + ], + "properties": { + "env_var": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "additionalProperties": false + }, "GetAiDefaultsResponse": { "type": "object", "required": [ @@ -9125,105 +10784,380 @@ } } }, - "GetServiceSpecResponse": { + "GetServiceSpecResponse": { + "type": "object", + "required": [ + "spec" + ], + "properties": { + "spec": { + "$ref": "#/components/schemas/ServiceSpec" + } + } + }, + "GetSetupScriptResponse": { + "type": "object", + "required": [ + "script" + ], + "properties": { + "script": { + "$ref": "#/components/schemas/SetupScript" + } + } + }, + "GetUserLimitsResponse": { + "type": "object", + "required": [ + "plan", + "custom", + "limits", + "usage" + ], + "properties": { + "custom": { + "type": "boolean" + }, + "limits": { + "$ref": "#/components/schemas/EffectiveLimits" + }, + "plan": { + "type": "string" + }, + "usage": { + "$ref": "#/components/schemas/LimitsUsage" + } + } + }, + "GetUserSettingsResponse": { + "type": "object", + "required": [ + "settings" + ], + "properties": { + "settings": { + "$ref": "#/components/schemas/UserSettings" + } + } + }, + "GetWorkspaceLogsResponse": { + "type": "object", + "required": [ + "lines", + "has_more" + ], + "properties": { + "cursor": { + "type": [ + "string", + "null" + ] + }, + "has_more": { + "type": "boolean" + }, + "lines": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LogLine" + } + } + } + }, + "GetWorkspaceResponse": { + "type": "object", + "required": [ + "vm" + ], + "properties": { + "failure": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/WorkspaceFailure", + "description": "Structured failure info when `vm.status == Failed`. `None` otherwise.\nComputed from the workspace's `failure_code`, `failure_reason`, and\n`creation_attempts` fields plus the retryable allowlist policy." + } + ] + }, + "vm": { + "$ref": "#/components/schemas/Vm" + } + } + }, + "GithubBindingResponse": { + "type": "object", + "required": [ + "binding" + ], + "properties": { + "binding": { + "$ref": "#/components/schemas/GithubRepoBinding" + } + } + }, + "GithubBindingsResponse": { "type": "object", "required": [ - "spec" + "bindings" ], "properties": { - "spec": { - "$ref": "#/components/schemas/ServiceSpec" + "bindings": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubRepoBinding" + } } } }, - "GetSetupScriptResponse": { + "GithubConnection": { "type": "object", "required": [ - "script" + "user_id", + "installation_id", + "github_user_id", + "github_login", + "account_login" ], "properties": { - "script": { - "$ref": "#/components/schemas/SetupScript" + "account_login": { + "type": "string" + }, + "github_login": { + "type": "string" + }, + "github_user_id": { + "type": "integer", + "format": "int64" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "user_id": { + "type": "string" } } }, - "GetUserLimitsResponse": { + "GithubJob": { "type": "object", "required": [ - "plan", - "custom", - "limits", - "usage" + "builds", + "id", + "binding_id", + "source_commit", + "source_ref", + "status", + "created_at" ], "properties": { - "custom": { - "type": "boolean" + "binding_id": { + "type": "string", + "format": "uuid" }, - "limits": { - "$ref": "#/components/schemas/EffectiveLimits" + "builds": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Build" + } }, - "plan": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "message": { + "type": [ + "string", + "null" + ] + }, + "source_commit": { "type": "string" }, - "usage": { - "$ref": "#/components/schemas/LimitsUsage" + "source_ref": { + "type": "string" + }, + "status": { + "type": "string" } } }, - "GetUserSettingsResponse": { + "GithubProject": { "type": "object", "required": [ - "settings" + "id", + "user_id", + "workspace_id", + "repository_name", + "deployment_mode", + "deployment_strategy", + "production_branch", + "manifest_path", + "allow_reimage" ], "properties": { - "settings": { - "$ref": "#/components/schemas/UserSettings" + "allow_reimage": { + "type": "boolean" + }, + "deployment_mode": { + "type": "string" + }, + "deployment_strategy": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "installation_id": { + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "production_branch": { + "type": "string" + }, + "repository_id": { + "type": [ + "string", + "null" + ] + }, + "repository_name": { + "type": "string" + }, + "repository_owner_id": { + "type": [ + "string", + "null" + ] + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" } } }, - "GetWorkspaceLogsResponse": { + "GithubRepoBinding": { "type": "object", "required": [ - "lines", - "has_more" + "id", + "user_id", + "workspace_id", + "repository_name", + "status", + "claim_expires_at", + "created_at" ], "properties": { - "cursor": { + "claim_expires_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "repository_id": { "type": [ "string", "null" ] }, - "has_more": { - "type": "boolean" + "repository_name": { + "type": "string" }, - "lines": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogLine" - } + "repository_owner_id": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "workspace_id": { + "type": "string" } } }, - "GetWorkspaceResponse": { + "InspectRequest": { "type": "object", "required": [ - "vm" + "installation_id", + "repository_id", + "branch", + "manifest_path" ], "properties": { - "failure": { - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "#/components/schemas/WorkspaceFailure", - "description": "Structured failure info when `vm.status == Failed`. `None` otherwise.\nComputed from the workspace's `failure_code`, `failure_reason`, and\n`creation_attempts` fields plus the retryable allowlist policy." - } + "branch": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "repository_id": { + "type": "integer", + "format": "int64" + } + } + }, + "Inspection": { + "type": "object", + "required": [ + "repository", + "commit", + "settings", + "requires_pull_request", + "manifest_paths" + ], + "properties": { + "commit": { + "type": "string" + }, + "content": { + "type": [ + "string", + "null" ] }, - "vm": { - "$ref": "#/components/schemas/Vm" + "manifest_paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "repository": { + "$ref": "#/components/schemas/Repository" + }, + "requires_pull_request": { + "type": "boolean" + }, + "settings": { + "$ref": "#/components/schemas/Settings" } } }, @@ -9314,7 +11248,7 @@ }, "status": { "type": "string", - "description": "Job execution status: \"running\", \"done\", \"failed\", \"cancelled\", \"unknown\"" + "description": "Job execution status: \"running\", \"finalizing\" (script finished, app\nstatus pending), \"done\", \"failed\", \"cancelled\", \"unknown\"" }, "stderr": { "type": [ @@ -9364,6 +11298,13 @@ "manifest" ], "properties": { + "deploy_config_digest": { + "type": [ + "string", + "null" + ], + "description": "SHA-256 of the versioned CLI deployment configuration, lowercase hexadecimal." + }, "manifest": { "description": "Inline `AppManifest` (the same canonical JSON shape recipes\nstore under `manifest`). Validation runs server-side via\n`validate_app_recipe` with the caller's publish context." }, @@ -9482,6 +11423,20 @@ } } }, + "ListResponse": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppRelease" + } + } + } + }, "ListServiceSpecsResponse": { "type": "object", "required": [ @@ -9612,6 +11567,20 @@ } } }, + "LogsResponse": { + "type": "object", + "required": [ + "lines" + ], + "properties": { + "lines": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "LookupByEmailRequest": { "type": "object", "required": [ @@ -9649,6 +11618,20 @@ } } }, + "ManifestPaths": { + "type": "object", + "required": [ + "paths" + ], + "properties": { + "paths": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "MarkKeyUsedRequest": { "type": "object", "required": [ @@ -9693,6 +11676,18 @@ } } }, + "Owner": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, "Page_ApiKeyResponse": { "type": "object", "description": "Paginated response envelope. `next_cursor: None` \u21d2 last page.", @@ -10290,6 +12285,27 @@ "textarea" ] }, + "PathsRequest": { + "type": "object", + "required": [ + "installation_id", + "repository_id", + "branch" + ], + "properties": { + "branch": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "repository_id": { + "type": "integer", + "format": "int64" + } + } + }, "PollCliSessionResponse": { "type": "object", "required": [ @@ -10363,6 +12379,27 @@ } } }, + "ProjectList": { + "type": "object", + "required": [ + "projects", + "jobs" + ], + "properties": { + "jobs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubJob" + } + }, + "projects": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GithubProject" + } + } + } + }, "QuickDeployRequest": { "type": "object", "required": [ @@ -10445,100 +12482,395 @@ "type": "string" } }, - "template_id": { + "template_id": { + "type": "string" + }, + "vcpu_count": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + } + }, + "QuickDeployResponse": { + "type": "object", + "required": [ + "workspace", + "message" + ], + "properties": { + "expected_apps": { + "type": "array", + "items": { + "$ref": "#/components/schemas/App" + } + }, + "installed_apps": { + "type": "array", + "items": { + "type": "string" + } + }, + "message": { + "type": "string" + }, + "workspace": { + "$ref": "#/components/schemas/Vm" + } + } + }, + "ReconcileAppsResponse": { + "type": "object", + "required": [ + "created", + "existing", + "install_jobs" + ], + "properties": { + "created": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppView" + } + }, + "existing": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AppView" + } + }, + "install_jobs": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + } + } + }, + "RefreshSourceRequest": { + "type": "object", + "required": [ + "source_commit", + "source_repo" + ], + "properties": { + "source_commit": { + "type": "string", + "description": "Exact, lowercase 40- or 64-character Git commit object ID." + }, + "source_repo": { + "type": "string", + "description": "Expected credential-free HTTPS origin. GitHub URL spelling is normalized." + } + }, + "additionalProperties": false + }, + "RefreshSourceResponse": { + "type": "object", + "required": [ + "job_id", + "workspace_id", + "source_commit" + ], + "properties": { + "job_id": { + "type": "string" + }, + "source_commit": { + "type": "string" + }, + "workspace_id": { + "type": "string" + } + } + }, + "RefreshSourceStatusResponse": { + "type": "object", + "required": [ + "job_id", + "status", + "stdout", + "stderr" + ], + "properties": { + "exit_code": { + "type": [ + "integer", + "null" + ], + "format": "int32" + }, + "job_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "stderr": { + "type": "string" + }, + "stdout": { + "type": "string" + } + } + }, + "RegisterPendingKeyRequest": { + "type": "object", + "required": [ + "email", + "public_key" + ], + "properties": { + "email": { + "type": "string" + }, + "public_key": { + "type": "string" + } + } + }, + "RegisterPendingKeyResponse": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "ReleaseApp": { + "type": "object", + "required": [ + "name", + "kind", + "start_command", + "source_files" + ], + "properties": { + "allowed_emails": { + "type": "array", + "items": { + "type": "string" + } + }, + "build_command": { + "type": [ + "string", + "null" + ] + }, + "configure_command": { + "type": [ + "string", + "null" + ] + }, + "custom_domain": { + "type": [ + "string", + "null" + ] + }, + "dependency_input_paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "dependency_output_paths": { + "type": "array", + "items": { + "type": "string" + } + }, + "depends_on": { + "type": "array", + "items": { + "type": "string" + } + }, + "environment": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "executables": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "generated_credentials": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GeneratedCredential" + } + }, + "health_command": { + "type": [ + "string", + "null" + ] + }, + "health_path": { + "type": [ + "string", + "null" + ] + }, + "health_timeout_seconds": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "install_command": { + "type": [ + "string", + "null" + ] + }, + "kind": { + "type": "string" + }, + "limits": { + "$ref": "#/components/schemas/ResourceLimits" + }, + "name": { "type": "string" }, - "vcpu_count": { + "port": { "type": [ "integer", "null" ], "format": "int32", "minimum": 0 - } - } - }, - "QuickDeployResponse": { - "type": "object", - "required": [ - "workspace", - "message" - ], - "properties": { - "expected_apps": { - "type": "array", - "items": { - "$ref": "#/components/schemas/App" - } }, - "installed_apps": { + "reconfigure_command": { + "type": [ + "string", + "null" + ] + }, + "restart_policy": { + "type": "string" + }, + "source_files": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/SourceFile" } }, - "message": { + "start_command": { "type": "string" }, - "workspace": { - "$ref": "#/components/schemas/Vm" + "visibility": { + "type": "string" + }, + "volumes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReleaseVolume" + } } - } + }, + "additionalProperties": false }, - "ReconcileAppsResponse": { + "ReleaseResponse": { "type": "object", "required": [ - "created", - "existing", - "install_jobs" + "release" ], "properties": { - "created": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AppView" - } - }, - "existing": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AppView" - } - }, - "install_jobs": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - } + "release": { + "$ref": "#/components/schemas/AppRelease" } } }, - "RegisterPendingKeyRequest": { + "ReleaseVolume": { "type": "object", "required": [ - "email", - "public_key" + "name", + "mount_path", + "size_mb" ], "properties": { - "email": { + "mount_path": { "type": "string" }, - "public_key": { + "name": { "type": "string" + }, + "size_mb": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "RepoList": { + "type": "object", + "required": [ + "repositories" + ], + "properties": { + "next_page": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Repository" + } } } }, - "RegisterPendingKeyResponse": { + "Repository": { "type": "object", "required": [ - "token" + "id", + "full_name", + "default_branch", + "private", + "owner" ], "properties": { - "token": { + "default_branch": { + "type": "string" + }, + "full_name": { "type": "string" + }, + "id": { + "type": "integer", + "format": "int64" + }, + "owner": { + "$ref": "#/components/schemas/Owner" + }, + "private": { + "type": "boolean" } } }, @@ -10599,6 +12931,36 @@ } } }, + "ResourceLimits": { + "type": "object", + "properties": { + "cpu_percent": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "memory_max_mb": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "tasks_max": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + } + }, + "additionalProperties": false + }, "RestoreSnapshotResponse": { "type": "object", "required": [ @@ -10676,6 +13038,83 @@ } } }, + "SaveRequest": { + "type": "object", + "required": [ + "installation_id", + "repository_id", + "workspace_id", + "branch", + "manifest_path", + "expected_commit", + "content", + "pull_request", + "deployment_mode", + "allow_reimage" + ], + "properties": { + "allow_reimage": { + "type": "boolean" + }, + "branch": { + "type": "string" + }, + "confirm_strategy_change": { + "type": "boolean" + }, + "content": { + "type": "string" + }, + "deployment_mode": { + "type": "string" + }, + "deployment_strategy": { + "type": [ + "string", + "null" + ] + }, + "expected_commit": { + "type": "string" + }, + "installation_id": { + "type": "integer", + "format": "int64" + }, + "manifest_path": { + "type": "string" + }, + "pull_request": { + "type": "boolean" + }, + "replace_binding_id": { + "type": [ + "string", + "null" + ], + "format": "uuid" + }, + "repository_id": { + "type": "integer", + "format": "int64" + }, + "secrets": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "workspace_id": { + "type": "string" + } + } + }, "ServiceActionResponse": { "type": "object", "required": [ @@ -10885,6 +13324,45 @@ } } }, + "Settings": { + "type": "object", + "required": [ + "name", + "port", + "start", + "install" + ], + "properties": { + "build": { + "type": [ + "string", + "null" + ] + }, + "install": { + "type": "string" + }, + "memory_mb": { + "type": [ + "integer", + "null" + ], + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + }, + "port": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "start": { + "type": "string" + } + } + }, "SetupScript": { "type": "object", "description": "Account-level setup script for reproducible workspace environments.\nScripts run once on first boot or on every start.", @@ -11102,6 +13580,44 @@ } } }, + "SourceFile": { + "type": "object", + "required": [ + "path", + "content_base64" + ], + "properties": { + "content_base64": { + "type": "string" + }, + "executable": { + "type": "boolean" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false + }, + "SourceRequest": { + "type": "object", + "required": [ + "repository", + "branch", + "manifest_path" + ], + "properties": { + "branch": { + "type": "string" + }, + "manifest_path": { + "type": "string" + }, + "repository": { + "type": "string" + } + } + }, "SpanNode": { "type": "object", "required": [ @@ -13730,6 +16246,9 @@ { "name": "Auth" }, + { + "name": "GitHub Deployments" + }, { "name": "API Keys" }, @@ -13782,4 +16301,4 @@ "name": "System" } ] -} \ No newline at end of file +}