Add missing cloud-runtime operations and schemas

PR review surfaced operations the cloud runtime serves that weren't
covered by the initial spec push, plus one path family missed entirely.

New methods on existing paths:

- /api/auth/session: add POST (create session cookie) and DELETE (logout)
- /api/secrets/{id}: add GET (read metadata) and PATCH (update)
- /api/hub/profiles: add POST (create profile)
- /api/hub/workflows: add POST (publish to hub)
- /api/hub/workflows/{share_id}: add DELETE (unpublish)
- /api/workspaces/{id}: add DELETE (soft-delete workspace)
- /api/workspace/members/{user_id}/api-keys: add DELETE (bulk revoke)
- /api/workflows/{workflow_id}/versions: add POST (create new version)
- /api/userdata/{file}/publish: add GET (read publish info)

New path family:

- /api/tasks (GET list) and /api/tasks/{task_id} (GET detail) for the
  background task framework

New component schemas (all tagged x-runtime: [cloud]):

CreateSessionResponse, DeleteSessionResponse, UpdateSecretRequest,
BulkRevokeAPIKeysResponse, CreateHubProfileRequest, PublishHubWorkflowRequest,
HubWorkflowDetail, AssetInfo, CreateWorkflowVersionRequest,
WorkflowVersionResponse, WorkflowPublishInfo, TaskEntry, TaskResponse,
TasksListResponse. Existing SecretMeta extended with provider and
last_used_at fields the cloud runtime actually returns.

New tag: task. Spectral lint passes with zero errors.
This commit is contained in:
Matt Miller 2026-05-06 14:20:11 -07:00
parent 6b1bfe046f
commit d25d49ddcd

View File

