Skip to content

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Nov 6, 2025

Current issues:

  • the widget.options and widget.spec need to be unified and the apiSchema needs to be updated to reflect the props API. Then this PR can be greatly simplified (or some other way to wire through the widget spec into the component props and have those types to the apiSchema)
  • relying on type guards for all widget types instead of discriminated union

┆Issue is synchronized with this Notion page by Unito

- Add proper type guards for all widget input specs (Color, TreeSelect, MultiSelect, FileUpload, Galleria)
- Enhance schemas with missing properties (format, placeholder, accept, extensions, tooltip)
- Fix widgets to honor runtime props like disabled while accessing spec metadata
- Eliminate all 'as any' usage in widget components with proper TypeScript types
- Clean separation: widget.spec.options for metadata, widget.options for runtime state
- Refactor devtools into modular structure with vue_widgets showcase nodes
@christian-byrne christian-byrne changed the title sync devtools nodes with test ComfyUI dir test global setup, add dev nodes for all new widget types sync devtools nodes with test ComfyUI dir in test global setup and add dev nodes for all new widget types Nov 6, 2025
@github-actions
Copy link

github-actions bot commented Nov 6, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 11/06/2025, 10:25:57 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 11/06/2025, 10:57:58 PM UTC

📈 Summary

  • Total Tests: 498
  • Passed: 464 ✅
  • Failed: 0
  • Flaky: 4 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 455 / ❌ 0 / ⚠️ 4 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

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

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

Bundle Size Report

Summary

  • Raw size: 12.2 MB baseline 12.2 MB — 🔴 +2.28 kB
  • Gzip: 2.49 MB baseline 2.49 MB — 🔴 +487 B
  • Brotli: 1.96 MB baseline 1.96 MB — 🔴 +456 B
  • Bundles: 58 current • 58 baseline • 13 added / 13 removed

Category Glance
App Entry Points 🔴 +2.28 kB (3.25 MB) · Vendor & Third-Party ⚪ 0 B (5.32 MB) · Other ⚪ 0 B (2.55 MB) · Graph Workspace ⚪ 0 B (792 kB) · Panels & Settings ⚪ 0 B (293 kB) · UI Components ⚪ 0 B (12.6 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.25 MB (baseline 3.25 MB) • 🔴 +2.28 kB

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-DWVrHB6o.js (new) 2.87 MB 🔴 +2.87 MB 🔴 +595 kB 🔴 +450 kB
assets/index-D2940QdZ.js (removed) 2.87 MB 🟢 -2.87 MB 🟢 -594 kB 🟢 -450 kB
assets/index-0SYk4ZID.js (new) 382 kB 🔴 +382 kB 🔴 +76.6 kB 🔴 +62.1 kB
assets/index-m2JLsAl3.js (removed) 382 kB 🟢 -382 kB 🟢 -76.6 kB 🟢 -62 kB
assets/index-Cdeizypm.js (removed) 1.75 kB 🟢 -1.75 kB 🟢 -573 B 🟢 -486 B
assets/index-laj-KRUi.js (new) 1.75 kB 🔴 +1.75 kB 🔴 +575 B 🔴 +486 B

Status: 3 added / 3 removed

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

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BxYtfGP8.js (removed) 792 kB 🟢 -792 kB 🟢 -155 kB 🟢 -119 kB
assets/GraphView-CSJwHrff.js (new) 792 kB 🔴 +792 kB 🔴 +155 kB 🔴 +119 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-CvDum833.js (removed) 8.18 kB 🟢 -8.18 kB 🟢 -2.48 kB 🟢 -2.17 kB
assets/UserSelectView-NsWoEiuv.js (new) 8.18 kB 🔴 +8.18 kB 🔴 +2.48 kB 🔴 +2.17 kB

Status: 1 added / 1 removed

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-DVRKAPIC.js (new) 23 kB 🔴 +23 kB 🔴 +5.48 kB 🔴 +4.8 kB
assets/CreditsPanel-ELjO8PJB.js (removed) 23 kB 🟢 -23 kB 🟢 -5.48 kB 🟢 -4.8 kB
assets/KeybindingPanel-B3kC_uHT.js (new) 15.3 kB 🔴 +15.3 kB 🔴 +3.78 kB 🔴 +3.33 kB
assets/KeybindingPanel-D5tJTifW.js (removed) 15.3 kB 🟢 -15.3 kB 🟢 -3.78 kB 🟢 -3.32 kB
assets/ExtensionPanel-Duj00HSL.js (removed) 12.1 kB 🟢 -12.1 kB 🟢 -2.84 kB 🟢 -2.5 kB
assets/ExtensionPanel-QpVkHdFm.js (new) 12.1 kB 🔴 +12.1 kB 🔴 +2.84 kB 🔴 +2.49 kB
assets/AboutPanel-BySxZ2dD.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +2.67 kB 🔴 +2.34 kB
assets/AboutPanel-DBUXot_1.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -2.67 kB 🟢 -2.34 kB
assets/ServerConfigPanel-CCO7QBEp.js (new) 8.23 kB 🔴 +8.23 kB 🔴 +2.17 kB 🔴 +1.91 kB
assets/ServerConfigPanel-RZY6apx0.js (removed) 8.23 kB 🟢 -8.23 kB 🟢 -2.17 kB 🟢 -1.91 kB
assets/UserPanel-BKkpHGUU.js (new) 7.94 kB 🔴 +7.94 kB 🔴 +2.07 kB 🔴 +1.81 kB
assets/UserPanel-Db6t2adE.js (removed) 7.94 kB 🟢 -7.94 kB 🟢 -2.07 kB 🟢 -1.81 kB
assets/settings-0O6mq5to.js 24.3 kB 24.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BYaBy7dC.js 20.4 kB 20.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C3vygQN4.js 25.7 kB 25.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CbKYXyH0.js 22.7 kB 22.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCholIsI.js 25 kB 25 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DFX7vRkK.js 19.8 kB 19.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-INJLrcmT.js 31.3 kB 31.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-iR6BKRXe.js 23.7 kB 23.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-YjQmudNE.js 23.5 kB 23.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-AGfKhKY6.js (new) 11.3 kB 🔴 +11.3 kB 🔴 +2.83 kB 🔴 +2.49 kB
assets/ComfyQueueButton-d7iP36iS.js (removed) 11.3 kB 🟢 -11.3 kB 🟢 -2.83 kB 🟢 -2.49 kB
assets/UserAvatar.vue_vue_type_script_setup_true_lang-D2s8tnS2.js 1.26 kB 1.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-COJcXVSE.js (new) 7.6 kB 🔴 +7.6 kB 🔴 +1.84 kB 🔴 +1.59 kB
assets/keybindingService-EUnaA9E6.js (removed) 7.6 kB 🟢 -7.6 kB 🟢 -1.85 kB 🟢 -1.59 kB
assets/serverConfigStore-BOo8M-7s.js 2.79 kB 2.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Vendor & Third-Party — 5.32 MB (baseline 5.32 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-Bfb5Ofrh.js 3.22 MB 3.22 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-PESgPnbc.js 517 B 517 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-JDoAqkQm.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-Dvg9y4X0.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-SdQKVoRx.js 92.6 kB 92.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 2.55 MB (baseline 2.55 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/commands-B2KZRBmX.js 15.1 kB 15.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Bw-ckyga.js 13.9 kB 13.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C_NmM85I.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CuozCW4W.js 14 kB 14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DGfVUJCR.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-dOJNDogK.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiE551e.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Fw7mvqSy.js 13.1 kB 13.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-FXnO1W4Q.js 13.2 kB 13.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B28vuueQ.js 58.7 kB 58.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B5DMAz5p.js 76.3 kB 76.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9oeRB3u.js 66.2 kB 66.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BfxLm2q9.js 68.4 kB 68.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bqw7zi8p.js 92.9 kB 92.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CxXcIMmb.js 80.3 kB 80.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DbrkzQIr.js 70.6 kB 70.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DwpdJL5U.js 67.5 kB 67.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-mC3TQk_1.js 59.4 kB 59.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-3I1vPgv4.js 181 kB 181 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B2huPGKQ.js 190 kB 190 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BWugyUzd.js 215 kB 215 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-bXqu6Stq.js 194 kB 194 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CtB2M3sY.js 229 kB 229 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D-rCrn-T.js 200 kB 200 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D38DSnl1.js 179 kB 179 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DAsU52ON.js 192 kB 192 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DnGONaA_.js 196 kB 196 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

@christian-byrne christian-byrne added the claude-review Add to trigger a PR code review from Claude Code label Nov 7, 2025
inputSpec: InputSpec
): inputSpec is FileUploadInputSpec => {
return inputSpec.type === 'FILEUPLOAD'
}
Copy link

Choose a reason for hiding this comment

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

[quality] medium Priority

Issue: Missing type guard for ImageInputSpec - no matching isImageInputSpec function exported
Context: All other input specs have corresponding type guard functions, but ImageInputSpec is missing its type guard
Suggestion: Add export const isImageInputSpec = (inputSpec: InputSpec): inputSpec is ImageInputSpec => inputSpec.type === 'IMAGE'

@@ -0,0 +1,477 @@
from __future__ import annotations

SAMPLE_IMAGE_DATA_URI = (
Copy link

Choose a reason for hiding this comment

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

[security] medium Priority

Issue: Hard-coded data URI images could pose security risks if served over network
Context: Base64 encoded images are embedded directly in code and could be executed if improperly handled
Suggestion: Consider loading these from secure static assets or validating data URIs before use

// PrimeVue TreeSelect expects 'options' to be an array of tree nodes
options: (specOptions.values as TreeNode[]) || [],
// Convert 'multiple' to PrimeVue's 'selectionMode'
selectionMode: (specOptions.multiple ? 'multiple' : 'single') as
Copy link

Choose a reason for hiding this comment

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

[architecture] high Priority

Issue: Type safety concern with casting selectionMode from boolean to union type
Context: Line 73 uses type assertion to cast boolean to union type which can break at runtime
Suggestion: Use proper conditional logic: selectionMode: specOptions.multiple ? 'multiple' : 'single' (remove the union type assertion)

// Include runtime props like disabled
...props.widget.options,
// PrimeVue TreeSelect expects 'options' to be an array of tree nodes
options: (specOptions.values as TreeNode[]) || [],
Copy link

Choose a reason for hiding this comment

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

[performance] medium Priority

Issue: Missing memoization for expensive tree node casting
Context: Line 71 performs array casting on every computed update which could be expensive with large tree data
Suggestion: Consider memoizing the tree node transformation or using a more efficient type check

return
}

const devtoolsDest = path.resolve(
Copy link

Choose a reason for hiding this comment

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

[security] high Priority

Issue: Directory traversal vulnerability - fs.copySync without path validation
Context: The devtoolsDest path is constructed from user input without validation, potentially allowing directory traversal attacks
Suggestion: Validate and sanitize the targetComfyDir path before using it in file operations. Use path.resolve() and check that the resolved path stays within expected boundaries

fs.copySync(devtoolsSrc, devtoolsDest, { overwrite: true })
console.warn('syncDevtools: copy complete')
} catch (error) {
console.error(`Failed to sync DevTools to ${devtoolsDest}:`, error)
Copy link

Choose a reason for hiding this comment

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

[quality] medium Priority

Issue: Error logging uses console.error but function continues execution after failure
Context: The function catches errors during file copying but doesn't throw or return error status to caller
Suggestion: Either throw the error to propagate failure or return a boolean indicating success/failure for better error handling

if (!spec || !isSelectButtonInputSpec(spec)) {
return []
}
return spec.options?.values || []
Copy link

Choose a reason for hiding this comment

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

[quality] low Priority

Issue: Potential null reference in options extraction
Context: Line 44 accesses spec.options?.values but could return undefined values, not empty array
Suggestion: Use more explicit fallback: return spec.options?.values ?? [] to ensure type safety

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Comprehensive PR Review

This review is generated by Claude. It may not always be accurate, as with human reviewers. If you believe that any of the comments are invalid or incorrect, please state why for each. For others, please implement the changes in one way or another.

Review Summary

PR: sync devtools nodes with test ComfyUI dir in test global setup and add dev nodes for all new widget types (#6623)
Impact: 705 additions, 44 deletions across 13 files

Issue Distribution

  • Critical: 0
  • High: 2
  • Medium: 4
  • Low: 1

Category Breakdown

  • Architecture: 1 issue
  • Security: 2 issues
  • Performance: 1 issue
  • Code Quality: 3 issues

Key Findings

Architecture & Design

The PR introduces comprehensive widget type support with proper schema definitions and type guards. However, there's an inconsistency in the TreeSelect component where type assertions are used instead of proper conditional logic, which could lead to runtime type errors. The overall architectural approach of extending the schema with new widget types is sound and follows established patterns.

Security Considerations

Two security concerns were identified:

  1. High Priority: Directory traversal vulnerability in devtoolsSync.ts where user input is used to construct file paths without proper validation
  2. Medium Priority: Hard-coded data URI images in Python files that could pose risks if improperly handled over networks

Performance Impact

The TreeSelect component performs array casting on every computed update without memoization, which could be expensive with large tree datasets. Consider implementing proper memoization for better performance with complex tree structures.

Integration Points

The PR properly extends the widget system architecture and maintains backward compatibility. The devtools synchronization feature integrates well with the test infrastructure. Type safety improvements ensure better developer experience and runtime reliability.

Positive Observations

  • Comprehensive schema definitions for all new widget types
  • Proper implementation of type guards for most widget specs
  • Good separation of concerns between schema validation and component implementation
  • Consistent use of Vue 3 Composition API patterns
  • Appropriate use of PrimeVue components with proper customization

References

Next Steps

  1. Address critical issues before merge
  2. Consider architectural feedback for long-term maintainability
  3. Add tests for uncovered scenarios
  4. Update documentation if needed

This is a comprehensive automated review. For architectural decisions requiring human judgment, please request additional manual review.

@github-actions github-actions bot removed the claude-review Add to trigger a PR code review from Claude Code label Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants