Skip to content

feat(workflows): compare deployment versions across UI and API - #8455

Merged
icecrasher321 merged 26 commits into
stagingfrom
feat/workflow-version-diff
Oct 2, 2026
Merged

icecrasher321 merged 26 commits into
stagingfrom
feat/workflow-version-diff

Conversation

@mzxchandra

@mzxchandra mzxchandra commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Compare deployment versions of the same workflow from a version row’s Compare action. The default is the previous saved version → selected version, or v1 → Draft when no predecessor exists. The modal supports saved versions and the current draft, with a read-only canvas and field changes beside it. Blocks match by stable IDs; this does not compare separate workflows or add a fork-sync preview.

The UI, redeployment checks, and authorized comparison operation share the canonical comparison engine. Action editor defaults remain distinct from unset values; only actual trigger deployment defaults are normalized. Structured values preserve array order, scalar types, explicit JSON nulls, and arbitrary own keys. Preview and API snapshots use the same runtime materialization while archive reads retain the original stored payload.

Canvas ports are resolved from each original snapshot. Removed connections keep their exact ports, including deleted branches, without changing live branch order or labels. Ghost layout uses the preview’s dimensions and each container’s coordinate space. Preview edges read only their own snapshot state.

A presentation registry covers every declared subblock type. It reuses column definitions, option labels, canonical value shaping, and branch-role helpers without mounting live editors. Actual tables render their declared columns; messages, tools, mappings, schemas, and files render labeled values. Array order and duplicate entries remain significant; object maps use stable key order. Masking happens after comparison so secret-only edits stay visible. Code and explicit JSON editor values keep text diffs.

The interface uses EMCN components, typography, and semantic colors. Comparison stays in the version action menu, and section titles have no counts. Connection changes include exact source/target identities and ports in the API, with branch labels in the UI.

The platform surface is GET /api/v2/workflows/{workflowId}/versions/compare?base=1&target=2, exposed through the generated CLI command sim workflows versions compare <workflowId> --base 1 --target 2, the MCP catalog, and Mothership’s shared CLI surface. The operation loads at most two snapshots from one workflow, checks a 16 MiB input budget before materialization, and caps the redacted result at 16 MiB. Credential-only changes remain detectable without disclosing their values. Native SDK convenience methods are not added.

Validation:

  • 675 focused tests pass across comparison, canonicalization, overlays, field rendering, text diffs, and trigger resolution. Regression failures were demonstrated before their fixes.
  • 10 integration checks pass against disposable PostgreSQL, including execution-default behavior through the real serializer/provider request, snapshot migration parity, arbitrary JSON keys, access boundaries, direction, exact ports, and input/result size admission.
  • Real HTTP acceptance passes for the session UI contract, v2 endpoint, generated CLI, and generated MCP operation, including authentication/authorization/validation errors, secret redaction, and unchanged archived snapshots. This suite is wired into CI with a JSON failure report.
  • Real-browser checks pass for both default selections, deleted condition/router rows, nested JSON changes, root/nested ghost collisions, and input/output/error/container port transitions. DOM measurements confirm no overlap, nested containment, and all expected edge paths. The structured presentation pass additionally verifies headers, duplicate keys, custom columns, secret-only edits, repeated messages/tools, input/response schemas, and same-name files. Reversing a comparison swaps added/removed rows correctly. Screenshots and reports were retained locally.
  • Application, CLI, workflow-renderer, and workflow-types type checks pass; lint and all 54 repository audits pass.

Merged current staging, retained its shared CI report directory and readiness handling, and regenerated the conflicting registry-boundary baseline; the executable tool registry remains outside client graphs.

…verlay

The comparison engine now reports which loop and parallel fields changed and
which blocks entered or left a container, and exposes the field lists and a
shared hasChanges helper. A new overlay module merges two workflow states into
one canvas: removed blocks, containers and edges ride along as ghosts at their
old positions (nudged clear of live cards), deleted condition and router
branches stay on the surviving card so their ghost edge keeps a handle, and
every edge is classified by canonical port key. The renderer edge view gains a
quiet ghost style for those removed connections.
The preview canvas accepts per-block and per-edge diff status: added and
modified cards get a ring and a shared status label, removed cards and
containers fade to a ghost, changed sub-block rows and sentence chips tint,
and ghost edges sit under live ones so a rewired port shows the new line on top.
Side-by-side view of two workflow states: the overlaid canvas on the left and a
change list on the right, sharing selection. Each touched block is a collapsible
card with the app's block tile; modified blocks show field rows as folded line
diffs with word marks, item-by-item list diffs for tools, conditions, routes and
input fields, old to new pairs for scalars, and only the fact for secrets. Added
and removed blocks show every field diffed against nothing, with long one-sided
bodies capped behind one expander. Fork comparisons group credentials, picked
resources and trigger paths into a muted environment bindings section.
The deploy modal offers "View changes" (live against the draft) when a redeploy
is pending and a "Compare" action on every version row, opening a full-width
comparison whose two sides are pickable from the header. The draft state hook is
shared with change detection and only subscribes while something to compare
against exists.
The synced deployed workflows list gets a "View changes" action per row. A new
internal route and fork use case return the target as its editor holds it and
the source deployment re-keyed into the target's block ids through the fork block
map (or the derived id the sync would assign), with condition and route ids and
variable ids aligned, so the two sides diff block for block like two versions of
one workflow.
Comparison: keep basic/advanced mode changes visible, include a tool's
permission, server and implementation fields in list diffs, include input field
defaults, read checkbox records as records, show whitespace-only edits, cap word
and line diffing so a pathological prompt cannot stall the pane, slot deleted
branches back at their old position, never reuse a ghost edge id, and mask
secret-looking keys at any depth (including key/value table rows) with a
name-based fallback when a block definition is unknown.

Change list: memoized cards that only re-render when their own selection
changes, nested cards for blocks inside an added or removed container, a
shared sign map, muted tokens that exist, hover and focus treatment, scroll
edge fades, and a shared skeleton for both hosts.

Fork preview: the before side is the target draft the sync overwrites, read
in one snapshot and scoped to the target workspace; variables and their
assignments are re-keyed by unique name; a create reports no target id; the
change rows are a discriminated union; the query key sits under the fork diff
keys so a sync invalidates it; a direction switch closes the preview.
…ew gaps

- Fork "View changes" now loads only the previewed workflow: its deployed
  state, its identity mapping, its target row and its block pairs, instead of
  every deployed state in the source workspace plus the full promote plan.
  The plan item comes from the same buildForkPromotePlanItems decision the
  promote uses. The route gets a per-user rate limit.
- Word marks give up past 64 edits per line pair, so many long rewritten
  lines cannot stall the tab.
- Agent tool params that their block marks as password fields are masked
  whatever their name.
- A list item whose label changed but whose body did not is no longer
  flagged as a masked value change.
- Hoist double casts under their annotations, make sourceWorkflowId
  optional on the wire for rollout, lazy-load both diff modals, and
  re-record the settings module baseline: the block registry the diff canvas
  needs is reached only through the lazy chunk opened on click.
@vercel

vercel Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 2, 2026 12:42am UTC

Request Review

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

Copy link
Copy Markdown
Contributor

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 52 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread apps/sim/ee/workspace-forking/components/fork-sync/fork-sync-view.tsx Outdated
Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Adds workflow version comparison across UI and API.

The PR appears safe to merge based on the changes since the previous review and the status of prior findings.

Summary

The PR adds deployment-version comparison across the editor, authorized v2 API, generated CLI and MCP surfaces. It shares semantic comparison logic, renders a read-only canvas and field changes, and adds size limits and acceptance coverage. The changes since the previous review extend masking to JSON-encoded tool parameters and test both encoded and object forms.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  UI[Version action and comparison modal] --> Engine[Canonical comparison engine]
  API[Authorized v2 compare endpoint] --> Engine
  CLI[Generated CLI and MCP operations] --> API
  Engine --> Canvas[Read-only canvas and field changes]
  Engine --> Result[Redacted API result]
Loading

Reviews (15) · Last reviewed commit: "fix(workflows): retain tool context when..."

Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
Comment thread apps/sim/lib/workflows/comparison/overlay.ts Outdated
@mzxchandra
mzxchandra marked this pull request as draft September 30, 2026 07:40
- Sync details load each replaced target's draft and diff it against the
  projected source, using the same projection and "has changes" rule as the
  per-workflow preview, so a row and its preview never disagree. Rows the sync
  would not change read "No changes" and offer no comparison.
- Preview buttons wait until the list matches the selected direction.
- Mask JSON-encoded secrets in text and scalar fields, and say "A masked
  value changed" when masking hides the only difference.
- Show role changes on agent messages, highlight a router's changed Context
  on the canvas, and keep ghost edges under live ones into containers.
- Added or removed loops and parallels list their iteration settings.
- Size ghost containers the way the preview draws them.
- "Order changed" only when items moved; CRLF and CR read as line breaks;
  collapsing unchanged lines closes every fold; selecting a nested block
  opens its container card; the version pickers have distinct names.
- Drop redundant mock resets flagged by check:test-patterns.
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cubic review

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

@cubic review

@mzxchandra I have started the AI code review. It will take a few minutes to complete.

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@mzxchandra I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

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 54 files

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
Comment thread apps/sim/lib/workflows/comparison/overlay.ts Outdated
Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
Comment thread apps/sim/ee/workspace-forking/application/sync-details.ts Outdated
- The sync list's per-workflow change check measures the target drafts in one
  query first and skips itself past the fork state limit, then reads drafts a
  few at a time and drops each after comparing, instead of holding them all.
- Mask keys with a secret word anywhere in them (secretAccessKey,
  aws_secret_access_key) while credential references stay readable.
- Inline diffs show whitespace-only changes.
- Opened folds reset when the compared bodies change.
- Ghost collision boxes use the canvas's own block measurement.
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@mzxchandra I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

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 55 files

Tip: cubic used a learning from your PR history. Let your coding agent read cubic learnings directly with the cubic MCP.

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
Comment thread apps/sim/lib/workflows/comparison/overlay.ts Outdated
Comment thread apps/sim/ee/workspace-forking/lib/copy/deploy-bridge.ts Outdated
…ection per comparison

- Agent message bodies go through the same masking as other text fields.
- The sync change check's size guard counts block outputs and data, not only sub-blocks.
- Picking another version clears the block selection.
@cubic-dev-ai

cubic-dev-ai Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 81 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Re-trigger cubic

@icecrasher321

Copy link
Copy Markdown
Collaborator

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

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 83 files

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Fix all with cubic | Re-trigger cubic

Comment thread apps/docs/openapi-v2-workflows.json
@icecrasher321

Copy link
Copy Markdown
Collaborator

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

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 84 files

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
@icecrasher321

Copy link
Copy Markdown
Collaborator

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

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 84 files

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/app/workspace/[workspaceId]/w/components/workflow-diff/utils.ts Outdated
@icecrasher321

Copy link
Copy Markdown
Collaborator

@greptile

@icecrasher321

Copy link
Copy Markdown
Collaborator

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@icecrasher321 I have started the AI code review. It will take a few minutes to complete.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 84 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.

Re-trigger cubic

@icecrasher321
icecrasher321 merged commit 4436f82 into staging Oct 2, 2026
62 of 63 checks passed
@icecrasher321
icecrasher321 deleted the feat/workflow-version-diff branch October 2, 2026 01:20

This branch was previously deployed

1 inactive deployment
Preview — 51242f6b Deployed Oct 2, 2026 by vercel[bot]
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