@ -72,6 +72,8 @@ tags:
description: "ComfyUI Hub: profiles, shared workflows, and labels (cloud-only)"
- name: workflows
description: Cloud workflow management and versioning (cloud-only)
- name: task
description: Background task management (cloud-only)
paths:
# ---------------------------------------------------------------------------
@ -2891,6 +2893,49 @@ paths:
type: integer
has_more:
type: boolean
post:
operationId: createHubProfile
tags: [hub]
summary: Create a Hub profile
description: "[cloud-only] Creates a hub profile for the specified workspace. Username is immutable after creation."
x-runtime: [cloud]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateHubProfileRequest"
responses:
"201":
description: Hub profile created
content:
application/json:
schema:
$ref: "#/components/schemas/HubProfile"
"400":
description: Bad request (e.g. invalid username)
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"409":
description: Username already taken or profile already exists
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
/api/hub/profiles/{username}:
get:
@ -3066,6 +3111,43 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/HubWorkflowList"
post:
operationId: publishHubWorkflow
tags: [hub]
summary: Publish a workflow to the hub
description: "[cloud-only] Publishes a workflow to the hub with metadata, thumbnail, and sample images."
x-runtime: [cloud]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PublishHubWorkflowRequest"
responses:
"200":
description: Workflow published to hub
content:
application/json:
schema:
$ref: "#/components/schemas/HubWorkflowDetail"
"400":
description: Bad request
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Workflow or profile not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
/api/hub/workflows/{share_id}:
get:
@ -3094,6 +3176,34 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
delete:
operationId: deleteHubWorkflow
tags: [hub]
summary: Unpublish a workflow from the hub
description: "[cloud-only] Removes a workflow from the hub listing."
x-runtime: [cloud]
parameters:
- name: share_id
in: path
required: true
schema:
type: string
description: Workflow share ID
responses:
"204":
description: Successfully unpublished
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Workflow not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
/api/hub/workflows/index:
get:
@ -3508,6 +3618,57 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
post:
operationId: createCloudWorkflowVersion
tags: [workflows]
summary: Create a new cloud workflow version
description: "[cloud-only] Creates a new workflow version with updated workflow JSON. Uses optimistic concurrency via base_version."
x-runtime: [cloud]
parameters:
- name: workflow_id
in: path
required: true
schema:
type: string
format: uuid
description: The workflow ID.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateWorkflowVersionRequest"
responses:
"201":
description: Version created
content:
application/json:
schema:
$ref: "#/components/schemas/WorkflowVersionResponse"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"403":
description: Forbidden — not the workflow owner
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"409":
description: Version conflict — base_version does not match latest
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
/api/workflows/published/{share_id}:
get:
@ -3560,6 +3721,44 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
post:
operationId: createAuthSession
tags: [auth]
summary: Create a session cookie
description: "[cloud-only] Creates a session cookie from the bearer token in the Authorization header. Returns a Set-Cookie header with a secure HttpOnly session cookie. Cookie authentication is not allowed for this endpoint."
x-runtime: [cloud]
responses:
"200":
description: Session created
content:
application/json:
schema:
$ref: "#/components/schemas/CreateSessionResponse"
"400":
description: Bad request — invalid or expired ID token
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
delete:
operationId: deleteAuthSession
tags: [auth]
summary: Delete session cookie (logout)
description: "[cloud-only] Clears the session cookie and optionally revokes the session on the server."
x-runtime: [cloud]
responses:
"200":
description: Session deleted
content:
application/json:
schema:
$ref: "#/components/schemas/DeleteSessionResponse"
/api/auth/token:
post:
@ -4270,6 +4469,39 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
delete:
operationId: bulkRevokeMemberApiKeys
tags: [workspace]
summary: Bulk revoke a member's API keys
description: "[cloud-only] Revokes all active API keys for a specific workspace member. Only workspace owners can perform this action."
x-runtime: [cloud]
parameters:
- name: user_id
in: path
required: true
schema:
type: string
minLength: 1
description: The member's user ID.
responses:
"200":
description: Keys revoked
content:
application/json:
schema:
$ref: "#/components/schemas/BulkRevokeAPIKeysResponse"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"403":
description: Forbidden — must be workspace owner
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
/api/workspace/members/{userId}:
patch:
@ -4517,6 +4749,40 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
delete:
operationId: deleteWorkspace
tags: [workspace]
summary: Delete a workspace
description: "[cloud-only] Soft-deletes a workspace. Requires owner role. Personal workspaces cannot be deleted."
x-runtime: [cloud]
parameters:
- name: id
in: path
required: true
schema:
type: string
description: The workspace ID.
responses:
"204":
description: Workspace deleted
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"403":
description: Forbidden — must be workspace owner
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
# ---------------------------------------------------------------------------
# User / settings / misc (cloud)
@ -4777,6 +5043,90 @@ paths:
$ref: "#/components/schemas/CloudError"
/api/secrets/{id}:
get:
operationId: getSecret
tags: [settings]
summary: Get secret metadata
description: "[cloud-only] Returns metadata for a specific secret. Does not return the plaintext secret value."
x-runtime: [cloud]
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
description: The secret ID.
responses:
"200":
description: Secret metadata
content:
application/json:
schema:
$ref: "#/components/schemas/SecretMeta"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
patch:
operationId: updateSecret
tags: [settings]
summary: Update a secret
description: "[cloud-only] Updates an existing secret's name and/or value. Both fields are optional; only provided fields are updated."
x-runtime: [cloud]
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
description: The secret ID.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateSecretRequest"
responses:
"200":
description: Secret updated
content:
application/json:
schema:
$ref: "#/components/schemas/SecretMeta"
"400":
description: Bad request
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"409":
description: Conflict — a secret with this name already exists
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
delete:
operationId: deleteSecret
tags: [settings]
@ -4865,6 +5215,38 @@ paths:
$ref: "#/components/schemas/CloudError"
/api/userdata/{file}/publish:
get:
operationId: getUserdataFilePublish
tags: [userdata]
summary: Get publish info for a userdata file
description: "[cloud-only] Returns the publish status and share info for a userdata workflow file."
x-runtime: [cloud]
parameters:
- name: file
in: path
required: true
schema:
type: string
description: File path relative to user data directory
responses:
"200":
description: Publish info (publish_time is null if never published)
content:
application/json:
schema:
$ref: "#/components/schemas/WorkflowPublishInfo"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Workflow not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
post:
operationId: publishUserdataFile
tags: [userdata]
@ -5087,6 +5469,118 @@ paths:
schema:
$ref: "#/components/schemas/CloudError"
/api/tasks:
get:
operationId: listTasks
tags: [task]
summary: List background tasks
description: "[cloud-only] Retrieve a paginated list of background tasks for the authenticated user. Supports filtering by task type, status, and creation time."
x-runtime: [cloud]
parameters:
- name: task_name
in: query
schema:
type: string
description: Filter by task type name (exact match).
- name: idempotency_key
in: query
schema:
type: string
description: Filter by idempotency key (exact match).
- name: status
in: query
schema:
type: string
description: Filter by one or more statuses (comma-separated).
- name: created_after
in: query
schema:
type: string
format: date-time
description: Filter tasks created after this timestamp.
- name: created_before
in: query
schema:
type: string
format: date-time
description: Filter tasks created before this timestamp.
- name: sort_order
in: query
schema:
type: string
enum: [asc, desc]
default: desc
description: Sort direction by create_time.
- name: offset
in: query
schema:
type: integer
minimum: 0
default: 0
description: Pagination offset (0-based).
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: Maximum items per page (1-100).
responses:
"200":
description: Tasks retrieved
content:
application/json:
schema:
$ref: "#/components/schemas/TasksListResponse"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"422":
description: Validation error
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
/api/tasks/{task_id}:
get:
operationId: getTask
tags: [task]
summary: Get task details
description: "[cloud-only] Retrieve full details for a specific background task."
x-runtime: [cloud]
parameters:
- name: task_id
in: path
required: true
schema:
type: string
format: uuid
description: Task identifier (UUID).
responses:
"200":
description: Task details
content:
application/json:
schema:
$ref: "#/components/schemas/TaskResponse"
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
"404":
description: Task not found
content:
application/json:
schema:
$ref: "#/components/schemas/CloudError"
components:
parameters:
@ -7336,9 +7830,361 @@ components:
type: string
name:
type: string
provider:
type: string
description: "[cloud-only] Provider identifier (e.g., huggingface, civitai)."
x-runtime: [cloud]
last_used_at:
type: string
format: date-time
description: "[cloud-only] When the secret was last used for decryption."
x-runtime: [cloud]
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
format: date-time
UpdateSecretRequest:
type: object
x-runtime: [cloud]
description: "[cloud-only] Request body for updating an existing user secret."
properties:
name:
type: string
description: New name for the secret
secret_value:
type: string
description: New secret value (API key, token, etc.)
CreateSessionResponse:
type: object
x-runtime: [cloud]
description: "[cloud-only] Response after creating a session cookie."
required:
- success
properties:
success:
type: boolean
expiresIn:
type: integer
description: Session expiration time in seconds.
DeleteSessionResponse:
type: object
x-runtime: [cloud]
description: "[cloud-only] Response after deleting a session cookie."
required:
- success
properties:
success:
type: boolean
CreateHubProfileRequest:
type: object
x-runtime: [cloud]
description: "[cloud-only] Request body for creating a new Hub profile."
required:
- workspace_id
- username
properties:
workspace_id:
type: string
username:
type: string
description: Unique URL-safe slug. Immutable after creation.
display_name:
type: string
description:
type: string
avatar_token:
type: string
website_urls:
type: array
items:
type: string
PublishHubWorkflowRequest:
type: object
x-runtime: [cloud]
description: "[cloud-only] Request body for publishing or updating a workflow on the Hub."
required:
- username
- name
- workflow_filename
- asset_ids
properties:
username:
type: string
name:
type: string
workflow_filename:
type: string
asset_ids:
type: array
items:
type: string
description:
type: string
tags:
type: array
items:
type: string
models:
type: array
items:
type: string
custom_nodes:
type: array
items:
type: string
tutorial_url:
type: string
metadata:
type: object
additionalProperties: true
thumbnail_type:
type: string
enum: [image, video, image_comparison]
thumbnail_token_or_url:
type: string
thumbnail_comparison_token_or_url:
type: string
sample_image_tokens_or_urls:
type: array
items:
type: string
HubWorkflowDetail:
type: object
x-runtime: [cloud]
description: "[cloud-only] Full Hub workflow detail including versions, assets, and statistics."
required:
- share_id
- workflow_id
- name
- workflow_json
- assets
- profile
- status
properties:
share_id:
type: string
workflow_id:
type: string
name:
type: string
status:
type: string
enum: [pending, approved, rejected, deprecated]
description:
type: string
thumbnail_type:
type: string
enum: [image, video, image_comparison]
thumbnail_url:
type: string
thumbnail_comparison_url:
type: string
tutorial_url:
type: string
metadata:
type: object
additionalProperties: true
sample_image_urls:
type: array
items:
type: string
publish_time:
type: string
format: date-time
nullable: true
workflow_json:
type: object
additionalProperties: true
assets:
type: array
items:
$ref: "#/components/schemas/AssetInfo"
profile:
$ref: "#/components/schemas/HubProfile"
AssetInfo:
type: object
x-runtime: [cloud]
description: "[cloud-only] Lightweight asset reference used in workflow publishing payloads."
required:
- id
- filename
properties:
id:
type: string
filename:
type: string
mime_type:
type: string
size_bytes:
type: integer
format: int64
BulkRevokeAPIKeysResponse:
type: object
x-runtime: [cloud]
description: "[cloud-only] Response after bulk-revoking API keys for a workspace member."
required:
- revoked_count
properties:
revoked_count:
type: integer
minimum: 0
CreateWorkflowVersionRequest:
type: object
x-runtime: [cloud]
description: "[cloud-only] Request body for creating a new version of a saved workflow."
required:
- base_version
- workflow_json
properties:
base_version:
type: integer
description: Version number this change is based on (for optimistic concurrency).
workflow_json:
type: object
additionalProperties: true
WorkflowVersionResponse:
type: object
x-runtime: [cloud]
description: "[cloud-only] Metadata for a single workflow version."
required:
- id
- version
- latest_version
- created_by
- created_at
properties:
id:
type: string
version:
type: integer
latest_version:
type: integer
created_by:
type: string
created_at:
type: string
format: date-time
WorkflowPublishInfo:
type: object
x-runtime: [cloud]
description: "[cloud-only] Publishing metadata for a workflow shared to the Hub."
required:
- workflow_id
- share_id
- listed
- assets
properties:
workflow_id:
type: string
share_id:
type: string
publish_time:
type: string
format: date-time
nullable: true
listed:
type: boolean
assets:
type: array
items:
$ref: "#/components/schemas/AssetInfo"
TaskEntry:
type: object
x-runtime: [cloud]
description: "[cloud-only] Task data for list views."
required:
- id
- task_name
- status
- create_time
properties:
id:
type: string
format: uuid
task_name:
type: string
status:
type: string
enum: [created, running, completed, failed]
create_time:
type: string
format: date-time
started_at:
type: string
format: date-time
completed_at:
type: string
format: date-time
TaskResponse:
type: object
x-runtime: [cloud]
description: "[cloud-only] Full task details including payload and result."
required:
- id
- idempotency_key
- task_name
- payload
- status
- create_time
- update_time
properties:
id:
type: string
format: uuid
idempotency_key:
type: string
task_name:
type: string
payload:
type: object
additionalProperties: true
status:
type: string
enum: [created, running, completed, failed]
result:
type: object
additionalProperties: true
create_time:
type: string
format: date-time
update_time:
type: string
format: date-time
started_at:
type: string
format: date-time
completed_at:
type: string
format: date-time
error:
type: string
TasksListResponse:
type: object
x-runtime: [cloud]
description: "[cloud-only] Paginated list of background tasks for the authenticated user."
required:
- tasks
- pagination
properties:
tasks:
type: array
items:
$ref: "#/components/schemas/TaskEntry"
pagination:
$ref: "#/components/schemas/PaginationInfo"