Skip to content

feat(persistence): add workspace-scoped storage keys and types#8517

Merged
christian-byrne merged 2 commits intomainfrom
01-31-feat_persistence_add_v2_infrastructure_1_4_
Feb 19, 2026
Merged

feat(persistence): add workspace-scoped storage keys and types#8517
christian-byrne merged 2 commits intomainfrom
01-31-feat_persistence_add_v2_infrastructure_1_4_

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Feb 1, 2026

Summary

Adds the foundational types and key generation utilities for workspace-scoped workflow draft persistence. This enables storing drafts per-workspace to prevent data leakage between different ComfyUI instances.

Screencast.from.2026-02-08.18-17-45.webm

Changes

  • What: Type definitions for draft storage (DraftIndexV2, DraftPayloadV2, session pointers) and key generation utilities with workspace/client scoping
  • Why: The current persistence system stores all drafts globally, causing cross-workspace data leakage when users work with multiple ComfyUI instances

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 1, 2026

📝 Walkthrough

Walkthrough

A new V2 draft persistence system is introduced with type definitions for draft metadata and storage structures, FNV-1a hash utilities for path-based key generation, and workspace-scoped storage key management functions. Includes comprehensive test coverage for all new utilities.

Changes

Cohort / File(s) Summary
Draft Type Definitions
src/platform/workflow/persistence/base/draftTypes.ts
Defines V2 draft persistence types including DraftEntryMeta, DraftIndexV2, DraftPayloadV2, ActivePathPointer, and OpenPathsPointer interfaces. Adds MAX_DRAFTS (32) and PERSIST_DEBOUNCE_MS (512) constants for configuration.
Hash Utilities
src/platform/workflow/persistence/base/hashUtil.ts, src/platform/workflow/persistence/base/hashUtil.test.ts
Implements fnv1a() for 32-bit hash computation and hashPath() for generating 8-character hex keys from paths. Tests validate consistency, bounds, Unicode handling, and specific output formatting.
Storage Key Management
src/platform/workflow/persistence/base/storageKeys.ts, src/platform/workflow/persistence/base/storageKeys.test.ts
Provides getWorkspaceId() function and StorageKeys constant with key generators (draftIndex, draftPayload, draftKey, activePath, openPaths) for workspace-scoped and client-specific storage keys. Tests verify correct key generation and workspace ID resolution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hops with glee through storage keys so bright,
Draft persistence blooms, a V2 sight!
Hashes hop along, paths find their way,
Workspace-scoped drafts save the day!
Type-safe and tested, a foundation so right! 🌾✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding workspace-scoped storage keys and types for draft persistence.
Description check ✅ Passed The description follows the template structure with Summary and Changes sections that clearly explain what was added and why, addressing the workspace data leakage problem.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 01-31-feat_persistence_add_v2_infrastructure_1_4_

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

Copy link
Contributor Author

christian-byrne commented Feb 1, 2026

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 02/18/2026, 11:26:37 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

Playwright: ✅ 524 passed, 0 failed · 2 flaky

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

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

Bundle Size Report

Summary

  • Raw size: 20 MB baseline 20 MB — ⚪ 0 B
  • Gzip: 4.26 MB baseline 4.26 MB — ⚪ 0 B
  • Brotli: 3.31 MB baseline 3.31 MB — ⚪ 0 B
  • Bundles: 231 current • 231 baseline

Category Glance
Vendor & Third-Party ⚪ 0 B (8.69 MB) · Other ⚪ 0 B (7.42 MB) · Data & Services ⚪ 0 B (2.16 MB) · Graph Workspace ⚪ 0 B (905 kB) · Panels & Settings ⚪ 0 B (427 kB) · Utilities & Hooks ⚪ 0 B (237 kB) · + 5 more

Per-category breakdown
App Entry Points — 21.7 kB (baseline 21.7 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BiEUGbUA.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Graph Workspace — 905 kB (baseline 905 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-B9ax1Zj_.js 905 kB 905 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Views & Navigation — 69 kB (baseline 69 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudAuthTimeoutView--frGssbH.js 4.96 kB 4.96 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudForgotPasswordView-K2yGvZeP.js 5.61 kB 5.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudLayoutView-CA3b1PQy.js 6.48 kB 6.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudLoginView-t4oym2gh.js 10.1 kB 10.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSignupView-ho-TzsLX.js 7.46 kB 7.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSorryContactSupportView-Dt5tckIJ.js 1.02 kB 1.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSubscriptionRedirectView-BGr14WuB.js 4.76 kB 4.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudSurveyView-B4IZR28d.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-Dw2vG5GB.js 296 B 296 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserCheckView-CXwh8w1y.js 8.41 kB 8.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserSelectView-CQK9v7jW.js 4.5 kB 4.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Panels & Settings — 427 kB (baseline 427 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/AboutPanel-LCqoDpN2.js 8.53 kB 8.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudRemoteConfig-DIv1nGek.js 1.49 kB 1.49 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/config-CH_cdA2N.js 996 B 996 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ExtensionPanel-bpoMdzRV.js 9.43 kB 9.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/KeybindingPanel-Ck7cnOgB.js 12.4 kB 12.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LegacyCreditsPanel-B5TrMq-9.js 20.7 kB 20.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/refreshRemoteConfig-kBOn1Axr.js 1.14 kB 1.14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SecretsPanel-DDWUtGKY.js 21.5 kB 21.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ServerConfigPanel-BBkWN3Lg.js 6.5 kB 6.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BPLxqAe3.js 29.8 kB 29.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BUIbWSEk.js 28 kB 28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C0d1Q_Kv.js 27.1 kB 27.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CAXBW2_0.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Cjk3QxCD.js 37.6 kB 37.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CrmQjb0f.js 31.6 kB 31.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D1AmG0ju.js 23.3 kB 23.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D6ltw1Hs.js 29.2 kB 29.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DqZYOPVX.js 23.9 kB 23.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DubbIIfi.js 28.1 kB 28.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-wh8yrcgf.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionPanel-kV0AvbEz.js 18.7 kB 18.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserPanel-YI6jKXnp.js 6.21 kB 6.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
User & Accounts — 16.1 kB (baseline 16.1 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-Bo0uaOOK.js 357 B 357 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auth-Dl-HIber.js 3.4 kB 3.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/firebaseAuthStore-BT-2yZcL.js 837 B 837 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/PasswordFields-PRmvmozX.js 4.51 kB 4.51 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SignUpForm-0_lw73mQ.js 3.01 kB 3.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UpdatePasswordContent-BHhDcxKF.js 2.42 kB 2.42 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspaceProfilePic-BbVtvHlF.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Editors & Dialogs — 785 B (baseline 785 B) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-Bz7d5yx9.js 785 B 785 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
UI Components — 36.6 kB (baseline 36.6 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Button-BSbVSHEC.js 2.98 kB 2.98 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudBadge-QozxHIt4.js 1.24 kB 1.24 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudFeedbackTopbarButton-BPCf20vq.js 1.64 kB 1.64 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyQueueButton-rlEjEIaK.js 7.17 kB 7.17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyQueueButton-VIo5UorP.js 842 B 842 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscribeButton-D7V7JFsu.js 2.35 kB 2.35 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/TopbarBadge-CFCM1GaS.js 7.45 kB 7.45 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-BG_h7fX0.js 1.17 kB 1.17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useTerminalTabs-CaJZi6Xz.js 9.89 kB 9.89 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-C-W7fvtO.js 1.84 kB 1.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Data & Services — 2.16 MB (baseline 2.16 MB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/api-G3buPaUX.js 647 kB 647 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/audioService-D9U7_blV.js 1.73 kB 1.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/bootstrapStore-C847N-Sg.js 2.08 kB 2.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/dialogService-CzToVyoa.js 1.38 MB 1.38 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/dialogService-Dcbzq7Us.js 774 B 774 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/dialogStore-DqEczCra.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/keybindingService-2z9GWgAk.js 6.57 kB 6.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/load3dService-DxrSdD5-.js 91 kB 91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/releaseStore-CGO0phkD.js 809 B 809 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/releaseStore-v1cj7S4Q.js 7.96 kB 7.96 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/serverConfigStore-DUe9-l1S.js 2.32 kB 2.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settingStore-D82P2Gwe.js 793 B 793 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/systemStatsStore-DzbABsdo.js 12.2 kB 12.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/userStore-BDSDHu9M.js 1.85 kB 1.85 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/workflowDraftStore-DcEty3KW.js 785 B 785 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
Utilities & Hooks — 237 kB (baseline 237 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/_plugin-vue_export-helper-BYZQdlgo.js 315 B 315 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/audioUtils-CAtNmhjC.js 858 B 858 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-CZQOOTdR.js 7 kB 7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/envUtil-C9Y4v_FL.js 466 B 466 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-Dct6u2-O.js 1.56 kB 1.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SkeletonUtils-CsnHjXS0.js 133 B 133 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/subscriptionCheckoutUtil-CIO-N4CK.js 2.53 kB 2.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useConflictDetection-BxdlsAh7.js 178 kB 178 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useCopyToClipboard-N_vzUkgQ.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useCurrentUser-BubVcADY.js 771 B 771 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useErrorHandling-9wDdGMXn.js 1.47 kB 1.47 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useExternalLink-B5xMNx28.js 1.66 kB 1.66 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useFeatureFlags-FkG-exBc.js 3.5 kB 3.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3d-BLqPvIUg.js 908 B 908 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3d-BzE6iXmk.js 14.6 kB 14.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3dViewer-BG4eXGNu.js 14.1 kB 14.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useLoad3dViewer-CkqSKKdF.js 887 B 887 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useSubscriptionCredits-nLppWaEX.js 2.75 kB 2.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useWorkspaceSwitch-84mKXcxh.js 1.25 kB 1.25 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useWorkspaceUI-BUe_OJVE.js 3 kB 3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Vendor & Third-Party — 8.69 MB (baseline 8.69 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-axios-C4mPrLmU.js 70.3 kB 70.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-chart-l-KY-tZQ.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-firebase-BvMr43CG.js 836 kB 836 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-i18n-cR3vmlFu.js 131 kB 131 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-markdown-oliHT-H5.js 102 kB 102 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-DIFkoP9Z.js 1.52 MB 1.52 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-DbhsokLF.js 1.73 MB 1.73 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-DAi_xVZa.js 255 kB 255 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-sentry-SQwstEKc.js 182 kB 182 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-ueviNA60.js 1.8 MB 1.8 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DN5cees9.js 625 kB 625 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-core-BjA-tjXK.js 311 kB 311 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vueuse-DcEOrMQz.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-CWHPCody.js 374 kB 374 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-yjs-CP_4YO8u.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-zod-DcCUUPIi.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 7.42 MB (baseline 7.42 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/AnimationControls-uhOvrOXP.js 4.61 kB 4.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ApiNodesSignInContent--Xr4RxpM.js 2.69 kB 2.69 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/AudioPreviewPlayer-DTGjLjIF.js 10.9 kB 10.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auto-Bt3L7FBS.js 1.7 kB 1.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/BaseViewTemplate--dbbFEs2.js 1.78 kB 1.78 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CancelSubscriptionDialogContent-DHFm0GZ1.js 4.85 kB 4.85 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/changeTracker-C3fl0K_2.js 9.38 kB 9.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/changeTracker-DZ9vmYDl.js 806 B 806 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudBadges--JQN-Kn5.js 1.42 kB 1.42 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudRunButtonWrapper-B2lIImQk.js 1.72 kB 1.72 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudSessionCookie-DmJdGiSf.js 3.15 kB 3.15 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/cloudSubscription-S-C3NLfb.js 1.38 kB 1.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/comfy-logo-single-BcOH_oP5.js 198 B 198 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyOrgHeader-CmrP3hho.js 910 B 910 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BE-vRwJl.js 16.6 kB 16.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BGHyTYD4.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Bh57dtIu.js 17.2 kB 17.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BhnFE3Dq.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C0TQG5MC.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CauhF9Qg.js 17.1 kB 17.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-D_1Nwml0.js 16.3 kB 16.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-D6_SlWq_.js 18.4 kB 18.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DDnyk4ZD.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Xb1k_0Gj.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-yQtLjIyn.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/constants-ogISyp4e.js 579 B 579 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/core-kWNOSVZc.js 72.5 kB 72.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CreateWorkspaceDialogContent-5pu3Wpsy.js 5.58 kB 5.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CurrentUserPopoverWorkspace-DhpRNUzh.js 19.9 kB 19.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/DeleteWorkspaceDialogContent-gan-vXUI.js 4.29 kB 4.29 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/EditWorkspaceDialogContent-U6zGF-FU.js 5.38 kB 5.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/GlobalToast-B3JoWcg_.js 2.91 kB 2.91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/graphHasMissingNodes-mJxQvkt8.js 761 B 761 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/groupNode-CuJ5Rojj.js 72.1 kB 72.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-B37HEt57.js 199 B 199 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-DReDPbev.js 503 kB 503 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeContent-Cbt6jZyc.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeFooter-CsC-FYf6.js 1.88 kB 1.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeHeader-C52A0tqP.js 1.08 kB 1.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/InviteMemberDialogContent-B-e31tm9.js 7.44 kB 7.44 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/InviteMemberUpsellDialogContent-DmCwx_Ok.js 3.88 kB 3.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LazyImage-hkB_HS4m.js 12.3 kB 12.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LeaveWorkspaceDialogContent-D1zUcz51.js 4.12 kB 4.12 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3D-Cg1I1zRH.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3D-CWlSwJBO.js 1.12 kB 1.12 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/load3d-DjSMF1kY.js 14.8 kB 14.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3DConfiguration-BNFcgVu0.js 6.27 kB 6.27 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3DControls-CRXObUk5.js 30.9 kB 30.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3dViewerContent-C_jNtBfZ.js 1.04 kB 1.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3dViewerContent-CU8aMdBt.js 23.1 kB 23.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bq33klKY.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BSrK10sS.js 120 kB 120 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C7kc0UfI.js 119 kB 119 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cndduh31.js 138 kB 138 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cp0fA684.js 189 kB 189 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-D4Cj1GDq.js 136 kB 136 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DaCNhwIS.js 140 kB 140 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DQ_OxQ4G.js 135 kB 135 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-HM49HWUY.js 169 kB 169 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-KjqrTSvt.js 156 kB 156 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-O2EnFePa.js 164 kB 164 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-BHB5UVIn.js 1.82 kB 1.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-BYoymEsG.js 1.43 kB 1.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-DVg0EyQw.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-CoCFfqkW.js 2.23 kB 2.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingModelsWarning-B3nye3bd.js 17.2 kB 17.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesContent-C5eja7kq.js 22.2 kB 22.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesFooter-BFz01DtY.js 7.54 kB 7.54 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesHeader-JfpleXg9.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nightlyBadges-D3JJQlok.js 1.05 kB 1.05 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictDialogContent-CDGOAnPO.js 10.5 kB 10.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictFooter-DhyemNV0.js 2.37 kB 2.37 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictHeader-DgbhznVf.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BHDxacOt.js 375 kB 375 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BzxC3xA2.js 345 kB 345 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C92z7Jao.js 461 kB 461 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CMJNOW2W.js 375 kB 375 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CPxgLLao.js 423 kB 423 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Curz6Nvc.js 368 kB 368 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DkB_F-Cq.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DS2DqIep.js 379 kB 379 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-mOwNzkna.js 390 kB 390 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-NvVROHN6.js 422 kB 422 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-WX8gf_Dw.js 372 kB 372 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeTemplates-BMAO5QYV.js 9.35 kB 9.35 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Preview3d-C1zGsfRn.js 4.86 kB 4.86 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-BlNc6I0i.js 665 B 665 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/RemoveMemberDialogContent-tcmdXXgb.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/RevokeInviteDialogContent-DwOSbSl5.js 4.01 kB 4.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-DLICfi3-.js 1.97 kB 1.97 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/saveMesh-Da7l1fjM.js 3.43 kB 3.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SelectValue-BLaUzhId.js 8.94 kB 8.94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SignInContent-DnkzCusq.js 19 kB 19 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/signInSchema-p9VvHm9M.js 1.53 kB 1.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-C8KGUioc.js 3.52 kB 3.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/src-D5pbLGY2.js 251 B 251 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscribeToRun-CU3pLljN.js 2.2 kB 2.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionPanelContentWorkspace-FyKDuV8i.js 21.6 kB 21.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionPanelContentWorkspace-R8YtTfmn.js 979 B 979 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionRequiredDialogContent-DeOZzbBz.js 26.2 kB 26.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SubscriptionRequiredDialogContentWorkspace-BrvAOF3y.js 45.9 kB 45.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/telemetry-zZf2dHJ2.js 226 B 226 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/types-DT3N7am7.js 204 B 204 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ValueControlPopover-CkKQFmD_.js 4.97 kB 4.97 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-DTUjK0ZE.js 445 B 445 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-DMPeCuhp.js 3.91 kB 3.91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-F8leYtSX.js 131 B 131 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-BDCRAbXS.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-DfUBpgxw.js 2.9 kB 2.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-7qXE9PZk.js 3.61 kB 3.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-CeaLzXAr.js 3.1 kB 3.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCrop-BPoirSZ4.js 22.1 kB 22.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputNumber-ChjwNvrs.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputNumber-CP6RMBKJ.js 392 B 392 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-BQ_QzI-O.js 1.86 kB 1.86 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-CvLvf7SF.js 1.95 kB 1.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLegacy-D3Vg0ghJ.js 794 B 794 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-wIs8y1Ja.js 2.88 kB 2.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-C9FcIgiN.js 1.1 kB 1.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetRecordAudio-DdeJBP7z.js 17.4 kB 17.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetSelect-BwfCCSEA.js 57.8 kB 57.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-DurObIpO.js 3.18 kB 3.18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-D4M7QPIz.js 2.5 kB 2.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-DhbPR9pT.js 393 B 393 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetWithControl-BZ0HIg1t.js 7.08 kB 7.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspacePanelContent-CZegjn79.js 29.3 kB 29.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

@christian-byrne christian-byrne changed the title feat(persistence): add V2 infrastructure feat(persistence): add workspace-scoped storage keys and types Feb 2, 2026
@christian-byrne christian-byrne force-pushed the 01-31-feat_persistence_add_v2_infrastructure_1_4_ branch from 86cf743 to 8212e12 Compare February 3, 2026 04:45
@christian-byrne christian-byrne marked this pull request as ready for review February 3, 2026 20:27
@christian-byrne christian-byrne requested a review from a team as a code owner February 3, 2026 20:27
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Feb 3, 2026
@christian-byrne christian-byrne force-pushed the 01-31-feat_persistence_add_v2_infrastructure_1_4_ branch from 8212e12 to 30b3c47 Compare February 3, 2026 20:38
@christian-byrne christian-byrne added area:workflows area:auth area:cloud needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.38 labels Feb 9, 2026
@christian-byrne christian-byrne force-pushed the 01-31-feat_persistence_add_v2_infrastructure_1_4_ branch from 30b3c47 to 186a3b9 Compare February 9, 2026 02:33
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: 2

🤖 Fix all issues with AI agents
In `@src/platform/workflow/persistence/base/draftTypes.ts`:
- Around line 81-85: Remove the unused exported constants MAX_DRAFTS and
PERSIST_DEBOUNCE_MS from draftTypes.ts: delete their declarations and any export
so they are no longer part of the module surface; keep using the canonical
MAX_DRAFTS from draftCache (which other modules already import) and verify no
code references PERSIST_DEBOUNCE_MS (if any exist, replace with the appropriate
debounce constant or inline value), ensuring only the single authoritative
MAX_DRAFTS symbol (from draftCache) remains exported in the codebase.

In `@src/platform/workflow/persistence/base/storageKeys.ts`:
- Around line 9-22: The getCurrentWorkspaceId function reads sessionStorage and
parses JSON without validating the parsed shape; update getCurrentWorkspaceId to
validate that the parsed workspace is a non-null object and that workspace.id is
a non-empty string and workspace.type is a string that can be compared to
'personal' (i.e., use explicit type guards instead of truthy checks), return
'personal' if validation fails, and avoid relying on any/implicit types so the
result conforms to WorkspaceWithRoleSchema expectations.

Comment on lines +81 to +85
/** Maximum number of drafts to keep per workspace */
export const MAX_DRAFTS = 32

/** Debounce delay for persisting graph changes (ms) */
export const PERSIST_DEBOUNCE_MS = 512
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n 'MAX_DRAFTS|PERSIST_DEBOUNCE_MS' src

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1209


🏁 Script executed:

head -20 src/platform/workflow/persistence/stores/workflowDraftStore.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 600


🏁 Script executed:

head -10 src/platform/workflow/persistence/base/draftCache.test.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 243


Remove these unused exported constants from draftTypes.ts.

PERSIST_DEBOUNCE_MS is never referenced anywhere in the codebase. MAX_DRAFTS is a duplicate—the active definition is in draftCache.ts and is imported from there. Neither should be exported from draftTypes.ts.

🔧 Change required
-/** Maximum number of drafts to keep per workspace */
-export const MAX_DRAFTS = 32
-
-/** Debounce delay for persisting graph changes (ms) */
-export const PERSIST_DEBOUNCE_MS = 512
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/** Maximum number of drafts to keep per workspace */
export const MAX_DRAFTS = 32
/** Debounce delay for persisting graph changes (ms) */
export const PERSIST_DEBOUNCE_MS = 512
🤖 Prompt for AI Agents
In `@src/platform/workflow/persistence/base/draftTypes.ts` around lines 81 - 85,
Remove the unused exported constants MAX_DRAFTS and PERSIST_DEBOUNCE_MS from
draftTypes.ts: delete their declarations and any export so they are no longer
part of the module surface; keep using the canonical MAX_DRAFTS from draftCache
(which other modules already import) and verify no code references
PERSIST_DEBOUNCE_MS (if any exist, replace with the appropriate debounce
constant or inline value), ensuring only the single authoritative MAX_DRAFTS
symbol (from draftCache) remains exported in the codebase.

Comment on lines +9 to +22
function getCurrentWorkspaceId(): string {
try {
const json = sessionStorage.getItem(
WORKSPACE_STORAGE_KEYS.CURRENT_WORKSPACE
)
if (!json) return 'personal'

const workspace = JSON.parse(json)
if (workspace.type === 'personal' || !workspace.id) return 'personal'
return workspace.id
} catch {
return 'personal'
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C3 'CURRENT_WORKSPACE' src

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 12354


🏁 Script executed:

#!/bin/bash
# Find workspace type definition
rg -n 'interface.*[Ww]orkspace|type.*[Ww]orkspace' src --type ts --type tsx -A 5 | head -80

# Also check workspaceAuthStore to see what structure is being written
sed -n '85,95p' src/stores/workspaceAuthStore.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 428


🏁 Script executed:

#!/bin/bash
# Find WorkspaceWithRole type definition
rg -n 'WorkspaceWithRole' src --type ts -A 10 | head -100

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 6859


Validate the workspace object shape before accessing id.

getCurrentWorkspaceId() reads from sessionStorage at module initialization time without validating the parsed value's structure. The check !workspace.id doesn't ensure id is a string—it could be any falsy/truthy value. Add explicit type guards to match the WorkspaceWithRoleSchema requirements (id must be a non-empty string).

🔧 Suggested fix
 function getCurrentWorkspaceId(): string {
   try {
     const json = sessionStorage.getItem(
       WORKSPACE_STORAGE_KEYS.CURRENT_WORKSPACE
     )
     if (!json) return 'personal'

-    const workspace = JSON.parse(json)
-    if (workspace.type === 'personal' || !workspace.id) return 'personal'
-    return workspace.id
+    const raw: unknown = JSON.parse(json)
+    if (!raw || typeof raw !== 'object') return 'personal'
+    const workspace = raw as Record<string, unknown>
+    if (workspace.type === 'personal') return 'personal'
+    if (typeof workspace.id !== 'string' || workspace.id.length === 0)
+      return 'personal'
+    return workspace.id
   } catch {
     return 'personal'
   }
 }

Aligns with "Validate trusted sources before processing" and "Never use any type; use proper TypeScript types."

🤖 Prompt for AI Agents
In `@src/platform/workflow/persistence/base/storageKeys.ts` around lines 9 - 22,
The getCurrentWorkspaceId function reads sessionStorage and parses JSON without
validating the parsed shape; update getCurrentWorkspaceId to validate that the
parsed workspace is a non-null object and that workspace.id is a non-empty
string and workspace.type is a string that can be compared to 'personal' (i.e.,
use explicit type guards instead of truthy checks), return 'personal' if
validation fails, and avoid relying on any/implicit types so the result conforms
to WorkspaceWithRoleSchema expectations.

simula-r
simula-r previously approved these changes Feb 10, 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. NOICE

christian-byrne and others added 2 commits February 18, 2026 15:21
Add foundational utilities for the V2 workflow persistence system:

- hashUtil: FNV-1a hash function for creating 8-char hex keys from paths
- storageKeys: Workspace-scoped key generators for localStorage/sessionStorage
- draftTypes: TypeScript interfaces for drafts, index, and pointers

Part of the V2 persistence rewrite to fix:
- QuotaExceededError on mobile (sessionStorage now stores pointers only)
- Draft leakage between workspaces (keys scoped by workspaceId)
- No multi-tab support (pointers scoped by clientId)

Amp-Thread-ID: https://ampcode.com/threads/T-019c16f4-05a2-779d-aa0e-a0e098308a95
Co-authored-by: Amp <amp@ampcode.com>
@christian-byrne christian-byrne force-pushed the 01-31-feat_persistence_add_v2_infrastructure_1_4_ branch from ba3ec21 to 64fd51d Compare February 18, 2026 23:25
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.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/platform/workflow/persistence/base/storageKeys.ts`:
- Around line 9-22: The getCurrentWorkspaceId function parses sessionStorage but
assumes workspace.id is a valid string; change it to validate the parsed object
shape before returning id: after JSON.parse, check that workspace is an object,
workspace.type is a string, and that workspace.id is typeof 'string' and not
empty/whitespace (e.g., workspace.id.trim().length > 0); only then return
workspace.id, otherwise return 'personal'. Keep the try/catch and continue to
treat missing/invalid data as 'personal'; reference
WORKSPACE_STORAGE_KEYS.CURRENT_WORKSPACE and function getCurrentWorkspaceId when
making the change.

@christian-byrne christian-byrne merged commit 8ab9a7b into main Feb 19, 2026
28 of 29 checks passed
@christian-byrne christian-byrne deleted the 01-31-feat_persistence_add_v2_infrastructure_1_4_ branch February 19, 2026 03:31
github-actions bot pushed a commit that referenced this pull request Feb 19, 2026
## Summary

Adds the foundational types and key generation utilities for
workspace-scoped workflow draft persistence. This enables storing drafts
per-workspace to prevent data leakage between different ComfyUI
instances.

[Screencast from 2026-02-08
18-17-45.webm](https://github.com/user-attachments/assets/f16226e9-c1db-469d-a0b7-aa6af725db53)

## Changes

- **What**: Type definitions for draft storage (`DraftIndexV2`,
`DraftPayloadV2`, session pointers) and key generation utilities with
workspace/client scoping
- **Why**: The current persistence system stores all drafts globally,
causing cross-workspace data leakage when users work with multiple
ComfyUI instances

---------

Co-authored-by: Amp <amp@ampcode.com>
@comfy-pr-bot
Copy link
Member

@christian-byrne Successfully backported to #8982

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Feb 19, 2026
DrJKL pushed a commit that referenced this pull request Feb 20, 2026
## Summary
- Remove `src/platform/workflow/persistence/base/draftTypes.ts` which is
not imported anywhere
- Fixes `knip` reporting it as an unused file

The file was added in #8517 but nothing consumes its exports yet.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8993-chore-remove-unused-draftTypes-ts-to-fix-knip-30d6d73d36508151a9e1e936864fd311)
by [Unito](https://www.unito.io)
pythongosssss pushed a commit that referenced this pull request Feb 20, 2026
## Summary
- Remove `src/platform/workflow/persistence/base/draftTypes.ts` which is
not imported anywhere
- Fixes `knip` reporting it as an unused file

The file was added in #8517 but nothing consumes its exports yet.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8993-chore-remove-unused-draftTypes-ts-to-fix-knip-30d6d73d36508151a9e1e936864fd311)
by [Unito](https://www.unito.io)
huntcsg pushed a commit that referenced this pull request Feb 21, 2026
## Summary
- Remove `src/platform/workflow/persistence/base/draftTypes.ts` which is
not imported anywhere
- Fixes `knip` reporting it as an unused file

The file was added in #8517 but nothing consumes its exports yet.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8993-chore-remove-unused-draftTypes-ts-to-fix-knip-30d6d73d36508151a9e1e936864fd311)
by [Unito](https://www.unito.io)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:auth area:cloud area:workflows size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants