diff --git a/.github/workflows/receive-endpoint-event.yml b/.github/workflows/receive-endpoint-event.yml
new file mode 100644
index 00000000..6ddaa13b
--- /dev/null
+++ b/.github/workflows/receive-endpoint-event.yml
@@ -0,0 +1,219 @@
+name: Receive endpoint change and generate CLI PR
+
+on:
+ workflow_dispatch:
+ inputs:
+ client_payload:
+ description: "Full client_payload JSON (the object under client_payload from the dispatch body)"
+ required: true
+ default: '{"relevant": true, "source_pr_url": "", "commit": "", "summary": "1 supported endpoint(s) affected: GET /api/v1/analytics/team", "changed_files": ["src/api/analytics/router.ts"], "changed_endpoints": [{"method": "GET", "path": "/api/v1/analytics/team", "change_type": "modified", "auth": ["userApiToken"], "summary": "team analytics", "source": "typescript", "api_server_files": ["src/api/analytics/router.ts"], "id": "analytics-team", "cli_command": "cloudos analytics team", "cli_source_file": "cloudos_cli/analytics/analytics.py", "query_params": ["teamId"]}]}'
+
+permissions:
+ contents: read
+
+jobs:
+ generate-pr:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.AGENT_PR_PAT }}
+ fetch-depth: 0
+
+ - name: Resolve payload
+ id: payload
+ env:
+ # Use env vars to safely pass user inputs — avoids single-quote injection
+ # when the JSON payload contains quotes.
+ CLIENT_PAYLOAD: ${{ inputs.client_payload }}
+ run: |
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+ # workflow_dispatch receives the client_payload object as a JSON string
+ # input — write it via env var (safe against single-quote injection).
+ printf '%s' "$CLIENT_PAYLOAD" > /tmp/payload.json
+ else
+ # repository_dispatch: client_payload is already JSON — write via tojson filter
+ cat <<'EOJSON' > /tmp/payload.json
+ ${{ toJson(github.event.client_payload) }}
+ EOJSON
+ fi
+
+ - name: Build Copilot PR body
+ run: |
+ python3 - <<'EOF'
+ import json
+ import sys
+
+ payload = json.load(open("/tmp/payload.json"))
+
+ if not payload.get("relevant", True):
+ print("Payload marked as not relevant — skipping.")
+ sys.exit(0)
+
+ endpoints = payload.get("changed_endpoints", [])
+ if not endpoints:
+ print("No changed endpoints in payload — skipping.")
+ sys.exit(0)
+
+ source_pr = payload.get("source_pr_url") or "manual trigger"
+ commit = payload.get("commit", "")
+ overall = payload.get("summary", "")
+ changed_files = payload.get("changed_files", [])
+ version = open("cloudos_cli/_version.py").read().strip()
+
+ fence = "```"
+
+ def fmt_list(items):
+ return ", ".join(items) if items else "—"
+
+ # Group endpoints by the CLI source file they map to, so the agent can
+ # tackle one module at a time.
+ by_file = {}
+ for ep in endpoints:
+ by_file.setdefault(ep.get("cli_source_file") or "(unknown)", []).append(ep)
+
+ lines = []
+ lines.append("## Sync cloudos-cli with a CloudOS API endpoint change\n")
+ lines.append(f"**Source PR:** {source_pr} ")
+ if commit:
+ lines.append(f"**api-server commit:** `{commit}` ")
+ lines.append(f"**Summary:** {overall}\n")
+
+ lines.append("### What changed (and where to act)\n")
+ lines.append(
+ "Each endpoint below was detected as changed in the api-server. "
+ "`source` tells you whether the change was found in the OpenAPI "
+ "`specification.yaml` (`specification`), in the TypeScript route/handler "
+ "code (`typescript`), or both. A `typescript`-only change means the "
+ "public contract may have shifted WITHOUT a spec update — read the "
+ "linked api-server files carefully before assuming the request/response "
+ "shape.\n"
+ )
+
+ for ep in endpoints:
+ method = ep.get("method") or ""
+ path = ep.get("path") or ""
+ change = ep.get("change_type") or "modified"
+ header = f"#### `{change}` — {method} {path}".strip()
+ lines.append(header)
+ if ep.get("new_path"):
+ lines.append(f"- **Renamed/new path:** `{ep['new_path']}`")
+ if ep.get("id"):
+ lines.append(f"- **Endpoint id:** `{ep['id']}` (key in `supported-endpoints.json`)")
+ if ep.get("cli_command"):
+ lines.append(f"- **CLI command to update:** `{ep['cli_command']}`")
+ if ep.get("cli_source_file"):
+ lines.append(f"- **CLI source file:** `{ep['cli_source_file']}`")
+ if ep.get("query_params"):
+ lines.append(f"- **Query params:** {fmt_list(ep['query_params'])}")
+ if ep.get("auth"):
+ lines.append(f"- **Auth strategies:** {fmt_list(ep['auth'])}")
+ lines.append(f"- **Detection source:** {ep.get('source', 'specification')}")
+ if ep.get("api_server_files"):
+ lines.append(
+ "- **api-server files that changed:** "
+ + fmt_list([f"`{f}`" for f in ep["api_server_files"]])
+ )
+ if ep.get("summary"):
+ lines.append(f"- **Notes:** {ep['summary']}")
+ lines.append("")
+
+ if changed_files:
+ lines.append("All changed api-server files
\n")
+ for f in changed_files:
+ lines.append(f"- `{f}`")
+ lines.append("\n \n")
+
+ lines.append("### Full machine-readable payload\n")
+ lines.append(f"{fence}json\n{json.dumps(endpoints, indent=2)}\n{fence}\n")
+
+ lines.append("### How cloudos-cli is structured\n")
+ lines.append(
+ "- CLI command groups register in `cloudos_cli/__main__.py`.\n"
+ "- Each module under `cloudos_cli//` has a `cli.py` (Click "
+ "commands / options) plus a logic class (e.g. `.py`) that "
+ "usually extends `Cloudos` in `cloudos_cli/clos.py`.\n"
+ "- All HTTP calls go through the wrappers in "
+ "`cloudos_cli/utils/requests.py` and send the `apikey` header.\n"
+ "- `supported-endpoints.json` is the source of truth mapping each "
+ "endpoint to its `cli_command` and `source_file`.\n"
+ )
+
+ lines.append("### Required steps\n")
+ lines.append(
+ "1. For every endpoint above, open its `cli_source_file` (fall back to "
+ "looking it up by `id` in `supported-endpoints.json` if missing) and "
+ "the api-server files listed, to understand the exact contract change.\n"
+ "2. Apply the change according to `change_type`:\n"
+ " - `added`: add the new command/option and wrapper call.\n"
+ " - `modified`: update params, request body, response parsing, and "
+ "any affected Click options to match the new contract.\n"
+ " - `removed`: deprecate/remove the wrapping command and its tests.\n"
+ " - renamed (`new_path` present): update the request path/URL builder.\n"
+ "3. Route all HTTP changes through `cloudos_cli/utils/requests.py`, keep "
+ "the `apikey` header, and match the style of neighbouring commands.\n"
+ "4. Add or update at least 2 tests under `tests//` using pytest "
+ "and `responses` (`@responses.activate`), covering happy path and one "
+ "failure/edge case.\n"
+ f"5. Bump the patch version in `cloudos_cli/_version.py` (currently "
+ f"`{version}`) and add a top `CHANGELOG.md` entry in the existing format.\n"
+ "6. Update `supported-endpoints.json` so the mapping reflects the new "
+ "path/params/method (and bump its `cli_version` if you change behaviour).\n"
+ )
+
+ body = "\n".join(lines)
+ open("/tmp/pr-body.md", "w").write(body)
+
+ # NOTE: PR title generation removed because it is not used by any subsequent step.
+ EOF
+
+ - name: Start Copilot cloud agent task (create session)
+ env:
+ # Agent tasks API requires a USER-to-server token (classic PAT / OAuth /
+ # GitHub App user token). Server-to-server (GITHUB_TOKEN / App installation
+ # tokens) are NOT supported.
+ GH_TOKEN: ${{ secrets.AGENT_PR_PAT }}
+ REPO: ${{ github.repository }}
+ AGENT_MODEL: claude-sonnet-4.6
+ run: |
+ set -euo pipefail
+ gh auth status
+
+ # Native cloud-agent session: POST /agents/repos/{owner}/{repo}/tasks.
+ # This starts the agent directly instead of assigning an issue, so it
+ # doesn't depend on the issue-assignment session bootstrap that was failing.
+ # Include "model" only when AGENT_MODEL is set (empty => auto selection).
+ jq -n \
+ --rawfile prompt /tmp/pr-body.md \
+ --arg base "main" \
+ --arg model "${AGENT_MODEL:-}" \
+ '{prompt: $prompt, base_ref: $base, create_pull_request: true}
+ + (if $model == "" then {} else {model: $model} end)' \
+ | gh api \
+ --method POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "/agents/repos/$REPO/tasks" \
+ --input -
+
+ echo "Cloud agent task created for $REPO (model: ${AGENT_MODEL:-auto})"
+
+ - name: Open fallback issue on failure
+ if: failure()
+ env:
+ GH_TOKEN: ${{ secrets.AGENT_PR_PAT }}
+ run: |
+ {
+ echo "The agent workflow failed."
+ echo
+ echo "Trigger payload:"
+ echo '```json'
+ cat /tmp/payload.json
+ echo
+ echo '```'
+ } > /tmp/failure-body.md
+
+ gh issue create \
+ --title "Agent workflow failed: could not create Copilot task PR" \
+ --body-file /tmp/failure-body.md \
+ --label "agent-failed"
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07f2df07..6c96664f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
## lifebit-ai/cloudos-cli: changelog
+## v2.94.0 (2026-06-19)
+
+### Feat:
+
+- Adds GitHub workflow to receive api-server endpoint events and open Copilot agent PRs
+- Adds `supported-endpoints.json` mapping wrapped API endpoints to CLI commands
+
## v2.91.0 (2026-05-28)
### Feat:
diff --git a/cloudos_cli/_version.py b/cloudos_cli/_version.py
index 1271f796..51e998d4 100644
--- a/cloudos_cli/_version.py
+++ b/cloudos_cli/_version.py
@@ -1 +1 @@
-__version__ = '2.91.0'
+__version__ = '2.94.0'
diff --git a/supported-endpoints.json b/supported-endpoints.json
new file mode 100644
index 00000000..f7a586c3
--- /dev/null
+++ b/supported-endpoints.json
@@ -0,0 +1,643 @@
+{
+ "version": "1.0",
+ "cli_version": "2.94.0",
+ "description": "Single source of truth mapping every API endpoint wrapped by cloudos-cli to the CLI command that wraps it. Used by the AI agent PR workflow to detect breaking changes in the api-server repo.",
+ "notes": [
+ "Path parameters are expressed as {param_name}.",
+ "Query parameters (teamId, page, limit, etc.) are omitted from 'path'; they appear in 'query_params'.",
+ "Entries with cli_command starting with '_internal/' are not directly user-facing but are called as helpers during a user command.",
+ "added_in_version reflects the CLI release when this mapping entry was first formally tracked. Historical endpoint additions were not back-filled."
+ ],
+ "endpoints": [
+ {
+ "id": "jobs-run",
+ "method": "POST",
+ "path": "/api/v2/jobs",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos job run",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also called by 'cloudos bash job' and 'cloudos bash array-job'"
+ },
+ {
+ "id": "jobs-array-metadata",
+ "method": "GET",
+ "path": "/api/v1/jobs/array-file/metadata",
+ "query_params": [],
+ "cli_command": "cloudos job run",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Called when submitting array jobs. Also called by 'cloudos bash array-job'"
+ },
+ {
+ "id": "jobs-status",
+ "method": "GET",
+ "path": "/api/v1/jobs/{job_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos job status",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also used internally by 'cloudos job logs', 'cloudos job results', 'cloudos job workdir', 'cloudos job related'"
+ },
+ {
+ "id": "jobs-details",
+ "method": "GET",
+ "path": "/api/v1/jobs/{job_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos job details",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Same endpoint as status but surfaced separately by the 'details' sub-command"
+ },
+ {
+ "id": "jobs-list",
+ "method": "GET",
+ "path": "/api/v2/jobs",
+ "query_params": ["teamId", "page", "limit"],
+ "cli_command": "cloudos job list",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "jobs-list-related-by-workdir",
+ "method": "GET",
+ "path": "/api/v2/jobs",
+ "query_params": ["workDirectory.folderId", "teamId"],
+ "cli_command": "cloudos job related",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Filters jobs by shared work-directory folder to find related analyses"
+ },
+ {
+ "id": "jobs-abort",
+ "method": "PUT",
+ "path": "/api/v2/jobs/{job_id}/abort",
+ "query_params": ["forceAbort", "teamId"],
+ "cli_command": "cloudos job abort",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "jobs-archive",
+ "method": "PUT",
+ "path": "/api/v1/jobs",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos job archive",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also called by 'cloudos job unarchive'. Body payload differentiates the action."
+ },
+ {
+ "id": "jobs-delete-results",
+ "method": "DELETE",
+ "path": "/api/v1/jobs/{job_id}/data",
+ "query_params": ["properties[]", "teamId"],
+ "cli_command": "cloudos job workdir",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Called when --delete flag is passed to 'cloudos job workdir'"
+ },
+ {
+ "id": "jobs-clone-resume-payload",
+ "method": "GET",
+ "path": "/api/v1/jobs/{job_id}/request-payload",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos job clone",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also called by 'cloudos job resume'"
+ },
+ {
+ "id": "jobs-clone-resume-submit",
+ "method": "POST",
+ "path": "/api/v2/jobs",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos job resume",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "POST after fetching the request-payload; also used by 'cloudos job clone'"
+ },
+ {
+ "id": "jobs-git-branches",
+ "method": "GET",
+ "path": "/api/v1/git/{strategy}/getBranches",
+ "query_params": [],
+ "cli_command": "cloudos job clone",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Used when resolving workflow branches for clone/resume. Also called by 'cloudos job resume'"
+ },
+ {
+ "id": "jobs-cost",
+ "method": "GET",
+ "path": "/api/v1/jobs/{job_id}/costs/compute",
+ "query_params": [],
+ "cli_command": "cloudos job cost",
+ "source_file": "cloudos_cli/cost/cost.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "jobs-workdir-folder-lookup",
+ "method": "GET",
+ "path": "/api/v1/folders/",
+ "query_params": ["id", "teamId"],
+ "cli_command": "cloudos job workdir",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also used internally to resolve folder status for 'cloudos job related'"
+ },
+ {
+ "id": "bash-job",
+ "method": "POST",
+ "path": "/api/v2/jobs",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos bash job",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": "Bash job submission"
+ },
+ {
+ "id": "bash-array-job-metadata",
+ "method": "GET",
+ "path": "/api/v1/jobs/array-file/metadata",
+ "query_params": [],
+ "cli_command": "cloudos bash array-job",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "bash-array-job-submit",
+ "method": "POST",
+ "path": "/api/v2/jobs",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos bash array-job",
+ "source_file": "cloudos_cli/jobs/job.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "queue-list-user",
+ "method": "GET",
+ "path": "/api/v1/teams/aws/v2/job-queues",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos queue list",
+ "source_file": "cloudos_cli/queue/queue.py",
+ "added_in_version": "2.91.0",
+ "notes": "Returns user-visible / team job queues"
+ },
+ {
+ "id": "queue-list-system",
+ "method": "GET",
+ "path": "/api/v1/teams/aws/v2/system-job-queues",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos queue list",
+ "source_file": "cloudos_cli/queue/queue.py",
+ "added_in_version": "2.91.0",
+ "notes": "Returns system-level job queues; results merged with user queues in the CLI output"
+ },
+ {
+ "id": "projects-list",
+ "method": "GET",
+ "path": "/api/v2/projects",
+ "query_params": ["teamId", "pageSize", "page"],
+ "cli_command": "cloudos project list",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also accepts 'search' query param when filtering by name"
+ },
+ {
+ "id": "projects-create",
+ "method": "POST",
+ "path": "/api/v1/projects",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos project create",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "workflows-list",
+ "method": "GET",
+ "path": "/api/v3/workflows",
+ "query_params": ["teamId", "pageSize", "page", "archived.status"],
+ "cli_command": "cloudos workflow list",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also accepts 'search' query param"
+ },
+ {
+ "id": "workflows-import",
+ "method": "POST",
+ "path": "/api/v2/workflows",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos workflow import",
+ "source_file": "cloudos_cli/import_wf/import_wf.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "workflows-import-legacy",
+ "method": "POST",
+ "path": "/api/v1/workflows",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos workflow import",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Legacy v1 fallback path for workflow import"
+ },
+ {
+ "id": "workflows-import-get-public-repo",
+ "method": "GET",
+ "path": "/api/v1/git/{platform}/getPublicRepo",
+ "query_params": [],
+ "cli_command": "cloudos workflow import",
+ "source_file": "cloudos_cli/import_wf/import_wf.py",
+ "added_in_version": "2.91.0",
+ "notes": "Fetches metadata for a public git repository before import"
+ },
+ {
+ "id": "workflows-import-get-config",
+ "method": "GET",
+ "path": "/api/v1/git/{platform}/getWorkflowConfig/{repo_name}/{repo_owner}",
+ "query_params": [],
+ "cli_command": "cloudos workflow import",
+ "source_file": "cloudos_cli/import_wf/import_wf.py",
+ "added_in_version": "2.91.0",
+ "notes": "Fetches the workflow main-file config for the repository"
+ },
+ {
+ "id": "cromwell-status",
+ "method": "GET",
+ "path": "/api/v1/cromwell",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos cromwell status",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "cromwell-start",
+ "method": "PUT",
+ "path": "/api/v1/cromwell/restart",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos cromwell start",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "cromwell-stop",
+ "method": "PUT",
+ "path": "/api/v1/cromwell/stop",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos cromwell stop",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "datasets-ls-project",
+ "method": "GET",
+ "path": "/api/v2/datasets",
+ "query_params": ["projectId", "teamId"],
+ "cli_command": "cloudos datasets ls",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Lists top-level dataset folders within a project"
+ },
+ {
+ "id": "datasets-ls-folder-items",
+ "method": "GET",
+ "path": "/api/v1/datasets/{folder_id}/items",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets ls",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Lists items inside a dataset folder"
+ },
+ {
+ "id": "datasets-ls-s3",
+ "method": "GET",
+ "path": "/api/v1/data-access/s3/bucket-contents",
+ "query_params": ["bucket", "path", "teamId"],
+ "cli_command": "cloudos datasets ls",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Lists S3 bucket contents for a given path"
+ },
+ {
+ "id": "datasets-ls-azure",
+ "method": "GET",
+ "path": "/api/v1/data-access/azure/container-contents",
+ "query_params": ["containerName", "path", "teamId"],
+ "cli_command": "cloudos datasets ls",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Lists Azure Blob Storage container contents"
+ },
+ {
+ "id": "datasets-ls-virtual-folder",
+ "method": "GET",
+ "path": "/api/v1/folders/virtual/{folder_id}/items",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets ls",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Lists items inside a virtual folder"
+ },
+ {
+ "id": "datasets-mv",
+ "method": "PUT",
+ "path": "/api/v1/dataItems/move",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets mv",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Moves files or folders to a different location"
+ },
+ {
+ "id": "datasets-rename-file",
+ "method": "PUT",
+ "path": "/api/v1/files/{item_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets rename",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Renames a file item"
+ },
+ {
+ "id": "datasets-rename-folder",
+ "method": "PUT",
+ "path": "/api/v1/folders/{item_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets rename",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Renames a folder item"
+ },
+ {
+ "id": "datasets-cp-virtual-folder",
+ "method": "POST",
+ "path": "/api/v1/folders/virtual",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets cp",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Creates a virtual folder copy. Also called by 'cloudos datasets mkdir'"
+ },
+ {
+ "id": "datasets-cp-s3-folder",
+ "method": "POST",
+ "path": "/api/v1/folders/s3",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets cp",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Copies an S3 folder into a dataset"
+ },
+ {
+ "id": "datasets-cp-s3-file",
+ "method": "POST",
+ "path": "/api/v1/files/s3",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets cp",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Copies an S3 file into a dataset"
+ },
+ {
+ "id": "datasets-cp-azure-folder",
+ "method": "POST",
+ "path": "/api/v1/folders/azure-blob",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets cp",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Copies an Azure Blob folder into a dataset"
+ },
+ {
+ "id": "datasets-cp-azure-file",
+ "method": "POST",
+ "path": "/api/v1/files/azure-blob",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets cp",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Copies an Azure Blob file into a dataset"
+ },
+ {
+ "id": "datasets-mkdir",
+ "method": "POST",
+ "path": "/api/v1/folders/virtual",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets mkdir",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Creates a new virtual folder"
+ },
+ {
+ "id": "datasets-rm-file",
+ "method": "DELETE",
+ "path": "/api/v1/files/{item_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets rm",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Deletes a file from a dataset"
+ },
+ {
+ "id": "datasets-rm-folder",
+ "method": "DELETE",
+ "path": "/api/v1/folders/{item_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets rm",
+ "source_file": "cloudos_cli/datasets/datasets.py",
+ "added_in_version": "2.91.0",
+ "notes": "Deletes a folder from a dataset"
+ },
+ {
+ "id": "datasets-link-mount-v2",
+ "method": "POST",
+ "path": "/api/v2/interactive-sessions/{session_id}/fuse-filesystem/mount",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets link",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Also called by 'cloudos link'. Falls back to v1 on error."
+ },
+ {
+ "id": "datasets-link-mount-v1-fallback",
+ "method": "POST",
+ "path": "/api/v1/interactive-sessions/{session_id}/fuse-filesystem/mount",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets link",
+ "source_file": "cloudos_cli/link/link.py",
+ "added_in_version": "2.91.0",
+ "notes": "Legacy v1 fallback. Also used by 'cloudos link'."
+ },
+ {
+ "id": "datasets-link-verify",
+ "method": "GET",
+ "path": "/api/v1/interactive-sessions/{session_id}/fuse-filesystems",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos datasets link",
+ "source_file": "cloudos_cli/link/link.py",
+ "added_in_version": "2.91.0",
+ "notes": "Polls mount status after requesting a link. Also used by 'cloudos link'."
+ },
+ {
+ "id": "interactive-session-list",
+ "method": "GET",
+ "path": "/api/v3/interactive-sessions",
+ "query_params": ["teamId", "page", "limit"],
+ "cli_command": "cloudos interactive-session list",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "interactive-session-create",
+ "method": "POST",
+ "path": "/api/v1/interactive-sessions",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos interactive-session create",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "interactive-session-status",
+ "method": "GET",
+ "path": "/api/v2/interactive-sessions/{session_id}",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos interactive-session status",
+ "source_file": "cloudos_cli/interactive_session/interactive_session.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "interactive-session-resume",
+ "method": "PUT",
+ "path": "/api/v1/interactive-sessions/{session_id}/resume",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos interactive-session resume",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "interactive-session-pause",
+ "method": "PUT",
+ "path": "/api/v1/interactive-sessions/{session_id}/abort",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos interactive-session pause",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "link-mount-v2",
+ "method": "POST",
+ "path": "/api/v2/interactive-sessions/{session_id}/fuse-filesystem/mount",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos link",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Primary mount call; falls back to v1 on failure"
+ },
+ {
+ "id": "link-mount-v1-fallback",
+ "method": "POST",
+ "path": "/api/v1/interactive-sessions/{session_id}/fuse-filesystem/mount",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos link",
+ "source_file": "cloudos_cli/link/link.py",
+ "added_in_version": "2.91.0",
+ "notes": "Legacy v1 fallback path"
+ },
+ {
+ "id": "link-verify",
+ "method": "GET",
+ "path": "/api/v1/interactive-sessions/{session_id}/fuse-filesystems",
+ "query_params": ["teamId"],
+ "cli_command": "cloudos link",
+ "source_file": "cloudos_cli/link/link.py",
+ "added_in_version": "2.91.0",
+ "notes": "Polls mount status after requesting a link"
+ },
+ {
+ "id": "procurement-images-list",
+ "method": "GET",
+ "path": "/api/v1/procurements/{procurement_id}/images",
+ "query_params": ["page", "limit"],
+ "cli_command": "cloudos procurement images list",
+ "source_file": "cloudos_cli/procurement/images.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "procurement-images-set",
+ "method": "PUT",
+ "path": "/api/v1/procurements/{procurement_id}/images",
+ "query_params": [],
+ "cli_command": "cloudos procurement images set",
+ "source_file": "cloudos_cli/procurement/images.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "procurement-images-reset",
+ "method": "PUT",
+ "path": "/api/v1/procurements/{procurement_id}/images/reset",
+ "query_params": [],
+ "cli_command": "cloudos procurement images reset",
+ "source_file": "cloudos_cli/procurement/images.py",
+ "added_in_version": "2.91.0",
+ "notes": null
+ },
+ {
+ "id": "_internal-cloud-azure-detect",
+ "method": "GET",
+ "path": "/api/v1/cloud/azure",
+ "query_params": ["teamId"],
+ "cli_command": "_internal/cloud-provider-detection",
+ "source_file": "cloudos_cli/utils/cloud.py",
+ "added_in_version": "2.91.0",
+ "notes": "Called internally to detect whether the workspace is running on Azure; affects which dataset copy endpoints are used"
+ },
+ {
+ "id": "_internal-users-me",
+ "method": "GET",
+ "path": "/api/v1/users/me",
+ "query_params": [],
+ "cli_command": "_internal/current-user",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Called internally to resolve the current authenticated user"
+ },
+ {
+ "id": "_internal-users-search-assist",
+ "method": "GET",
+ "path": "/api/v1/users/search-assist",
+ "query_params": ["q", "teamId"],
+ "cli_command": "_internal/user-search",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Called internally to resolve a username/email to a user ID"
+ },
+ {
+ "id": "_internal-folders-status",
+ "method": "GET",
+ "path": "/api/v1/folders/",
+ "query_params": ["id", "status[]", "teamId"],
+ "cli_command": "_internal/folder-deletion-status",
+ "source_file": "cloudos_cli/clos.py",
+ "added_in_version": "2.91.0",
+ "notes": "Called internally to poll folder deletion status during 'cloudos job workdir' and dataset operations"
+ }
+ ]
+}