Skip to content

Conversation

@Myestery
Copy link
Collaborator

@Myestery Myestery commented Dec 2, 2025

When importing a workflow file that has the same name as an existing open workflow, create a new tab with a unique suffix (2), (3), etc. instead of silently failing or replacing the existing workflow.

  • Add forceNew parameter to createTemporary() in workflowStore
  • Always create new temporary workflow when importing via file picker
  • Remove logic that looked up persisted workflows by name during import
Screen.Recording.2025-12-02.at.22.03.48.mov

┆Issue is synchronized with this Notion page by Unito

When importing a workflow file that has the same name as an existing
open workflow, create a new tab with a unique suffix (2), (3), etc.
instead of silently failing or replacing the existing workflow.

- Add forceNew parameter to createTemporary() in workflowStore
- Always create new temporary workflow when importing via file picker
- Remove logic that looked up persisted workflows by name during import
@Myestery Myestery requested a review from a team as a code owner December 2, 2025 21:01
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Dec 2, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

📝 Walkthrough

Walkthrough

Prefers reopening an existing persisted workflow by path during restoration (resetting it and restoring its changeTracker); if none matches, creates a fresh temporary workflow via workflowStore.createNewTemporary(...). workflowStore.createTemporary was changed to attempt reuse; createNewTemporary always produces a new workflow.

Changes

Cohort / File(s) Summary
Workflow service: restoration/path-based load
src/platform/workflow/core/services/workflowService.ts
Switched restoration from value-based to path-based: when a valid persisted workflow path is provided and that workflow exists but isn't loaded, open it, apply workflowData with reset, and restore changeTracker. If no suitable persisted workflow exists, call workflowStore.createNewTemporary(...) to create a fresh temporary workflow.
Workflow store: temporary workflow creation API
src/platform/workflow/management/stores/workflowStore.ts
Added createNewWorkflow internal helper and new public createNewTemporary(path?: string, workflowData?: ComfyWorkflowJSON). Reworked createTemporary(path?, workflowData?) to try reusing an existing loaded/persisted workflow (by filename/path and changeTracker presence) and fall back to createNewWorkflow when reuse isn't possible. Export/interface updated to include createNewTemporary.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch allow-multiple-same-workflow-names

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

@github-actions
Copy link

github-actions bot commented Dec 2, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/03/2025, 02:40:29 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 2, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/03/2025, 02:48:53 AM UTC

📈 Summary

  • Total Tests: 494
  • Passed: 480 ✅
  • Failed: 0
  • Flaky: 5 ⚠️
  • Skipped: 9 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 471 / ❌ 0 / ⚠️ 5 / ⏭️ 9
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 2, 2025

Bundle Size Report

Summary

  • Raw size: 17 MB baseline 17 MB — 🔴 +563 B
  • Gzip: 3.37 MB baseline 3.37 MB — 🔴 +2 B
  • Brotli: 2.59 MB baseline 2.59 MB — 🟢 -354 B
  • Bundles: 97 current • 97 baseline • 37 added / 37 removed

Category Glance
App Entry Points 🔴 +563 B (3.21 MB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · Graph Workspace ⚪ 0 B (929 kB) · Panels & Settings ⚪ 0 B (298 kB) · UI Components ⚪ 0 B (169 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.21 MB (baseline 3.21 MB) • 🔴 +563 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-lXafyvTr.js (new) 2.99 MB 🔴 +2.99 MB 🔴 +621 kB 🔴 +472 kB
assets/index-DcGew2Zq.js (removed) 2.98 MB 🟢 -2.98 MB 🟢 -621 kB 🟢 -472 kB
assets/index-DP0pwRlL.js (new) 223 kB 🔴 +223 kB 🔴 +47.5 kB 🔴 +39.2 kB
assets/index-wcwD5H-V.js (removed) 223 kB 🟢 -223 kB 🟢 -47.5 kB 🟢 -39.1 kB
assets/index-DqMqwcSX.js (new) 345 B 🔴 +345 B 🔴 +244 B 🔴 +198 B
assets/index-MmMQ31KT.js (removed) 345 B 🟢 -345 B 🟢 -246 B 🟢 -200 B

Status: 3 added / 3 removed

Graph Workspace — 929 kB (baseline 929 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-CW9_iM8d.js (new) 929 kB 🔴 +929 kB 🔴 +180 kB 🔴 +138 kB
assets/GraphView-pFhvc8d2.js (removed) 929 kB 🟢 -929 kB 🟢 -180 kB 🟢 -138 kB

Status: 1 added / 1 removed

Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-CyoXMkaj.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.89 kB
assets/UserSelectView-rzxV6RrT.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.9 kB

Status: 1 added / 1 removed

Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-CUv2vr7X.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/CreditsPanel-DKsXZrEm.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.5 kB
assets/KeybindingPanel-D4DUB2m5.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.01 kB
assets/KeybindingPanel-DBvDPFXg.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.02 kB
assets/ExtensionPanel-65Xsjp3m.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.26 kB
assets/ExtensionPanel-CctrSxBK.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.58 kB 🟢 -2.26 kB
assets/AboutPanel-CVDJM8I8.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/AboutPanel-pptP42R4.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/ServerConfigPanel-CmdoePt8.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/ServerConfigPanel-UKL5UI13.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/UserPanel-BXiSvbOs.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/UserPanel-dQCu5ExV.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 169 kB (baseline 169 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-BCyX9MtF.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.52 kB 🟢 -7.31 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-CiQpuNDC.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.52 kB 🔴 +7.32 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CZMHwGFN.js (removed) 47.6 kB 🟢 -47.6 kB 🟢 -10.3 kB 🟢 -8.9 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-Daf4gc37.js (new) 47.6 kB 🔴 +47.6 kB 🔴 +10.3 kB 🔴 +8.89 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-CfLtBC7o.js (removed) 39.4 kB 🟢 -39.4 kB 🟢 -9.08 kB 🟢 -7.96 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-CLAlHGIF.js (new) 39.4 kB 🔴 +39.4 kB 🔴 +9.08 kB 🔴 +7.96 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-C7XM10Wv.js (new) 12.9 kB 🔴 +12.9 kB 🔴 +3.37 kB 🔴 +2.98 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-UIq99ecG.js (removed) 12.9 kB 🟢 -12.9 kB 🟢 -3.37 kB 🟢 -2.97 kB
assets/ComfyQueueButton-B48FdeyZ.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.22 kB
assets/ComfyQueueButton-B4j4vZ2h.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.22 kB
assets/MediaTitle.vue_vue_type_script_setup_true_lang-B-hHv3Fr.js (removed) 897 B 🟢 -897 B 🟢 -502 B 🟢 -432 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-vxZTu1qS.js (new) 897 B 🔴 +897 B 🔴 +502 B 🔴 +429 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-B4R5m1qI.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-C9RSl9Jc.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-C-GzTNBl.js 2 kB 2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-CVUEPytQ.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/keybindingService-XqquAn8A.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.58 kB
assets/audioService-BXO9zome.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +955 B 🔴 +818 B
assets/audioService-OmKGvfLN.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -958 B 🟢 -825 B
assets/serverConfigStore-W1zhjkBH.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-BHgK3pda.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +650 B 🔴 +543 B
assets/audioUtils-CMFC4MGG.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -652 B 🟢 -546 B
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-BCOr5Gfm.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-DsoOPVgr.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-CjsaCDb8.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-CzjUILzD.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-BEWVLQIi.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-ChfJg1-a.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.23 kB 🔴 +4.63 kB
assets/WidgetRecordAudio-o7qk2M3m.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.24 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-CABd_mtA.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.4 kB 🔴 +3.04 kB
assets/AudioPreviewPlayer-DbI94_ev.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.4 kB 🟢 -3.04 kB
assets/WidgetGalleria-C-dbjBGM.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.45 kB 🟢 -1.3 kB
assets/WidgetGalleria-UKKE7y5a.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.45 kB 🔴 +1.3 kB
assets/WidgetColorPicker-CdBaa78W.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-DVIzXQdE.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetMarkdown-0K0kX2-I.js (removed) 3.1 kB 🟢 -3.1 kB 🟢 -1.29 kB 🟢 -1.13 kB
assets/WidgetMarkdown-CLVsGmfr.js (new) 3.1 kB 🔴 +3.1 kB 🔴 +1.29 kB 🔴 +1.13 kB
assets/WidgetAudioUI-BjCSDcGS.js (new) 2.82 kB 🔴 +2.82 kB 🔴 +1.12 kB 🔴 +1.02 kB
assets/WidgetAudioUI-ClUdB5ZB.js (removed) 2.82 kB 🟢 -2.82 kB 🟢 -1.12 kB 🟢 -1.01 kB
assets/WidgetTextarea-DO4oJ3Ll.js (removed) 2.48 kB 🟢 -2.48 kB 🟢 -1.01 kB 🟢 -903 B
assets/WidgetTextarea-mC90msXh.js (new) 2.48 kB 🔴 +2.48 kB 🔴 +1.01 kB 🔴 +884 B
assets/WidgetInputText-DUMzViqq.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +917 B 🔴 +850 B
assets/WidgetInputText-qi2PtuwS.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -918 B 🟢 -845 B
assets/MediaImageBottom-CuyLXEVy.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -742 B 🟢 -645 B
assets/MediaImageBottom-VUum3kca.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +743 B 🔴 +645 B
assets/MediaAudioBottom-BHKTy7eZ.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -742 B 🟢 -655 B
assets/MediaAudioBottom-BKGRKLJw.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +743 B 🔴 +655 B
assets/MediaVideoBottom-BAc88bRQ.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -741 B 🟢 -653 B
assets/MediaVideoBottom-Bu5yZGyV.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +741 B 🔴 +657 B
assets/Media3DBottom-BssROnTo.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +731 B 🔴 +649 B
assets/Media3DBottom-M20XNT-L.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -734 B 🟢 -648 B
assets/Media3DTop-B1l-NMg8.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +762 B 🔴 +652 B
assets/Media3DTop-DpW9W3RZ.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -766 B 🟢 -655 B
assets/WidgetSelect-naBFWJBe.js (removed) 655 B 🟢 -655 B 🟢 -342 B 🟢 -288 B
assets/WidgetSelect-U9qN1Nuv.js (new) 655 B 🔴 +655 B 🔴 +342 B 🔴 +289 B
assets/WidgetInputNumber-mPq1pi71.js (new) 595 B 🔴 +595 B 🔴 +331 B 🔴 +278 B
assets/WidgetInputNumber-qUiY3mfj.js (removed) 595 B 🟢 -595 B 🟢 -330 B 🟢 -276 B
assets/Load3D-CkczT795.js (new) 424 B 🔴 +424 B 🔴 +266 B 🔴 +223 B
assets/Load3D-CXTvX3cK.js (removed) 424 B 🟢 -424 B 🟢 -269 B 🟢 -223 B
assets/WidgetLegacy-CsBMYOMF.js (removed) 364 B 🟢 -364 B 🟢 -237 B 🟢 -198 B
assets/WidgetLegacy-etNp97Ug.js (new) 364 B 🔴 +364 B 🔴 +235 B 🔴 +193 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-B_r9Y3e-.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-Df0PRhSp.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-_g8aBAAL.js 2.76 kB 2.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-8e6QYQW0.js 283 kB 283 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-A_9dx4yn.js 304 kB 304 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BbD3HDi7.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BOJhIPft.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C-Pw33mW.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-ChLyG0UJ.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CUVPxA4l.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dx5Y4xrW.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JqO5mNmW.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-f0b59iz3.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-65U3rWW6.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-C53mIaDW.js 1.58 kB 1.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 17 added / 17 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/platform/workflow/management/stores/workflowStore.ts (1)

368-372: createTemporary forceNew flag + conflict-free paths look correct; consider documenting the new param

The new forceNew parameter, combined with getUnconflictedPath, cleanly separates behaviors:

  • forceNew === true: always creates a fresh ComfyWorkflow with a unique path under ComfyWorkflow.basePath, enabling multiple open tabs with the same base filename without clobbering workflowLookup.
  • forceNew === false: preserves the prior reuse path by locating an existing workflow by fullFilename and, when it’s a non-workflows/ directory with a changeTracker, resetting that tracker with workflowData and returning the existing instance.

This matches the PR goal while keeping older call sites' semantics intact.

Two small follow-ups you may want to consider:

  • Update the local WorkflowStore interface’s createTemporary signature to include the optional forceNew?: boolean parameter so any consumers typed against WorkflowStore (rather than ReturnType<typeof useWorkflowStore>) get accurate IntelliSense and avoid confusion.
  • Add a focused test around createTemporary with forceNew: true to assert that repeated calls with the same path yield distinct paths (e.g. foo.json, foo (2).json) and don’t reuse the same workflow instance.

Also applies to: 376-390

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e887d69 and 4e9a4e3.

📒 Files selected for processing (2)
  • src/platform/workflow/core/services/workflowService.ts (2 hunks)
  • src/platform/workflow/management/stores/workflowStore.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/stores/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/stores/**/*.{ts,tsx}: Maintain clear public interfaces and restrict extension access in stores
Use TypeScript for type safety in state management stores

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/stores/*Store.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores with the *Store.ts suffix

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/workflow/core/services/workflowService.ts
🧠 Learnings (3)
📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:14.779Z
Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue files

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : When writing tests for subgraph-related code, always import from the barrel export at `@/lib/litegraph/src/litegraph` to avoid circular dependency issues

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
🧬 Code graph analysis (1)
src/platform/workflow/management/stores/workflowStore.ts (2)
src/stores/userFileStore.ts (1)
  • createTemporary (64-66)
src/platform/workflow/validation/schemas/workflowSchema.ts (1)
  • ComfyWorkflowJSON (456-458)
🪛 ESLint
src/platform/workflow/core/services/workflowService.ts

[error] 10-10: Unable to resolve path to module '@/platform/workflow/management/stores/workflowStore'.

(import-x/no-unresolved)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (2)
src/platform/workflow/core/services/workflowService.ts (2)

9-10: Type-only ComfyWorkflow import looks good; check ESLint resolver config

Switching to import type { ComfyWorkflow } while keeping useWorkflowStore as a value import is correct and avoids pulling the class into the runtime bundle unnecessarily. Static analysis, however, reports import-x/no-unresolved for this module path; please confirm that the ESLint import resolver is configured to understand the @ alias and that the path matches the actual file location so pnpm lint passes cleanly.


315-319: Force creation of a new temporary workflow for string/null loads

Routing the value === null || typeof value === 'string' case through workflowStore.createTemporary(path ? appendJsonExt(path) : undefined, workflowData, true) ensures that imports and other string-based loads always get a fresh temporary workflow with a conflict-free path, which aligns with the “multiple tabs with same name” goal. The use of appendJsonExt is also consistent with save paths elsewhere.

Please sanity-check the flows that hit this branch (e.g. file picker imports, loadApiJson, importA1111, and duplicateWorkflow) to confirm they now open separate tabs with suffixes instead of reusing or overwriting an existing one.

When importing a workflow file that has the same name as an existing
open workflow, create a new tab with a unique suffix (2), (3), etc.
instead of silently failing or replacing the existing workflow.

- Add forceNew parameter to createTemporary() in workflowStore
- Always create new temporary workflow when importing via file picker
- Remove logic that looked up persisted workflows by name during import
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/platform/workflow/core/services/workflowService.ts (1)

333-337: Consider adding clarity for the boolean parameter.

The true argument represents forceNew per the PR changes. While the implementation is correct, consider improving readability:

       const tempWorkflow = workflowStore.createTemporary(
         path ? appendJsonExt(path) : undefined,
         workflowData,
-        true
+        /* forceNew */ true
       )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e9a4e3 and 8299a20.

📒 Files selected for processing (1)
  • src/platform/workflow/core/services/workflowService.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/workflow/core/services/workflowService.ts
🧠 Learnings (3)
📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:14.779Z
Learning: Applies to **/*.{ts,tsx,vue} : Use `const settingStore = useSettingStore()` and `settingStore.get('Comfy.SomeSetting')` to retrieve settings in TypeScript/Vue files

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : When writing tests for subgraph-related code, always import from the barrel export at `@/lib/litegraph/src/litegraph` to avoid circular dependency issues

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
🪛 ESLint
src/platform/workflow/core/services/workflowService.ts

[error] 10-10: Unable to resolve path to module '@/platform/workflow/management/stores/workflowStore'.

(import-x/no-unresolved)

🪛 GitHub Actions: CI: Size Data
src/platform/workflow/core/services/workflowService.ts

[error] 318-318: TS1361: 'ComfyWorkflow' cannot be used as a value because it was imported using 'import type'.

🪛 GitHub Check: collect
src/platform/workflow/core/services/workflowService.ts

[failure] 318-318:
'ComfyWorkflow' cannot be used as a value because it was imported using 'import type'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: deploy-and-comment
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: test
🔇 Additional comments (1)
src/platform/workflow/core/services/workflowService.ts (1)

315-331: Logic for workflow restoration vs. re-import looks correct.

The conditional properly distinguishes between:

  1. Restoration case (persisted but not loaded) → reuse existing workflow
  2. Re-import case (already loaded) → fall through to create new tab with suffix

Once the import issue on line 9 is fixed, this logic should work as intended.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/platform/workflow/core/services/workflowService.ts (1)

318-333: Consider adding error handling for the restoration flow.

The path-based restoration logic correctly implements the PR objective. However, the async operations (openWorkflow, reset, restore) could fail and there's no error handling to gracefully recover or inform the user.

Consider wrapping the restoration flow in a try-catch block:

       if (existingWorkflow?.isPersisted && !existingWorkflow.isLoaded) {
+        try {
           const loadedWorkflow =
             await workflowStore.openWorkflow(existingWorkflow)
           loadedWorkflow.changeTracker.reset(workflowData)
           loadedWorkflow.changeTracker.restore()
           return
+        } catch (error) {
+          console.error('Failed to restore workflow:', error)
+          // Fall through to create new temporary workflow
+        }
       }

Based on coding guidelines requiring proper error handling in services.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8299a20 and 50a1ba4.

📒 Files selected for processing (1)
  • src/platform/workflow/core/services/workflowService.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/platform/workflow/core/services/workflowService.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/workflow/core/services/workflowService.ts
🧠 Learnings (1)
📚 Learning: 2025-11-24T19:47:14.779Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:14.779Z
Learning: Applies to **/*.{ts,tsx} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • src/platform/workflow/core/services/workflowService.ts
🧬 Code graph analysis (1)
src/platform/workflow/core/services/workflowService.ts (2)
src/platform/workflow/management/stores/workflowStore.ts (1)
  • ComfyWorkflow (35-139)
packages/shared-frontend-utils/src/formatUtil.ts (1)
  • appendJsonExt (28-33)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
🔇 Additional comments (1)
src/platform/workflow/core/services/workflowService.ts (1)

9-12: Import fix correctly resolves the previous type-only import issue.

The runtime import of ComfyWorkflow now properly supports both type annotations and access to the static basePath property at line 320, addressing the TS1361 error flagged in the previous review.

…n parameter

Replace boolean parameter with two distinct methods (createTemporary and createNewTemporary)
to make intent explicit and improve code readability. This addresses code review feedback
about avoiding bare boolean arguments as function parameters.
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Dec 3, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/platform/workflow/management/stores/workflowStore.ts (1)

401-418: Use strict equality and clarify the comment.

Two minor suggestions:

  1. Line 404: Use === instead of == for strict equality comparison
  2. The comment "Try to reuse existing persisted workflow" is misleading — the condition actually reuses loaded workflows that are not in the workflows directory
-    // Try to reuse existing persisted workflow with the same filename
+    // Try to reuse an existing loaded workflow with the same filename
+    // that is not stored in the workflows directory
     if (path && workflowData) {
       const existingWorkflow = workflows.value.find(
-        (w) => w.fullFilename == path
+        (w) => w.fullFilename === path
       )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50a1ba4 and d119391.

📒 Files selected for processing (2)
  • src/platform/workflow/core/services/workflowService.ts (1 hunks)
  • src/platform/workflow/management/stores/workflowStore.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
src/**/stores/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/stores/**/*.{ts,tsx}: Maintain clear public interfaces and restrict extension access in stores
Use TypeScript for type safety in state management stores

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
  • src/platform/workflow/core/services/workflowService.ts
**/stores/*Store.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores with the *Store.ts suffix

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/workflow/core/services/workflowService.ts
🧬 Code graph analysis (1)
src/platform/workflow/management/stores/workflowStore.ts (3)
src/platform/workflow/validation/schemas/workflowSchema.ts (1)
  • ComfyWorkflowJSON (456-458)
src/stores/queueStore.ts (1)
  • workflow (314-316)
src/stores/userFileStore.ts (1)
  • createTemporary (64-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: setup
  • GitHub Check: test
🔇 Additional comments (4)
src/platform/workflow/management/stores/workflowStore.ts (3)

175-178: LGTM!

The createNewTemporary method signature is correctly added to the WorkflowStore interface, matching the implementation signature.


372-391: LGTM!

Good refactoring to centralize workflow creation logic into a dedicated helper function. This reduces code duplication between createTemporary and createNewTemporary.


420-431: LGTM!

The createNewTemporary method correctly implements the PR objective by always creating a new workflow with a unique path suffix, without attempting to reuse existing workflows. This is the right approach for the import use case.

src/platform/workflow/core/services/workflowService.ts (1)

317-341: LGTM! Clear logic for distinguishing restoration vs re-import cases.

The implementation correctly handles the two scenarios:

  1. Restoration case (persisted but not loaded): Reuses the existing workflow and restores its change tracker state
  2. Re-import case (already loaded or not persisted): Creates a new temporary workflow with a unique suffix via createNewTemporary

This aligns well with the PR objective of allowing workflows with the same name to be opened as new tabs.

Copy link
Contributor

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

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

LGTM. I thought of some other edge cases, but after testing manually, it seems they all still work properly.

@Myestery Myestery enabled auto-merge (squash) December 3, 2025 02:44
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/platform/workflow/management/stores/workflowStore.ts (1)

372-432: Temporary workflow creation/reuse logic meets requirements; consider tightening reuse predicate

The refactor into createNewWorkflow plus getUnconflictedPath nicely centralizes temporary workflow instantiation and guarantees unique paths for conflicting names, which aligns with the “(2), (3), …” tab requirement.

In createTemporary, the reuse branch:

  • looks up by fullFilename,
  • requires a changeTracker,
  • and excludes items whose directory starts with the workflows base.

This will happily reuse any loaded ComfyWorkflow whose directory does not start with 'workflows', which is fine if and only if those are truly temporary workflows you want to overwrite (and not, say, persisted subgraph files that also use ComfyWorkflow). If that’s not guaranteed, it would be safer to additionally require the candidate to be temporary and/or explicitly scoped under the expected base path.

Also, note that reuse only occurs when both path and workflowData are provided; any caller passing just path will now always get a new workflow. Please double‑check that all intended reuse call sites do pass workflowData.

If you want to tighten the reuse guard and avoid unnecessary getUnconflictedPath work, something like this keeps the same behavior but narrows the match:

-  const createTemporary = (path?: string, workflowData?: ComfyWorkflowJSON) => {
-    const fullPath = getUnconflictedPath(
-      ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
-    )
-
-    // Try to reuse an existing loaded workflow with the same filename
-    // that is not stored in the workflows directory
-    if (path && workflowData) {
+  const createTemporary = (path?: string, workflowData?: ComfyWorkflowJSON) => {
+    // Try to reuse an existing loaded temporary workflow with the same filename
+    if (path && workflowData) {
       const existingWorkflow = workflows.value.find(
         (w) => w.fullFilename === path
       )
       if (
         existingWorkflow?.changeTracker &&
+        existingWorkflow.isTemporary &&
         !existingWorkflow.directory.startsWith(
           ComfyWorkflow.basePath.slice(0, -1)
         )
       ) {
         existingWorkflow.changeTracker.reset(workflowData)
         return existingWorkflow
       }
     }
 
-    return createNewWorkflow(fullPath, workflowData)
+    const fullPath = getUnconflictedPath(
+      ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
+    )
+    return createNewWorkflow(fullPath, workflowData)
   }

This keeps the new behavior but ensures you only ever reuse loaded temporary workflows and avoids computing an unconflicted path when you’re going to reuse an existing instance anyway.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d119391 and 43b5f81.

📒 Files selected for processing (1)
  • src/platform/workflow/management/stores/workflowStore.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/stores/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/stores/**/*.{ts,tsx}: Maintain clear public interfaces and restrict extension access in stores
Use TypeScript for type safety in state management stores

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
**/stores/*Store.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores with the *Store.ts suffix

Files:

  • src/platform/workflow/management/stores/workflowStore.ts
🧬 Code graph analysis (1)
src/platform/workflow/management/stores/workflowStore.ts (1)
src/stores/userFileStore.ts (1)
  • createTemporary (64-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
  • GitHub Check: setup
🔇 Additional comments (2)
src/platform/workflow/management/stores/workflowStore.ts (2)

171-178: New createNewTemporary interface entry is consistent

The WorkflowStore interface now explicitly advertises createNewTemporary with the same signature as the implementation and returned store, which cleanly separates "maybe reuse" (createTemporary) from "always new" usage. No issues here.


802-816: createNewTemporary is correctly exposed and already being used appropriately

The distinction between createTemporary (with reuse logic for same-filename workflows not in the workflows directory) and createNewTemporary (always creates new) is intentional and well-documented. Current call sites are using the correct function: workflowService.ts uses createNewTemporary for imports/file-picker flows where always-new semantics are required, while workflowActionsService.ts and useJobMenu.ts use createTemporary where session-level reuse is appropriate. No migration is needed—the separation of concerns is properly implemented.

@Myestery Myestery merged commit c698838 into main Dec 3, 2025
26 checks passed
@Myestery Myestery deleted the allow-multiple-same-workflow-names branch December 3, 2025 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants