Add Cyclops CS Backend API reference documentation#2001
Conversation
…penAPI spec Add a native MDX generator that renders the Cyclops CS backend (trycua/cloud) HTTP API reference from its committed Swagger 2.0 spec. The spec is vendored to scripts/docs-generators/specs/ so the generator runs hermetically in this repo, mirroring the existing cua-driver/lume generators. - scripts/docs-generators/cyclops-cs.ts: Swagger 2.0 -> MDX-safe reference, with --check drift mode; plugged into config.json + ci-check-docs. - scripts/docs-generators/sync-cyclops-cs-spec.ts + sync-cyclops-cs-spec.yml: routine to refresh the vendored spec from trycua/cloud and regenerate (repository_dispatch + daily schedule + manual), opening a PR on drift. - docs/content/docs/reference/cyclops-cs/http-api.mdx: generated reference, added to the Reference nav. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0156qv6iUCo254UG1AY1CVJc
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds an end-to-end documentation pipeline for the Cyclops CS backend HTTP API: a vendored Swagger 2.0 spec, a TSX generator that converts it to an MDX reference page, a sync script that fetches and normalizes the upstream spec before re-running the generator, the generated MDX output with navigation metadata, a scheduled GitHub Actions workflow that opens a PR on spec drift, and CI trigger updates. ChangesCyclops CS API docs generation pipeline
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/sync-cyclops-cs-spec.yml:
- Around line 35-56: Pin all GitHub Actions to specific commit SHAs instead of
mutable version tags to strengthen supply-chain security. Replace the version
tags (`@v4`, `@v6`) in the uses clauses for actions/checkout, actions/setup-node,
pnpm/action-setup, and peter-evans/create-pull-request with their corresponding
commit SHA hashes. Additionally, add persist-credentials: false to the
actions/checkout action to disable default credential persistence, which reduces
the risk of credential leakage in the workflow.
In `@scripts/docs-generators/specs/cyclops-cs.swagger.json`:
- Around line 2-10: The Swagger specification in cyclops-cs.swagger.json lacks
an explicit schemes declaration at the top level, which could cause tooling to
treat bearer-token authentication over cleartext protocols. Add a schemes field
at the root level of the spec (adjacent to the swagger, info, and basePath
fields) that explicitly declares HTTPS as the only allowed transport scheme to
ensure secure transport for authenticated endpoints.
- Around line 309-314: The path parameter in the Swagger specification is
missing the required attribute. For Swagger 2.0 compliance, any parameter with
"in": "path" must have "required": true explicitly set. Locate all path
parameters (those with "in": "path") in the cyclops-cs.swagger.json file and add
the "required": true property to each one. This includes the "path" parameter
shown in the diff and any other path parameters throughout the file, ensuring
the Swagger specification is valid and generates correct documentation.
In `@scripts/docs-generators/sync-cyclops-cs-spec.ts`:
- Around line 44-51: The fetch call in the block where /^https?:\/\// is tested
lacks an abort timeout, which can cause the workflow to hang indefinitely on
stalled connections. Add an AbortController with a timeout (e.g., 30 seconds) to
the fetch request in the source parameter. Create the controller before the
fetch call, set a timeout that calls controller.abort() after the specified
duration, and pass the controller's signal in the fetch options alongside the
headers. This ensures the network request will be cancelled if it exceeds the
timeout threshold.
- Around line 37-40: In the function that retrieves the source path, when the
indexOf method finds the --from flag (i !== -1), add an explicit check to
validate that args[i + 1] exists before returning it. If --from is present but
args[i + 1] is undefined or falsy, throw an error or exit the process with a
clear message indicating that --from requires a value argument. This ensures CLI
mistakes are caught immediately instead of silently falling back to the
environment variable or default value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b5294948-6511-4102-8579-bdb569adfcaf
📒 Files selected for processing (9)
.github/workflows/ci-check-docs.yml.github/workflows/sync-cyclops-cs-spec.ymldocs/content/docs/reference/cyclops-cs/http-api.mdxdocs/content/docs/reference/cyclops-cs/meta.jsondocs/content/docs/reference/meta.jsonscripts/docs-generators/config.jsonscripts/docs-generators/cyclops-cs.tsscripts/docs-generators/specs/cyclops-cs.swagger.jsonscripts/docs-generators/sync-cyclops-cs-spec.ts
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
|
|
||
| - name: Install pnpm | ||
| uses: pnpm/action-setup@v4 | ||
|
|
||
| - name: Install Node dependencies | ||
| run: pnpm install | ||
| working-directory: docs | ||
|
|
||
| - name: Sync spec and regenerate | ||
| env: | ||
| CYCLOPS_CS_SPEC_SOURCE: "https://api.github.com/repos/trycua/cloud/contents/cyclops-cs/backend/docs/swagger.json?ref=main" | ||
| GITHUB_TOKEN: ${{ secrets.CLOUD_REPO_TOKEN }} | ||
| run: npx tsx scripts/docs-generators/sync-cyclops-cs-spec.ts | ||
|
|
||
| - name: Open PR on drift | ||
| uses: peter-evans/create-pull-request@v6 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Pin all GitHub Actions to commit SHAs and disable checkout credential persistence.
This workflow currently uses mutable action tags (Lines 35, 38, 43, 56) and default checkout credential persistence (Line 35), which weakens CI supply-chain security.
🧰 Tools
🪛 zizmor (1.26.1)
[error] 35-35: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 38-38: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 43-43: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 56-56: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/sync-cyclops-cs-spec.yml around lines 35 - 56, Pin all
GitHub Actions to specific commit SHAs instead of mutable version tags to
strengthen supply-chain security. Replace the version tags (`@v4`, `@v6`) in the
uses clauses for actions/checkout, actions/setup-node, pnpm/action-setup, and
peter-evans/create-pull-request with their corresponding commit SHA hashes.
Additionally, add persist-credentials: false to the actions/checkout action to
disable default credential persistence, which reduces the risk of credential
leakage in the workflow.
Source: Linters/SAST tools
| "swagger": "2.0", | ||
| "info": { | ||
| "description": "Backend sidecar for the cyclops-cs SPA — Keycloak-authenticated key management, authenticated reverse proxies (gateway / k8s / orch), and deprecated batch/label endpoints that now return 410 Gone. The /api/gateway proxy is the sole ingress to pool orchestrators (CUA-527); per-pool Tailscale Ingresses have been removed.", | ||
| "title": "Cyclops CS Backend API", | ||
| "contact": {}, | ||
| "version": "0.1" | ||
| }, | ||
| "basePath": "/", | ||
| "paths": { |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Declare HTTPS transport explicitly for bearer-token endpoints.
The spec defines header-based auth but does not declare schemes, so tooling may treat transport as protocol-agnostic/cleartext. Add an explicit HTTPS-only scheme at the top level.
Suggested patch
{
"swagger": "2.0",
+ "schemes": ["https"],
"info": {Also applies to: 1554-1561
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/docs-generators/specs/cyclops-cs.swagger.json` around lines 2 - 10,
The Swagger specification in cyclops-cs.swagger.json lacks an explicit schemes
declaration at the top level, which could cause tooling to treat bearer-token
authentication over cleartext protocols. Add a schemes field at the root level
of the spec (adjacent to the swagger, info, and basePath fields) that explicitly
declares HTTPS as the only allowed transport scheme to ensure secure transport
for authenticated endpoints.
Source: Linters/SAST tools
| { | ||
| "type": "string", | ||
| "description": "Upstream path (proxied verbatim, no validation)", | ||
| "name": "path", | ||
| "in": "path" | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Fix invalid Swagger path parameters marked as optional.
For Swagger 2.0, any in: "path" parameter must be required. Here, path is part of the route template but currently rendered as optional (Line 313 and Line 1154), which makes the spec invalid and generates incorrect docs.
Suggested patch
{
"type": "string",
"description": "Upstream path (proxied verbatim, no validation)",
"name": "path",
- "in": "path"
+ "in": "path",
+ "required": true
} {
"type": "string",
"description": "Upstream path (proxied verbatim)",
"name": "path",
- "in": "path"
+ "in": "path",
+ "required": true
}Also applies to: 1151-1155
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/docs-generators/specs/cyclops-cs.swagger.json` around lines 309 -
314, The path parameter in the Swagger specification is missing the required
attribute. For Swagger 2.0 compliance, any parameter with "in": "path" must have
"required": true explicitly set. Locate all path parameters (those with "in":
"path") in the cyclops-cs.swagger.json file and add the "required": true
property to each one. This includes the "path" parameter shown in the diff and
any other path parameters throughout the file, ensuring the Swagger
specification is valid and generates correct documentation.
| const i = args.indexOf('--from'); | ||
| if (i !== -1 && args[i + 1]) return args[i + 1]; | ||
| if (process.env.CYCLOPS_CS_SPEC_SOURCE) return process.env.CYCLOPS_CS_SPEC_SOURCE; | ||
| return DEFAULT_LOCAL; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Fail fast when --from is provided without a value.
If --from is present but missing its argument, the script silently falls back to env/default. That makes CLI mistakes hard to detect.
Proposed fix
function resolveSource(args: string[]): string {
const i = args.indexOf('--from');
- if (i !== -1 && args[i + 1]) return args[i + 1];
+ if (i !== -1) {
+ if (!args[i + 1] || args[i + 1].startsWith('--')) {
+ throw new Error('`--from` requires a path or URL value.');
+ }
+ return args[i + 1];
+ }
if (process.env.CYCLOPS_CS_SPEC_SOURCE) return process.env.CYCLOPS_CS_SPEC_SOURCE;
return DEFAULT_LOCAL;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const i = args.indexOf('--from'); | |
| if (i !== -1 && args[i + 1]) return args[i + 1]; | |
| if (process.env.CYCLOPS_CS_SPEC_SOURCE) return process.env.CYCLOPS_CS_SPEC_SOURCE; | |
| return DEFAULT_LOCAL; | |
| const i = args.indexOf('--from'); | |
| if (i !== -1) { | |
| if (!args[i + 1] || args[i + 1].startsWith('--')) { | |
| throw new Error('`--from` requires a path or URL value.'); | |
| } | |
| return args[i + 1]; | |
| } | |
| if (process.env.CYCLOPS_CS_SPEC_SOURCE) return process.env.CYCLOPS_CS_SPEC_SOURCE; | |
| return DEFAULT_LOCAL; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/docs-generators/sync-cyclops-cs-spec.ts` around lines 37 - 40, In the
function that retrieves the source path, when the indexOf method finds the
--from flag (i !== -1), add an explicit check to validate that args[i + 1]
exists before returning it. If --from is present but args[i + 1] is undefined or
falsy, throw an error or exit the process with a clear message indicating that
--from requires a value argument. This ensures CLI mistakes are caught
immediately instead of silently falling back to the environment variable or
default value.
| if (/^https?:\/\//.test(source)) { | ||
| const headers: Record<string, string> = { Accept: 'application/vnd.github.raw+json' }; | ||
| if (process.env.GITHUB_TOKEN) headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; | ||
| const res = await fetch(source, { headers }); | ||
| if (!res.ok) { | ||
| throw new Error(`Failed to fetch spec from ${source}: ${res.status} ${res.statusText}`); | ||
| } | ||
| return await res.text(); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Add a timeout to the upstream fetch to prevent workflow hangs.
Line 47 performs a network call without an abort timeout, so a stalled connection can block the sync job for a long time.
Proposed fix
async function readSource(source: string): Promise<string> {
if (/^https?:\/\//.test(source)) {
const headers: Record<string, string> = { Accept: 'application/vnd.github.raw+json' };
if (process.env.GITHUB_TOKEN) headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
- const res = await fetch(source, { headers });
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 30_000);
+ const res = await fetch(source, { headers, signal: controller.signal }).finally(() => {
+ clearTimeout(timeout);
+ });
if (!res.ok) {
throw new Error(`Failed to fetch spec from ${source}: ${res.status} ${res.statusText}`);
}
return await res.text();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (/^https?:\/\//.test(source)) { | |
| const headers: Record<string, string> = { Accept: 'application/vnd.github.raw+json' }; | |
| if (process.env.GITHUB_TOKEN) headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; | |
| const res = await fetch(source, { headers }); | |
| if (!res.ok) { | |
| throw new Error(`Failed to fetch spec from ${source}: ${res.status} ${res.statusText}`); | |
| } | |
| return await res.text(); | |
| if (/^https?:\/\//.test(source)) { | |
| const headers: Record<string, string> = { Accept: 'application/vnd.github.raw+json' }; | |
| if (process.env.GITHUB_TOKEN) headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; | |
| const controller = new AbortController(); | |
| const timeout = setTimeout(() => controller.abort(), 30_000); | |
| const res = await fetch(source, { headers, signal: controller.signal }).finally(() => { | |
| clearTimeout(timeout); | |
| }); | |
| if (!res.ok) { | |
| throw new Error(`Failed to fetch spec from ${source}: ${res.status} ${res.statusText}`); | |
| } | |
| return await res.text(); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/docs-generators/sync-cyclops-cs-spec.ts` around lines 44 - 51, The
fetch call in the block where /^https?:\/\// is tested lacks an abort timeout,
which can cause the workflow to hang indefinitely on stalled connections. Add an
AbortController with a timeout (e.g., 30 seconds) to the fetch request in the
source parameter. Create the controller before the fetch call, set a timeout
that calls controller.abort() after the specified duration, and pass the
controller's signal in the fetch options alongside the headers. This ensures the
network request will be cancelled if it exceeds the timeout threshold.
- cyclops-cs.ts: render `in: path` parameters as required (Swagger 2.0
mandates it), correcting the catch-all proxy `{path}` params that the
upstream spec left unflagged; regenerated http-api.mdx accordingly.
- sync-cyclops-cs-spec.ts: add a 30s AbortController timeout to the upstream
fetch so a stalled connection can't hang the CI sync job; fail fast when
`--from` is passed without a value.
Deliberately not changed: the new workflow keeps version-tagged actions
(repo-wide convention; no other workflow SHA-pins), and the vendored
swagger.json is left untouched for `schemes`/`required` since it is an
auto-synced artifact — those belong upstream in the cloud swaggo
annotations, and the generator now enforces path-param required regardless.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0156qv6iUCo254UG1AY1CVJc
Summary
Adds comprehensive HTTP API reference documentation for the Cyclops CS Backend by introducing a vendored OpenAPI/Swagger 2.0 spec and an automated documentation generator. This enables the docs site to maintain up-to-date API reference material that stays in sync with the backend's actual interface.
Key Changes
Vendored OpenAPI spec (
scripts/docs-generators/specs/cyclops-cs.swagger.json): Committed copy of the Cyclops CS backend's Swagger 2.0 specification, sourced from the privatetrycua/cloudrepository. Documents 29 endpoints across 9 groups (batch, config, gateway, keys, namespaces, passthrough, pool templates, user keys, and health).Documentation generator (
scripts/docs-generators/cyclops-cs.ts): New TypeScript generator that transforms the vendored Swagger spec into MDX documentation. Produces a comprehensive reference page with endpoint tables, parameter documentation, response schemas, and deprecation notices. Includes MDX-safe escaping for special characters and template syntax.Spec sync automation (
scripts/docs-generators/sync-cyclops-cs-spec.ts): Utility script that refreshes the vendored spec from its source of truth intrycua/cloud. Supports fetching from local checkouts, filesystem paths, or GitHub API URLs (with optional token authentication for private repos).CI workflow (
.github/workflows/sync-cyclops-cs-spec.yml): New GitHub Actions workflow that automatically syncs the vendored spec and regenerates docs when triggered by:trycua/cloud(when swagger.json changes)Generated documentation (
docs/content/docs/reference/cyclops-cs/http-api.mdx): Auto-generated MDX page documenting all 29 endpoints with full parameter tables, response schemas, and descriptions. Includes sections for deprecated batch/label endpoints (returning 410 Gone) and active endpoints for keys, namespaces, gateway proxying, and orchestrator access.Documentation configuration: Updated
scripts/docs-generators/config.jsonanddocs/content/docs/reference/meta.jsonto register the new Cyclops CS Backend reference section in the docs site navigation.Implementation Details
cua-driverdocumentation generator's approach to MDX escaping and table formatting, ensuring consistency across the docs site.CLOUD_REPO_TOKEN(a provisioned PAT/GitHub App token) to authenticate against the privatetrycua/cloudrepository, since the built-inGITHUB_TOKENcannot access other private repos.ci-check-docs.ymlnow monitor the vendored spec file for drift and trigger documentation regeneration when needed.https://claude.ai/code/session_0156qv6iUCo254UG1AY1CVJc
Summary by CodeRabbit
New Features
Documentation