Skip to content

feat(sdk): flows deploy --flow, flows versions, flows rollback (cloud#4115) - #597

Merged
khaliqgant merged 2 commits into
mainfrom
flow-versions-cli
Oct 3, 2026
Merged

khaliqgant merged 2 commits into
mainfrom
flow-versions-cli

Conversation

@AgentRelayBot

@AgentRelayBot AgentRelayBot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

CLI side of AgentWorkforce/cloud#4115: immutable flow versions, where the listener points at its active version. Server side: AgentWorkforce/cloud#4118 (data + API) and AgentWorkforce/cloud#4121 (bump, POST …/versions, rollback). This PR needs #4121 deployed for --flow, versions and rollback. The version suffix on the create form appears once #4118 is live, and is simply absent before.

What changes

flows deploy <file> --flow <name|listener-id> is the one-command update the owner asked for. The cloud#4112 guide prints flows deploy cloud-software-garden.flow.ts --flow 'Cloud Software Garden'.

  • It deploys the source as the next version of that flow, via POST /api/v1/flows/listeners/<id>/versions. The body carries only the source, its requirements and any plugins.
  • Repository, triggers, approver, agents and run budget stay on the listener.
  • --repo, --on, --approver, --agents, --name and --draft are refused beside --flow, by name, before any request, so nobody thinks they took effect.
  • --flow takes the deployed name (case-insensitive, current workspace) or the listener id. An unknown or ambiguous name is refused with the remedy.
  • Requirements are derived from the new source against the listener's own repository and triggers, and missing integrations get the same connect prompt as the create form.

Output:

DEPLOYED <id> listening · version 4 (was 3)
DEPLOYED <id> listening · re-activated version 2 (was 4; active version went down)
DEPLOYED <id> listening · version 4 (unchanged)

The second line is an orchestrator requirement: when bytes match an earlier version, the active number going down must not read as a failure.

The create form appends the version Cloud reports (DEPLOYED agent-9 listening · version 1) when Cloud returns one, and is otherwise unchanged.

flows versions <name|id> lists versions newest first, with the active one marked. flows rollback <name|id> <version> moves the pointer and rewrites nothing (ACTIVATED <id> listening · re-activated version 2 (was 3; active version went down)). Both support --json.

Structure

  • cloud-versions.ts: resolve flow, read listener, deploy a version, activate.
  • cloud-versions-wire.ts: parse and describe version changes.
  • cli/cloud-versions.ts: the three CLI handlers.
  • cloud-deploy.ts: source loading extracted into loadDeploySource so both forms share it, with no behaviour change to the create path.

Tests

  • tests/cloud-deploy.test.ts, 6 new cases against the fetch-mocked Cloud contract:
    • bump by name, where the POST body keys are exactly requirements, source, workspaceId;
    • bump by id, which skips the list, plus the "went down" wording;
    • settings beside --flow refused before any request;
    • unknown and ambiguous names;
    • the create form's version suffix;
    • versions / rollback, including a bad version argument.
  • tests/relay-cli-surface.test.ts: sample invocations for the --flow form, versions and rollback, as the drift table requires for new verbs. The gate logic is unchanged.
  • Local results: cloud-deploy 58/58, CLI surface 85/85, tsc --noEmit and tsc -p tsconfig.tests.json clean.
  • I could not get a clean local full-suite run. Live-kernel/daemon suites fail without test:prep (the cargo kernel build), which I skipped, and the run hit my timeout. None of those failures are in files this PR touches; CI is the authority here.

Docs: docs/CLOUD.md gets a "Versions" section, and README.md one line.

Humans merge this repo; I won't.

🤖 Generated with Claude Code


Note

Medium Risk
Changes the cloud deploy CLI and version API client on a production-critical path, though listener-setting flags are explicitly refused and behavior is covered by mocked API tests.

Overview
Adds immutable hosted flow versions on the CLI: ship source updates without recreating the listener, inspect history, and roll the active pointer back.

flows deploy <file> --flow <name|listener-id> posts only source, requirements, and plugins to POST …/listeners/<id>/versions. Repo, triggers, approver, agents, and budget stay on the listener; --repo, --on, --approver, --agents, --name, and --draft are rejected if passed alongside --flow. Output includes version transitions (version 4 (was 3), re-activation when bytes match an older version, including when the active number goes down).

flows versions and flows rollback list recorded versions (active marked) and call activate without deleting history; both support --json. Initial create deploys show a version suffix when Cloud returns one.

Implementation splits cloud-versions / cloud-versions-wire and cli/cloud-versions, with loadDeploySource shared between create and version deploy paths. Docs in README.md and docs/CLOUD.md; contract tests in cloud-deploy.test.ts and CLI surface samples.

Reviewed by Cursor Bugbot for commit f059813. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Adds flows deploy <file> --flow <name|listener-id> to make an existing flow's next version without changing its listener, plus flows versions and flows rollback to list and move the active version.

  • --repo, --on, --approver, --agents, --name, and --draft are refused beside --flow, by name, before any request.
  • A source declaring a harness Cloud cannot run is refused before the version is posted.
  • --flow resolves a uuid, a non-uuid listener id the workspace lists, or a unique name in the current workspace; unknown or ambiguous names are refused with the remedy.
  • Deploys whose bytes match an earlier version re-activate that version, and output notes when the active version goes down.
  • rollback accepts a positive whole number up to nine digits; anything else is refused before any request.
  • Requirements are derived from the new source against the listener's own repository and triggers, with the same connect prompt as the create form.
  • Requires the Cloud API from AgentWorkforce/cloud#4118 and #4121; the version suffix in create output appears only when the server reports one.

Written for commit f059813. Summary will update on new commits.

Review in cubic

…#4115)

A deployed flow's source is immutable on Cloud: a change becomes the next
version and the listener points at it.

- `flows deploy <file> --flow <name|listener-id>` deploys the source as the
  next version of an existing flow and changes nothing else. --repo, --on,
  --approver, --agents, --name and --draft are refused beside it, by name.
  Output: `DEPLOYED <id> listening · version 4 (was 3)`.
- The create form reports the version Cloud recorded, when Cloud returns one.
- Bytes that match an earlier version re-activate it, and the line says so:
  `re-activated version 2 (was 4; active version went down)`.
- `flows versions <name|id>` lists versions newest first, the active one
  marked; `flows rollback <name|id> <version>` moves the pointer.

Source loading is shared between the create and version forms
(loadDeploySource).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Session-Id: 6ef9d620-3fc8-4bb3-bb0b-593d915c67ea
@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 71ce9d09-0f8c-436b-9853-6f52c1e18f27

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f0887c8. Configure here.

Comment thread packages/sdk/src/cloud-versions.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 11 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/sdk/src/cloud-versions.ts Outdated
Comment thread packages/sdk/src/cloud-versions-wire.ts Outdated
Comment thread packages/sdk/src/cli/cloud-versions.ts Outdated
Comment thread packages/sdk/src/cloud-versions.ts
…on-uuid ids; safe version integers

Review feedback on #597.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Session-Id: 6ef9d620-3fc8-4bb3-bb0b-593d915c67ea
@khaliqgant

Copy link
Copy Markdown
Member

End-to-end against production Cloud (agentrelay.com, cloud#4118 + cloud#4121 live at 55ac3bde9), using this PR's built CLI (head f059813):

On a throwaway draft flow, created then deleted:

Case Output
create --draft SAVED … draft · version 1
--flow <name>, changed file version 2 (was 1)
original bytes again re-activated version 1 (was 2; active version went down)
identical bytes version 1 (unchanged)
--flow with --repo refused before any request
flows versions both listed, active marked
flows rollback <id> 2 ACTIVATED … re-activated version 2 (was 1), list shows 2 active
same-name create, matching settings redeploy, no 409
same-name create, different approver flow_settings_mismatch naming the approver
unknown --flow name refused with a pointer to flows deployments

A real run on the bumped version: claude-cred-probe was bumped to version 2 (one added echo step) with flows deploy … --flow claude-cred-probe, invoked, and run 1913623a completed with 6 steps instead of the previous 5. It was then rolled back with flows rollback claude-cred-probe 1; the active version and the listener's source mirror are both back on 94737815dd37.

Not covered: the dashboard history and rollback UI, and the published npm package (after merge and release).

@khaliqgant
khaliqgant merged commit 731567a into main Oct 3, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants