Skip to content

feat(workflows): compare workflow versions and preview fork sync changes - #8455

Open
mzxchandra wants to merge 15 commits into
stagingfrom
feat/workflow-version-diff
Open

mzxchandra wants to merge 15 commits into
stagingfrom
feat/workflow-version-diff

Conversation

@mzxchandra

Copy link
Copy Markdown
Contributor

Summary

Adds a workflow version diff: a read-only canvas that paints added, modified and removed blocks and connections, next to a change list with field-level diffs.
It is used in two places.

  • Deploy modal: "View changes" compares any two deployment versions, or a version against the current draft.
  • Workspace fork sync: each workflow in the sync list gets a "View changes" button that previews what the sync would write over the target's current draft.

How it works:

  • lib/workflows/comparison gains container (loop/parallel) config changes and buildWorkflowDiffOverlay, which merges both states into one canvas with removed blocks and edges drawn as ghosts, nudged clear of live blocks.
  • The change list renders every field as a diff: code and prompts as line diffs with word marks and folded context, lists (conditions, routes, tools, input fields) as keyed item diffs, and added or removed blocks as a diff against nothing.
  • Secrets are masked everywhere: password sub-blocks, secret-looking keys at any depth (including JSON-encoded tool params and header tables), and block tools' own password params. A change hidden by masking still shows as "a masked value changed".
  • The fork preview re-keys the source's block ids into the target's through the persisted block map (O(1) lookups, falling back to the same deterministic derive the promote uses), so a block present on both sides compares as itself. The diff joins by id with Maps and Sets, so it is linear in block count.
  • The fork preview loads only the previewed workflow: its deployed state, its identity mapping, its target row and its block pairs. The plan item comes from the same buildForkPromotePlanItems decision the promote makes.

Guards against slow input: line diffs cap at 2000 lines, word marks give up past 64 edits per line pair or 4000 characters, and both diff modals are lazy-loaded.

The settings route's module baseline is re-recorded (+355 modules). The growth is the block registry that the diff canvas needs, reached only through the lazy chunk opened on click. The tool registry stays out.

Follow-ups, not in this PR:

  • The fork preview shows the source as deployed. The resource remaps, custom block swaps and cleared references that the sync applies at write time are listed by the sync page's own sections, not painted on the canvas. A reference the sync would clear already hard-blocks the sync until it is dropped.
  • Credential and selector values show as stored ids rather than resolved display names.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

  • Unit tests for the comparison engine, overlay, change-list helpers (masking, pairing, text diff rows), compare-pair resolution, the fork preview use case and its route: 2,835 tests passing across the affected areas.
  • bun run check:api-validation:strict, the module-budget check, biome, and type-check for apps/sim and packages/workflow-renderer all pass.
  • Browser E2E on local dev: compared deployment versions and the draft in the deploy modal, previewed push and pull syncs on a fork, and checked ghosts, container changes, long code bodies and masked fields.
  • The single-workflow fork preview returns byte-identical responses to the previous whole-workspace implementation on a live fork, in both directions.

Reviewers: the overlay placement (lib/workflows/comparison/overlay.ts) and the single-workflow plan resolution (resolveForkPlanItem) deserve the closest look.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos

Screenshots available on request; the deploy modal and fork sync page both open the same comparison view.

🤖 Generated with Claude Code

…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.

Project Deployment Actions Updated
docs Ready Ready Preview Oct 1, 2026 12:52am 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

@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Adds workflow version comparison and fork sync preview features.

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

Summary

The PR adds a read-only workflow comparison canvas and field-level change list for deployment versions and fork-sync previews. Fork previews load one workflow and align source block IDs with the target; the latest changes switch five tests to absolute imports.

  • Previously reported findings are resolved or fixed in the current code.
  • No new issue was identified in the changes since the previous review.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Deployment versions or fork-sync workflow] --> B[Load comparison states]
  B --> C[Generate workflow diff]
  C --> D[Build canvas overlay]
  C --> E[Render field-level change list]
Loading

Reviews (8) · Last reviewed commit: "test(workflows): use absolute imports in..."

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/lib/workflows/comparison/overlay.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/lib/workflows/comparison/overlay.ts
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 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.

Comment thread apps/sim/app/api/workspaces/[id]/fork/workflow-diff/route.test.ts Outdated

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

Confidence score: 5/5

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

Re-trigger cubic

…comes, not mock calls

- Key the comparison view by the picked version pair instead of resetting on state identity, so live draft updates no longer clear the selection.
- Agent message changes hidden by masking say so, like other fields.
- Fork preview tests assert results, with mocks that answer only the right arguments, instead of asserting mock calls.
@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.

No issues found across 55 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

@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.

No issues found across 55 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

@mzxchandra
mzxchandra marked this pull request as ready for review September 30, 2026 08:34

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

Confidence score: 5/5

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

Re-trigger cubic

@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.

No issues found across 55 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

This branch was successfully deployed

1 active deployment
Preview — 5793bb21 Deployed Oct 1, 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