Skip to content

feat: add per-tab workspace authentication infrastructure#8073

Merged
simula-r merged 19 commits intomainfrom
feat/workspace-auth-infrastructure
Jan 16, 2026
Merged

feat: add per-tab workspace authentication infrastructure#8073
simula-r merged 19 commits intomainfrom
feat/workspace-auth-infrastructure

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Jan 15, 2026

Summary

Add workspace authentication composables and types for per-tab workspace isolation. This infrastructure enables users to work in different workspaces in different browser tabs.

Changes

  • useWorkspaceAuth composable - workspace token management
    • Exchange Firebase token for workspace-scoped JWT via POST /api/auth/token
    • Auto-refresh tokens 5 minutes before expiry
    • Per-tab sessionStorage caching
  • useWorkspaceSwitch composable - workspace switching with unsaved changes confirmation
  • WorkspaceWithRole/WorkspaceTokenResponse types - aligned with backend API
  • firebaseAuthStore.getAuthHeader() - prioritizes workspace tokens over Firebase tokens
  • useSessionCookie - uses Firebase token directly (getIdToken()) since getAuthHeader() now returns workspace token

Backend Dependency

  • POST /api/auth/token - exchange Firebase token for workspace token
  • GET /api/workspaces - list user's workspaces

Related

┆Issue is synchronized with this Notion page by Unito

@christian-byrne christian-byrne requested a review from a team as a code owner January 15, 2026 05:23
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jan 15, 2026
@github-actions
Copy link

github-actions bot commented Jan 15, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 01/16/2026, 01:14:51 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Jan 15, 2026

🎭 Playwright Tests: ⚠️ Passed with flaky tests

Results: 503 passed, 0 failed, 2 flaky, 8 skipped (Total: 513)

❌ Failed Tests

📊 Browser Reports
  • chromium: View Report (✅ 493 / ❌ 0 / ⚠️ 1 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 7 / ❌ 0 / ⚠️ 1 / ⏭️ 0)

@github-actions
Copy link

github-actions bot commented Jan 15, 2026

Bundle Size Report

Summary

  • Raw size: 19.8 MB baseline 19.8 MB — 🔴 +1.64 kB
  • Gzip: 4.04 MB baseline 4.03 MB — 🔴 +450 B
  • Brotli: 3.08 MB baseline 3.08 MB — 🔴 +634 B
  • Bundles: 99 current • 99 baseline • 38 added / 38 removed

Category Glance
App Entry Points 🔴 +1.48 kB (3.35 MB) · UI Components 🔴 +156 B (209 kB) · Vendor & Third-Party ⚪ 0 B (9.34 MB) · Other ⚪ 0 B (5.37 MB) · Graph Workspace ⚪ 0 B (1.15 MB) · Panels & Settings ⚪ 0 B (372 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.35 MB (baseline 3.34 MB) • 🔴 +1.48 kB

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-B_JuSexx.js (new) 3.14 MB 🔴 +3.14 MB 🔴 +659 kB 🔴 +500 kB
assets/index-CTdE0r-A.js (removed) 3.14 MB 🟢 -3.14 MB 🟢 -658 kB 🟢 -500 kB
assets/index-Ch-M9KuX.js (new) 200 kB 🔴 +200 kB 🔴 +44.1 kB 🔴 +36.4 kB
assets/index-DOTBadGH.js (removed) 200 kB 🟢 -200 kB 🟢 -44.1 kB 🟢 -36.4 kB
assets/index-Bon55rL6.js (removed) 345 B 🟢 -345 B 🟢 -245 B 🟢 -237 B
assets/index-BWxdoeoj.js (new) 345 B 🔴 +345 B 🔴 +240 B 🔴 +209 B

Status: 3 added / 3 removed

Graph Workspace — 1.15 MB (baseline 1.15 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BqoD_prL.js (removed) 1.15 MB 🟢 -1.15 MB 🟢 -220 kB 🟢 -166 kB
assets/GraphView-C-sqC7E4.js (new) 1.15 MB 🔴 +1.15 MB 🔴 +220 kB 🔴 +166 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-IMxquKAk.js (new) 6.66 kB 🔴 +6.66 kB 🔴 +2.16 kB 🔴 +1.91 kB
assets/UserSelectView-K5Sfl3Ba.js (removed) 6.66 kB 🟢 -6.66 kB 🟢 -2.16 kB 🟢 -1.92 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-BykppL_K.js (new) 25.2 kB 🔴 +25.2 kB 🔴 +5.76 kB 🔴 +5.02 kB
assets/LegacyCreditsPanel-De6WAg1h.js (removed) 25.2 kB 🟢 -25.2 kB 🟢 -5.76 kB 🟢 -5.03 kB
assets/KeybindingPanel-DdEJetj-.js (removed) 14.9 kB 🟢 -14.9 kB 🟢 -3.59 kB 🟢 -3.13 kB
assets/KeybindingPanel-hGCPGbQG.js (new) 14.9 kB 🔴 +14.9 kB 🔴 +3.59 kB 🔴 +3.14 kB
assets/ExtensionPanel-Cf_woTBZ.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.63 kB 🔴 +2.31 kB
assets/ExtensionPanel-DWqlmjiv.js (removed) 11.1 kB 🟢 -11.1 kB 🟢 -2.63 kB 🟢 -2.31 kB
assets/AboutPanel-6M5JoC1_.js (new) 9.2 kB 🔴 +9.2 kB 🔴 +2.47 kB 🔴 +2.22 kB
assets/AboutPanel-BDr43kul.js (removed) 9.2 kB 🟢 -9.2 kB 🟢 -2.47 kB 🟢 -2.22 kB
assets/ServerConfigPanel-B1TLxbyI.js (new) 7.55 kB 🔴 +7.55 kB 🔴 +2.06 kB 🔴 +1.83 kB
assets/ServerConfigPanel-BpQW2rc7.js (removed) 7.55 kB 🟢 -7.55 kB 🟢 -2.06 kB 🟢 -1.82 kB
assets/UserPanel-CHjiob4S.js (removed) 6.92 kB 🟢 -6.92 kB 🟢 -1.8 kB 🟢 -1.58 kB
assets/UserPanel-CxGJm3bB.js (new) 6.92 kB 🔴 +6.92 kB 🔴 +1.81 kB 🔴 +1.58 kB
assets/settings-BGQfQzTx.js 25.6 kB 25.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BVE4KHTw.js 22.7 kB 22.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BVtpJmlU.js 30.9 kB 30.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C2aO00Dz.js 28.6 kB 28.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Cm3ieBXR.js 27.8 kB 27.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CzQKMdK3.js 26.2 kB 26.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CzYUIUnL.js 27.1 kB 27.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DwKpL7jw.js 26.3 kB 26.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DX8feV4n.js 25.3 kB 25.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-mWzYycGc.js 22 kB 22 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-U4AdZ8Rl.js 34.9 kB 34.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 209 kB (baseline 209 kB) • 🔴 +156 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LazyImage.vue_vue_type_script_setup_true_lang-ds0Wz_ox.js (new) 69.7 kB 🔴 +69.7 kB 🔴 +14.2 kB 🔴 +12.3 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-GUCUijeW.js (removed) 69.6 kB 🟢 -69.6 kB 🟢 -14.2 kB 🟢 -12.3 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-BLWW1v3T.js (new) 56.4 kB 🔴 +56.4 kB 🔴 +8.78 kB 🔴 +7.54 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-DdaampcC.js (removed) 56.4 kB 🟢 -56.4 kB 🟢 -8.78 kB 🟢 -7.54 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-5CJnRKvT.js (removed) 48.1 kB 🟢 -48.1 kB 🟢 -10.4 kB 🟢 -8.99 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CYY3pk5W.js (new) 48.1 kB 🔴 +48.1 kB 🔴 +10.4 kB 🔴 +9 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-DIRKH2Ub.js (removed) 16.4 kB 🟢 -16.4 kB 🟢 -4.11 kB 🟢 -3.64 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-KBRtkmWQ.js (new) 16.4 kB 🔴 +16.4 kB 🔴 +4.11 kB 🔴 +3.64 kB
assets/ComfyQueueButton-DtI8BmeT.js (new) 8.87 kB 🔴 +8.87 kB 🔴 +2.59 kB 🔴 +2.31 kB
assets/ComfyQueueButton-Ru1oOPTL.js (removed) 8.87 kB 🟢 -8.87 kB 🟢 -2.6 kB 🟢 -2.32 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-B8x6BwMS.js (new) 3.75 kB 🔴 +3.75 kB 🔴 +1.47 kB 🔴 +1.33 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-DagYMOAZ.js (removed) 3.75 kB 🟢 -3.75 kB 🟢 -1.47 kB 🟢 -1.33 kB
assets/WidgetButton-DA8H7w5_.js (removed) 2.25 kB 🟢 -2.25 kB 🟢 -1.01 kB 🟢 -909 B
assets/WidgetButton-iZqFrS7W.js (new) 2.25 kB 🔴 +2.25 kB 🔴 +1.01 kB 🔴 +890 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-Cqjernlb.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -889 B 🟢 -770 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-DanFh_J-.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +889 B 🔴 +765 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-IJTLOeU1.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 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-COPsiRH4.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.58 kB
assets/keybindingService-ih3oSWOm.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.57 kB
assets/audioService-BVWWA1kc.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +960 B 🔴 +823 B
assets/audioService-C8WYpyWY.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -960 B 🟢 -827 B
assets/serverConfigStore-DyIvWaGz.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-BNdNhbgR.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +649 B 🔴 +553 B
assets/audioUtils-CqC2GGMw.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -650 B 🟢 -549 B

Status: 1 added / 1 removed

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

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DZdD68iT.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-C9GFBFnP.js 3.93 MB 3.93 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-NX-4NPlN.js 1.95 MB 1.95 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-7Sidv1he.js 111 kB 111 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-Bz1zdJb0.js 2.08 MB 2.08 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DFkXpum7.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-DMH2Ziq4.js 165 kB 165 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BF8peZ5_.js 420 kB 420 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 5.37 MB (baseline 5.37 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscriptionRequiredDialogContent-CdIaOrFD.js (new) 29.3 kB 🔴 +29.3 kB 🔴 +6.5 kB 🔴 +5.66 kB
assets/SubscriptionRequiredDialogContent-r4z7lRA5.js (removed) 29.3 kB 🟢 -29.3 kB 🟢 -6.51 kB 🟢 -5.65 kB
assets/WidgetRecordAudio-jt85ROWY.js (removed) 20.5 kB 🟢 -20.5 kB 🟢 -5.24 kB 🟢 -4.65 kB
assets/WidgetRecordAudio-YVc7_FhX.js (new) 20.5 kB 🔴 +20.5 kB 🔴 +5.24 kB 🔴 +4.64 kB
assets/AudioPreviewPlayer-ag6_2DzB.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.36 kB 🟢 -3.01 kB
assets/AudioPreviewPlayer-Bjf3udPd.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.36 kB 🔴 +3.01 kB
assets/ValueControlPopover-CsjmQZOi.js (removed) 5.53 kB 🟢 -5.53 kB 🟢 -1.72 kB 🟢 -1.53 kB
assets/ValueControlPopover-D8o966tl.js (new) 5.53 kB 🔴 +5.53 kB 🔴 +1.72 kB 🔴 +1.53 kB
assets/WidgetGalleria-CFPWQpH2.js (removed) 4.14 kB 🟢 -4.14 kB 🟢 -1.46 kB 🟢 -1.32 kB
assets/WidgetGalleria-DjLR_c4U.js (new) 4.14 kB 🔴 +4.14 kB 🔴 +1.46 kB 🔴 +1.32 kB
assets/WidgetColorPicker-ByHYUklI.js (removed) 3.44 kB 🟢 -3.44 kB 🟢 -1.4 kB 🟢 -1.25 kB
assets/WidgetColorPicker-CacfaoKc.js (new) 3.44 kB 🔴 +3.44 kB 🔴 +1.39 kB 🔴 +1.25 kB
assets/WidgetTextarea-3ud0QGgF.js (new) 3.12 kB 🔴 +3.12 kB 🔴 +1.23 kB 🔴 +1.09 kB
assets/WidgetTextarea-NSEM84ko.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.23 kB 🟢 -1.09 kB
assets/WidgetMarkdown-C-W6Kh0C.js (new) 3.12 kB 🔴 +3.12 kB 🔴 +1.29 kB 🔴 +1.14 kB
assets/WidgetMarkdown-Ci-UPUje.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.29 kB 🟢 -1.14 kB
assets/WidgetAudioUI-DrGdtBN5.js (new) 2.93 kB 🔴 +2.93 kB 🔴 +1.18 kB 🔴 +1.07 kB
assets/WidgetAudioUI-sVna7fVY.js (removed) 2.93 kB 🟢 -2.93 kB 🟢 -1.18 kB 🟢 -1.07 kB
assets/WidgetToggleSwitch-CfIQYwW-.js (removed) 2.7 kB 🟢 -2.7 kB 🟢 -1.14 kB 🟢 -1.02 kB
assets/WidgetToggleSwitch-N4mKwUOe.js (new) 2.7 kB 🔴 +2.7 kB 🔴 +1.14 kB 🔴 +1.02 kB
assets/WidgetInputText-DgbrBAEW.js (removed) 2.03 kB 🟢 -2.03 kB 🟢 -935 B 🟢 -865 B
assets/WidgetInputText-DLDAR5qY.js (new) 2.03 kB 🔴 +2.03 kB 🔴 +934 B 🔴 +866 B
assets/Media3DTop-DOGcRJ5U.js (new) 1.53 kB 🔴 +1.53 kB 🔴 +782 B 🔴 +671 B
assets/Media3DTop-gGKC-7vL.js (removed) 1.53 kB 🟢 -1.53 kB 🟢 -782 B 🟢 -671 B
assets/WidgetSelect-DEMgsPlI.js (removed) 772 B 🟢 -772 B 🟢 -379 B 🟢 -367 B
assets/WidgetSelect-DpWqiOgK.js (new) 772 B 🔴 +772 B 🔴 +375 B 🔴 +359 B
assets/WidgetInputNumber-CYSVC_hQ.js (removed) 712 B 🟢 -712 B 🟢 -364 B 🟢 -324 B
assets/WidgetInputNumber-CznRVLWZ.js (new) 712 B 🔴 +712 B 🔴 +359 B 🔴 +331 B
assets/Load3D-Bfigus94.js (new) 463 B 🔴 +463 B 🔴 +281 B 🔴 +238 B
assets/Load3D-sTMnGbSJ.js (removed) 463 B 🟢 -463 B 🟢 -282 B 🟢 -237 B
assets/WidgetLegacy-BhpjlBKj.js (new) 403 B 🔴 +403 B 🔴 +252 B 🔴 +211 B
assets/WidgetLegacy-C4MiZYoB.js (removed) 403 B 🟢 -403 B 🟢 -253 B 🟢 -213 B
assets/commands-B32ZbeYu.js 16.5 kB 16.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-B7wQT83I.js 17 kB 17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BK3JVjMG.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C6twMpaZ.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CDUWpEwM.js 18.3 kB 18.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CfZ6FPZ-.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-COIPP_pv.js 17 kB 17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CoPn_77e.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CuRNS4XD.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DBHjCSPA.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DZJaRLKH.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-1xe9mJcT.js 153 kB 153 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BDbqANM9.js 133 kB 133 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C5vA3tlg.js 113 kB 113 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C9PB4dAA.js 110 kB 110 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Crtx3T9I.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CwvL_tUQ.js 96.9 kB 96.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DcqqM32b.js 116 kB 116 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DOSqX4rX.js 126 kB 126 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-g8x-i8LL.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-QRFd-m2Q.js 97.6 kB 97.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-RbCMslZY.js 137 kB 137 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-DUiRGHAk.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-bDoNEAep.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-BrNs2ijx.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-2h3z0SXa.js 324 kB 324 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-4bBZvQjV.js 298 kB 298 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B1OXtv5-.js 295 kB 295 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C_xG1nNM.js 324 kB 324 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CAgbt7pL.js 365 kB 365 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cghy43iq.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DHrs5gc0.js 328 kB 328 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DPFlfVHx.js 321 kB 321 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DsMfXcAJ.js 366 kB 366 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DWdQhd19.js 337 kB 337 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-mAfdiTdx.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-CTa5K4p_.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-BAyqYPiH.js 3.21 kB 3.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 16 added / 16 removed

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

Adds workspace-based authentication and switching behind a feature flag: new workspace auth Pinia store with token exchange, persistence, refresh and error types; session cookie and firebase auth flows updated to prefer workspace tokens; UI composable for switch confirmation; feature-flag and remote-config additions, tests and i18n strings.

Changes

Cohort / File(s) Summary
Workspace Auth Store & Types
src/stores/workspaceAuthStore.ts, src/platform/auth/workspace/workspaceTypes.ts, src/platform/auth/workspace/workspaceConstants.ts
New Pinia store useWorkspaceAuthStore with Zod validation and WorkspaceAuthError, workspace token exchange/refresh (with retries and request-id), sessionStorage persistence/clearing, WorkspaceWithRole interface, and storage/refresh constants.
Session Cookie & Auth Integration
src/platform/auth/session/useSessionCookie.ts, src/stores/firebaseAuthStore.ts
createSession / deleteSession wrapped in try/catch and use early-return warnings; createSession uses Firebase ID token when team_workspaces_enabled, otherwise legacy auth header; getAuthHeader now prefers workspace token from sessionStorage (expiry check), falls back to Firebase ID token, then API key; workspace keys cleared on logout.
Feature Flags & Remote Config
src/composables/useFeatureFlags.ts, src/platform/remoteConfig/types.ts
Adds TEAM_WORKSPACES_ENABLED feature flag and teamWorkspacesEnabled getter (remote-first, API fallback); adds team_workspaces_enabled?: boolean to RemoteConfig.
Workspace Switching UI & i18n
src/platform/auth/workspace/useWorkspaceSwitch.ts, src/locales/en/main.json
New useWorkspaceSwitch composable with hasUnsavedChanges() and switchWithConfirmation() (confirmation dialog, calls workspace switch, reloads on success); new locale keys for workspace unsaved-changes prompt and workspaceAuth error messages.
Current User Logout Handling
src/composables/auth/useCurrentUser.ts
Tightened onUserLogout watcher to only fire when previous user was non-null and current becomes null.
Tests
src/platform/auth/workspace/useWorkspaceAuth.test.ts, src/platform/auth/workspace/useWorkspaceSwitch.test.ts
Adds comprehensive Vitest tests covering workspace auth initialization, switch, token refresh and errors, feature-flag gating, and switch confirmation flows.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SessionHandler as Session Cookie
    participant Firebase as Firebase Auth
    participant API as Backend API
    participant Storage as SessionStorage

    User->>SessionHandler: createSession()
    alt team_workspaces_enabled = true
        SessionHandler->>Firebase: getIdToken()
        Firebase-->>SessionHandler: Firebase ID Token
        SessionHandler->>API: POST /auth/session (Authorization: Bearer <token>)
    else team_workspaces_enabled = false
        SessionHandler->>Firebase: getAuthHeader()
        Firebase-->>SessionHandler: Auth Header
        SessionHandler->>API: POST /auth/session (existing header)
    end
    API-->>SessionHandler: Response (ok / error)
    SessionHandler-->>User: Success or logged warning
Loading
sequenceDiagram
    participant User
    participant UI as UI Component
    participant Switch as useWorkspaceSwitch
    participant WorkflowStore as Workflow Store
    participant Dialog as Dialog Service
    participant Firebase as Firebase Auth
    participant WorkspaceAuth as Workspace Auth Store
    participant API as Backend API
    participant Storage as SessionStorage

    User->>UI: Trigger switchWithConfirmation(newWorkspaceId)
    UI->>Switch: switchWithConfirmation(newWorkspaceId)
    Switch->>WorkflowStore: check modifiedWorkflows
    alt Unsaved changes & different workspace
        Switch->>Dialog: confirm unsaved changes (i18n text)
        Dialog-->>User: prompt
        alt User confirms
            Switch->>Firebase: getIdToken()
            Firebase-->>Switch: Firebase ID Token
            Switch->>WorkspaceAuth: switchWorkspace(newWorkspaceId, idToken)
            WorkspaceAuth->>API: POST /auth/token (exchange firebase token)
            API-->>WorkspaceAuth: Workspace token + metadata
            WorkspaceAuth->>Storage: persist token, workspace, expiresAt
            WorkspaceAuth-->>Switch: success
            Switch->>UI: location.reload()
        else User cancels
            Switch-->>UI: return false
        end
    else No unsaved changes or same workspace
        Switch->>WorkspaceAuth: switchWorkspace or no-op
        WorkspaceAuth-->>UI: success / no-op
    end
Loading

Possibly related PRs

Suggested reviewers

  • shinshin86
  • KarryCharon
  • DrJKL
  • Yorha4D
  • pythongosssss
✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8bc757 and 24e7d95.

📒 Files selected for processing (3)
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/stores/workspaceAuthStore.ts
🧰 Additional context used
📓 Path-based instructions (10)
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/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.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/stores/workspaceAuthStore.ts
src/stores/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores as *Store.ts (e.g., nodeStore.ts)

Files:

  • src/stores/workspaceAuthStore.ts
🧠 Learnings (42)
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Don't Mock What You Don't Own

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.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/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use waitForTimeout in Playwright tests - use Locator actions and retrying assertions instead

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/stores/**/*.ts : Name Pinia stores as `*Store.ts` (e.g., `nodeStore.ts`)

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Use TypeScript for type safety in state management stores

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use vue-i18n for all string literals in Vue components - place translation entries in `src/locales/en/main.json`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-09T23:59:06.942Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7926
File: src/stores/assetDownloadStore.ts:101-126
Timestamp: 2026-01-09T23:59:06.942Z
Learning: In src/stores/assetDownloadStore.ts, the empty catch block in pollSingleDownload within pollStaleDownloads is intentional. Do not suggest adding error logging or handling for polling failures in this function.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-12T23:02:37.473Z
Learnt from: Myestery
Repo: Comfy-Org/ComfyUI_frontend PR: 7422
File: .github/workflows/pr-update-playwright-expectations.yaml:131-135
Timestamp: 2025-12-12T23:02:37.473Z
Learning: In the `.github/workflows/pr-update-playwright-expectations.yaml` workflow in the Comfy-Org/ComfyUI_frontend repository, the snapshot update process is intentionally scoped to only add and update snapshot images. Deletions of snapshot files are handled explicitly outside this workflow and should not be suggested as part of this automation.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
🧬 Code graph analysis (3)
src/platform/auth/workspace/useWorkspaceSwitch.test.ts (2)
src/platform/auth/workspace/workspaceTypes.ts (1)
  • WorkspaceWithRole (1-6)
src/platform/auth/workspace/useWorkspaceSwitch.ts (1)
  • useWorkspaceSwitch (8-49)
src/stores/workspaceAuthStore.ts (5)
src/platform/auth/workspace/workspaceTypes.ts (1)
  • WorkspaceWithRole (1-6)
src/platform/auth/workspace/workspaceConstants.ts (2)
  • TOKEN_REFRESH_BUFFER_MS (7-7)
  • WORKSPACE_STORAGE_KEYS (1-5)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/auth/workspace/useWorkspaceSwitch.ts (3)
src/stores/workspaceAuthStore.ts (1)
  • useWorkspaceAuthStore (46-373)
src/platform/workflow/management/stores/workflowStore.ts (1)
  • useWorkflowStore (208-863)
src/services/dialogService.ts (1)
  • useDialogService (48-570)
⏰ 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 (14)
src/stores/workspaceAuthStore.ts (7)

1-16: LGTM!

Imports are properly organized with separate import type statements as per coding guidelines.


36-44: LGTM!

Clean error class implementation with structured error codes for distinguishing permanent vs transient failures.


46-62: LGTM!

Good use of shallowRef for the workspace object and plain variables for internal timer/request state that doesn't need reactivity.


64-111: LGTM!

Timer management and session persistence helpers are well-implemented with proper error handling for non-critical sessionStorage operations.


113-164: LGTM!

Session initialization properly validates stored data including expiry check, clears corrupted/expired sessions, and respects the feature flag.


271-333: LGTM!

Token refresh logic properly captures request ID, guards against stale operations, and implements exponential backoff for transient errors while immediately clearing context for permanent auth failures.


335-373: LGTM!

Clear public interface with appropriate actions exposed. clearWorkspaceContext correctly invalidates stale operations.

src/platform/auth/workspace/useWorkspaceSwitch.ts (3)

1-7: LGTM!

Imports are properly organized with separate import type for the WorkspaceWithRole type.


15-17: LGTM!

Correctly checks modifiedWorkflows.length to detect unsaved changes across all workflows, not just the active one.


45-49: LGTM!

Clean composable API exposing only the necessary functions.

src/platform/auth/workspace/useWorkspaceSwitch.test.ts (4)

1-9: LGTM!

Imports are properly organized with WorkspaceWithRole type imported to prevent type drift in tests. Good use of vi.hoisted() for mock variables.


11-47: LGTM!

Mocks are properly hoisted and structured. The getter pattern for modifiedWorkflows ensures tests read the current mock value at call time rather than capturing a stale reference.


51-66: LGTM!

Good test hygiene with vi.clearAllMocks() in beforeEach and vi.unstubAllGlobals() in afterEach to prevent test pollution.


91-165: Good behavioral coverage of switchWithConfirmation.

Tests cover key scenarios: same workspace no-op, direct switch without dialog, dialog confirmation flow, user cancellation, and error handling. This aligns with the guideline to aim for behavioral coverage of critical features.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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: 9

🤖 Fix all issues with AI agents
In `@src/platform/auth/workspace/useWorkspaceAuth.test.ts`:
- Around line 1-5: The test file fails at runtime because afterEach is used but
not imported from vitest; update the import line that currently imports
beforeEach, describe, expect, it, vi to also import afterEach so the test
teardown calls succeed (ensure the import includes afterEach alongside
beforeEach, describe, expect, it, vi) and run the tests to confirm
useWorkspaceAuth and WorkspaceAuthError tests no longer throw a ReferenceError.
- Around line 61-86: The suite contains multiple tiny "initial state" specs that
act as change-detector tests; consolidate them into a single test or remove
them: replace the separate it blocks under the describe('initial state') with
one it('has correct initial state') that calls useWorkspaceAuth() once and
asserts all initial values (currentWorkspace.value, workspaceToken.value,
isAuthenticated.value, isLoading.value, error.value) in one test, or delete the
describe block entirely if those defaults are already exercised by other
behavior tests.
- Around line 562-585: Add a test for the edge case where currentWorkspace is
set but workspaceToken is null: call useWorkspaceAuth(), set currentWorkspace
(via switchWorkspace or by directly setting the returned currentWorkspace ref)
while mocking token retrieval to return null (e.g.,
mockGetIdToken.mockResolvedValue(null) and/or stub fetch so no workspaceToken is
created), then assert isAuthenticated.value is false; reference the
isAuthenticated computed, useWorkspaceAuth, currentWorkspace, workspaceToken and
switchWorkspace symbols when locating where to add the new test.

In `@src/platform/auth/workspace/useWorkspaceAuth.ts`:
- Around line 89-118: The initializeFromSession function currently casts
JSON.parse(workspaceJson) to WorkspaceWithRole without validation; to harden it,
parse workspaceJson into a plain object, verify minimal required fields (e.g.,
workspace.id exists and is a string, and any other critical props like name or
role if required), and if validation fails call clearSessionStorage() and return
false; only after validation assign currentWorkspace.value = workspace as
WorkspaceWithRole and proceed with setting workspaceToken, error, and
scheduleTokenRefresh; refer to initializeFromSession, persistToSession,
WorkspaceWithRole, currentWorkspace, and clearSessionStorage when locating where
to add the checks.

In `@src/platform/auth/workspace/useWorkspaceSwitch.test.ts`:
- Around line 6-14: Replace the module-scope mock variables with vi.hoisted() so
they exist before vi.mock runs: hoist mockSwitchWorkspace and
mockCurrentWorkspace (the ref used for currentWorkspace) using vi.hoisted(),
then keep the vi.mock for useWorkspaceAuth returning currentWorkspace and
switchWorkspace; ensure you reference the same symbols mockSwitchWorkspace and
mockCurrentWorkspace inside the mocked useWorkspaceAuth so the mock is
initialized reliably.
- Around line 16-22: The mock for useWorkflowStore captures
mockActiveWorkflow.value at module-evaluation time causing stale values; change
the mock to return activeWorkflow via a getter or function so it reads
mockActiveWorkflow.value at call time (e.g., have useWorkflowStore return an
object with a get activeWorkflow() { return mockActiveWorkflow.value } or
activeWorkflow: () => mockActiveWorkflow.value) so updates to mockActiveWorkflow
in beforeEach/tests are reflected.

In `@src/platform/auth/workspace/useWorkspaceSwitch.ts`:
- Around line 34-40: The catch block for workspaceAuth.switchWorkspace silently
swallows errors; modify the catch to accept the caught error (e.g., catch (err))
and log it before returning false—use the existing logging utility if available
(or console.error) and include context like "Failed to switch workspace" along
with err; keep the return false behavior intact in the useWorkspaceSwitch logic.
- Around line 17-32: The switchWithConfirmation function calls
t('workspace.unsavedChanges.title') and t('workspace.unsavedChanges.message')
but those keys are missing from the English i18n locale; add a workspace object
in your English locale with unsavedChanges.title (e.g. "You have unsaved
changes") and unsavedChanges.message (e.g. "You have unsaved changes. Do you
want to discard them and switch workspaces?"), ensure the keys exist for other
locales as needed, and reload/validate the vue-i18n resources so the t(...)
calls resolve at runtime.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23694f3 and 9b071ed.

📒 Files selected for processing (7)
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
🧰 Additional context used
📓 Path-based instructions (10)
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/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.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/stores/firebaseAuthStore.ts
src/stores/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores as *Store.ts (e.g., nodeStore.ts)

Files:

  • src/stores/firebaseAuthStore.ts
🧠 Learnings (25)
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Don't Mock What You Don't Own

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Leverage VueUse functions for performance-enhancing composables

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
🧬 Code graph analysis (6)
src/platform/auth/workspace/useWorkspaceSwitch.ts (3)
src/platform/auth/workspace/useWorkspaceAuth.ts (1)
  • useWorkspaceAuth (30-243)
src/platform/workflow/management/stores/workflowStore.ts (1)
  • useWorkflowStore (208-863)
src/services/dialogService.ts (1)
  • useDialogService (48-570)
src/platform/auth/workspace/useWorkspaceAuth.test.ts (1)
src/platform/auth/workspace/useWorkspaceAuth.ts (2)
  • useWorkspaceAuth (30-243)
  • WorkspaceAuthError (20-28)
src/platform/auth/session/useSessionCookie.ts (1)
src/scripts/api.ts (1)
  • api (1336-1336)
src/platform/auth/workspace/useWorkspaceAuth.ts (3)
src/platform/auth/workspace/workspaceTypes.ts (2)
  • WorkspaceWithRole (1-6)
  • WorkspaceTokenResponse (8-18)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/stores/firebaseAuthStore.ts (1)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/auth/workspace/useWorkspaceSwitch.test.ts (1)
src/platform/auth/workspace/useWorkspaceSwitch.ts (1)
  • useWorkspaceSwitch (7-47)
⏰ 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). (1)
  • GitHub Check: playwright-tests-chromium-sharded (6, 8)
🔇 Additional comments (28)
src/stores/firebaseAuthStore.ts (2)

152-162: Documentation update looks good.

The JSDoc accurately reflects the new authentication precedence order: workspace token → Firebase token → API key.


164-175: Timestamp format is consistent—no issue here.

The code correctly converts expires_at from the API (string) to milliseconds via new Date(data.expires_at).getTime(), stores it as a numeric string (expiresAt.toString()), and parses it back with parseInt(expiresAt, 10) in both useWorkspaceAuth.ts (line 101) and firebaseAuthStore.ts (line 169). The chain is consistent and valid.

Likely an incorrect or invalid review comment.

src/platform/auth/session/useSessionCookie.ts (2)

17-22: Correct use of Firebase token for session creation.

Using getIdToken() directly instead of getAuthHeader() is the right approach here. Session cookies should be created with the Firebase identity token since they represent the user's identity, not a workspace-scoped context. The explicit error message clarifies the requirement.


24-31: LGTM.

The Authorization header correctly uses the Firebase token directly.

src/platform/auth/workspace/workspaceTypes.ts (1)

1-18: Well-structured type definitions.

The interfaces cleanly separate workspace metadata (WorkspaceWithRole) from the token exchange response (WorkspaceTokenResponse). The expires_at as a string aligns with typical API patterns (ISO 8601).

Note: Consumers parsing expires_at for expiry checks will need to convert this ISO string to a timestamp. Ensure consistency in how this value is stored/compared (see related comment in firebaseAuthStore.ts).

src/platform/auth/workspace/useWorkspaceSwitch.test.ts (3)

40-49: Good test setup with proper cleanup.

The beforeEach correctly clears mocks and resets state. The window.location.reload mock is appropriately scoped.


51-72: Good behavioral coverage for hasUnsavedChanges.

Tests cover the three relevant states: modified, not modified, and null workflow. This is appropriate behavioral testing per coding guidelines.


74-154: Comprehensive switchWithConfirmation test coverage.

Tests appropriately cover:

  • Same workspace no-op
  • Direct switch without dialog
  • Dialog shown with unsaved changes
  • User cancel path
  • User confirm path with reload
  • Error handling

This provides good behavioral coverage for the critical workspace switching flow.

src/platform/auth/workspace/useWorkspaceSwitch.ts (1)

7-15: Clean composable structure with proper function declarations.

The composable correctly uses function declarations per repository guidelines. Dependencies are properly injected at the top level.

src/platform/auth/workspace/useWorkspaceAuth.test.ts (9)

6-28: Mock setup looks appropriate.

The mocks are contained, minimal, and properly leverage Vitest utilities. The mockGetIdToken is correctly defined outside the mock factory to allow per-test configuration.


30-47: Fixtures are well-structured and type-safe.

Good use of as const assertions to ensure type literals match the expected union types from WorkspaceWithRole and WorkspaceTokenResponse.


49-59: Test setup ensures proper isolation.

Good practices: activating a fresh Pinia instance, clearing mocks, using fake timers for timing tests, and clearing sessionStorage between tests.


88-166: Comprehensive session initialization tests.

Good behavioral coverage including valid data, empty storage, expired tokens, malformed JSON, and partial data scenarios. Each test properly verifies both return values and side effects.


168-369: Thorough switchWorkspace test coverage.

Good coverage of the token exchange flow including success path, sessionStorage persistence, loading state transitions, and comprehensive error code mapping for HTTP responses (401, 403, 404, 500). The API request validation test ensures correct request structure.


371-418: clearWorkspaceContext tests verify state cleanup.

Tests properly set up state before clearing, ensuring they verify actual behavior rather than just default values.


420-448: Header generation tests are appropriately behavioral.

The tests verify header generation based on actual state transitions rather than mocking internal state directly.


450-519: Token refresh scheduling tests use timers effectively.

Good use of vi.useFakeTimers() and vi.advanceTimersByTime() to test timing-dependent behavior. The vi.waitFor() pattern handles async assertions correctly.


521-560: refreshToken tests cover guard clause and update behavior.

Properly tests both the early return when no workspace is set and the successful token update flow.

src/platform/auth/workspace/useWorkspaceAuth.ts (10)

1-10: Imports are well-organized.

Type imports are correctly separated from value imports per coding guidelines. All imports are utilized.


12-18: Constants are appropriately scoped and typed.

Good use of as const for STORAGE_KEYS to ensure type narrowing. The 5-minute refresh buffer is reasonable for token lifecycle management.


20-28: Custom error class follows standard pattern.

The WorkspaceAuthError provides typed error codes for consumers to handle specific failure modes.


30-42: Composable state setup is well-structured.

Good choice of shallowRef for currentWorkspace (avoids unnecessary deep reactivity) and ref for primitives. The isAuthenticated computed efficiently derives authentication state.


44-60: Timer management is correctly implemented.

scheduleTokenRefresh properly clears any existing timer before scheduling, and Math.max(0, ...) prevents negative delays. The void refreshToken() correctly acknowledges the floating promise.


62-87: Session persistence functions handle storage errors gracefully.

The try/catch blocks ensure the composable degrades gracefully when sessionStorage is unavailable or full.


192-208: Refresh error handling appropriately preserves context for recoverable errors.

The function correctly clears context only for permanent failures (ACCESS_DENIED, WORKSPACE_NOT_FOUND) while preserving state for transient errors (network issues, server errors) to allow retry.


210-217: Header generation is straightforward and correct.

Returns typed AuthHeader when token exists, null otherwise.


219-225: Context cleanup is complete and correctly ordered.

Clears the refresh timer first before nullifying state, preventing any race conditions.


227-243: Lifecycle cleanup and API surface are well-defined.

The onUnmounted hook ensures timers are cleared when the component using this composable unmounts. The return object exposes a clean public API.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

simula-r
simula-r previously approved these changes Jan 15, 2026
Copy link
Contributor

@simula-r simula-r left a comment

Choose a reason for hiding this comment

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

LGTM

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: 4

🤖 Fix all issues with AI agents
In `@src/platform/auth/workspace/useWorkspaceAuth.ts`:
- Around line 201-217: refreshToken currently aborts on TOKEN_EXCHANGE_FAILED
without retrying or rescheduling; update refreshToken to detect transient
failures from switchWorkspace (err instanceof WorkspaceAuthError && err.code ===
'TOKEN_EXCHANGE_FAILED') and implement an exponential backoff retry loop (e.g.,
retry 3 times with increasing delay) before giving up, and if retries succeed
ensure the next token refresh is rescheduled; only call clearWorkspaceContext
when error codes are ACCESS_DENIED or WORKSPACE_NOT_FOUND as before.
- Around line 180-186: The code in useWorkspaceAuth currently assumes the
fetched response matches WorkspaceTokenResponse and directly accesses
data.workspace and data.role; change this to validate the JSON at runtime (e.g.,
using a Zod schema for WorkspaceTokenResponse) by parsing the response.json()
result with schema.safeParse(data) and handle the failure path (log/error/throw)
before using fields like expires_at, workspace, and role; update the assignment
that creates WorkspaceWithRole to only run after safeParse succeeds so you never
destructure an unexpected shape.
- Around line 236-238: The composable useWorkspaceAuth relies on Vue component
setup lifecycle (it calls onUnmounted to clearRefreshTimer) but this isn't
documented or enforced; add a JSDoc above the useWorkspaceAuth export stating it
must be called from a component setup context, and add a runtime guard at the
start of useWorkspaceAuth that uses Vue's getCurrentInstance() (or equivalent)
to detect missing setup context and throw a clear error directing callers to use
it inside setup; ensure references to onUnmounted and clearRefreshTimer remain
unchanged but are only used after the guard so the timer cannot leak when used
outside a component.

In `@src/stores/firebaseAuthStore.ts`:
- Around line 166-178: Export the existing STORAGE_KEYS constant from
useWorkspaceAuth.ts and import it into firebaseAuthStore.ts, replacing the
duplicated string literals 'Comfy.Workspace.Token' and
'Comfy.Workspace.ExpiresAt' with STORAGE_KEYS.TOKEN and STORAGE_KEYS.EXPIRES_AT
(or the exact property names used in useWorkspaceAuth.ts); modify the module
export in useWorkspaceAuth.ts to export STORAGE_KEYS and update
firebaseAuthStore.ts to import { STORAGE_KEYS } and use STORAGE_KEYS when
calling sessionStorage.getItem and building the Authorization header to remove
duplication and keep a single source of truth.
♻️ Duplicate comments (5)
src/platform/auth/workspace/useWorkspaceAuth.test.ts (3)

1-5: Missing afterEach import causes runtime failure.

Line 67 uses afterEach but it's not imported from vitest on line 2. This will cause a ReferenceError at runtime.

🐛 Proposed fix
-import { beforeEach, describe, expect, it, vi } from 'vitest'
+import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

71-96: Initial state tests are borderline change-detector tests.

Per coding guidelines, tests should avoid only asserting default values. These tests verify initial state but don't test behavior. Consider consolidating into a single test or removing if the initial state is implicitly verified by other tests.


572-595: Consider adding edge case for isAuthenticated.

The computed returns true only when both currentWorkspace and workspaceToken are non-null. Consider adding a test case for when workspace is present but token is null (though this state may not be reachable via public API).

src/platform/auth/workspace/useWorkspaceAuth.ts (2)

112-113: Add minimal validation after JSON.parse.

This concern was previously raised. The type assertion as WorkspaceWithRole on untrusted sessionStorage data could cause runtime issues if storage is corrupted or tampered with.


181-181: Validate expires_at before scheduling refresh.

This was previously flagged. If data.expires_at is malformed, new Date(data.expires_at).getTime() returns NaN, causing scheduleTokenRefresh to fire immediately and potentially loop.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b071ed and 9b391af.

📒 Files selected for processing (6)
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/remoteConfig/types.ts
  • src/stores/firebaseAuthStore.ts
🧰 Additional context used
📓 Path-based instructions (14)
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/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.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/stores/firebaseAuthStore.ts
src/stores/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores as *Store.ts (e.g., nodeStore.ts)

Files:

  • src/stores/firebaseAuthStore.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/composables/useFeatureFlags.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/composables/useFeatureFlags.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/composables/useFeatureFlags.ts
src/composables/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables as useXyz.ts (e.g., useForm.ts)

Files:

  • src/composables/useFeatureFlags.ts
🧠 Learnings (31)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/firebaseAuthStore.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Don't Mock What You Don't Own

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.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/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{services,composables}/**/*.{ts,tsx} : Use `api.apiURL()` for backend endpoints instead of constructing URLs directly

Applied to files:

  • src/stores/firebaseAuthStore.ts
📚 Learning: 2026-01-06T19:20:56.167Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/services/assetService.ts:484-491
Timestamp: 2026-01-06T19:20:56.167Z
Learning: In `src/platform/assets/services/assetService.ts`, prefer using `schema.safeParse()` over `schema.parse()` for validating API responses to avoid throwing ZodError with internal schema details; follow the existing pattern: call `safeParse()`, check `result.success`, and use `fromZodError(result.error)` to format error messages for logging while throwing user-friendly errors.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
🧬 Code graph analysis (5)
src/platform/auth/workspace/useWorkspaceAuth.test.ts (1)
src/platform/auth/workspace/useWorkspaceAuth.ts (2)
  • useWorkspaceAuth (31-252)
  • WorkspaceAuthError (21-29)
src/platform/auth/session/useSessionCookie.ts (1)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/stores/firebaseAuthStore.ts (2)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/composables/useFeatureFlags.ts (2)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/platform/auth/workspace/useWorkspaceAuth.ts (4)
src/platform/auth/workspace/workspaceTypes.ts (2)
  • WorkspaceWithRole (1-6)
  • WorkspaceTokenResponse (8-18)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
⏰ 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: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: test
🔇 Additional comments (15)
src/platform/remoteConfig/types.ts (1)

45-45: LGTM!

The new team_workspaces_enabled field follows the established pattern for feature flags in RemoteConfig, using an optional boolean type consistent with the other flags.

src/platform/auth/session/useSessionCookie.ts (1)

24-38: LGTM!

The branching logic correctly handles both paths:

  • When team_workspaces_enabled is true, uses Firebase token directly (avoiding workspace token for session creation)
  • When false, maintains backward compatibility with getAuthHeader()

The if/else pattern is appropriate here for performing side effects per repository conventions.

src/stores/firebaseAuthStore.ts (1)

153-188: LGTM on the workspace-first authentication flow.

The implementation correctly:

  1. Checks feature flag before attempting workspace token lookup
  2. Validates token existence and expiry before use
  3. Falls back to Firebase token, then API key as documented

The parseInt with radix 10 and Date.now() comparison handle edge cases appropriately (NaN comparisons fail safely).

src/composables/useFeatureFlags.ts (2)

20-21: LGTM!

The new TEAM_WORKSPACES_ENABLED enum member follows the established naming convention.


96-102: LGTM!

The teamWorkspacesEnabled getter follows the established pattern: remote config takes precedence, falling back to the API feature flag with a safe default of false.

src/platform/auth/workspace/useWorkspaceAuth.test.ts (6)

6-32: LGTM on mock setup.

Good use of vi.hoisted() for mockRemoteConfig to ensure proper hoisting of the mutable mock state per coding guidelines.


98-176: LGTM on initializeFromSession tests.

Good behavioral coverage including:

  • Valid session restoration
  • Empty storage handling
  • Expired token detection and cleanup
  • Malformed data recovery
  • Partial data rejection

178-379: LGTM on switchWorkspace tests.

Comprehensive coverage of:

  • Successful token exchange flow
  • Session storage persistence
  • Loading state transitions
  • All error codes (401, 403, 404, 500) with correct WorkspaceAuthError codes
  • API request validation

381-458: LGTM on clearWorkspaceContext and getWorkspaceAuthHeader tests.

Good coverage of state clearing and header generation behaviors.


460-529: LGTM on token refresh scheduling tests.

Good use of vi.advanceTimersByTime and vi.waitFor for testing timer-based behavior. The 5-minute buffer calculation matches the implementation constant.


597-640: LGTM on feature flag disabled tests.

Good coverage verifying that initializeFromSession and switchWorkspace are no-ops when the feature flag is disabled, ensuring safe fallback behavior.

src/platform/auth/workspace/useWorkspaceAuth.ts (4)

56-88: LGTM!

Utility functions for timer management and session storage are well-implemented with appropriate error handling.


219-226: LGTM!

Clean implementation returning the correct AuthHeader type.


228-234: LGTM!

Comprehensive cleanup of timer, reactive state, and session storage.


34-43: The current architecture is sound. useWorkspaceAuth() creates isolated state per composable instance, which synchronizes via sessionStorage as a shared source of truth. This is standard Vue 3 composition API design and appropriate for a workspace authentication composable. The state isolation pattern is intentional and correct—revisit only if future requirements demand truly reactive shared state across multiple simultaneous instances (e.g., by extracting to Pinia).

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

simula-r
simula-r previously approved these changes Jan 15, 2026
Copy link
Contributor

@simula-r simula-r left a comment

Choose a reason for hiding this comment

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

LGTM

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: 6

🤖 Fix all issues with AI agents
In `@src/platform/auth/workspace/useWorkspaceAuth.test.ts`:
- Around line 483-552: The microtask flush in the "schedules token refresh 5
minutes before expiry" test uses await Promise.resolve() after
vi.advanceTimersByTime — replace that with a proper Vitest timer flush like
await vi.runOnlyPendingTimersAsync() (or await vi.waitFor(() => {/* assertion
*/})) to reliably process the scheduled refresh; update the test that calls
switchWorkspace from useWorkspaceAuth() and verify mockFetch calls after using
vi.runOnlyPendingTimersAsync(), ensuring vi is available in the scope for timer
control.
- Around line 43-47: Tests declare a duplicate WORKSPACE_STORAGE_KEYS object
which can drift from the real constant in the composable; remove the local
WORKSPACE_STORAGE_KEYS definition and import WORKSPACE_STORAGE_KEYS from the
useWorkspaceAuth module (the composable under test), place that import with the
other top-of-file imports, and update assertions to reference the imported
WORKSPACE_STORAGE_KEYS so tests always use the canonical keys.

In `@src/platform/auth/workspace/useWorkspaceAuth.ts`:
- Around line 267-308: In refreshToken(), ensure you clear the workspace auth
state on terminal failures so stale tokens aren't reused: inside the catch
branch of refreshToken (function refreshToken) add calls to
clearWorkspaceContext() (or the equivalent token-clear function) whenever you
detect permanent errors (existing ACCESS_DENIED or WORKSPACE_NOT_FOUND handling)
and also for other non-recoverable error codes such as INVALID_FIREBASE_TOKEN
and NOT_AUTHENTICATED, and after exhausting retries (when attempt === maxRetries
and the error is not transient/TOKEN_EXCHANGE_FAILED) so that failed refreshes
remove the expired token from the context rather than leaving it in place.
- Line 1: Replace the manual setTimeout/clearTimeout usage in useWorkspaceAuth
(the token refresh timer logic where a timeout is created and cleared — e.g.,
the functions/vars that set a refresh timer and clear it) with VueUse's
useTimeoutFn: import useTimeoutFn from '@vueuse/core', create a timeout via
useTimeoutFn(callback, delay) to start/stop the refresh logic, call the returned
start/stop functions instead of setTimeout/clearTimeout, and remove explicit
clearTimeout cleanup (useTimeoutFn auto-cleans on unmount); ensure the same
callback and delay semantics are preserved and replace any refreshTimerId
references with the start/stop handle.

In `@src/platform/auth/workspace/useWorkspaceSwitch.test.ts`:
- Around line 50-53: The test currently overwrites window.location via
Object.defineProperty in beforeEach which can leak between tests; replace that
with vi.stubGlobal('location', { reload: mockReload }) (and restore in afterEach
or let vi restore automatically) so the global is stubbed consistently like
other mocks; update any references to window.location.reload to use the stubbed
object and ensure mockReload is used as the reload implementation.

In `@src/stores/firebaseAuthStore.ts`:
- Around line 166-183: The getAuthHeader function should explicitly guard
against parseInt returning NaN for the expiresAt value: after reading expiresAt
from sessionStorage (WORKSPACE_STORAGE_KEYS.EXPIRES_AT) and converting with
parseInt, check Number.isFinite(expiryTime) or !Number.isNaN(expiryTime) before
comparing with Date.now(); if the parsed expiry is NaN treat it as expired (do
not return the workspaceToken). Update the logic around workspaceToken/expiresAt
so malformed expiry values are rejected early and the function falls back to
null.
♻️ Duplicate comments (3)
src/platform/auth/workspace/useWorkspaceAuth.test.ts (3)

1-4: Past review issue resolved - afterEach is now properly imported.

The afterEach import that was missing in a previous commit is now included, resolving the runtime ReferenceError.


80-96: Initial state tests are properly consolidated.

The separate initial state assertions have been consolidated into a single test per the past review feedback, avoiding change-detector anti-patterns while still verifying the baseline state.


619-629: Edge case for isAuthenticated computed is properly covered.

This test addresses the past review suggestion to test the scenario where currentWorkspace is set but workspaceToken is null, ensuring isAuthenticated correctly returns false.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b391af and 1876d2e.

📒 Files selected for processing (6)
  • src/locales/en/main.json
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
🧰 Additional context used
📓 Path-based instructions (10)
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/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.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/stores/firebaseAuthStore.ts
src/stores/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores as *Store.ts (e.g., nodeStore.ts)

Files:

  • src/stores/firebaseAuthStore.ts
🧠 Learnings (45)
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.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/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Don't Mock What You Don't Own

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.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/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2026-01-08T02:40:22.621Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:22.621Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: When testing components, import the real type definitions from the component files instead of duplicating interface definitions in the test files. This prevents type drift and maintains consistency.

Applied to files:

  • src/stores/firebaseAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/firebaseAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-06T19:20:56.167Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/services/assetService.ts:484-491
Timestamp: 2026-01-06T19:20:56.167Z
Learning: In `src/platform/assets/services/assetService.ts`, prefer using `schema.safeParse()` over `schema.parse()` for validating API responses to avoid throwing ZodError with internal schema details; follow the existing pattern: call `safeParse()`, check `result.success`, and use `fromZodError(result.error)` to format error messages for logging while throwing user-friendly errors.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Never use `as any` type assertions - fix the underlying type issue

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Leverage VueUse functions for performance-enhancing composables

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement cleanup for async operations in Vue components

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
🧬 Code graph analysis (4)
src/platform/auth/workspace/useWorkspaceAuth.test.ts (1)
src/platform/auth/workspace/useWorkspaceAuth.ts (3)
  • WORKSPACE_STORAGE_KEYS (31-35)
  • useWorkspaceAuth (58-343)
  • WorkspaceAuthError (39-47)
src/platform/auth/workspace/useWorkspaceSwitch.test.ts (1)
src/platform/auth/workspace/useWorkspaceSwitch.ts (1)
  • useWorkspaceSwitch (7-47)
src/stores/firebaseAuthStore.ts (3)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/platform/auth/workspace/useWorkspaceAuth.ts (1)
  • WORKSPACE_STORAGE_KEYS (31-35)
src/platform/auth/workspace/useWorkspaceAuth.ts (4)
src/platform/auth/workspace/workspaceTypes.ts (1)
  • WorkspaceWithRole (1-6)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
⏰ 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). (7)
  • GitHub Check: deploy-and-comment
  • GitHub Check: deploy-and-comment
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: test
  • GitHub Check: collect
  • GitHub Check: lint-and-format
🔇 Additional comments (11)
src/stores/firebaseAuthStore.ts (2)

26-28: LGTM - Imports align with workspace authentication infrastructure.

The imports of WORKSPACE_STORAGE_KEYS from the new workspace auth module and remoteConfig properly support the workspace-first authentication path. This also addresses the previous review feedback about consolidating duplicate storage key strings.


154-165: JSDoc accurately reflects the updated authentication precedence.

The documentation clearly describes the three-tier authentication hierarchy (workspace → Firebase → API key) and the return types. This helps maintainers understand the new behavior.

src/locales/en/main.json (1)

2596-2610: LGTM - Locale keys properly support the workspace authentication feature.

The new locale entries follow existing conventions and provide clear, user-friendly messages for both the unsaved changes dialog and workspace authentication errors. The {error} interpolation placeholder in tokenExchangeFailed allows for dynamic error details.

src/platform/auth/workspace/useWorkspaceSwitch.test.ts (2)

5-27: LGTM - Mock hoisting issues from past reviews have been properly addressed.

The vi.hoisted() pattern is correctly applied to mockSwitchWorkspace, mockCurrentWorkspace, and mockActiveWorkflow. The workflowStore mock now uses a getter for activeWorkflow, ensuring the mock reads the current value at call time rather than capturing a stale value.


56-159: Comprehensive behavioral test coverage for workspace switching.

The tests properly cover all branches: same-workspace no-op, direct switch without confirmation, dialog display with unsaved changes, user cancellation, successful confirmation with reload, and error handling. Each test verifies meaningful behavior rather than just asserting mock interactions.

src/platform/auth/workspace/useWorkspaceAuth.test.ts (2)

195-398: Comprehensive switchWorkspace test coverage with proper error code mapping.

The tests thoroughly verify:

  • Successful token exchange flow with correct API request format
  • SessionStorage persistence of workspace data
  • Loading state transitions
  • All error code mappings (NOT_AUTHENTICATED, ACCESS_DENIED, WORKSPACE_NOT_FOUND, INVALID_FIREBASE_TOKEN, TOKEN_EXCHANGE_FAILED)

This provides strong confidence in the error handling behavior.


632-678: Feature flag disabled tests ensure graceful degradation.

The tests properly verify that when team_workspaces_enabled is false:

  1. initializeFromSession returns false without populating state
  2. switchWorkspace is a no-op (no fetch, no state changes)

This ensures the feature can be safely disabled without breaking existing functionality.

src/platform/auth/workspace/workspaceTypes.ts (1)

1-6: The suggested Zod schema already exists and is properly implemented.

WorkspaceWithRoleSchema is already defined in useWorkspaceAuth.ts (lines 12–17) with all required fields including the role enum. The schema is correctly used with safeParse() for validation, following the Zod 3.x pattern. The current architecture—keeping type definitions in workspaceTypes.ts and validation schemas in the composable where they're consumed—is appropriate and consistent with the codebase.

Likely an incorrect or invalid review comment.

src/platform/auth/workspace/useWorkspaceAuth.ts (3)

49-63: Setup-context guard prevents lifecycle leaks.
Clear runtime guard plus explicit error is a solid safety net for composable usage.


126-168: Session restore is defensively validated.
Expiry checks and schema validation before state assignment are solid.


170-265: Switch flow has clear error mapping and state updates.
Status-specific errors plus persistence/refresh scheduling make the flow robust.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@coderabbitai coderabbitai bot requested a review from KarryCharon January 15, 2026 22:00
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

🤖 Fix all issues with AI agents
In `@src/platform/auth/workspace/useWorkspaceAuth.ts`:
- Around line 295-306: The retry delay uses a raw setTimeout in useWorkspaceAuth
(inside the loop that checks isTransientError with attempt, maxRetries and
baseDelayMs), which won't be cleaned up if the component unmounts; replace the
new Promise(resolve => setTimeout(...)) with a managed timer (e.g. useTimeoutFn
from `@vueuse/core` or create an AbortController/track a timer id and clear it in
onUnmounted) so the pending delay is cancelled when the hook/component
unmounts—ensure the logic still awaits the timer before continuing the loop and
reference the same variables (isTransientError, attempt, maxRetries,
baseDelayMs) when implementing the managed delay.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1876d2e and 2c80b7e.

📒 Files selected for processing (3)
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
🧰 Additional context used
📓 Path-based instructions (8)
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/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
🧠 Learnings (50)
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Don't Mock What You Don't Own

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.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/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use waitForTimeout in Playwright tests - use Locator actions and retrying assertions instead

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.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/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-13T05:34:22.209Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:22.209Z
Learning: In Playwright tests in the Comfy-Org/ComfyUI_frontend repository, the `toPass()` assertion method implements incremental backoff during retries, so increasing the timeout value (e.g., to 5000ms) is sufficient for handling async operations without being overly aggressive.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-06T19:20:56.167Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/services/assetService.ts:484-491
Timestamp: 2026-01-06T19:20:56.167Z
Learning: In `src/platform/assets/services/assetService.ts`, prefer using `schema.safeParse()` over `schema.parse()` for validating API responses to avoid throwing ZodError with internal schema details; follow the existing pattern: call `safeParse()`, check `result.success`, and use `fromZodError(result.error)` to format error messages for logging while throwing user-friendly errors.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Leverage VueUse functions for performance-enhancing composables

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-08T02:40:22.621Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:22.621Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: When testing components, import the real type definitions from the component files instead of duplicating interface definitions in the test files. This prevents type drift and maintains consistency.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement cleanup for async operations in Vue components

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Avoid using `ref` with `watch` if a `computed` would suffice - minimize refs and derived state

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Watch out for Code Smells and refactor to avoid them

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Use `ref` for reactive state, `computed()` for derived values, and `watch`/`watchEffect` for side effects in Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
🧬 Code graph analysis (2)
src/platform/auth/workspace/useWorkspaceSwitch.test.ts (1)
src/platform/auth/workspace/useWorkspaceSwitch.ts (1)
  • useWorkspaceSwitch (7-47)
src/platform/auth/workspace/useWorkspaceAuth.ts (4)
src/platform/auth/workspace/workspaceTypes.ts (1)
  • WorkspaceWithRole (1-6)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
⏰ 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: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect
  • GitHub Check: setup
🔇 Additional comments (16)
src/platform/auth/workspace/useWorkspaceAuth.ts (5)

1-48: LGTM on imports, schemas, and error class.

Good separation of type imports, comprehensive Zod schemas for runtime validation, and well-defined custom error class with error codes.


50-84: LGTM on composable setup with proper documentation and lifecycle management.

The JSDoc clearly documents the component setup requirement, and the runtime guard at line 60-64 prevents misuse. Good use of useTimeoutFn from VueUse for automatic cleanup, and appropriate use of shallowRef for the workspace object.


125-167: LGTM on session initialization with robust validation.

Proper validation flow: checks feature flag, validates expiry timestamp, uses Zod safeParse for workspace data, and clears storage on any failure. This addresses previous concerns about storage tampering.


169-264: LGTM on switchWorkspace with comprehensive error handling and validation.

Good coverage of error codes (401/403/404/5xx), Zod validation of API response, and explicit isNaN check on the expiry timestamp to prevent refresh loops.


314-343: LGTM on header generation and cleanup.

getWorkspaceAuthHeader and clearWorkspaceContext are straightforward and correctly implemented. The cleanup properly stops the refresh timer before clearing state.

src/platform/auth/workspace/useWorkspaceSwitch.test.ts (3)

1-55: LGTM on test setup with proper mock patterns.

Good use of vi.hoisted() for mock variables, getter pattern for activeWorkflow to avoid stale values, and vi.stubGlobal/vi.unstubAllGlobals for proper location mock cleanup. Based on learnings about keeping module mocks contained.


57-78: LGTM on hasUnsavedChanges tests.

Tests cover the three relevant states: modified workflow, unmodified workflow, and null workflow. These verify actual behavior rather than just mocks.


80-160: LGTM on switchWithConfirmation tests.

Comprehensive behavioral coverage:

  • Same workspace no-op
  • Direct switch without dialog when clean
  • Confirmation dialog shown when dirty
  • User cancel handling
  • User confirm with reload
  • Error handling without reload

Tests properly verify side effects (reload called/not called) and return values.

src/platform/auth/workspace/useWorkspaceAuth.test.ts (8)

1-8: LGTM on imports using the real composable exports.

Importing WORKSPACE_STORAGE_KEYS and WorkspaceAuthError from the composable under test prevents drift between tests and implementation. Based on learnings about importing real type definitions from component modules.


10-20: Custom useTimeoutFn mock enables timer testing.

This mock captures the callback and delay ref, allowing fake timers to control when the refresh callback fires. This approach tests the actual scheduling behavior rather than just verifying useTimeoutFn was called.


89-105: LGTM on consolidated initial state test.

Single test for all initial values avoids change-detector anti-pattern while still verifying the initial contract. Based on past review feedback.


107-202: LGTM on initializeFromSession tests.

Good coverage of:

  • Valid session restoration
  • Empty storage
  • Expired token (with storage cleanup verification)
  • Malformed JSON (with storage cleanup)
  • Partial data (missing token)

Tests verify both return values and side effects on sessionStorage.


204-407: LGTM on switchWorkspace tests.

Comprehensive error code coverage (NOT_AUTHENTICATED, ACCESS_DENIED, WORKSPACE_NOT_FOUND, INVALID_FIREBASE_TOKEN, TOKEN_EXCHANGE_FAILED) plus verification of:

  • State updates (currentWorkspace, workspaceToken, isAuthenticated)
  • Loading state during async operation
  • SessionStorage persistence
  • Correct API request format

These tests verify behavior, not just mock interactions.


492-560: LGTM on token refresh scheduling tests with proper async timer handling.

Uses vi.advanceTimersByTimeAsync for reliable async timer flushing and vi.waitFor for assertions that depend on async cleanup. This addresses past feedback about using consistent async timer handling.


627-638: LGTM on isAuthenticated edge case test.

Tests the edge case where currentWorkspace is set but workspaceToken is null by directly manipulating refs. While this state shouldn't occur through the public API, it validates the computed property's correctness independently.


640-686: LGTM on feature flag disabled tests.

Verifies that both initializeFromSession and switchWorkspace are no-ops when team_workspaces_enabled is false, ensuring the feature can be safely gated.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.37 Backport PRs for cloud 1.37 labels Jan 15, 2026
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: 7

🤖 Fix all issues with AI agents
In `@auth-implementation-review-FINAL.md`:
- Around line 3-24: Update the status language that incorrectly marks PR `#8073`
as merged and the overall header "FULLY IMPLEMENTED & ALIGNED": change the
"Frontend: Workspace Tokens" row (currently "✅ **Merged PR#8073**") to "🔁 In
review / Pending merge (PR `#8073`)" or a conditional phrasing, and replace the
top-level label "FULLY IMPLEMENTED & ALIGNED" with a conditional phrase such as
"IMPLEMENTATION IN PROGRESS / PENDING MERGE" so the Executive Summary accurately
reflects the open PR state.

In `@auth-implementation-review.md`:
- Around line 131-132: The markdown file has several fenced code blocks missing
language identifiers (notably the backtick fences near the areas referenced
around lines 131, 268-269, 287-288, 348-349, and 360-361); update each
triple-backtick fence to include the correct language token (e.g., ```mermaid,
```go, ```typescript, ```json) matching the block contents so markdownlint
passes and syntax highlighting is correct, by locating the fences in the file
and prepending the appropriate language name after the opening ``` for each
block.
- Around line 3-23: Update the "Status" section / "Executive Summary" table and
the "Critical Finding" paragraph to reflect PR `#8073`: change the "Frontend:
Workspace Tokens" and "Frontend: Workspace UI" rows from "NOT IMPLEMENTED" to
the appropriate merged/implemented status (or add a note that this document is a
historical review of PR `#6295`) and adjust the "Critical Finding" sentence
accordingly so it no longer claims tokens/UI are unimplemented; look for the
"Executive Summary" header, the "Status" table, and the "Critical Finding"
paragraph to make these edits.

In `@jwt-firebase-schema.md`:
- Around line 1-9: The example JSON contains live secrets/PII (API key in the
cache key pattern "firebase:authUser:AIzaSy...", and fields like "accessToken",
"refreshToken", "apiKey", "uid", "email", "displayName", "photoURL") — replace
all real tokens, keys and personal identifiers with synthetic placeholders or
redacted templates (e.g. "<REDACTED_API_KEY>", "<REDACTED_ACCESS_TOKEN>",
"<REDACTED_UID>", "<user@example.com>") so the sample key and value use
non-sensitive dummy values while preserving the same shape for
"stsTokenManager", "providerData", "apiKey" and top-level fields.
- Around line 1-9: Add a top-level H1 heading and replace the raw key/value text
with fenced code blocks that include language tags: use a ```text``` fence for
the key string (e.g., the firebase:authUser:... line) and a ```json``` fenced
block for the JSON value; ensure the JSON value is valid/sanitized (use
placeholders like <REDACTED_...> or example values) so the linter rules
MD041/MD040/MD034 are satisfied and bare URLs are not flagged.

In `@src/stores/firebaseAuthStore.ts`:
- Around line 167-183: The logout flow fails to clear workspace sessionStorage
so getAuthHeader() can return a stale WORKSPACE_STORAGE_KEYS.TOKEN after
sign-out; update the sign-out path to call clearWorkspaceContext() (or
equivalent cleanup) when the onAuthStateChanged handler detects user === null or
within the logout() action itself, ensuring WORKSPACE_STORAGE_KEYS.TOKEN and
WORKSPACE_STORAGE_KEYS.EXPIRES_AT are removed from sessionStorage so
getAuthHeader() cannot return a stale Bearer token.

In `@src/stores/workspaceAuthStore.ts`:
- Around line 53-55: refreshToken() can capture a workspace id and later retries
may call switchWorkspace for a stale workspace, overwriting a newer session; add
a request-id/epoch guard and abort logic so only the latest refresh/switch
applies: add an incrementing refreshRequestId (or token) that's updated whenever
the active workspace changes, attach the current id to each attempt inside
refreshToken() and its retry loop, and before calling switchWorkspace (and
before writing to sessionStorage/state) verify the requestId matches the current
active value; also clear/ignore refreshTimerId retries when the active workspace
changes so stale timers cannot apply updates.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c80b7e and 32d401a.

📒 Files selected for processing (15)
  • WORKSPACE_AUTH_IMPLEMENTATION.md
  • auth-implementation-review-FINAL.md
  • auth-implementation-review.md
  • jwt-firebase-schema.md
  • per-tab-auth-analysis.md
  • per-tab-auth-thread-analysis.md
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • storage-strategy.md
  • workspace-token-refresh-analysis.md
🧰 Additional context used
📓 Path-based instructions (14)
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/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.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/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
src/stores/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores as *Store.ts (e.g., nodeStore.ts)

Files:

  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.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/composables/auth/useCurrentUser.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/composables/auth/useCurrentUser.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/composables/auth/useCurrentUser.ts
src/composables/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables as useXyz.ts (e.g., useForm.ts)

Files:

  • src/composables/auth/useCurrentUser.ts
🧠 Learnings (52)
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.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/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-13T05:34:22.209Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:22.209Z
Learning: In Playwright tests in the Comfy-Org/ComfyUI_frontend repository, the `toPass()` assertion method implements incremental backoff during retries, so increasing the timeout value (e.g., to 5000ms) is sufficient for handling async operations without being overly aggressive.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use waitForTimeout in Playwright tests - use Locator actions and retrying assertions instead

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
  • src/platform/auth/session/useSessionCookie.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2026-01-08T02:40:22.621Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:22.621Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: When testing components, import the real type definitions from the component files instead of duplicating interface definitions in the test files. This prevents type drift and maintains consistency.

Applied to files:

  • src/stores/firebaseAuthStore.ts
  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Leverage VueUse functions for performance-enhancing composables

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/composables/**/*.ts : Name composables as `useXyz.ts` (e.g., `useForm.ts`)

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-06T19:20:56.167Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/services/assetService.ts:484-491
Timestamp: 2026-01-06T19:20:56.167Z
Learning: In `src/platform/assets/services/assetService.ts`, prefer using `schema.safeParse()` over `schema.parse()` for validating API responses to avoid throwing ZodError with internal schema details; follow the existing pattern: call `safeParse()`, check `result.success`, and use `fromZodError(result.error)` to format error messages for logging while throwing user-friendly errors.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
  • src/composables/auth/useCurrentUser.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-06T19:17:12.355Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/composables/useUploadModelWizard.ts:207-219
Timestamp: 2026-01-06T19:17:12.355Z
Learning: In `src/platform/assets/composables/useUploadModelWizard.ts`, the `uploadModel()` function should have a concurrency guard at the beginning that checks if `isUploading.value` is already true and returns false early to prevent race conditions from multiple rapid invocations.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement cleanup for async operations in Vue components

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Avoid using `ref` with `watch` if a `computed` would suffice - minimize refs and derived state

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Watch out for Code Smells and refactor to avoid them

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use useIntersectionObserver for visibility detection instead of custom scroll handlers

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Use `ref` for reactive state, `computed()` for derived values, and `watch`/`watchEffect` for side effects in Composition API

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/stores/**/*.ts : Name Pinia stores as `*Store.ts` (e.g., `nodeStore.ts`)

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Use TypeScript for type safety in state management stores

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2026-01-08T21:44:05.435Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7897
File: src/stores/assetDownloadStore.ts:117-117
Timestamp: 2026-01-08T21:44:05.435Z
Learning: In src/stores/assetDownloadStore.ts, the api.addEventListener('asset_download', handleAssetDownload) call at module level is intentional and should persist for the application lifetime since it's a singleton Pinia store managing global WebSocket events.

Applied to files:

  • src/stores/workspaceAuthStore.ts
🧬 Code graph analysis (5)
src/platform/auth/workspace/useWorkspaceAuth.test.ts (3)
src/platform/auth/workspace/useWorkspaceAuth.ts (3)
  • useWorkspaceAuth (8-30)
  • WORKSPACE_STORAGE_KEYS (5-5)
  • WorkspaceAuthError (6-6)
src/platform/auth/workspace/workspaceConstants.ts (1)
  • WORKSPACE_STORAGE_KEYS (1-5)
src/stores/workspaceAuthStore.ts (1)
  • WorkspaceAuthError (36-44)
src/platform/auth/workspace/workspaceConstants.ts (1)
src/platform/auth/workspace/useWorkspaceAuth.ts (1)
  • WORKSPACE_STORAGE_KEYS (5-5)
src/stores/firebaseAuthStore.ts (4)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/platform/auth/workspace/useWorkspaceAuth.ts (1)
  • WORKSPACE_STORAGE_KEYS (5-5)
src/platform/auth/workspace/workspaceConstants.ts (1)
  • WORKSPACE_STORAGE_KEYS (1-5)
src/platform/auth/workspace/useWorkspaceAuth.ts (1)
src/stores/workspaceAuthStore.ts (1)
  • useWorkspaceAuthStore (46-345)
src/stores/workspaceAuthStore.ts (6)
src/platform/auth/workspace/useWorkspaceAuth.ts (2)
  • WorkspaceAuthError (6-6)
  • WORKSPACE_STORAGE_KEYS (5-5)
src/platform/auth/workspace/workspaceTypes.ts (1)
  • WorkspaceWithRole (1-6)
src/platform/auth/workspace/workspaceConstants.ts (2)
  • TOKEN_REFRESH_BUFFER_MS (7-7)
  • WORKSPACE_STORAGE_KEYS (1-5)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
🪛 LanguageTool
WORKSPACE_AUTH_IMPLEMENTATION.md

[grammar] ~141-~141: Ensure spelling is correct
Context: ...res Firebase token validation (adds ~50-100ms per refresh, 24x/day per user = negligi...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~640-~640: Ensure spelling is correct
Context: ...ce.value) </script> ``` Integrate into topbar (e.g., `src/components/topbar/ComfyTopb...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~1188-~1188: Ensure spelling is correct
Context: ... 1. Integrate WorkspaceSwitcher into topbar 2. Add workspace initialization to app moun...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~1269-~1269: Consider an alternative adverb to strengthen your wording.
Context: ...Fix: - Ensure auto-refresh timer is properly cleaned up in onUnmounted - Use singl...

(PROPERLY_THOROUGHLY)


[grammar] ~1387-~1387: Ensure spelling is correct
Context: ...ytes - Token expiry timestamp: ~15 bytes - ClientId: ~50 bytes Total: ~1.5 KB per tab ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[uncategorized] ~1456-~1456: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... on Switch**: Workspace switch requires full page reload - Mitigation: Future enhancem...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

per-tab-auth-thread-analysis.md

[style] ~117-~117: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... - Workspace-specific node favorites? - Workspace-specific recent items? --- ### 🟡 **MEDIUM: Fu...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~138-~138: Use a hyphen to join words.
Context: .... User Experience: - Jarring full page reload - Loss of ephemeral UI st...

(QB_NEW_EN_HYPHEN)

auth-implementation-review.md

[grammar] ~394-~394: Ensure spelling is correct
Context: ...ic 3. ❌ Workspace token refresh (before 1hr expiry) 4. ❌ Per-tab workspace context ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~1103-~1103: Ensure spelling is correct
Context: ...initial load - Workspace switcher in topbar - Visual indicator of current workspace 3...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

workspace-token-refresh-analysis.md

[uncategorized] ~108-~108: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ls than native refresh token flow 3. Rate Limiting Exposure - Firebase token verifica...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[grammar] ~111-~111: Ensure spelling is correct
Context: ...imits - Though: Workspace tokens are 1hr, so only 24 refreshes/day per user 4. ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

auth-implementation-review-FINAL.md

[grammar] ~237-~237: Ensure spelling is correct
Context: ...h signing to Slot 2 4. After token TTL (1hr), remove Slot 1 from JWKS 5. Move Slot ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~703-~703: Ensure spelling is correct
Context: ...*: Workspace token from sessionStorage (1hr window) 2. ❌ Cannot steal: Firebase...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~711-~711: Ensure spelling is correct
Context: ...Storing Firebase token in localStorage (1hr compromise) - Better: httpOnly cook...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~960-~960: Ensure spelling is correct
Context: ...Refresh**: - Timer scheduled correctly (5min before expiry) - Refresh calls switchWo...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~1187-~1187: Ensure spelling is correct
Context: ...orage isolation - ✅ Auto token refresh (5min before expiry) - ✅ Error handling for a...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~1206-~1206: Ensure spelling is correct
Context: ... key management - ✅ Short-lived tokens (1hr TTL) - ✅ Zero-downtime key rotation - ✅...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
jwt-firebase-schema.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


3-3: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


9-9: Bare URL used

(MD034, no-bare-urls)


9-9: Bare URL used

(MD034, no-bare-urls)


9-9: Bare URL used

(MD034, no-bare-urls)


9-9: Bare URL used

(MD034, no-bare-urls)

auth-implementation-review.md

131-131: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


268-268: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


287-287: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


348-348: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


360-360: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

workspace-token-refresh-analysis.md

125-125: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


126-126: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


126-126: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


136-136: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


137-137: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


137-137: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


149-149: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


150-150: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


150-150: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


163-163: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


164-164: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


164-164: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


305-305: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


305-305: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


310-310: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


327-327: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


327-327: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


336-336: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


337-337: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


337-337: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


348-348: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


349-349: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


349-349: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


368-368: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


369-369: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


369-369: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


379-379: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


380-380: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


380-380: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


548-548: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


555-555: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

⏰ 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: setup
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (7)
src/composables/auth/useCurrentUser.ts (1)

43-46: Logout watcher now correctly gates on the non-null → null transition.

This avoids false positives on initial null emissions.

src/platform/auth/workspace/workspaceConstants.ts (1)

1-7: Centralized constants look good.

Single source of truth for storage keys and refresh buffer improves maintainability.

src/platform/auth/workspace/useWorkspaceAuth.test.ts (1)

57-67: [Your rewritten review comment text here]
[Exactly ONE classification tag]

src/platform/auth/workspace/useWorkspaceAuth.ts (1)

8-29: Clean wrapper with a stable public surface.
The composable cleanly exposes the store state and actions without extra side effects.

src/platform/auth/session/useSessionCookie.ts (1)

27-47: Verify API-key session creation when team workspaces are enabled.
When team_workspaces_enabled is true, createSession only uses getIdToken() and returns early if absent (Line 27-35). If API-key auth is still a supported cloud path, session cookies will never be created. Please confirm the intended behavior or add an explicit API-key fallback.

workspace-token-refresh-analysis.md (1)

1-24: Clear, implementation-aligned analysis.
The recommendation and flow description match the shipped Firebase token exchange approach.

per-tab-auth-analysis.md (1)

113-123: Risk assessment is clear and actionable.
The matrix and API-key caveat make the tradeoffs explicit and align with the per-tab strategy.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@coderabbitai coderabbitai bot requested a review from Myestery January 15, 2026 22:37
christian-byrne and others added 12 commits January 15, 2026 16:19
Add WorkspaceWithRoleSchema validation for parsed session storage data
to ensure data integrity before using it. If validation fails,
clear session storage and return false.
Add workspace.unsavedChanges.title and workspace.unsavedChanges.message
for the confirmation dialog shown when switching workspaces with
unsaved changes. Also add workspaceAuth.errors.* keys for all error
messages used by useWorkspaceAuth.
Replace module-scope mock variables with vi.hoisted() so they exist
before vi.mock runs. Also use getter for activeWorkflow to ensure
updates to mockActiveWorkflow in tests are reflected at call time.
Add test verifying isAuthenticated returns false when currentWorkspace
is set but workspaceToken is null.
Add documentation and runtime check to ensure useWorkspaceAuth is
called from within a Vue component setup function, as it relies on
onUnmounted for cleanup. Throws a clear error if called outside
of component context.
Implement retry logic with exponential backoff (1s, 2s, 4s) for
TOKEN_EXCHANGE_FAILED errors in refreshToken. Only clear workspace
context on permanent errors (ACCESS_DENIED, WORKSPACE_NOT_FOUND).
After max retries, log error but don't clear context to allow
manual recovery.
The interface is no longer needed since we use Zod schema for
runtime validation of API responses.
…g, and fix tests

- Replace manual setTimeout/clearTimeout with VueUse's useTimeoutFn for automatic cleanup on unmount
- Clear workspace context on all terminal errors in refreshToken (ACCESS_DENIED, WORKSPACE_NOT_FOUND, INVALID_FIREBASE_TOKEN, NOT_AUTHENTICATED, and after exhausting retries)
- Import WORKSPACE_STORAGE_KEYS from module in tests instead of duplicating
- Use vi.stubGlobal for window.location mock instead of Object.defineProperty
- Use vi.advanceTimersByTimeAsync for proper timer flush in tests

Amp-Thread-ID: https://ampcode.com/threads/T-019bc39a-2d74-740e-8723-4f7c0f607e92
Co-authored-by: Amp <amp@ampcode.com>
…issues

- Convert useWorkspaceAuth composable to workspaceAuthStore for proper
  global singleton state management
- Replace VueUse useTimeoutFn with native setTimeout for timer management
- Remove getCurrentInstance() guard (stores don't need component context)
- Extract WORKSPACE_STORAGE_KEYS to workspaceConstants.ts to avoid
  circular dependencies
- Keep useWorkspaceAuth() as backward-compatible wrapper

Fix session cookie error handling:
- createSession: log warnings instead of throwing (graceful degradation)
- deleteSession: log warnings instead of throwing (logout always succeeds)

Fix onUserLogout firing on initial mount:
- Check prevUser && !user to only fire on logout transition

Amp-Thread-ID: https://ampcode.com/threads/T-019bc3ba-76df-764f-8e1e-73864ff0b477
Co-authored-by: Amp <amp@ampcode.com>
- Delete useWorkspaceAuth.ts composable wrapper entirely
- Update useWorkspaceSwitch.ts to import useWorkspaceAuthStore with storeToRefs
- Update tests to use the store directly instead of the wrapper
- Consumers now import from @/stores/workspaceAuthStore directly
- Update auth-implementation-review docs to reflect PR #8073 status
- Redact PII/secrets in jwt-firebase-schema.md
- Clear workspace sessionStorage on logout in firebaseAuthStore
- Add request-id guard to workspaceAuthStore refreshToken() to prevent
  stale refresh operations from overwriting newer workspace contexts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@simula-r simula-r force-pushed the feat/workspace-auth-infrastructure branch from ecc2ae7 to 29d84fc Compare January 16, 2026 00:19
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: 3

🤖 Fix all issues with AI agents
In `@src/platform/auth/workspace/useWorkspaceSwitch.test.ts`:
- Around line 6-8: Replace the ad-hoc inline type in the test's
mockCurrentWorkspace with the real WorkspaceWithRole type: import
WorkspaceWithRole into the test, create a small fixture object conforming to
WorkspaceWithRole (e.g., minimal { id: string, /* required role fields */ }) and
use that fixture for mockCurrentWorkspace.value (or null) instead of `null as {
id: string } | null`; update the hoisted mockCurrentWorkspace declaration to
reference the imported type/fixture so the test stays in sync with the real
type.
- Around line 10-15: The test is mocking the wrong module; replace the vi.mock
target to mock '@/stores/workspaceAuthStore' instead of
'@/platform/auth/workspace/useWorkspaceAuth' and return useWorkspaceAuthStore:
() => ({ currentWorkspace: mockCurrentWorkspace, switchWorkspace:
mockSwitchWorkspace }); also update the mockCurrentWorkspace's type to
WorkspaceWithRole (import WorkspaceWithRole from
'@/platform/auth/workspace/workspaceTypes') so the test shape matches the real
store and prevents type drift; ensure the test imports or declares
WorkspaceWithRole and uses that type for mockCurrentWorkspace and any related
assertions.

In `@src/platform/auth/workspace/useWorkspaceSwitch.ts`:
- Around line 15-17: The hasUnsavedChanges function currently only checks
workflowStore.activeWorkflow?.isModified, which misses unsaved changes in other
tabs; update hasUnsavedChanges to return true if any workflow in
workflowStore.modifiedWorkflows (or by iterating workflowStore.workflows and
checking .isModified) is modified so the workspace switch confirmation triggers
for any modified workflow; locate the hasUnsavedChanges function and replace the
single-active check with a check against workflowStore.modifiedWorkflows (or an
any/isModified predicate) and keep the boolean return semantics.
♻️ Duplicate comments (9)
src/composables/auth/useCurrentUser.ts (1)

43-46: Return the watcher disposer to allow cleanup.
watch() returns a stop handle, but onUserLogout discards it, which can leave subscriptions alive when used outside component scope or registered multiple times. Based on learnings, please return the disposer.

♻️ Proposed fix
-  const onUserLogout = (callback: () => void) => {
-    watch(resolvedUserInfo, (user, prevUser) => {
-      if (prevUser && !user) callback()
-    })
-  }
+  const onUserLogout = (callback: () => void) =>
+    watch(resolvedUserInfo, (user, prevUser) => {
+      if (prevUser && !user) callback()
+    })
src/platform/auth/workspace/useWorkspaceSwitch.test.ts (1)

57-159: Use test(...) instead of it(...) for Vitest cases.
Project test conventions standardize on test. Based on learnings.

src/stores/firebaseAuthStore.ts (2)

176-177: Use feature-flag fallback instead of direct remoteConfig check.

The direct remoteConfig.value.team_workspaces_enabled check can skip workspace tokens before remote config loads; prefer the feature-flag composable to keep behavior consistent.


184-187: Guard against NaN expiry values.

parseInt can return NaN; add an explicit check so malformed values are treated as expired.

♻️ Suggested fix
-      if (workspaceToken && expiresAt) {
-        const expiryTime = parseInt(expiresAt, 10)
-        if (Date.now() < expiryTime) {
+      if (workspaceToken && expiresAt) {
+        const expiryTime = parseInt(expiresAt, 10)
+        if (!Number.isNaN(expiryTime) && Date.now() < expiryTime) {
           return {
             Authorization: `Bearer ${workspaceToken}`
           }
         }
       }
src/platform/auth/workspace/useWorkspaceSwitch.ts (1)

36-41: Log the switch failure for diagnostics.

The catch swallows the error, which makes failures hard to trace in production.

♻️ Suggested improvement
-    } catch {
+    } catch (error) {
+      console.error('Failed to switch workspace:', error)
       return false
     }
src/platform/auth/workspace/useWorkspaceAuth.test.ts (2)

2-2: Prefer test(...) over it(...) in Vitest suites.

Please swap it to test (and update the import) for consistency across this file. Based on learnings, keep Vitest cases on test(...).

♻️ Example change
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
+import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'

-  it('has correct initial state values', () => {
+  test('has correct initial state values', () => {

Also applies to: 70-87


66-68: Restore stubbed globals between tests.

vi.stubGlobal is used across the suite; add vi.unstubAllGlobals() in afterEach to avoid leakage across tests. Based on learnings, keep module mocks contained.

♻️ Suggested fix
   afterEach(() => {
+    vi.unstubAllGlobals()
     vi.useRealTimers()
   })
src/stores/workspaceAuthStore.ts (2)

17-34: The viewer role is still missing from the Zod schemas.

The role enums only include 'owner' and 'member'. As noted in a previous review, if the backend supports a 'viewer' role, requests with that role will fail Zod validation. Additionally, the WorkspaceWithRole type in src/platform/auth/workspace/workspaceTypes.ts also only has 'owner' | 'member'.

If the backend does support 'viewer', both the Zod schemas here and the TypeScript type need to be updated:

Proposed fix
 const WorkspaceWithRoleSchema = z.object({
   id: z.string(),
   name: z.string(),
   type: z.enum(['personal', 'team']),
-  role: z.enum(['owner', 'member'])
+  role: z.enum(['owner', 'member', 'viewer'])
 })

 const WorkspaceTokenResponseSchema = z.object({
   token: z.string(),
   expires_at: z.string(),
   workspace: z.object({
     id: z.string(),
     name: z.string(),
     type: z.enum(['personal', 'team'])
   }),
-  role: z.enum(['owner', 'member']),
+  role: z.enum(['owner', 'member', 'viewer']),
   permissions: z.array(z.string())
 })

Please confirm whether the backend API supports a 'viewer' role. If it does, both the Zod schemas and the WorkspaceWithRole type in workspaceTypes.ts need updating.


166-265: The refreshRequestId++ on every switchWorkspace call breaks token refresh retries.

When refreshToken() calls switchWorkspace(), the request ID increment (line 172) makes the capturedRequestId stale, causing subsequent retry attempts to abort at line 280.

Flow:

  1. refreshToken() captures refreshRequestId = N
  2. First retry calls switchWorkspace() → increments to N+1
  3. If it fails, next loop iteration checks N !== N+1 → aborts

This means retries will never execute because the first switchWorkspace call always invalidates them.

Proposed fix: only increment request ID for user-initiated workspace switches
-  async function switchWorkspace(workspaceId: string): Promise<void> {
+  async function switchWorkspace(
+    workspaceId: string,
+    options: { isRefresh?: boolean } = {}
+  ): Promise<void> {
     if (!remoteConfig.value.team_workspaces_enabled) {
       return
     }

-    // Increment request ID to invalidate any in-flight stale refresh operations
-    refreshRequestId++
+    // Only increment request ID for user-initiated switches (not refreshes)
+    // This invalidates stale refresh operations without breaking retry logic
+    if (!options.isRefresh) {
+      refreshRequestId++
+    }

     isLoading.value = true

Then update refreshToken to pass the flag:

       try {
-        await switchWorkspace(workspaceId)
+        await switchWorkspace(workspaceId, { isRefresh: true })
         return
       } catch (err) {
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ecc2ae7 and 29d84fc.

📒 Files selected for processing (12)
  • src/composables/auth/useCurrentUser.ts
  • src/composables/useFeatureFlags.ts
  • src/locales/en/main.json
  • src/platform/auth/session/useSessionCookie.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/remoteConfig/types.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
🧰 Additional context used
📓 Path-based instructions (14)
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/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
src/**/*.ts

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

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

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.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

src/**/*.{ts,tsx,vue}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.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/composables/auth/useCurrentUser.ts
  • src/composables/useFeatureFlags.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/composables/auth/useCurrentUser.ts
  • src/composables/useFeatureFlags.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/composables/auth/useCurrentUser.ts
  • src/composables/useFeatureFlags.ts
src/composables/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name composables as useXyz.ts (e.g., useForm.ts)

Files:

  • src/composables/auth/useCurrentUser.ts
  • src/composables/useFeatureFlags.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/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
src/stores/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name Pinia stores as *Store.ts (e.g., nodeStore.ts)

Files:

  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
🧠 Learnings (43)
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Don't Mock What You Don't Own

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.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/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use waitForTimeout in Playwright tests - use Locator actions and retrying assertions instead

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Tests should be cross-platform compatible using `path.resolve`, `path.join`, and `path.sep` for Windows, macOS, and Linux compatibility

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.test.ts
  • src/platform/remoteConfig/types.ts
  • src/platform/auth/workspace/workspaceTypes.ts
  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
  • src/composables/auth/useCurrentUser.ts
  • src/stores/firebaseAuthStore.ts
  • src/stores/workspaceAuthStore.ts
  • src/platform/auth/workspace/workspaceConstants.ts
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/auth/session/useSessionCookie.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/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-22T21:36:46.909Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:46.909Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-13T05:34:22.209Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:22.209Z
Learning: In Playwright tests in the Comfy-Org/ComfyUI_frontend repository, the `toPass()` assertion method implements incremental backoff during retries, so increasing the timeout value (e.g., to 5000ms) is sufficient for handling async operations without being overly aggressive.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceAuth.test.ts
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/locales/en/main.json
  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • src/composables/auth/useCurrentUser.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/stores/**/*.ts : Name Pinia stores as `*Store.ts` (e.g., `nodeStore.ts`)

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Maintain clear public interfaces and restrict extension access in stores

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Use TypeScript for type safety in state management stores

Applied to files:

  • src/stores/workspaceAuthStore.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use vue-i18n for all string literals in Vue components - place translation entries in `src/locales/en/main.json`

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-12-05T20:35:28.330Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/locales/en/main.json:2257-2272
Timestamp: 2025-12-05T20:35:28.330Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, vue-i18n pluralization uses a two-parameter pattern: `t('key', { count: value })` where the `count` property in the interpolation object automatically triggers plural selection from pipe-separated locale strings (e.g., "no items | 1 item | {count} items"). This is the correct pattern used throughout the codebase, as validated by Playwright tests.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
📚 Learning: 2026-01-09T23:59:06.942Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7926
File: src/stores/assetDownloadStore.ts:101-126
Timestamp: 2026-01-09T23:59:06.942Z
Learning: In src/stores/assetDownloadStore.ts, the empty catch block in pollSingleDownload within pollStaleDownloads is intentional. Do not suggest adding error logging or handling for polling failures in this function.

Applied to files:

  • src/platform/auth/workspace/useWorkspaceSwitch.ts
🧬 Code graph analysis (5)
src/platform/auth/workspace/useWorkspaceSwitch.test.ts (1)
src/platform/auth/workspace/useWorkspaceSwitch.ts (1)
  • useWorkspaceSwitch (8-49)
src/stores/firebaseAuthStore.ts (3)
src/platform/auth/workspace/workspaceConstants.ts (1)
  • WORKSPACE_STORAGE_KEYS (1-5)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/stores/workspaceAuthStore.ts (5)
src/platform/auth/workspace/workspaceTypes.ts (1)
  • WorkspaceWithRole (1-6)
src/platform/auth/workspace/workspaceConstants.ts (2)
  • TOKEN_REFRESH_BUFFER_MS (7-7)
  • WORKSPACE_STORAGE_KEYS (1-5)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
src/types/authTypes.ts (1)
  • AuthHeader (9-9)
src/platform/auth/workspace/useWorkspaceSwitch.ts (2)
src/platform/workflow/management/stores/workflowStore.ts (1)
  • useWorkflowStore (208-863)
src/services/dialogService.ts (1)
  • useDialogService (48-570)
src/composables/useFeatureFlags.ts (2)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1336-1336)
⏰ 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: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect
  • GitHub Check: setup
🔇 Additional comments (16)
src/platform/remoteConfig/types.ts (1)

45-45: LGTM — optional flag addition is safe and backward compatible.

src/platform/auth/workspace/workspaceTypes.ts (1)

1-6: LGTM — clear and appropriately scoped workspace type.

src/platform/auth/workspace/workspaceConstants.ts (1)

1-7: LGTM — constants are clear and consistent.

src/composables/useFeatureFlags.ts (1)

20-22: LGTM — remote-first flag resolution matches existing pattern.

Also applies to: 96-101

src/stores/firebaseAuthStore.ts (1)

110-120: Good cleanup of workspace session state on logout.

This prevents stale workspace tokens from persisting after sign-out.

src/locales/en/main.json (1)

2595-2609: Workspace strings look complete.

Thanks for adding the new i18n keys for unsaved changes and workspace auth errors.

src/platform/auth/session/useSessionCookie.ts (1)

22-67: Session creation update looks solid.

Using Firebase ID tokens when workspaces are enabled avoids passing workspace-scoped JWTs to the session endpoint, and the warning-based error handling keeps the flow resilient.

src/stores/workspaceAuthStore.ts (9)

1-16: LGTM!

Imports are properly organized with type imports separated as per coding guidelines. Good use of shallowRef for the workspace object.


36-44: LGTM!

Clean custom error class with proper error identification and optional error codes for categorization.


46-62: LGTM!

Good use of shallowRef for the workspace object and proper computed getter for isAuthenticated. The mutable let variables for timer and request ID are appropriate here since they need to be reassigned for their functionality.


64-81: LGTM!

Clean timer management with proper cleanup and safe delay calculation using Math.max(0, ...).


83-111: LGTM!

Good defensive coding around sessionStorage operations, which can throw in private browsing mode. Silent failure with warning is appropriate for non-critical persistence.


113-164: LGTM!

Clean session lifecycle management with proper validation of stored data. The Zod schema validation before using session data is a good defensive practice.


267-329: Good retry logic structure, but blocked by the issue above.

The retry mechanism with exponential backoff and distinction between permanent/transient errors is well-designed. The stale request ID checks (lines 280, 302, 323) correctly prevent state overwrites after workspace switches.

However, as noted in the previous comment, this logic is currently broken because switchWorkspace always increments refreshRequestId.

Once the switchWorkspace fix is applied, verify the retry behavior works correctly.


331-348: LGTM!

Clean implementations. clearWorkspaceContext correctly increments refreshRequestId to invalidate any in-flight refresh operations before clearing state.


350-369: LGTM!

Clean public API surface. Private helpers are correctly encapsulated within the store. As per learnings, the store maintains a clear public interface.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

- Update hasUnsavedChanges to check modifiedWorkflows instead of just activeWorkflow
- Fix test to mock workspaceAuthStore instead of useWorkspaceAuth
- Use WorkspaceWithRole type for mockCurrentWorkspace

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@simula-r simula-r force-pushed the feat/workspace-auth-infrastructure branch from d8bc757 to 24e7d95 Compare January 16, 2026 01:13
@simula-r simula-r merged commit 6048fab into main Jan 16, 2026
28 checks passed
@simula-r simula-r deleted the feat/workspace-auth-infrastructure branch January 16, 2026 01:24
github-actions bot pushed a commit that referenced this pull request Jan 16, 2026
## Summary
Add workspace authentication composables and types for per-tab workspace
isolation. This infrastructure enables users to work in different
workspaces in different browser tabs.

## Changes
- **useWorkspaceAuth composable** - workspace token management
- Exchange Firebase token for workspace-scoped JWT via `POST
/api/auth/token`
  - Auto-refresh tokens 5 minutes before expiry
  - Per-tab sessionStorage caching
- **useWorkspaceSwitch composable** - workspace switching with unsaved
changes confirmation
- **WorkspaceWithRole/WorkspaceTokenResponse types** - aligned with
backend API
- **firebaseAuthStore.getAuthHeader()** - prioritizes workspace tokens
over Firebase tokens
- **useSessionCookie** - uses Firebase token directly (getIdToken())
since getAuthHeader() now returns workspace token

## Backend Dependency
- `POST /api/auth/token` - exchange Firebase token for workspace token
- `GET /api/workspaces` - list user's workspaces

## Related
- #6295

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8073-feat-add-per-tab-workspace-authentication-infrastructure-2e96d73d3650816c8cf9dae9c330aebb)
by [Unito](https://www.unito.io)

---------

Co-authored-by: anthropic/claude <noreply@anthropic.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Simula_r <18093452+simula-r@users.noreply.github.com>
@comfy-pr-bot
Copy link
Member

@christian-byrne Successfully backported to #8089

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Jan 16, 2026
simula-r added a commit that referenced this pull request Jan 22, 2026
…astructure (#8089)

Backport of #8073 to `cloud/1.37`

Automatically created by backport workflow.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8089-backport-cloud-1-37-feat-add-per-tab-workspace-authentication-infrastructure-2ea6d73d36508133ace5f3b984f5ae96)
by [Unito](https://www.unito.io)

Co-authored-by: Christian Byrne <cbyrne@comfy.org>
Co-authored-by: anthropic/claude <noreply@anthropic.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Simula_r <18093452+simula-r@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:auth area:cloud cloud/1.37 Backport PRs for cloud 1.37 size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants