Skip to content

refactor(stores): model execution and workflow-diff state as status enums#5197

Merged
waleedlatif1 merged 1 commit into
stagingfrom
refactor/store-status-enums
Jun 24, 2026
Merged

refactor(stores): model execution and workflow-diff state as status enums#5197
waleedlatif1 merged 1 commit into
stagingfrom
refactor/store-status-enums

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Convert the execution and workflow-diff Zustand stores from independent booleans (boolean-soup) to a single discriminated status enum as the source of truth, with derived boolean selectors.
    • ExecutionStatus = 'idle' | 'running' | 'debugging' → derives isExecuting/isDebugging.
    • WorkflowDiffStatus = 'none' | 'staged' | 'showing' → derives hasActiveDiff/isShowingDiff/isDiffReady.
  • Illegal states (e.g. isDebugging && !isExecuting, isShowingDiff && !hasActiveDiff) are now unrepresentable; the former runtime guards become compile-time-correct transitions. Matches the existing HydrationPhase convention.
  • Derived booleans are spread into every state patch from a single helper, so the enum and booleans cannot drift. All ~40 consumers are unchanged.
  • Fixes a latent edge: setIsExecuting(true) now always clears the run path (as before), independent of resulting status.

Type of Change

  • Refactor / improvement

Testing

  • 58 unit tests (execution + workflow-diff) assert the exhaustive status→derived-boolean mapping, no-drift invariants, and that critical transitions are byte-identical (run-path clear on running/preserve on debugging, diff toggle guard, clear/RESET, undo-redo writers).
  • tsc 0 errors (compiles all consumers against the new types), Biome clean.

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)

@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 24, 2026 4:39pm

Request Review

@cursor

cursor Bot commented Jun 24, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes how run and diff-overlay state transitions are encoded (execution start/stop/debug and diff show/hide), but legacy booleans are derived consistently and tests lock in prior behavior; regression risk is mainly in edge cases around debug mode and diff undo/redo.

Overview
Replaces independent boolean flags in the execution and workflow-diff Zustand stores with a single status field as the source of truth, while still persisting the legacy booleans via deriveExecutionFlags and deriveDiffFlags so existing readers stay unchanged.

For execution, ExecutionStatus (idle | running | debugging) drives a new setStatus API; setIsExecuting / setIsDebugging now translate into status transitions (e.g. starting execution preserves an active debug session, stopping always returns to idle). Run-path clearing remains tied to starting execution via clearRunPath.

For workflow diff, WorkflowDiffStatus (none | staged | showing) centralizes overlay lifecycle; toggleDiffView, reset/initial patches, and undo/redo diff writers use deriveDiffFlags instead of hand-setting three booleans.

Adds focused unit tests for status→flag mapping, transitions, and no-drift invariants; execution tests run under @vitest-environment node with a registry mock, and global Vitest mocks include status / setStatus.

Reviewed by Cursor Bugbot for commit ad97d21. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 40ed2ec. Configure here.

@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces independent boolean flags in the execution and workflow-diff Zustand stores with discriminated status enum fields (ExecutionStatus, WorkflowDiffStatus) as the single source of truth, with derived boolean selectors kept on the state object for backward compatibility. The refactor eliminates illegal combinations like isDebugging && !isExecuting at the type level rather than through runtime guards.

  • ExecutionStatus = 'idle' | 'running' | 'debugging' drives isExecuting/isDebugging via deriveExecutionFlags; setStatus is added as a new primitive action and setIsExecuting/setIsDebugging are reimplemented on top of it.
  • WorkflowDiffStatus = 'none' | 'staged' | 'showing' drives hasActiveDiff/isShowingDiff/isDiffReady via deriveDiffFlags; RESET_DIFF_STATE is exported and toggleDiffView becomes a single status compare-and-flip.
  • All ~40 consumers are call-site–unchanged; the global Vitest setup mock and use-undo-redo are updated to use the new enum and helpers.

Confidence Score: 5/5

Safe to merge — the change is a contained store refactor with no consumer-visible API breakage and thorough test coverage.

The enum-based approach eliminates an entire class of illegal state combinations that previously had to be guarded at runtime. All ~40 consumers keep reading the same derived booleans unchanged, backward compatibility is maintained by spreading the derived flags directly onto the stored state objects, and 58 unit tests verify exhaustive status→boolean mapping and critical transition invariants. The setIsExecuting and setIsDebugging reimplementations are byte-identical in effect to the old code, confirmed by test coverage.

No files require special attention. All changes are well-scoped to store internals and helpers.

Important Files Changed

Filename Overview
apps/sim/stores/execution/types.ts Introduces ExecutionStatus enum type and deriveExecutionFlags helper; updates WorkflowExecutionState to carry status as the source of truth alongside derived booleans. Documentation and default state updated consistently.
apps/sim/stores/execution/store.ts Adds setStatus primitive; rewrites setIsExecuting (preserves debug mode, always clears run path on start) and setIsDebugging (idempotent false-when-not-debugging) on top of it. No consumers changed.
apps/sim/stores/workflow-diff/types.ts Introduces WorkflowDiffStatus, DiffStatusFlags, and deriveDiffFlags; documents the invariant that hasActiveDiff === isDiffReady for all statuses.
apps/sim/stores/workflow-diff/store.ts Exports RESET_DIFF_STATE (now as const with status: 'none' included), simplifies toggleDiffView to a single status compare-and-flip, and seeds initial state via deriveDiffFlags('none').
apps/sim/hooks/use-undo-redo.ts Replaces five manual boolean-spreading call sites with ...deriveDiffFlags(status) spreads; no logic change.
apps/sim/stores/execution/store.test.ts Adds exhaustive status→flag mapping, no-drift invariant, and critical transition tests; mocks the workflow registry to keep the suite a true node-environment unit test.
apps/sim/stores/workflow-diff/store.test.ts New test file covering deriveDiffFlags exhaustive mapping, initial/reset state, toggleDiffView transitions, clearDiff, and _batchedStateUpdate no-drift invariant; all heavy dependencies mocked.
apps/sim/vitest.setup.ts Adds status: 'idle' and setStatus: vi.fn() to the global execution store mock so all component tests see the updated shape.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph ExecutionStatus
        EI[idle\nisExecuting=false\nisDebugging=false]
        ER[running\nisExecuting=true\nisDebugging=false]
        ED[debugging\nisExecuting=true\nisDebugging=true]
    end

    subgraph WorkflowDiffStatus
        DN[none\nhasActiveDiff=false\nisShowingDiff=false\nisDiffReady=false]
        DS[staged\nhasActiveDiff=true\nisShowingDiff=false\nisDiffReady=true]
        DW[showing\nhasActiveDiff=true\nisShowingDiff=true\nisDiffReady=true]
    end

    EI -->|setIsExecuting true| ER
    EI -->|setIsDebugging true| ED
    ER -->|setIsDebugging true| ED
    ER -->|setIsExecuting false| EI
    ED -->|setIsDebugging false| ER
    ED -->|setIsExecuting false| EI
    ED -->|setIsExecuting true| ED

    DN -->|showDiff / _batchedStateUpdate| DW
    DS -->|toggleDiffView| DW
    DW -->|toggleDiffView| DS
    DS -->|clearDiff / RESET| DN
    DW -->|clearDiff / RESET| DN
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    subgraph ExecutionStatus
        EI[idle\nisExecuting=false\nisDebugging=false]
        ER[running\nisExecuting=true\nisDebugging=false]
        ED[debugging\nisExecuting=true\nisDebugging=true]
    end

    subgraph WorkflowDiffStatus
        DN[none\nhasActiveDiff=false\nisShowingDiff=false\nisDiffReady=false]
        DS[staged\nhasActiveDiff=true\nisShowingDiff=false\nisDiffReady=true]
        DW[showing\nhasActiveDiff=true\nisShowingDiff=true\nisDiffReady=true]
    end

    EI -->|setIsExecuting true| ER
    EI -->|setIsDebugging true| ED
    ER -->|setIsDebugging true| ED
    ER -->|setIsExecuting false| EI
    ED -->|setIsDebugging false| ER
    ED -->|setIsExecuting false| EI
    ED -->|setIsExecuting true| ED

    DN -->|showDiff / _batchedStateUpdate| DW
    DS -->|toggleDiffView| DW
    DW -->|toggleDiffView| DS
    DS -->|clearDiff / RESET| DN
    DW -->|clearDiff / RESET| DN
Loading

Reviews (5): Last reviewed commit: "refactor(stores): model execution and wo..." | Re-trigger Greptile

Comment thread apps/sim/stores/execution/types.ts
@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces independent boolean fields (isExecuting/isDebugging and hasActiveDiff/isShowingDiff/isDiffReady) in the execution and workflow-diff Zustand stores with a single discriminated status enum per store, using a derive*Flags helper to keep the legacy booleans in sync. All ~40 consumers continue reading the same boolean fields unchanged.

  • Execution store: introduces ExecutionStatus = 'idle' | 'running' | 'debugging' and a new setStatus primitive; setIsExecuting and setIsDebugging become thin wrappers that translate their boolean arguments into enum transitions, with setIsExecuting(true) always clearing the run path regardless of whether the resulting status is running or debugging.
  • Workflow-diff store: introduces WorkflowDiffStatus = 'none' | 'staged' | 'showing'; RESET_DIFF_STATE is exported (needed by tests) and typed as const; toggleDiffView's two-check guard collapses to a single status === 'none' check.
  • Tests: 58 new unit assertions covering exhaustive enum→boolean mappings, no-drift invariants, and byte-identical transition behaviour for both stores; use-undo-redo call sites are updated mechanically to spread deriveDiffFlags().

Confidence Score: 5/5

Safe to merge — the refactor is mechanical and all consumer call sites remain unchanged.

