improvement(forking): fork time ux#5348
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Execution & APIs: Workspace fork/sync: Promote is gated so sync cannot proceed while references would clear in the target. The diff annotates UI: The promote modal splits Blocking sync vs informational Will be cleared, disables Sync until blockers are resolved, handles server Reviewed by Cursor Bugbot for commit 1aec450. Configure here. |
Greptile SummaryThis PR improves the fork/sync UX across four axes: (1) copying non-referenced source resources during sync so users can bring along tables, KBs, files, and tools that exist in the source but are not wired into any workflow; (2) a zero-cleared-refs gate that blocks sync when any reference would clear in a target workflow, paired with an authoritative in-transaction re-check (TOCTOU guard); (3) a fix for the
Confidence Score: 4/5Safe to merge; the auth fix, workspace-scoping guard, and zero-cleared-refs gate are additive correctness improvements with no destructive side effects on the happy path. Three areas need a second look: the clearDependentsOnRemap BFS per-key visited set makes the MCP tool-selector exemption fragile for future block structures; required: true in the mapping service is only correct if forkRequiredPending treats copy selection as equivalent to mapping (not verifiable from the diff); and search removal from the copy picker is a concrete usability regression for large workspaces. apps/sim/lib/workspaces/fork/remap/remap-references.ts (BFS visited-set scope), apps/sim/lib/workspaces/fork/mapping/mapping-service.ts (required: true behavioural change), apps/sim/app/workspace/.../fork-resource-picker.tsx (search removal) Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Promote Modal
participant Diff as GET /fork/diff
participant Promote as POST /fork/promote
participant Gate as collectForkSyncBlockers
participant Copy as copyPromoteUnmappedResources
participant Write as Workflow Write Loop
UI->>Diff: fetch diff (direction, otherWorkspaceId)
Diff-->>UI: plan + copyableUnmapped + clearedRefs annotated
UI->>UI: split clearedRefs into blockers + informational
Note over UI: Sync disabled while blockers.length > 0
UI->>Promote: POST copyResources + mappings
Promote->>Promote: buildPromoteCopySelection
Promote->>Gate: collectForkSyncBlockers with gateResolver
alt blockers found
Gate-->>Promote: ForkSyncBlocker[]
Promote-->>UI: blocked cleared-refs
UI->>UI: toast + await diff refetch
else zero blockers
Gate-->>Promote: empty
Promote->>Copy: copy selected resources
Copy-->>Promote: augmented resolver
Promote->>Write: remap + write workflows
Write-->>Promote: snapshots + blockPairs
Promote-->>UI: promoteRunId + stats
end
%%{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"}}}%%
sequenceDiagram
participant UI as Promote Modal
participant Diff as GET /fork/diff
participant Promote as POST /fork/promote
participant Gate as collectForkSyncBlockers
participant Copy as copyPromoteUnmappedResources
participant Write as Workflow Write Loop
UI->>Diff: fetch diff (direction, otherWorkspaceId)
Diff-->>UI: plan + copyableUnmapped + clearedRefs annotated
UI->>UI: split clearedRefs into blockers + informational
Note over UI: Sync disabled while blockers.length > 0
UI->>Promote: POST copyResources + mappings
Promote->>Promote: buildPromoteCopySelection
Promote->>Gate: collectForkSyncBlockers with gateResolver
alt blockers found
Gate-->>Promote: ForkSyncBlocker[]
Promote-->>UI: blocked cleared-refs
UI->>UI: toast + await diff refetch
else zero blockers
Gate-->>Promote: empty
Promote->>Copy: copy selected resources
Copy-->>Promote: augmented resolver
Promote->>Write: remap + write workflows
Write-->>Promote: snapshots + blockPairs
Promote-->>UI: promoteRunId + stats
end
Reviews (1): Last reviewed commit: "improvement(forking): fork time ux" | Re-trigger Greptile |
Summary
Fork time UX improvements.
Type of Change
Testing
Tested manually
Checklist