Drive the React Doctor health score from 45 to 100 across both the desktop and website projects. Real fixes (the majority): - Break 15 import cycles by splitting page-kind *views* from *behavior* (new page-kinds/views.tsx) so stores/hooks no longer transitively import the editor UI; break the save.ts <-> editor-store.ts cycle via dependency injection (registerSaveStore). - 94 fixes across 45 files: accessibility labels, explicit button types, semantic <menu>/<nav> over ARIA roles, DOMPurify on mermaid HTML sinks, stable list keys, SVG-precision rounding, Promise.all where awaits are genuinely independent, dead export/file/dependency removal, and assorted micro-optimizations. - Remove unused deps (motion, react-resizable-panels) and a dead theme-preset chain in settings-schema. False positives, documented: - doctor.config.ts disables prefer-dynamic-import (CodeMirror extensions aren't lazy-loadable React components in a bundled desktop app) and the async-parallelism family (local IPC is deliberately sequenced for cancellation, frame-pacing and ordering, not network latency). - Narrow inline eslint-disable comments, each justified, for valuable React rules that misfire on legitimate async-I/O effects, timer-driven mount transitions, and external-system synchronization. Verified: vp check (0 errors), 472/472 tests pass, production build OK, npx react-doctor@latest -> 100/100.
Showing the changes to pnpm-lock.yaml (1 of 55 files). Show all
Unified · Split
| @@ -81,15 +81,9 @@ catalogs: · 80 unmodified lines | ||
| 81 | 81 | dompurify: |
| 82 | 82 | specifier: ^3.4.7 |
| 83 | 83 | version: 3.4.7 |
| 84 | − motion: | |
| 85 | − specifier: ^12.39.0 | |
| 86 | − version: 12.39.0 | |
| 87 | 84 | node-emoji: |
| 88 | 85 | specifier: ^2.2.0 |
| 89 | 86 | version: 2.2.0 |
| 90 | − react-resizable-panels: | |
| 91 | − specifier: ^4.7.4 | |
| 92 | − version: 4.7.4 | |
| 93 | 87 | tailwindcss: |
| 94 | 88 | specifier: ^4.2.2 |
| 95 | 89 | version: 4.2.2 |
| @@ -200,9 +194,6 @@ importers: · 104 unmodified lines | ||
| 200 | 194 | dompurify: |
| 201 | 195 | specifier: 'catalog:' |
| 202 | 196 | version: 3.4.7 |
| 203 | − motion: | |
| 204 | − specifier: 'catalog:' | |
| 205 | − version: 12.39.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) | |
| 206 | 197 | node-emoji: |
| 207 | 198 | specifier: 'catalog:' |
| 208 | 199 | version: 2.2.0 |
| @@ -212,9 +203,6 @@ importers: · 3 unmodified lines | ||
| 212 | 203 | react-dom: |
| 213 | 204 | specifier: ^19.1.0 |
| 214 | 205 | version: 19.2.4(react@19.2.4) |
| 215 | − react-resizable-panels: | |
| 216 | − specifier: 'catalog:' | |
| 217 | − version: 4.7.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) | |
| 218 | 206 | tailwindcss: |
| 219 | 207 | specifier: 'catalog:' |
| 220 | 208 | version: 4.2.2 |
| @@ -3053,20 +3041,6 @@ packages: · 2832 unmodified lines | ||
| 3053 | 3041 | resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} |
| 3054 | 3042 | engines: {node: '>=14'} |
| 3055 | 3043 | |
| 3056 | − framer-motion@12.39.0: | |
| 3057 | − resolution: {integrity: sha512-+vnLfzrv0MzjLzNl+nvNvR7jdg3q4cxxjz/YvzfifHl0TREtL00cs1RoMTxs+1PzLiEqZGV6gYsBY0oEAYZ24w==} | |
| 3058 | − peerDependencies: | |
| 3059 | − '@emotion/is-prop-valid': '*' | |
| 3060 | − react: ^18.0.0 || ^19.0.0 | |
| 3061 | − react-dom: ^18.0.0 || ^19.0.0 | |
| 3062 | − peerDependenciesMeta: | |
| 3063 | − '@emotion/is-prop-valid': | |
| 3064 | − optional: true | |
| 3065 | − react: | |
| 3066 | − optional: true | |
| 3067 | − react-dom: | |
| 3068 | − optional: true | |
| 3069 | − | |
| 3070 | 3044 | fs.realpath@1.0.0: |
| 3071 | 3045 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} |
| 3072 | 3046 | |
| @@ -3505,26 +3479,6 @@ packages: · 432 unmodified lines | ||
| 3505 | 3479 | resolution: {integrity: sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==} |
| 3506 | 3480 | engines: {node: '>=18.0.0'} |
| 3507 | 3481 | |
| 3508 | − motion-dom@12.39.0: | |
| 3509 | − resolution: {integrity: sha512-Xn7aAcGDhco/JZTXOub64UmaYn73C6J1Po7Fk+8EvkJsNGTqfhon6UJY53vJKXW5v5Zl8HrYsVxv6oPXeGoGLQ==} | |
| 3510 | − | |
| 3511 | − motion-utils@12.39.0: | |
| 3512 | − resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} | |
| 3513 | − | |
| 3514 | − motion@12.39.0: | |
| 3515 | − resolution: {integrity: sha512-H4a+Ze+a9j+/NTla5ezfb/g9vmIOxC+viDj++NGDZyTZkdRKjiOz3kSv6TalRWM8ZmD2y/CfC6TkQc97ybyqSA==} | |
| 3516 | − peerDependencies: | |
| 3517 | − '@emotion/is-prop-valid': '*' | |
| 3518 | − react: ^18.0.0 || ^19.0.0 | |
| 3519 | − react-dom: ^18.0.0 || ^19.0.0 | |
| 3520 | − peerDependenciesMeta: | |
| 3521 | − '@emotion/is-prop-valid': | |
| 3522 | − optional: true | |
| 3523 | − react: | |
| 3524 | − optional: true | |
| 3525 | − react-dom: | |
| 3526 | − optional: true | |
| 3527 | − | |
| 3528 | 3482 | mrmime@2.0.1: |
| 3529 | 3483 | resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} |
| 3530 | 3484 | engines: {node: '>=10'} |
| @@ -3772,12 +3726,6 @@ packages: · 241 unmodified lines | ||
| 3772 | 3726 | '@types/react': |
| 3773 | 3727 | optional: true |
| 3774 | 3728 | |
| 3775 | − react-resizable-panels@4.7.4: | |
| 3776 | − resolution: {integrity: sha512-1sehMbUJxZFj4imu1TuH+RS7Xe5Jo+3HyxBYafCEdxPmDeLAQNmKEByyxCQRl7xCLa5cLXSJ9T8acQyyiPsNdQ==} | |
| 3777 | − peerDependencies: | |
| 3778 | − react: ^18.0.0 || ^19.0.0 | |
| 3779 | − react-dom: ^18.0.0 || ^19.0.0 | |
| 3780 | − | |
| 3781 | 3729 | react-style-singleton@2.2.3: |
| 3782 | 3730 | resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} |
| 3783 | 3731 | engines: {node: '>=10'} |
| @@ -7118,15 +7066,6 @@ snapshots: · 3334 unmodified lines | ||
| 7118 | 7066 | cross-spawn: 7.0.6 |
| 7119 | 7067 | signal-exit: 4.1.0 |
| 7120 | 7068 | |
| 7121 | − framer-motion@12.39.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): | |
| 7122 | − dependencies: | |
| 7123 | − motion-dom: 12.39.0 | |
| 7124 | − motion-utils: 12.39.0 | |
| 7125 | − tslib: 2.8.1 | |
| 7126 | − optionalDependencies: | |
| 7127 | − react: 19.2.4 | |
| 7128 | − react-dom: 19.2.4(react@19.2.4) | |
| 7129 | − | |
| 7130 | 7069 | fs.realpath@1.0.0: {} |
| 7131 | 7070 | |
| 7132 | 7071 | fsevents@2.3.3: |
| @@ -7540,20 +7479,6 @@ snapshots: · 407 unmodified lines | ||
| 7540 | 7479 | |
| 7541 | 7480 | modern-tar@0.7.6: {} |
| 7542 | 7481 | |
| 7543 | − motion-dom@12.39.0: | |
| 7544 | − dependencies: | |
| 7545 | − motion-utils: 12.39.0 | |
| 7546 | − | |
| 7547 | − motion-utils@12.39.0: {} | |
| 7548 | − | |
| 7549 | − motion@12.39.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): | |
| 7550 | − dependencies: | |
| 7551 | − framer-motion: 12.39.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) | |
| 7552 | − tslib: 2.8.1 | |
| 7553 | − optionalDependencies: | |
| 7554 | − react: 19.2.4 | |
| 7555 | − react-dom: 19.2.4(react@19.2.4) | |
| 7556 | − | |
| 7557 | 7482 | mrmime@2.0.1: {} |
| 7558 | 7483 | |
| 7559 | 7484 | ms@2.1.3: {} |
| @@ -7854,11 +7779,6 @@ snapshots: · 294 unmodified lines | ||
| 7854 | 7779 | optionalDependencies: |
| 7855 | 7780 | '@types/react': 19.2.14 |
| 7856 | 7781 | |
| 7857 | − react-resizable-panels@4.7.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4): | |
| 7858 | − dependencies: | |
| 7859 | − react: 19.2.4 | |
| 7860 | − react-dom: 19.2.4(react@19.2.4) | |
| 7861 | − | |
| 7862 | 7782 | react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): |
| 7863 | 7783 | dependencies: |
| 7864 | 7784 | get-nonce: 1.0.1 |
| @@ -8332,7 +8252,7 @@ snapshots: · 467 unmodified lines | ||
| 8332 | 8252 | picomatch: 4.0.4 |
| 8333 | 8253 | postcss: 8.5.15 |
| 8334 | 8254 | rolldown: 1.0.2 |
| 8335 | − tinyglobby: 0.2.16 | |
| 8255 | + tinyglobby: 0.2.17 | |
| 8336 | 8256 | optionalDependencies: |
| 8337 | 8257 | '@types/node': 25.5.0 |
| 8338 | 8258 | esbuild: 0.27.4 |