All state transitions are covered by tests that assert both the enum value and its derived booleans, so a drift between them would be caught immediately. The behavioral changes are intentional and correctly implemented: setIsExecuting(true) always clears the run path, setIsDebugging(false) preserves status when not in debugging mode, and setIsExecuting(false) always returns to idle. The only finding is a minor docstring inaccuracy on setIsDebugging.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/stores/execution/types.ts Introduces ExecutionStatus enum and deriveExecutionFlags helper; updates WorkflowExecutionState and ExecutionActions interfaces. Logic is correct; minor docstring inaccuracy on setIsDebugging.
apps/sim/stores/execution/store.ts Adds setStatus primitive; rewrites setIsExecuting and setIsDebugging as enum-based transitions. Logic is correct: run-path clearing, debug-session preservation, and idle transitions all match the documented behaviour.
apps/sim/stores/workflow-diff/types.ts Adds WorkflowDiffStatus enum, DiffStatusFlags type, and deriveDiffFlags helper. hasActiveDiff and isDiffReady are correctly kept in lockstep (both false for none, both true for staged/showing).
apps/sim/stores/workflow-diff/store.ts Replaces three independent boolean initializations with deriveDiffFlags('none') spread; exports RESET_DIFF_STATE as const; simplifies toggleDiffView guard from two boolean checks to a single status===none check. All transitions are correct.
apps/sim/hooks/use-undo-redo.ts Replaces three manual boolean assignments with deriveDiffFlags spread at every undo/redo call site. Change is mechanical and complete across all 5 affected locations.
apps/sim/stores/execution/store.test.ts Adds exhaustive enum→boolean mapping tests, status-transition tests, and no-drift invariants. Registry store mocked to allow node environment execution.
apps/sim/stores/workflow-diff/store.test.ts New test file covering deriveDiffFlags mapping, initial/reset state, toggleDiffView, clearDiff, and _batchedStateUpdate. Mocks all heavy transitive imports to keep tests fast in the node environment.
apps/sim/vitest.setup.ts Adds status:'idle' to mock return values and exposes setStatus vi.fn() on the mock execution store to match the new interface.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph ExecutionStore["Execution Store"]
        EI[idle\nisExecuting=false\nisDebugging=false]
        ER[running\nisExecuting=true\nisDebugging=false]
        ED[debugging\nisExecuting=true\nisDebugging=true]

        EI -->|setIsExecuting true| ER
        ER -->|setIsDebugging true| ED
        ED -->|setIsDebugging false| ER
        ER -->|setIsExecuting false| EI
        ED -->|setIsExecuting false| EI
        ED -->|setIsExecuting true\n+ clearRunPath| ED
    end

    subgraph DiffStore["Workflow-Diff Store"]
        DN[none\nhasActiveDiff=false\nisShowingDiff=false\nisDiffReady=false]
        DS[staged\nhasActiveDiff=true\nisShowingDiff=false\nisDiffReady=true]
        DW[showing\nhasActiveDiff=true\nisShowingDiff=true\nisDiffReady=true]

        DN -->|setProposedChanges| DW
        DW -->|toggleDiffView| DS
        DS -->|toggleDiffView| DW
        DW -->|clearDiff| DN
        DS -->|clearDiff| DN
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    subgraph ExecutionStore["Execution Store"]
        EI[idle\nisExecuting=false\nisDebugging=false]
        ER[running\nisExecuting=true\nisDebugging=false]
        ED[debugging\nisExecuting=true\nisDebugging=true]

        EI -->|setIsExecuting true| ER
        ER -->|setIsDebugging true| ED
        ED -->|setIsDebugging false| ER
        ER -->|setIsExecuting false| EI
        ED -->|setIsExecuting false| EI
        ED -->|setIsExecuting true\n+ clearRunPath| ED
    end

    subgraph DiffStore["Workflow-Diff Store"]
        DN[none\nhasActiveDiff=false\nisShowingDiff=false\nisDiffReady=false]
        DS[staged\nhasActiveDiff=true\nisShowingDiff=false\nisDiffReady=true]
        DW[showing\nhasActiveDiff=true\nisShowingDiff=true\nisDiffReady=true]

        DN -->|setProposedChanges| DW
        DW -->|toggleDiffView| DS
        DS -->|toggleDiffView| DW
        DW -->|clearDiff| DN
        DS -->|clearDiff| DN
    end
Loading

Reviews (2): Last reviewed commit: "refactor(stores): model execution and wo..." | Re-trigger Greptile

Comment thread apps/sim/stores/execution/types.ts
@waleedlatif1 waleedlatif1 force-pushed the refactor/store-status-enums branch from 40ed2ec to ad97d21 Compare June 24, 2026 16:39
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ad97d21. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1 waleedlatif1 merged commit b52fcc0 into staging Jun 24, 2026
28 checks passed
@waleedlatif1 waleedlatif1 deleted the refactor/store-status-enums branch June 24, 2026 17:45
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.

1 participant