feat(extensibility): plugin externals contract, runtime plugin loading, rsbuild 2 pipeline, and create-ohif scaffolding - #6168
feat(extensibility): plugin externals contract, runtime plugin loading, rsbuild 2 pipeline, and create-ohif scaffolding#6168sedghi wants to merge 32 commits into
Conversation
…ngerouslyUseDynamicConfig
…normalize mode main fields All 26 per-package prod configs now import the shared externals contract (react/react-dom/react/jsx-runtime added as externals everywhere). Fixes the ohif-ui-next UMD library name collision with @ohif/ui. Normalizes the four non-conforming mode main fields to dist/ohif-<name>.umd.js and rewrites modes/segmentation's legacy standalone config to the standard mode shape.
pluginConfig.json gains a $schema pointer; the never-read version fields are removed. Schema is draft-07 with additionalProperties:false.
…ce-worker bypass Both nginx templates gain an opt-in CSP_HEADER add_header (envsubst allowlist updated) and a /plugins/ location block with explicit MIME types, cache tiers, and no SPA fallback. The service-worker precache excludes plugins/ and a NetworkOnly route bypasses /plugins/ fetches (rspack.pwa.js only; the rsbuild dev pipeline generates no service worker). netlify.toml's Report-Only header now mirrors the documented baseline with interim unsafe-inline.
…nConfig runtimeExtensionLoader.ts is the single gate for the loadModule fallthrough: URL-shaped specifiers must pass a deny-by-default origin allowlist (same-origin implicit, extras via window.config.runtimeExtensionOrigins) and unknown bare names throw a descriptive error. The codegen emits the gated epilogue and the config is structurally validated at build with actionable messages.
pnpm plugin add installs via pnpm and writes the pluginConfig entry in one step; doctor validates declared plugins, peer ranges against version.txt, dangling references, and singleton copies in directory plugins.
The published set is now exactly the shared-surface packages (@OHIF/core, @ohif/ui-next, @ohif/i18n, @ohif/extension-default, @ohif/extension-cornerstone) with repaired tarball metadata (publishConfig dist rewrites, files, keywords, peer hygiene). The remaining extensions, all modes, and @ohif/ui are private: true and stay version-stamped. verify-tarballs enforces the tier invariant and publish-list parity; verify-umd-global proves a built UMD assigns its window global. @ohif/app now devDepends on @ohif/ui.
Adds Track B runtime loading: descriptors in window.config.extensions/modes are loaded through runtimeExtensionLoader with a strict globalName discriminator (present => UMD global, absent => ESM default), a fail-closed coreVersionRange gate (includePrerelease), stylesheet injection, and a window.__ohif audit record reconciled and surfaced via NotificationService. runtimeShared.ts exposes the twelve host singletons (react, @OHIF/core, @ohif/ui-next, @ohif/i18n, @cornerstonejs/*, ...) on window so runtime bundles resolve them, with a parity test binding the list to pluginExternals.hostSharedPackages.
Shared resolveConfig gains exact-match dedupe aliases so directory and node_modules plugins resolve one copy of react/@OHIF/core/etc. through both pipelines. Tailwind content globs extend from pluginConfig entries so out-of-tree and installed plugins render styled. Adds the directory-plugin verification recipe.
…oyment templates pnpm create ohif scaffolds standalone extensions/modes, a full workspace (a user-owned repo with a committed ohif.config.json manifest and a managed .ohif viewer harness), or a config-only deployment. A migrate subcommand ports CLI-era extensions to the current contract. Templates vendor the externals contract; unit and e2e smoke tests cover scaffold, build, and UMD global.
Adds the curated gallery (data file + published JSON Schema), the build-with-an-agent contract page, the CLI-era porting companion to create-ohif migrate, and the de-forking guide. The docs build now runs gallery and AGENTS.md sync validation ahead of docusaurus build.
Deletes platform/cli, the root cli script, ohif-cli.md and its images. Installation, pluginConfig, and migration-guide pages are rewritten around pnpm add + pluginConfig + create-ohif; a client redirect sends the old /development/ohif-cli path to the CLI-removal migration page. AGENTS.md drops the stale module-federation and yarn claims and gains the extension contract summary.
rsbuild.config.ts gains a production path that reproduces the old rspack.pwa.js build: the service-worker manifest injection (ported via tools.rspack, /plugins/ excluded), the VERSION_NUMBER/COMMIT_HASH/BUILD_NUM defines, and the two inline index.html scripts kept byte-stable. platform/app build and dev scripts now run rsbuild; @rspack/cli and core move to the root so per-package UMD builds keep resolving them; rspack.pwa.js is deleted. scripts/verify-build-parity.mjs became a single-pipeline production build smoke. Parity proven by a 17-check contract harness, a headless boot with a valid sw.js, and a docker container smoke.
…peline The single-pipeline cutover dropped the babel-plugin-istanbul post-loader that rspack.pwa.js applied under COVERAGE=true; re-added it (COVERAGE-gated only, so dev and production builds are unaffected) so playwright coverage keeps working.
…ferences Adds .rspack/CONTRACT.md documenting why contract v2 (ESM + import map) stays deferred (rslib pre-1.0) and the criteria to revisit. Reconciles comments and docs that still named the deleted rspack.pwa.js to point at rsbuild.config.ts, and documents that vtk.js is externalized without a host global (a v1 gap a runtime plugin must not rely on).
Adds a pnpm-workspace.yaml carrying allowBuilds to the extension and mode templates so pnpm 11 stops erroring on dependency build scripts and pnpm install succeeds unattended. Switches the extension template from a separate extracted stylesheet to style-loader runtime injection, so a plugin's CSS loads whether it is bundled into the host, loaded at runtime, or compiled from source (an extracted dist/index.css was silently unloaded under the bundled path). The example panel now sets a theme-aware color; the dead index.css runtime-descriptor hint and docs references are dropped.
…onfig The glsl rule was only ever consumed by vtk.js sources and has been commented out of the shared base config for the whole branch; remove the orphaned rules/loadShaders.js module and its commented require/usage lines instead of carrying dead code into the consolidated pipeline.
…face Eight extensions import @ohif/ui-next at runtime without declaring it, so a standalone (de-forked) build of any of them would not externalize the package correctly; declare the workspace peer explicitly. platform/core no longer uses @ohif/ui anywhere, so drop the stale peer from its published metadata. Lockfile regenerated for both.
…d a scaffold smoke harness externals-parity gains a fourth invariant leg: every peerDependency a scaffolded plugin declares must be a package the host actually shares at runtime (pluginExternals.hostSharedPackages), since anything else would be externalized by the build but resolve to undefined when the UMD loads. scripts/scaffold-smoke.mjs is the documented manual end-to-end gate: scaffold both templates, pnpm install, build, assert the dist artifacts and the UMD global contract under stubbed host globals, then run each scaffold's own test suite. It lives outside the published files list and requires network, so it stays a repo-side gate rather than a CI job.
…webpack-named deps AGENTS.md still described extensions as self-contained webpack builds; point it at the shared .rspack pipeline and note that webpack-merge and @svgr/webpack are kept on purpose because both are rspack-compatible despite their names.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
✅ Deploy Preview for ohif-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe PR migrates OHIF build and publishing workflows to Rspack/Rsbuild, adds runtime plugin loading with validation and auditing, introduces ChangesPlugin platform migration
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (4)
extensions/measurement-tracking/package.json (1)
24-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the
dev:dicom-pdfscript.The
dev:dicom-pdfscript appears to be a copy-paste error from thedicom-pdfextension, as it just aliases the standarddevscript in themeasurement-trackingpackage.♻️ Proposed fix
"dev": "cross-env NODE_ENV=development rspack build --config .rspack/rspack.dev.js --watch", - "dev:dicom-pdf": "pnpm run dev", "build": "cross-env NODE_ENV=production rspack build --config .rspack/rspack.prod.js",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@extensions/measurement-tracking/package.json` around lines 24 - 26, Remove the dev:dicom-pdf entry from the measurement-tracking package scripts, leaving the standard dev and build scripts unchanged.platform/docs/docs/configuration/dataSources/dicom-web.md (1)
106-108: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueChange the code block language to
bashorsh.The code block contains a shell command, not JavaScript.
♻️ Proposed fix
-```js +```bash cross-env NODE_ENV=development PROXY_TARGET=/pacs/dicom-web PROXY_DOMAIN=http://localhost:8042 PROXY_PATH_REWRITE_FROM=/pacs/dicom-web PROXY_PATH_REWRITE_TO=/dicom-web APP_CONFIG=config/docker-nginx-orthanc.js rsbuild dev --config ../../rsbuild.config.ts</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@platform/docs/docs/configuration/dataSources/dicom-web.mdaround lines 106 -
108, Change the fenced code block containing the cross-env command from
JavaScript syntax highlighting to bash or sh, without modifying the command
itself.</details> <!-- cr-comment:v1:9d4256e8fb97756ef0178743 --> </blockquote></details> <details> <summary>platform/docs/docs/configuration/configurationFiles.md (1)</summary><blockquote> `448-448`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_ **Specify a language for fenced code blocks.** As indicated by static analysis, several fenced code blocks are missing a language specifier. Adding a language like `text` or `csp` improves formatting and resolves the markdownlint warnings. - `platform/docs/docs/configuration/configurationFiles.md#L448-L448`: Add `text` to the code fence. - `platform/docs/docs/deployment/runtime-plugins.md#L28-L28`: Add `text` to the code fence. - `platform/docs/docs/deployment/runtime-plugins.md#L99-L99`: Add `text` to the code fence. - `platform/docs/docs/deployment/runtime-plugins.md#L145-L145`: Add `text` to the code fence. - `platform/docs/docs/development/create-ohif.md#L48-L48`: Add `text` to the code fence. - `platform/docs/docs/development/create-ohif.md#L86-L86`: Add `text` to the code fence. <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@platform/docs/docs/configuration/configurationFiles.mdat line 448, Update
the fenced code blocks at
platform/docs/docs/configuration/configurationFiles.md:448-448,
platform/docs/docs/deployment/runtime-plugins.md:28-28, 99-99, and 145-145, and
platform/docs/docs/development/create-ohif.md:48-48 and 86-86 to include the
text language specifier on each opening fence.</details> <!-- cr-comment:v1:399fed159e3df243e39ede2d --> _Source: Linters/SAST tools_ </blockquote></details> <details> <summary>platform/docs/docs/development/out-of-tree.md (1)</summary><blockquote> `134-136`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_ **Add a language identifier to the fenced code block.** Specifying a language like `text` helps with syntax highlighting and resolves markdown linter warnings. <details> <summary>♻️ Proposed fix</summary> ```diff -``` +```text <directory>/src/**/*.{jsx,js,ts,tsx,css}</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@platform/docs/docs/development/out-of-tree.mdaround lines 134 - 136, Add
the text language identifier to the fenced code block containing the directory
glob, changing the opening fence to use text while preserving the block
contents.</details> <!-- cr-comment:v1:7ce01cb2e0ba3816f88262e9 --> _Source: Linters/SAST tools_ </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Inline comments:
In @.rspack/resolveConfig.js:
- Around line 69-75: Remove the path.resolve(__dirname, '../../../node_modules')
entry from the moduleSearchPaths array in resolveConfig.js. Preserve the
existing repository-root and platform-specific node_modules paths.In @.rspack/rules/cssToJavaScript.js:
- Around line 19-22: Update the plugins configuration in the PostCSS setup to
pass tailwindcss and autoprefixer directly as plugin instances, removing the
extra nested arrays so postcss-loader can apply both plugins.In
@platform/app/src/routes/Mode/Mode.tsx:
- Around line 104-108: Update the registerExtension catch block in the
loadModules flow to report failures for built-in extensions even when
recordRegistrationError finds no audit record. Log the caught error
unconditionally or update recordRegistrationError to emit a console.error when
no matching record exists, while preserving existing auditing and runtime
failure surfacing.In
@platform/core/package.json:
- Line 24: Update the package.json sideEffects setting from the string value
"false" to the boolean false, preserving the existing configuration intent.In
@platform/create-ohif/README.md:
- Around line 17-25: The README usage block for create-ohif must match the
bin/create-ohif.mjs USAGE definition: expand --template to include workspace and
deployment, and document the migrate [--dry-run] subcommand. Update only
the CLI arguments documentation while preserving the existing option
descriptions.In
@platform/create-ohif/templates/mode/src/toolbarButtons.ts:
- Around line 4-10: Update setToolActiveToolbar.commandOptions.toolGroupIds to
remove the dangling 'mpr' entry, leaving only the 'default' tool group created
by onModeEnter.In
@platform/create-ohif/templates/workspace/scripts/ohif.mjs:
- Line 144: Update the package classification logic in the section assignment to
recognize both scoped and unscoped mode package names, including names such as
mode-basic and@ohif/mode-basic, while continuing to classify other packages as
extensions.In
@platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md:
- Around line 107-114: Restore the historical Webpack references in all three
affected version-3.11 documents: in
platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md
lines 107-114, replace .rspack/rspack.pwa.js with .webpack/webpack.pwa.js in
both the command and explanation; in
platform/docs/versioned_docs/version-3.11/development/ohif-cli.md line 309,
replace rspack.pwa.js with webpack.pwa.js; and in
platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md
line 108, replace .rspack/rspack.pwa.js with .webpack/webpack.pwa.js.In
@platform/ui-next/package.json:
- Around line 25-30: Update the publishConfig.exports map in package.json to
avoid exposing raw TypeScript and TSX source paths through ./lib/* and
./components/*. If the SDK supports only root-module runtime imports, remove
these deep exports; otherwise, redirect them to transpiled JavaScript artifacts
that are included in the published package.In
@scripts/verify-build-parity.mjs:
- Around line 65-74: Guard the spawnSync results in both treeContains and
hasWasm before accessing stdout.trim(). Handle r.error or a non-success status
explicitly, producing a clear command-unavailable/failure result instead of
allowing null stdout to cause a TypeError, while preserving the existing match
behavior for successful grep/sh execution.In
@scripts/verify-directory-plugin.ps1:
- Line 1: Save scripts/verify-directory-plugin.ps1 with a UTF-8 BOM, preserving
its existing content and Windows PowerShell 5.1 compatibility.
Nitpick comments:
In@extensions/measurement-tracking/package.json:
- Around line 24-26: Remove the dev:dicom-pdf entry from the
measurement-tracking package scripts, leaving the standard dev and build scripts
unchanged.In
@platform/docs/docs/configuration/configurationFiles.md:
- Line 448: Update the fenced code blocks at
platform/docs/docs/configuration/configurationFiles.md:448-448,
platform/docs/docs/deployment/runtime-plugins.md:28-28, 99-99, and 145-145, and
platform/docs/docs/development/create-ohif.md:48-48 and 86-86 to include the
text language specifier on each opening fence.In
@platform/docs/docs/configuration/dataSources/dicom-web.md:
- Around line 106-108: Change the fenced code block containing the cross-env
command from JavaScript syntax highlighting to bash or sh, without modifying the
command itself.In
@platform/docs/docs/development/out-of-tree.md:
- Around line 134-136: Add the text language identifier to the fenced code block
containing the directory glob, changing the opening fence to use text while
preserving the block contents.</details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `79d665b9-9811-4593-b285-58a8a44982bb` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 28550c962fa10a456b18a27bc57e6434404f01bb and cde390bdd6d2b572899d9fc727850d3f4aced783. </details> <details> <summary>⛔ Files ignored due to path filters (24)</summary> * `.webpack/resolveConfig.js` is excluded by `!**/.webpack/**` * `.webpack/rules/loadShaders.js` is excluded by `!**/.webpack/**` * `extensions/cornerstone/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/default/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/dicom-microscopy/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/measurement-tracking/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/test-extension/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `modes/preclinical-4d/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `modes/segmentation/.webpack/webpack.prod.js` is excluded by `!**/.webpack/**` * `modes/tmtv/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `modes/usAnnotation/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `platform/app/.webpack/webpack.pwa.js` is excluded by `!**/.webpack/**` * `platform/core/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `platform/create-ohif/test/fixtures/cli-era/extension/.webpack/webpack.prod.js` is excluded by `!**/.webpack/**` * `platform/create-ohif/test/fixtures/cli-era/mode/.webpack/webpack.prod.js` is excluded by `!**/.webpack/**` * `platform/docs/docs/assets/img/add-mode.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/cli-search-no-verbose.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/cli-search-with-verbose.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/clock-mode.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/clock-mode1.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/create-mode.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/mode-template.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/ohif-cli-list.png` is excluded by `!**/*.png` * `pnpm-lock.yaml` is excluded by `!**/pnpm-lock.yaml` </details> <details> <summary>📒 Files selected for processing (273)</summary> * `.circleci/config.yml` * `.docker/Viewer-v3.x/default.conf.template` * `.docker/Viewer-v3.x/default.ssl.conf.template` * `.docker/Viewer-v3.x/entrypoint.sh` * `.rspack/helpers/excludeNodeModulesExcept.js` * `.rspack/pluginExternals.js` * `.rspack/resolveConfig.js` * `.rspack/rspack.base.js` * `.rspack/rules/cssToJavaScript.js` * `.rspack/rules/loadWebWorkers.js` * `.rspack/rules/stylusToJavaScript.js` * `.rspack/rules/transpileJavaScript.js` * `AGENTS.md` * `Dockerfile` * `extensions/cornerstone-dicom-pmap/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-pmap/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-pmap/package.json` * `extensions/cornerstone-dicom-rt/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-rt/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-rt/package.json` * `extensions/cornerstone-dicom-seg/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-seg/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-seg/package.json` * `extensions/cornerstone-dicom-sr/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-sr/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-sr/package.json` * `extensions/cornerstone-dynamic-volume/.rspack/rspack.dev.js` * `extensions/cornerstone-dynamic-volume/.rspack/rspack.prod.js` * `extensions/cornerstone-dynamic-volume/package.json` * `extensions/cornerstone/.rspack/rspack.dev.js` * `extensions/cornerstone/.rspack/rspack.prod.js` * `extensions/cornerstone/package.json` * `extensions/default/.rspack/rspack.dev.js` * `extensions/default/.rspack/rspack.prod.js` * `extensions/default/package.json` * `extensions/dicom-microscopy/.rspack/rspack.dev.js` * `extensions/dicom-microscopy/.rspack/rspack.prod.js` * `extensions/dicom-microscopy/package.json` * `extensions/dicom-pdf/.rspack/rspack.dev.js` * `extensions/dicom-pdf/.rspack/rspack.prod.js` * `extensions/dicom-pdf/package.json` * `extensions/dicom-video/.rspack/rspack.dev.js` * `extensions/dicom-video/.rspack/rspack.prod.js` * `extensions/dicom-video/package.json` * `extensions/measurement-tracking/.rspack/rspack.dev.js` * `extensions/measurement-tracking/.rspack/rspack.prod.js` * `extensions/measurement-tracking/package.json` * `extensions/test-extension/.rspack/rspack.dev.js` * `extensions/test-extension/.rspack/rspack.prod.js` * `extensions/test-extension/package.json` * `extensions/tmtv/.rspack/rspack.dev.js` * `extensions/tmtv/.rspack/rspack.prod.js` * `extensions/tmtv/package.json` * `extensions/usAnnotation/.rspack/rspack.dev.js` * `extensions/usAnnotation/.rspack/rspack.prod.js` * `extensions/usAnnotation/package.json` * `modes/basic-dev-mode/.rspack/rspack.dev.js` * `modes/basic-dev-mode/.rspack/rspack.prod.js` * `modes/basic-dev-mode/package.json` * `modes/basic-test-mode/.rspack/rspack.dev.js` * `modes/basic-test-mode/.rspack/rspack.prod.js` * `modes/basic-test-mode/package.json` * `modes/basic/.rspack/rspack.prod.js` * `modes/basic/package.json` * `modes/longitudinal/.rspack/rspack.dev.js` * `modes/longitudinal/.rspack/rspack.prod.js` * `modes/longitudinal/package.json` * `modes/microscopy/.rspack/rspack.dev.js` * `modes/microscopy/.rspack/rspack.prod.js` * `modes/microscopy/package.json` * `modes/preclinical-4d/.rspack/rspack.dev.js` * `modes/preclinical-4d/.rspack/rspack.prod.js` * `modes/preclinical-4d/package.json` * `modes/segmentation/.rspack/rspack.prod.js` * `modes/segmentation/package.json` * `modes/tmtv/.rspack/rspack.dev.js` * `modes/tmtv/.rspack/rspack.prod.js` * `modes/tmtv/package.json` * `modes/usAnnotation/.rspack/rspack.dev.js` * `modes/usAnnotation/.rspack/rspack.prod.js` * `modes/usAnnotation/package.json` * `netlify.toml` * `package.json` * `platform/app/.rspack/CONTRACT.md` * `platform/app/.rspack/rules/fontsToJavaScript.js` * `platform/app/.rspack/writePluginImportsFile.js` * `platform/app/package.json` * `platform/app/pluginConfig.json` * `platform/app/pluginConfig.schema.json` * `platform/app/src/App.tsx` * `platform/app/src/__tests__/pluginImportsCodegen.test.js` * `platform/app/src/appInit.js` * `platform/app/src/index.js` * `platform/app/src/loadDynamicConfig.js` * `platform/app/src/loadDynamicConfig.test.js` * `platform/app/src/routes/Mode/Mode.tsx` * `platform/app/src/runtimeExtensionLoader.test.js` * `platform/app/src/runtimeExtensionLoader.ts` * `platform/app/src/runtimeShared.test.js` * `platform/app/src/runtimeShared.ts` * `platform/app/src/service-worker.js` * `platform/app/src/types/runtimeExtensions.d.ts` * `platform/app/tailwind.config.js` * `platform/cli/CHANGELOG.md` * `platform/cli/package.json` * `platform/cli/src/commands/addExtension.js` * `platform/cli/src/commands/addExtensions.js` * `platform/cli/src/commands/addMode.js` * `platform/cli/src/commands/constants/notFound.js` * `platform/cli/src/commands/createPackage.js` * `platform/cli/src/commands/enums/colors.js` * `platform/cli/src/commands/enums/endPoints.js` * `platform/cli/src/commands/enums/index.js` * `platform/cli/src/commands/enums/keywords.js` * `platform/cli/src/commands/index.js` * `platform/cli/src/commands/linkPackage.js` * `platform/cli/src/commands/listPlugins.js` * `platform/cli/src/commands/removeExtension.js` * `platform/cli/src/commands/removeExtensions.js` * `platform/cli/src/commands/removeMode.js` * `platform/cli/src/commands/searchPlugins.js` * `platform/cli/src/commands/unlinkPackage.js` * `platform/cli/src/commands/utils/addToConfig.js` * `platform/cli/src/commands/utils/createDirectoryContents.js` * `platform/cli/src/commands/utils/createLicense.js` * `platform/cli/src/commands/utils/createReadme.js` * `platform/cli/src/commands/utils/editPackageJson.js` * `platform/cli/src/commands/utils/findOhifExtensionsToRemoveAfterRemovingMode.js` * `platform/cli/src/commands/utils/findRequiredOhifExtensionsForMode.js` * `platform/cli/src/commands/utils/getVersionedPackageName.js` * `platform/cli/src/commands/utils/getYarnInfo.js` * `platform/cli/src/commands/utils/index.js` * `platform/cli/src/commands/utils/initGit.js` * `platform/cli/src/commands/utils/installNPMPackage.js` * `platform/cli/src/commands/utils/prettyPrint.js` * `platform/cli/src/commands/utils/private/getPackageNameAndScope.js` * `platform/cli/src/commands/utils/private/index.js` * `platform/cli/src/commands/utils/private/manipulatePluginConfigFile.js` * `platform/cli/src/commands/utils/private/readPluginConfigFile.js` * `platform/cli/src/commands/utils/private/writePluginConfigFile.js` * `platform/cli/src/commands/utils/removeFromConfig.js` * `platform/cli/src/commands/utils/throwIfExtensionUsedByInstalledMode.js` * `platform/cli/src/commands/utils/uninstallNPMPackage.js` * `platform/cli/src/commands/utils/validate.js` * `platform/cli/src/commands/utils/validatePnpm.js` * `platform/cli/src/index.js` * `platform/cli/src/questions.js` * `platform/core/.rspack/rspack.dev.js` * `platform/core/.rspack/rspack.prod.js` * `platform/core/package.json` * `platform/create-ohif/README.md` * `platform/create-ohif/bin/create-ohif.mjs` * `platform/create-ohif/package.json` * `platform/create-ohif/scripts/scaffold-smoke.mjs` * `platform/create-ohif/templates/deployment/README.md` * `platform/create-ohif/templates/deployment/app-config.js` * `platform/create-ohif/templates/deployment/docker-compose.yml` * `platform/create-ohif/templates/extension/AGENTS.md` * `platform/create-ohif/templates/extension/README.md` * `platform/create-ohif/templates/extension/_gitignore` * `platform/create-ohif/templates/extension/_npmrc` * `platform/create-ohif/templates/extension/_prettierrc` * `platform/create-ohif/templates/extension/_rspack/pluginExternals.js` * `platform/create-ohif/templates/extension/_rspack/rspack.prod.js` * `platform/create-ohif/templates/extension/package.json` * `platform/create-ohif/templates/extension/pnpm-workspace.yaml` * `platform/create-ohif/templates/extension/public/.gitkeep` * `platform/create-ohif/templates/extension/src/__tests__/extension.test.ts` * `platform/create-ohif/templates/extension/src/__tests__/harness.ts` * `platform/create-ohif/templates/extension/src/commandsModule.ts` * `platform/create-ohif/templates/extension/src/getHangingProtocolModule.ts` * `platform/create-ohif/templates/extension/src/getPanelModule.tsx` * `platform/create-ohif/templates/extension/src/getSopClassHandlerModule.ts` * `platform/create-ohif/templates/extension/src/getToolbarModule.tsx` * `platform/create-ohif/templates/extension/src/getViewportModule.tsx` * `platform/create-ohif/templates/extension/src/id.ts` * `platform/create-ohif/templates/extension/src/index.tsx` * `platform/create-ohif/templates/extension/src/panels/ExamplePanel.tsx` * `platform/create-ohif/templates/extension/src/styles.css` * `platform/create-ohif/templates/extension/src/viewports/ExampleViewport.tsx` * `platform/create-ohif/templates/extension/tailwind.config.js` * `platform/create-ohif/templates/extension/tsconfig.json` * `platform/create-ohif/templates/mode/AGENTS.md` * `platform/create-ohif/templates/mode/README.md` * `platform/create-ohif/templates/mode/_gitignore` * `platform/create-ohif/templates/mode/_npmrc` * `platform/create-ohif/templates/mode/_prettierrc` * `platform/create-ohif/templates/mode/_rspack/pluginExternals.js` * `platform/create-ohif/templates/mode/_rspack/rspack.prod.js` * `platform/create-ohif/templates/mode/package.json` * `platform/create-ohif/templates/mode/pnpm-workspace.yaml` * `platform/create-ohif/templates/mode/src/__tests__/mode.test.ts` * `platform/create-ohif/templates/mode/src/id.ts` * `platform/create-ohif/templates/mode/src/index.ts` * `platform/create-ohif/templates/mode/src/toolbarButtons.ts` * `platform/create-ohif/templates/mode/tsconfig.json` * `platform/create-ohif/templates/workspace/Dockerfile` * `platform/create-ohif/templates/workspace/_gitignore` * `platform/create-ohif/templates/workspace/config/app-config.js` * `platform/create-ohif/templates/workspace/extensions/.gitkeep` * `platform/create-ohif/templates/workspace/modes/.gitkeep` * `platform/create-ohif/templates/workspace/ohif.config.json` * `platform/create-ohif/templates/workspace/package.json` * `platform/create-ohif/templates/workspace/scripts/ohif.mjs` * `platform/create-ohif/test/fixtures/cli-era/extension/.gitignore` * `platform/create-ohif/test/fixtures/cli-era/extension/.prettierrc` * `platform/create-ohif/test/fixtures/cli-era/extension/babel.config.js` * `platform/create-ohif/test/fixtures/cli-era/extension/dependencies.json` * `platform/create-ohif/test/fixtures/cli-era/extension/src/id.js` * `platform/create-ohif/test/fixtures/cli-era/extension/src/index.tsx` * `platform/create-ohif/test/fixtures/cli-era/mode/.gitignore` * `platform/create-ohif/test/fixtures/cli-era/mode/.prettierrc` * `platform/create-ohif/test/fixtures/cli-era/mode/babel.config.js` * `platform/create-ohif/test/fixtures/cli-era/mode/dependencies.json` * `platform/create-ohif/test/fixtures/cli-era/mode/src/id.js` * `platform/create-ohif/test/fixtures/cli-era/mode/src/index.tsx` * `platform/create-ohif/tests/externals-parity.test.mjs` * `platform/create-ohif/tests/manifest.test.mjs` * `platform/create-ohif/tests/migrate.test.mjs` * `platform/create-ohif/tests/scaffold.test.mjs` * `platform/docs/docs/configuration/configurationFiles.md` * `platform/docs/docs/configuration/dataSources/dicom-web.md` * `platform/docs/docs/deployment/runtime-plugins.md` * `platform/docs/docs/development/create-ohif.md` * `platform/docs/docs/development/ohif-cli.md` * `platform/docs/docs/development/out-of-tree.md` * `platform/docs/docs/development/publishing.md` * `platform/docs/docs/development/video-tutorials.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/build-tooling.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/cli-removal.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/customization-url.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/node-version.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/package-manager.md` * `platform/docs/docs/migration-guide/3p8-to-3p9/0-general.md` * `platform/docs/docs/migration-guide/cli-era-extensions.md` * `platform/docs/docs/migration-guide/deforking.md` * `platform/docs/docs/migration-guide/from-v2.md` * `platform/docs/docs/platform/extensions/building-with-agents.md` * `platform/docs/docs/platform/extensions/gallery.mdx` * `platform/docs/docs/platform/extensions/index.md` * `platform/docs/docs/platform/extensions/installation.md` * `platform/docs/docs/platform/extensions/pluginConfig.md` * `platform/docs/docs/platform/extensions/runtime-extensions.md` * `platform/docs/docs/platform/modes/index.md` * `platform/docs/docs/platform/modes/installation.md` * `platform/docs/docusaurus.config.js` * `platform/docs/package.json` * `platform/docs/scripts/check-agents-md-sync.mjs` * `platform/docs/scripts/validate-gallery.mjs` * `platform/docs/src/data/extension-gallery.json` * `platform/docs/static/schemas/extension-gallery.schema.json` * `platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md` * `platform/docs/versioned_docs/version-3.11/development/ohif-cli.md` * `platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md` * `platform/docs/versioned_docs/version-3.11/migration-guide/from-v2.md` * `platform/i18n/.rspack/rspack.dev.js` * `platform/i18n/.rspack/rspack.prod.js` * `platform/i18n/package.json` * `platform/ui-next/.rspack/rspack.dev.js` * `platform/ui-next/.rspack/rspack.prod.js` * `platform/ui-next/.rspack/template.html` * `platform/ui-next/package.json` * `platform/ui/.rspack/rspack.dev.js` * `platform/ui/.rspack/rspack.prod.js` * `platform/ui/package.json` * `playwright.config.ts` * `publish-package.mjs` * `rsbuild.config.ts` * `scripts/ohif-plugin.mjs` * `scripts/verify-build-parity.mjs` * `scripts/verify-directory-plugin.ps1` * `scripts/verify-tarballs.mjs` * `scripts/verify-umd-global.mjs` </details> <details> <summary>💤 Files with no reviewable changes (44)</summary> * platform/cli/src/commands/enums/colors.js * platform/cli/src/questions.js * platform/cli/src/commands/utils/editPackageJson.js * platform/cli/src/commands/enums/keywords.js * platform/cli/src/commands/constants/notFound.js * platform/cli/src/commands/removeExtension.js * platform/cli/src/commands/utils/createDirectoryContents.js * platform/cli/src/commands/utils/installNPMPackage.js * platform/cli/src/commands/utils/getYarnInfo.js * platform/cli/src/commands/enums/index.js * platform/cli/src/commands/addMode.js * platform/docs/docs/development/ohif-cli.md * platform/cli/src/commands/index.js * platform/cli/src/commands/createPackage.js * platform/cli/src/commands/utils/createLicense.js * platform/cli/src/commands/utils/private/manipulatePluginConfigFile.js * platform/cli/src/commands/utils/getVersionedPackageName.js * platform/cli/src/commands/utils/index.js * platform/cli/src/commands/addExtensions.js * platform/cli/src/commands/enums/endPoints.js * platform/cli/src/commands/utils/initGit.js * platform/cli/src/commands/utils/uninstallNPMPackage.js * platform/cli/src/commands/listPlugins.js * platform/cli/src/commands/utils/createReadme.js * platform/cli/src/commands/utils/private/index.js * platform/cli/src/commands/utils/findOhifExtensionsToRemoveAfterRemovingMode.js * platform/cli/src/commands/utils/throwIfExtensionUsedByInstalledMode.js * platform/cli/package.json * platform/cli/src/commands/utils/validate.js * platform/cli/src/commands/removeExtensions.js * platform/cli/src/commands/utils/private/getPackageNameAndScope.js * platform/cli/src/commands/removeMode.js * platform/cli/src/commands/utils/removeFromConfig.js * platform/cli/src/commands/linkPackage.js * platform/cli/src/commands/addExtension.js * platform/cli/src/commands/utils/prettyPrint.js * platform/cli/src/commands/utils/private/writePluginConfigFile.js * platform/cli/src/index.js * platform/cli/src/commands/utils/private/readPluginConfigFile.js * platform/cli/src/commands/searchPlugins.js * platform/cli/src/commands/utils/addToConfig.js * platform/cli/src/commands/utils/validatePnpm.js * platform/cli/src/commands/utils/findRequiredOhifExtensionsForMode.js * platform/cli/src/commands/unlinkPackage.js </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 11
🧹 Nitpick comments (4)
extensions/measurement-tracking/package.json (1)
24-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the
dev:dicom-pdfscript.The
dev:dicom-pdfscript appears to be a copy-paste error from thedicom-pdfextension, as it just aliases the standarddevscript in themeasurement-trackingpackage.♻️ Proposed fix
"dev": "cross-env NODE_ENV=development rspack build --config .rspack/rspack.dev.js --watch", - "dev:dicom-pdf": "pnpm run dev", "build": "cross-env NODE_ENV=production rspack build --config .rspack/rspack.prod.js",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@extensions/measurement-tracking/package.json` around lines 24 - 26, Remove the dev:dicom-pdf entry from the measurement-tracking package scripts, leaving the standard dev and build scripts unchanged.platform/docs/docs/configuration/dataSources/dicom-web.md (1)
106-108: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueChange the code block language to
bashorsh.The code block contains a shell command, not JavaScript.
♻️ Proposed fix
-```js +```bash cross-env NODE_ENV=development PROXY_TARGET=/pacs/dicom-web PROXY_DOMAIN=http://localhost:8042 PROXY_PATH_REWRITE_FROM=/pacs/dicom-web PROXY_PATH_REWRITE_TO=/dicom-web APP_CONFIG=config/docker-nginx-orthanc.js rsbuild dev --config ../../rsbuild.config.ts</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@platform/docs/docs/configuration/dataSources/dicom-web.mdaround lines 106 -
108, Change the fenced code block containing the cross-env command from
JavaScript syntax highlighting to bash or sh, without modifying the command
itself.</details> <!-- cr-comment:v1:9d4256e8fb97756ef0178743 --> </blockquote></details> <details> <summary>platform/docs/docs/configuration/configurationFiles.md (1)</summary><blockquote> `448-448`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_ **Specify a language for fenced code blocks.** As indicated by static analysis, several fenced code blocks are missing a language specifier. Adding a language like `text` or `csp` improves formatting and resolves the markdownlint warnings. - `platform/docs/docs/configuration/configurationFiles.md#L448-L448`: Add `text` to the code fence. - `platform/docs/docs/deployment/runtime-plugins.md#L28-L28`: Add `text` to the code fence. - `platform/docs/docs/deployment/runtime-plugins.md#L99-L99`: Add `text` to the code fence. - `platform/docs/docs/deployment/runtime-plugins.md#L145-L145`: Add `text` to the code fence. - `platform/docs/docs/development/create-ohif.md#L48-L48`: Add `text` to the code fence. - `platform/docs/docs/development/create-ohif.md#L86-L86`: Add `text` to the code fence. <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@platform/docs/docs/configuration/configurationFiles.mdat line 448, Update
the fenced code blocks at
platform/docs/docs/configuration/configurationFiles.md:448-448,
platform/docs/docs/deployment/runtime-plugins.md:28-28, 99-99, and 145-145, and
platform/docs/docs/development/create-ohif.md:48-48 and 86-86 to include the
text language specifier on each opening fence.</details> <!-- cr-comment:v1:399fed159e3df243e39ede2d --> _Source: Linters/SAST tools_ </blockquote></details> <details> <summary>platform/docs/docs/development/out-of-tree.md (1)</summary><blockquote> `134-136`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_ **Add a language identifier to the fenced code block.** Specifying a language like `text` helps with syntax highlighting and resolves markdown linter warnings. <details> <summary>♻️ Proposed fix</summary> ```diff -``` +```text <directory>/src/**/*.{jsx,js,ts,tsx,css}</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@platform/docs/docs/development/out-of-tree.mdaround lines 134 - 136, Add
the text language identifier to the fenced code block containing the directory
glob, changing the opening fence to use text while preserving the block
contents.</details> <!-- cr-comment:v1:7ce01cb2e0ba3816f88262e9 --> _Source: Linters/SAST tools_ </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Inline comments:
In @.rspack/resolveConfig.js:
- Around line 69-75: Remove the path.resolve(__dirname, '../../../node_modules')
entry from the moduleSearchPaths array in resolveConfig.js. Preserve the
existing repository-root and platform-specific node_modules paths.In @.rspack/rules/cssToJavaScript.js:
- Around line 19-22: Update the plugins configuration in the PostCSS setup to
pass tailwindcss and autoprefixer directly as plugin instances, removing the
extra nested arrays so postcss-loader can apply both plugins.In
@platform/app/src/routes/Mode/Mode.tsx:
- Around line 104-108: Update the registerExtension catch block in the
loadModules flow to report failures for built-in extensions even when
recordRegistrationError finds no audit record. Log the caught error
unconditionally or update recordRegistrationError to emit a console.error when
no matching record exists, while preserving existing auditing and runtime
failure surfacing.In
@platform/core/package.json:
- Line 24: Update the package.json sideEffects setting from the string value
"false" to the boolean false, preserving the existing configuration intent.In
@platform/create-ohif/README.md:
- Around line 17-25: The README usage block for create-ohif must match the
bin/create-ohif.mjs USAGE definition: expand --template to include workspace and
deployment, and document the migrate [--dry-run] subcommand. Update only
the CLI arguments documentation while preserving the existing option
descriptions.In
@platform/create-ohif/templates/mode/src/toolbarButtons.ts:
- Around line 4-10: Update setToolActiveToolbar.commandOptions.toolGroupIds to
remove the dangling 'mpr' entry, leaving only the 'default' tool group created
by onModeEnter.In
@platform/create-ohif/templates/workspace/scripts/ohif.mjs:
- Line 144: Update the package classification logic in the section assignment to
recognize both scoped and unscoped mode package names, including names such as
mode-basic and@ohif/mode-basic, while continuing to classify other packages as
extensions.In
@platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md:
- Around line 107-114: Restore the historical Webpack references in all three
affected version-3.11 documents: in
platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md
lines 107-114, replace .rspack/rspack.pwa.js with .webpack/webpack.pwa.js in
both the command and explanation; in
platform/docs/versioned_docs/version-3.11/development/ohif-cli.md line 309,
replace rspack.pwa.js with webpack.pwa.js; and in
platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md
line 108, replace .rspack/rspack.pwa.js with .webpack/webpack.pwa.js.In
@platform/ui-next/package.json:
- Around line 25-30: Update the publishConfig.exports map in package.json to
avoid exposing raw TypeScript and TSX source paths through ./lib/* and
./components/*. If the SDK supports only root-module runtime imports, remove
these deep exports; otherwise, redirect them to transpiled JavaScript artifacts
that are included in the published package.In
@scripts/verify-build-parity.mjs:
- Around line 65-74: Guard the spawnSync results in both treeContains and
hasWasm before accessing stdout.trim(). Handle r.error or a non-success status
explicitly, producing a clear command-unavailable/failure result instead of
allowing null stdout to cause a TypeError, while preserving the existing match
behavior for successful grep/sh execution.In
@scripts/verify-directory-plugin.ps1:
- Line 1: Save scripts/verify-directory-plugin.ps1 with a UTF-8 BOM, preserving
its existing content and Windows PowerShell 5.1 compatibility.
Nitpick comments:
In@extensions/measurement-tracking/package.json:
- Around line 24-26: Remove the dev:dicom-pdf entry from the
measurement-tracking package scripts, leaving the standard dev and build scripts
unchanged.In
@platform/docs/docs/configuration/configurationFiles.md:
- Line 448: Update the fenced code blocks at
platform/docs/docs/configuration/configurationFiles.md:448-448,
platform/docs/docs/deployment/runtime-plugins.md:28-28, 99-99, and 145-145, and
platform/docs/docs/development/create-ohif.md:48-48 and 86-86 to include the
text language specifier on each opening fence.In
@platform/docs/docs/configuration/dataSources/dicom-web.md:
- Around line 106-108: Change the fenced code block containing the cross-env
command from JavaScript syntax highlighting to bash or sh, without modifying the
command itself.In
@platform/docs/docs/development/out-of-tree.md:
- Around line 134-136: Add the text language identifier to the fenced code block
containing the directory glob, changing the opening fence to use text while
preserving the block contents.</details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `79d665b9-9811-4593-b285-58a8a44982bb` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 28550c962fa10a456b18a27bc57e6434404f01bb and cde390bdd6d2b572899d9fc727850d3f4aced783. </details> <details> <summary>⛔ Files ignored due to path filters (24)</summary> * `.webpack/resolveConfig.js` is excluded by `!**/.webpack/**` * `.webpack/rules/loadShaders.js` is excluded by `!**/.webpack/**` * `extensions/cornerstone/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/default/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/dicom-microscopy/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/measurement-tracking/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `extensions/test-extension/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `modes/preclinical-4d/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `modes/segmentation/.webpack/webpack.prod.js` is excluded by `!**/.webpack/**` * `modes/tmtv/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `modes/usAnnotation/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `platform/app/.webpack/webpack.pwa.js` is excluded by `!**/.webpack/**` * `platform/core/.webpack/webpack.dev.js` is excluded by `!**/.webpack/**` * `platform/create-ohif/test/fixtures/cli-era/extension/.webpack/webpack.prod.js` is excluded by `!**/.webpack/**` * `platform/create-ohif/test/fixtures/cli-era/mode/.webpack/webpack.prod.js` is excluded by `!**/.webpack/**` * `platform/docs/docs/assets/img/add-mode.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/cli-search-no-verbose.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/cli-search-with-verbose.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/clock-mode.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/clock-mode1.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/create-mode.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/mode-template.png` is excluded by `!**/*.png` * `platform/docs/docs/assets/img/ohif-cli-list.png` is excluded by `!**/*.png` * `pnpm-lock.yaml` is excluded by `!**/pnpm-lock.yaml` </details> <details> <summary>📒 Files selected for processing (273)</summary> * `.circleci/config.yml` * `.docker/Viewer-v3.x/default.conf.template` * `.docker/Viewer-v3.x/default.ssl.conf.template` * `.docker/Viewer-v3.x/entrypoint.sh` * `.rspack/helpers/excludeNodeModulesExcept.js` * `.rspack/pluginExternals.js` * `.rspack/resolveConfig.js` * `.rspack/rspack.base.js` * `.rspack/rules/cssToJavaScript.js` * `.rspack/rules/loadWebWorkers.js` * `.rspack/rules/stylusToJavaScript.js` * `.rspack/rules/transpileJavaScript.js` * `AGENTS.md` * `Dockerfile` * `extensions/cornerstone-dicom-pmap/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-pmap/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-pmap/package.json` * `extensions/cornerstone-dicom-rt/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-rt/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-rt/package.json` * `extensions/cornerstone-dicom-seg/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-seg/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-seg/package.json` * `extensions/cornerstone-dicom-sr/.rspack/rspack.dev.js` * `extensions/cornerstone-dicom-sr/.rspack/rspack.prod.js` * `extensions/cornerstone-dicom-sr/package.json` * `extensions/cornerstone-dynamic-volume/.rspack/rspack.dev.js` * `extensions/cornerstone-dynamic-volume/.rspack/rspack.prod.js` * `extensions/cornerstone-dynamic-volume/package.json` * `extensions/cornerstone/.rspack/rspack.dev.js` * `extensions/cornerstone/.rspack/rspack.prod.js` * `extensions/cornerstone/package.json` * `extensions/default/.rspack/rspack.dev.js` * `extensions/default/.rspack/rspack.prod.js` * `extensions/default/package.json` * `extensions/dicom-microscopy/.rspack/rspack.dev.js` * `extensions/dicom-microscopy/.rspack/rspack.prod.js` * `extensions/dicom-microscopy/package.json` * `extensions/dicom-pdf/.rspack/rspack.dev.js` * `extensions/dicom-pdf/.rspack/rspack.prod.js` * `extensions/dicom-pdf/package.json` * `extensions/dicom-video/.rspack/rspack.dev.js` * `extensions/dicom-video/.rspack/rspack.prod.js` * `extensions/dicom-video/package.json` * `extensions/measurement-tracking/.rspack/rspack.dev.js` * `extensions/measurement-tracking/.rspack/rspack.prod.js` * `extensions/measurement-tracking/package.json` * `extensions/test-extension/.rspack/rspack.dev.js` * `extensions/test-extension/.rspack/rspack.prod.js` * `extensions/test-extension/package.json` * `extensions/tmtv/.rspack/rspack.dev.js` * `extensions/tmtv/.rspack/rspack.prod.js` * `extensions/tmtv/package.json` * `extensions/usAnnotation/.rspack/rspack.dev.js` * `extensions/usAnnotation/.rspack/rspack.prod.js` * `extensions/usAnnotation/package.json` * `modes/basic-dev-mode/.rspack/rspack.dev.js` * `modes/basic-dev-mode/.rspack/rspack.prod.js` * `modes/basic-dev-mode/package.json` * `modes/basic-test-mode/.rspack/rspack.dev.js` * `modes/basic-test-mode/.rspack/rspack.prod.js` * `modes/basic-test-mode/package.json` * `modes/basic/.rspack/rspack.prod.js` * `modes/basic/package.json` * `modes/longitudinal/.rspack/rspack.dev.js` * `modes/longitudinal/.rspack/rspack.prod.js` * `modes/longitudinal/package.json` * `modes/microscopy/.rspack/rspack.dev.js` * `modes/microscopy/.rspack/rspack.prod.js` * `modes/microscopy/package.json` * `modes/preclinical-4d/.rspack/rspack.dev.js` * `modes/preclinical-4d/.rspack/rspack.prod.js` * `modes/preclinical-4d/package.json` * `modes/segmentation/.rspack/rspack.prod.js` * `modes/segmentation/package.json` * `modes/tmtv/.rspack/rspack.dev.js` * `modes/tmtv/.rspack/rspack.prod.js` * `modes/tmtv/package.json` * `modes/usAnnotation/.rspack/rspack.dev.js` * `modes/usAnnotation/.rspack/rspack.prod.js` * `modes/usAnnotation/package.json` * `netlify.toml` * `package.json` * `platform/app/.rspack/CONTRACT.md` * `platform/app/.rspack/rules/fontsToJavaScript.js` * `platform/app/.rspack/writePluginImportsFile.js` * `platform/app/package.json` * `platform/app/pluginConfig.json` * `platform/app/pluginConfig.schema.json` * `platform/app/src/App.tsx` * `platform/app/src/__tests__/pluginImportsCodegen.test.js` * `platform/app/src/appInit.js` * `platform/app/src/index.js` * `platform/app/src/loadDynamicConfig.js` * `platform/app/src/loadDynamicConfig.test.js` * `platform/app/src/routes/Mode/Mode.tsx` * `platform/app/src/runtimeExtensionLoader.test.js` * `platform/app/src/runtimeExtensionLoader.ts` * `platform/app/src/runtimeShared.test.js` * `platform/app/src/runtimeShared.ts` * `platform/app/src/service-worker.js` * `platform/app/src/types/runtimeExtensions.d.ts` * `platform/app/tailwind.config.js` * `platform/cli/CHANGELOG.md` * `platform/cli/package.json` * `platform/cli/src/commands/addExtension.js` * `platform/cli/src/commands/addExtensions.js` * `platform/cli/src/commands/addMode.js` * `platform/cli/src/commands/constants/notFound.js` * `platform/cli/src/commands/createPackage.js` * `platform/cli/src/commands/enums/colors.js` * `platform/cli/src/commands/enums/endPoints.js` * `platform/cli/src/commands/enums/index.js` * `platform/cli/src/commands/enums/keywords.js` * `platform/cli/src/commands/index.js` * `platform/cli/src/commands/linkPackage.js` * `platform/cli/src/commands/listPlugins.js` * `platform/cli/src/commands/removeExtension.js` * `platform/cli/src/commands/removeExtensions.js` * `platform/cli/src/commands/removeMode.js` * `platform/cli/src/commands/searchPlugins.js` * `platform/cli/src/commands/unlinkPackage.js` * `platform/cli/src/commands/utils/addToConfig.js` * `platform/cli/src/commands/utils/createDirectoryContents.js` * `platform/cli/src/commands/utils/createLicense.js` * `platform/cli/src/commands/utils/createReadme.js` * `platform/cli/src/commands/utils/editPackageJson.js` * `platform/cli/src/commands/utils/findOhifExtensionsToRemoveAfterRemovingMode.js` * `platform/cli/src/commands/utils/findRequiredOhifExtensionsForMode.js` * `platform/cli/src/commands/utils/getVersionedPackageName.js` * `platform/cli/src/commands/utils/getYarnInfo.js` * `platform/cli/src/commands/utils/index.js` * `platform/cli/src/commands/utils/initGit.js` * `platform/cli/src/commands/utils/installNPMPackage.js` * `platform/cli/src/commands/utils/prettyPrint.js` * `platform/cli/src/commands/utils/private/getPackageNameAndScope.js` * `platform/cli/src/commands/utils/private/index.js` * `platform/cli/src/commands/utils/private/manipulatePluginConfigFile.js` * `platform/cli/src/commands/utils/private/readPluginConfigFile.js` * `platform/cli/src/commands/utils/private/writePluginConfigFile.js` * `platform/cli/src/commands/utils/removeFromConfig.js` * `platform/cli/src/commands/utils/throwIfExtensionUsedByInstalledMode.js` * `platform/cli/src/commands/utils/uninstallNPMPackage.js` * `platform/cli/src/commands/utils/validate.js` * `platform/cli/src/commands/utils/validatePnpm.js` * `platform/cli/src/index.js` * `platform/cli/src/questions.js` * `platform/core/.rspack/rspack.dev.js` * `platform/core/.rspack/rspack.prod.js` * `platform/core/package.json` * `platform/create-ohif/README.md` * `platform/create-ohif/bin/create-ohif.mjs` * `platform/create-ohif/package.json` * `platform/create-ohif/scripts/scaffold-smoke.mjs` * `platform/create-ohif/templates/deployment/README.md` * `platform/create-ohif/templates/deployment/app-config.js` * `platform/create-ohif/templates/deployment/docker-compose.yml` * `platform/create-ohif/templates/extension/AGENTS.md` * `platform/create-ohif/templates/extension/README.md` * `platform/create-ohif/templates/extension/_gitignore` * `platform/create-ohif/templates/extension/_npmrc` * `platform/create-ohif/templates/extension/_prettierrc` * `platform/create-ohif/templates/extension/_rspack/pluginExternals.js` * `platform/create-ohif/templates/extension/_rspack/rspack.prod.js` * `platform/create-ohif/templates/extension/package.json` * `platform/create-ohif/templates/extension/pnpm-workspace.yaml` * `platform/create-ohif/templates/extension/public/.gitkeep` * `platform/create-ohif/templates/extension/src/__tests__/extension.test.ts` * `platform/create-ohif/templates/extension/src/__tests__/harness.ts` * `platform/create-ohif/templates/extension/src/commandsModule.ts` * `platform/create-ohif/templates/extension/src/getHangingProtocolModule.ts` * `platform/create-ohif/templates/extension/src/getPanelModule.tsx` * `platform/create-ohif/templates/extension/src/getSopClassHandlerModule.ts` * `platform/create-ohif/templates/extension/src/getToolbarModule.tsx` * `platform/create-ohif/templates/extension/src/getViewportModule.tsx` * `platform/create-ohif/templates/extension/src/id.ts` * `platform/create-ohif/templates/extension/src/index.tsx` * `platform/create-ohif/templates/extension/src/panels/ExamplePanel.tsx` * `platform/create-ohif/templates/extension/src/styles.css` * `platform/create-ohif/templates/extension/src/viewports/ExampleViewport.tsx` * `platform/create-ohif/templates/extension/tailwind.config.js` * `platform/create-ohif/templates/extension/tsconfig.json` * `platform/create-ohif/templates/mode/AGENTS.md` * `platform/create-ohif/templates/mode/README.md` * `platform/create-ohif/templates/mode/_gitignore` * `platform/create-ohif/templates/mode/_npmrc` * `platform/create-ohif/templates/mode/_prettierrc` * `platform/create-ohif/templates/mode/_rspack/pluginExternals.js` * `platform/create-ohif/templates/mode/_rspack/rspack.prod.js` * `platform/create-ohif/templates/mode/package.json` * `platform/create-ohif/templates/mode/pnpm-workspace.yaml` * `platform/create-ohif/templates/mode/src/__tests__/mode.test.ts` * `platform/create-ohif/templates/mode/src/id.ts` * `platform/create-ohif/templates/mode/src/index.ts` * `platform/create-ohif/templates/mode/src/toolbarButtons.ts` * `platform/create-ohif/templates/mode/tsconfig.json` * `platform/create-ohif/templates/workspace/Dockerfile` * `platform/create-ohif/templates/workspace/_gitignore` * `platform/create-ohif/templates/workspace/config/app-config.js` * `platform/create-ohif/templates/workspace/extensions/.gitkeep` * `platform/create-ohif/templates/workspace/modes/.gitkeep` * `platform/create-ohif/templates/workspace/ohif.config.json` * `platform/create-ohif/templates/workspace/package.json` * `platform/create-ohif/templates/workspace/scripts/ohif.mjs` * `platform/create-ohif/test/fixtures/cli-era/extension/.gitignore` * `platform/create-ohif/test/fixtures/cli-era/extension/.prettierrc` * `platform/create-ohif/test/fixtures/cli-era/extension/babel.config.js` * `platform/create-ohif/test/fixtures/cli-era/extension/dependencies.json` * `platform/create-ohif/test/fixtures/cli-era/extension/src/id.js` * `platform/create-ohif/test/fixtures/cli-era/extension/src/index.tsx` * `platform/create-ohif/test/fixtures/cli-era/mode/.gitignore` * `platform/create-ohif/test/fixtures/cli-era/mode/.prettierrc` * `platform/create-ohif/test/fixtures/cli-era/mode/babel.config.js` * `platform/create-ohif/test/fixtures/cli-era/mode/dependencies.json` * `platform/create-ohif/test/fixtures/cli-era/mode/src/id.js` * `platform/create-ohif/test/fixtures/cli-era/mode/src/index.tsx` * `platform/create-ohif/tests/externals-parity.test.mjs` * `platform/create-ohif/tests/manifest.test.mjs` * `platform/create-ohif/tests/migrate.test.mjs` * `platform/create-ohif/tests/scaffold.test.mjs` * `platform/docs/docs/configuration/configurationFiles.md` * `platform/docs/docs/configuration/dataSources/dicom-web.md` * `platform/docs/docs/deployment/runtime-plugins.md` * `platform/docs/docs/development/create-ohif.md` * `platform/docs/docs/development/ohif-cli.md` * `platform/docs/docs/development/out-of-tree.md` * `platform/docs/docs/development/publishing.md` * `platform/docs/docs/development/video-tutorials.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/build-tooling.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/cli-removal.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/customization-url.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/node-version.md` * `platform/docs/docs/migration-guide/3p12-to-3p13/package-manager.md` * `platform/docs/docs/migration-guide/3p8-to-3p9/0-general.md` * `platform/docs/docs/migration-guide/cli-era-extensions.md` * `platform/docs/docs/migration-guide/deforking.md` * `platform/docs/docs/migration-guide/from-v2.md` * `platform/docs/docs/platform/extensions/building-with-agents.md` * `platform/docs/docs/platform/extensions/gallery.mdx` * `platform/docs/docs/platform/extensions/index.md` * `platform/docs/docs/platform/extensions/installation.md` * `platform/docs/docs/platform/extensions/pluginConfig.md` * `platform/docs/docs/platform/extensions/runtime-extensions.md` * `platform/docs/docs/platform/modes/index.md` * `platform/docs/docs/platform/modes/installation.md` * `platform/docs/docusaurus.config.js` * `platform/docs/package.json` * `platform/docs/scripts/check-agents-md-sync.mjs` * `platform/docs/scripts/validate-gallery.mjs` * `platform/docs/src/data/extension-gallery.json` * `platform/docs/static/schemas/extension-gallery.schema.json` * `platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md` * `platform/docs/versioned_docs/version-3.11/development/ohif-cli.md` * `platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md` * `platform/docs/versioned_docs/version-3.11/migration-guide/from-v2.md` * `platform/i18n/.rspack/rspack.dev.js` * `platform/i18n/.rspack/rspack.prod.js` * `platform/i18n/package.json` * `platform/ui-next/.rspack/rspack.dev.js` * `platform/ui-next/.rspack/rspack.prod.js` * `platform/ui-next/.rspack/template.html` * `platform/ui-next/package.json` * `platform/ui/.rspack/rspack.dev.js` * `platform/ui/.rspack/rspack.prod.js` * `platform/ui/package.json` * `playwright.config.ts` * `publish-package.mjs` * `rsbuild.config.ts` * `scripts/ohif-plugin.mjs` * `scripts/verify-build-parity.mjs` * `scripts/verify-directory-plugin.ps1` * `scripts/verify-tarballs.mjs` * `scripts/verify-umd-global.mjs` </details> <details> <summary>💤 Files with no reviewable changes (44)</summary> * platform/cli/src/commands/enums/colors.js * platform/cli/src/questions.js * platform/cli/src/commands/utils/editPackageJson.js * platform/cli/src/commands/enums/keywords.js * platform/cli/src/commands/constants/notFound.js * platform/cli/src/commands/removeExtension.js * platform/cli/src/commands/utils/createDirectoryContents.js * platform/cli/src/commands/utils/installNPMPackage.js * platform/cli/src/commands/utils/getYarnInfo.js * platform/cli/src/commands/enums/index.js * platform/cli/src/commands/addMode.js * platform/docs/docs/development/ohif-cli.md * platform/cli/src/commands/index.js * platform/cli/src/commands/createPackage.js * platform/cli/src/commands/utils/createLicense.js * platform/cli/src/commands/utils/private/manipulatePluginConfigFile.js * platform/cli/src/commands/utils/getVersionedPackageName.js * platform/cli/src/commands/utils/index.js * platform/cli/src/commands/addExtensions.js * platform/cli/src/commands/enums/endPoints.js * platform/cli/src/commands/utils/initGit.js * platform/cli/src/commands/utils/uninstallNPMPackage.js * platform/cli/src/commands/listPlugins.js * platform/cli/src/commands/utils/createReadme.js * platform/cli/src/commands/utils/private/index.js * platform/cli/src/commands/utils/findOhifExtensionsToRemoveAfterRemovingMode.js * platform/cli/src/commands/utils/throwIfExtensionUsedByInstalledMode.js * platform/cli/package.json * platform/cli/src/commands/utils/validate.js * platform/cli/src/commands/removeExtensions.js * platform/cli/src/commands/utils/private/getPackageNameAndScope.js * platform/cli/src/commands/removeMode.js * platform/cli/src/commands/utils/removeFromConfig.js * platform/cli/src/commands/linkPackage.js * platform/cli/src/commands/addExtension.js * platform/cli/src/commands/utils/prettyPrint.js * platform/cli/src/commands/utils/private/writePluginConfigFile.js * platform/cli/src/index.js * platform/cli/src/commands/utils/private/readPluginConfigFile.js * platform/cli/src/commands/searchPlugins.js * platform/cli/src/commands/utils/addToConfig.js * platform/cli/src/commands/utils/validatePnpm.js * platform/cli/src/commands/utils/findRequiredOhifExtensionsForMode.js * platform/cli/src/commands/unlinkPackage.js </details> </details> <details> <summary>🛑 Comments failed to post (11)</summary><blockquote> <details> <summary>.rspack/resolveConfig.js (1)</summary><blockquote> 69-75: _🎯 Functional Correctness_ | _🟡 Minor_ | _⚡ Quick win_ <details> <summary>🧩 Analysis chain</summary> 🌐 Web query: `rspack resolve.modules relative absolute path resolution behavior` 💡 Result: In Rspack, the resolve.modules option specifies a list of directories that are searched when resolving "module" requests—requests that do not start with './', '../', or '/' [1][2]. The behavior of path resolution in Rspack distinguishes between three types of paths [1][2]: 1. Absolute Paths: These paths are already fully qualified. Rspack returns the path directly without further parsing [1][2]. 2. Relative Paths: These start with './' or '../'. Rspack resolves these relative to the directory of the file containing the import or require statement (the context directory) [1][2]. 3. Module Paths: These do not start with './', '../', or '/'. Rspack resolves these by searching the directories listed in resolve.modules, which defaults to ["node_modules"] [3][1][2]. Regarding the resolve.modules configuration specifically: - When you provide a path in resolve.modules, it can be either an absolute path or a folder name [4]. - If a folder name is provided (e.g., "node_modules"), Rspack searches for this folder in the current directory and its ancestors until it reaches the root, following standard Node.js module resolution rules [1][2]. - If an absolute path is provided, Rspack treats it as a specific directory to search for modules [4]. Additional configuration options that influence this behavior include: - resolve.preferAbsolute: If set to true, Rspack opts for absolute paths during resolution, relative to resolve.roots [3][5]. - resolve.roots: A list of directories used to resolve server-relative URLs (those beginning with '/') [3][5]. - resolve.preferRelative: When enabled, this directs the resolver to prefer resolving requests as relative requests rather than looking into the directories defined in resolve.modules [4]. Rspack utilizes the rspack-resolver library, which is a high-performance, Rust-based implementation compatible with webpack's enhanced-resolve algorithm [6][7]. Citations: - 1: https://rspack.rs/guide/features/module-resolution - 2: https://rspack.rs/guide/features/module-resolution.md - 3: https://rspack.rs/config/resolve - 4: https://docs.rs/rspack_resolver/latest/rspack_resolver/struct.ResolveOptions.html - 5: https://v2.rspack.rs/config/resolve - 6: https://www.rspack.rs/api/javascript-api/resolver - 7: https://docs.rs/rspack_resolver/latest/rspack_resolver/index.html --- 🏁 Script executed: ```shell #!/bin/bash set -euo pipefail printf '\n## file listing\n' git ls-files .rspack/resolveConfig.js .rspack 2>/dev/null || true printf '\n## line count\n' wc -l .rspack/resolveConfig.js printf '\n## relevant excerpt\n' sed -n '1,180p' .rspack/resolveConfig.js printf '\n## sibling tree\n' find .rspack -maxdepth 2 -type f | sortRepository: OHIF/Viewers
Length of output: 5132
🏁 Script executed:
#!/bin/bash set -euo pipefail python3 - <<'PY' from pathlib import Path p = Path('.rspack/resolveConfig.js') text = p.read_text() for i, line in enumerate(text.splitlines(), 1): if 'moduleSearchPaths' in line or 'node_modules' in line or 'All paths are anchored' in line: print(f"{i}: {line}") PYRepository: OHIF/Viewers
Length of output: 1570
🏁 Script executed:
#!/bin/bash set -euo pipefail # Show only the surrounding resolve config references. rg -n "moduleSearchPaths|resolve\.modules|node_modules|platform/app/node_modules|platform/ui/node_modules|All paths are anchored" .rspack -SRepository: OHIF/Viewers
Length of output: 2640
🏁 Script executed:
#!/bin/bash set -euo pipefail rg -n "\.\./\.\./\.\./node_modules|node_modules.*\.\./\.\./\.\./" . -SRepository: OHIF/Viewers
Length of output: 901
Remove the repo-escaping
../../../node_modulesfallback
.rspack/resolveConfig.js:72points outside the repository and can shadow the intended singleton copy if a parentnode_modulesexists. Keep this resolver anchored to the repo-root paths.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.rspack/resolveConfig.js around lines 69 - 75, Remove the path.resolve(__dirname, '../../../node_modules') entry from the moduleSearchPaths array in resolveConfig.js. Preserve the existing repository-root and platform-specific node_modules paths..rspack/rules/cssToJavaScript.js (1)
19-22: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Check existing postcss configurations for the correct format rg -C 5 "plugins:" --type jsRepository: OHIF/Viewers
Length of output: 150
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== .rspack/rules/cssToJavaScript.js ==" cat -n .rspack/rules/cssToJavaScript.js | sed -n '1,220p' echo echo "== Search for postcssOptions / plugins usage ==" rg -n -C 4 "postcssOptions|tailwindcss\\(|autoprefixer\\(" .rspack . --type js || trueRepository: OHIF/Viewers
Length of output: 3002
🏁 Script executed:
#!/bin/bash set -euo pipefail # Inspect the PostCSS loader documentation-like usage in the repo, if any. rg -n -C 3 "postcss-loader|postcssOptions|plugins:" . --type js --type ts --type cjs --type mjs || trueRepository: OHIF/Viewers
Length of output: 178
🌐 Web query:
postcss-loader plugins array nested arrays plugin instances documentation💡 Result:
In postcss-loader, the plugins array is designed to hold PostCSS plugin instances, strings (plugin names), or configuration tuples [1][2]. A configuration tuple is represented as an array where the first element is the plugin name or instance, and the second element is the options object [1][3]. Specifically, the syntax is: ["plugin-name-or-instance", { pluginOptions }] While the postcss-loader documentation primarily demonstrates this tuple structure for configuring plugins, it does not explicitly provide for or document the use of deeply "nested arrays" (e.g., arrays within arrays within the plugins list) for standard plugin definition [1][4]. If you are attempting to pass configuration, you should follow the official tuple format [1][5]: // Example of proper tuple syntax in webpack.config.js plugins: [ ["postcss-preset-env", { stage: 0 }], "postcss-import" ] If you have a complex scenario requiring a different structure, it is recommended to use the function form of postcssOptions, which allows you to programmatically define your plugins array based on the loader context [1][6]: // Example using a function for complex plugin logic options: { postcssOptions: (loaderContext) => { return { plugins: [ ["postcss-short", { prefix: "x" }], "postcss-preset-env" ] }; } } If you encounter unexpected behavior with nested structures, it is likely because the loader expects either a direct plugin instance, a string identifier, or the specific [plugin, options] tuple format [1][2].
Citations:
- 1: http://github.com/webpack-contrib/postcss-loader
- 2: https://www.npmjs.com/package/postcss-loader
- 3: https://github.com/webpack/postcss-loader/
- 4: https://github.com/webpack/postcss-loader/blob/main/README.md
- 5: https://v4.webpack.js.org/loaders/postcss-loader/
- 6: https://webpack.js.org/loaders/postcss-loader/
Flatten the PostCSS plugins array
postcss-loaderexpects plugin instances or[plugin, options]tuples here. Remove the extra brackets so both Tailwind and Autoprefixer are applied.
plugins: [tailwindcss(tailwindConfigPath), autoprefixer('last 2 version', 'ie >= 11')]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.rspack/rules/cssToJavaScript.js around lines 19 - 22, Update the plugins configuration in the PostCSS setup to pass tailwindcss and autoprefixer directly as plugin instances, removing the extra nested arrays so postcss-loader can apply both plugins.platform/app/src/routes/Mode/Mode.tsx (1)
104-108: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Registration failures for built-in extensions are now silently swallowed.
recordRegistrationErroronly mutates an existing audit record and is a no-op (no logging) when none exists. Extensions loaded throughloadModules(the in-tree/built-in ones) are never audited, so ifregisterExtensionthrows for one of them, the error is caught here,recordRegistrationErrorfinds no matching record,surfaceRuntimeExtensionFailureshas nothing to show, and loading proceeds withsetExtensionDependenciesLoaded(true). Previously such a throw propagated loudly. This hides real registration bugs in first-party extensions.Consider logging unconditionally in the catch (or making
recordRegistrationErrorconsole.errorwhen no record is found).🐛 Proposed fix (Mode.tsx)
try { await extensionManager.registerExtension(extension); } catch (error) { + console.error(`Failed to register extension "${extensionId}"`, error); recordRegistrationError(extensionId, error); }📝 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.try { await extensionManager.registerExtension(extension); } catch (error) { console.error(`Failed to register extension "${extensionId}"`, error); recordRegistrationError(extensionId, error); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/app/src/routes/Mode/Mode.tsx` around lines 104 - 108, Update the registerExtension catch block in the loadModules flow to report failures for built-in extensions even when recordRegistrationError finds no audit record. Log the caught error unconditionally or update recordRegistrationError to emit a console.error when no matching record exists, while preserving existing auditing and runtime failure surfacing.platform/core/package.json (1)
24-24: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== package.json ==" sed -n '1,120p' platform/core/package.json echo echo "== search for sideEffects usage ==" rg -n '"sideEffects"|sideEffects' -S . echo echo "== top-level package manager clues ==" git ls-files | rg '(^|/)(package.json|webpack|vite|rollup|tsup|esbuild|next\.config|nx\.json|turbo\.json|babel\.config|vite\.config|rollup\.config|tsup\.config)'Repository: OHIF/Viewers
Length of output: 4688
🏁 Script executed:
#!/bin/bash set -euo pipefail python3 - <<'PY' import json, pathlib p = pathlib.Path('platform/core/package.json') data = json.loads(p.read_text()) print("sideEffects type:", type(data.get("sideEffects")).__name__, "value:", data.get("sideEffects")) PYRepository: OHIF/Viewers
Length of output: 185
🌐 Web query:
webpack package.json sideEffects string value boolean array glob pattern documentation💡 Result:
The sideEffects property in package.json is used to inform webpack whether a package or its modules contain side effects, allowing webpack to perform tree shaking (pruning unused exports) more effectively [1][2]. The property accepts the following values: 1. Boolean (false): Setting "sideEffects": false tells webpack that none of the files in the package contain side effects [1][2]. This is the safest way to enable tree shaking for a package [2]. 2. Array of glob patterns: If a package contains some files with side effects (such as CSS imports or polyfills), you can provide an array of glob patterns to specify which files have side effects [1][2]. Files not matched by these patterns are assumed to be side-effect-free [1][2]. Glob patterns used in the array support syntax such as ,, {a,b}, and [a-z] [1]. Patterns that do not include a forward slash (/)—for example, ".css"—are treated as /*.css [1]. Important Considerations: - If a module is incorrectly marked as side-effect-free, it can lead to broken application code [2]. Only set "sideEffects": false if you are certain the code is pure [2]. - Side effects include actions like modifying global state, modifying prototypes, or importing CSS files [2]. - The optimization.sideEffects option in your webpack.config.js controls how this property is respected; it can be set to true (default in production), false (disabled), or 'flag' (only use the manually placed sideEffects flag in package.json, without analyzing source code) [3][4]. Note: The value should be a boolean or an array of strings [1][5]. A string value (e.g., "sideEffects": "false") is generally not used for the same purpose as the boolean false and is not recommended as a configuration pattern [6].
Citations:
- 1: https://webpack.js.org/guides/tree-shaking/
- 2: https://docs.webpack.js.org/guides/tree-shaking
- 3: https://webpack.js.org/configuration/optimization/
- 4: https://github.com/webpack/webpack/blob/master/declarations/WebpackOptions.d.ts
- 5: webpack/webpack#6536
- 6: webpack/webpack#6074
Use
falseforsideEffects
sideEffectsexpects a boolean or an array of glob patterns; the string"false"won’t act as the boolean flag.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/core/package.json` at line 24, Update the package.json sideEffects setting from the string value "false" to the boolean false, preserving the existing configuration intent.platform/create-ohif/README.md (1)
17-25: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
README arguments are out of date with the CLI.
The bin supports
--template <workspace|extension|mode|deployment>and amigrate <path> [--dry-run]subcommand, but this arguments block only lists<extension|mode>and omitsmigrate. Align the README withbin/create-ohif.mjs'sUSAGE.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/create-ohif/README.md` around lines 17 - 25, The README usage block for create-ohif must match the bin/create-ohif.mjs USAGE definition: expand --template to include workspace and deployment, and document the migrate <path> [--dry-run] subcommand. Update only the CLI arguments documentation while preserving the existing option descriptions.platform/create-ohif/templates/mode/src/toolbarButtons.ts (1)
4-10: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Remove the dangling
'mpr'toolGroupId.
toolGroupIds: ['default', 'mpr']references an'mpr'tool group that this scaffold never creates —src/index.ts'sonModeEnteronly creates'default'. This is likely leftover from an MPR-capable template and will confuse authors who copy this scaffold as-is.🔧 Proposed fix
export const setToolActiveToolbar = { commandName: 'setToolActive', commandOptions: { - toolGroupIds: ['default', 'mpr'], + toolGroupIds: ['default'], }, context: 'CORNERSTONE', };📝 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.export const setToolActiveToolbar = { commandName: 'setToolActive', commandOptions: { toolGroupIds: ['default'], }, context: 'CORNERSTONE', };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/create-ohif/templates/mode/src/toolbarButtons.ts` around lines 4 - 10, Update setToolActiveToolbar.commandOptions.toolGroupIds to remove the dangling 'mpr' entry, leaving only the 'default' tool group created by onModeEnter.platform/create-ohif/templates/workspace/scripts/ohif.mjs (1)
144-144: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Support unscoped mode package names.
The current regex
/\/mode-/correctly matches scoped packages like@ohif/mode-basic, but fails to identify unscoped mode packages (e.g.,mode-basic), incorrectly classifying them as extensions.🐛 Proposed fix
- const section = /\/mode-/.test(plugin.packageName) ? 'modes' : 'extensions'; + const section = /(^|\/)mode-/.test(plugin.packageName) ? 'modes' : 'extensions';📝 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.const section = /(^|\/)mode-/.test(plugin.packageName) ? 'modes' : 'extensions';🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/create-ohif/templates/workspace/scripts/ohif.mjs` at line 144, Update the package classification logic in the section assignment to recognize both scoped and unscoped mode package names, including names such as mode-basic and `@ohif/mode-basic`, while continuing to classify other packages as extensions.platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md (1)
107-114: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Revert erroneous find-and-replace in historical versioned documentation.
A global find-and-replace appears to have accidentally modified the
versioned_docs/for version 3.11 and older migration guides. In version 3.11, the project used Webpack (andwebpack-dev-serverwith.webpack/webpack.pwa.js), not Rspack. Updating these historical documents to reference Rspack breaks the instructions for users consulting historical versions (as seen wherewebpack-dev-serveris instructed to consume an.rspack/config).
platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md#L107-L114: Revert.rspack/rspack.pwa.jsback to.webpack/webpack.pwa.jsin both the code block and the explanation below it.platform/docs/versioned_docs/version-3.11/development/ohif-cli.md#L309-L309: Revertrspack.pwa.jsback towebpack.pwa.js.platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md#L108-L108: Revert.rspack/rspack.pwa.jsback to.webpack/webpack.pwa.js.📍 Affects 3 files
platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md#L107-L114(this comment)platform/docs/versioned_docs/version-3.11/development/ohif-cli.md#L309-L309platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md#L108-L108🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md` around lines 107 - 114, Restore the historical Webpack references in all three affected version-3.11 documents: in platform/docs/versioned_docs/version-3.11/configuration/dataSources/dicom-web.md lines 107-114, replace .rspack/rspack.pwa.js with .webpack/webpack.pwa.js in both the command and explanation; in platform/docs/versioned_docs/version-3.11/development/ohif-cli.md line 309, replace rspack.pwa.js with webpack.pwa.js; and in platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/0-general.md line 108, replace .rspack/rspack.pwa.js with .webpack/webpack.pwa.js.platform/ui-next/package.json (1)
25-30: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Avoid exporting raw
.ts/.tsxfiles to npm consumers.The
publishConfig.exportsmap points deep imports like./components/*directly to thesrc/*.tsxsource files. Since third-party plugin authors install this SDK package from npm, they will receive raw TypeScript/JSX files.
- If their bundler attempts to process them, it will likely fail with parse errors because bundlers typically exclude
node_modulesfrom TS/JSX compilation (this is also true for thecreate-ohiftemplate).- If it is externalized by
^@ohif/`` during bundling, it becomes a runtime dependency on@ohif/ui-next/components/.... However, the OHIF host runtime loader only provisions the root `@ohif/ui-next` UMD global, causing the deep import to fail at runtime.If the SDK contract only supports importing the root module at runtime, consider removing these deep exports to prevent consumers from relying on auto-imports that will break. If deep imports are strictly needed, the individual components must be transpiled to JavaScript before publishing.
📦 Proposed fix to limit exports to built artifacts
"exports": { ".": "./dist/ohif-ui-next.umd.js", - "./tailwind.config": "./tailwind.config.js", - "./lib/*": "./src/lib/*.ts", - "./components/*": "./src/components/*.tsx" + "./tailwind.config": "./tailwind.config.js" }📝 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."exports": { ".": "./dist/ohif-ui-next.umd.js", "./tailwind.config": "./tailwind.config.js" }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@platform/ui-next/package.json` around lines 25 - 30, Update the publishConfig.exports map in package.json to avoid exposing raw TypeScript and TSX source paths through ./lib/* and ./components/*. If the SDK supports only root-module runtime imports, remove these deep exports; otherwise, redirect them to transpiled JavaScript artifacts that are included in the published package.scripts/verify-build-parity.mjs (1)
65-74: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Guard
spawnSyncresult before calling.trim()on stdout.
treeContainsandhasWasmboth call.trim()onr.stdoutwithout checkingr.error/r.statusfirst. Ifgreporsharen't resolvable on the host (e.g. a non-Linux dev machine, since this script has no OS guard),spawnSyncsetsr.errorand leavesr.stdoutasnull, producing an opaqueTypeErrorinstead of a clear "grep/sh not found" failure.🛡️ Proposed fix
function treeContains(dir, needle, includeGlob) { const args = ['-r', '-l', '-F', needle]; if (includeGlob) { args.push(`--include=${includeGlob}`); } args.push(dir); const r = spawnSync('grep', args, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }); + if (r.error) { + throw new Error(`treeContains: failed to run grep - ${r.error.message}`); + } // grep exit 0 = match, 1 = no match, >1 = error. - return r.status === 0 && r.stdout.trim().length > 0; + return r.status === 0 && (r.stdout || '').trim().length > 0; }Also applies to: 85-90
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/verify-build-parity.mjs` around lines 65 - 74, Guard the spawnSync results in both treeContains and hasWasm before accessing stdout.trim(). Handle r.error or a non-success status explicitly, producing a clear command-unavailable/failure result instead of allowing null stdout to cause a TypeError, while preserving the existing match behavior for successful grep/sh execution.scripts/verify-directory-plugin.ps1 (1)
1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Save this script with a UTF-8 BOM.
Static analysis flags this file as containing non-ASCII characters without a BOM. Windows PowerShell 5.1 (which this script explicitly targets, and whose Set-Content encoding quirks it already works around at lines 64-66) can misinterpret non-BOM files under the system codepage, garbling any non-ASCII content in comments/strings.
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)
[warning] Missing BOM encoding for non-ASCII encoded file 'verify-directory-plugin.ps1'
(PSUseBOMForUnicodeEncodedFile)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/verify-directory-plugin.ps1` at line 1, Save scripts/verify-directory-plugin.ps1 with a UTF-8 BOM, preserving its existing content and Windows PowerShell 5.1 compatibility.Source: Linters/SAST tools
| '@ohif/i18n': ohifI18n, | ||
| '@ohif/extension-default': ohifExtensionDefault, | ||
| '@ohif/extension-cornerstone': ohifExtensionCornerstone, | ||
| '@cornerstonejs/core': cornerstoneCore, |
There was a problem hiding this comment.
What about modes/basic to allow the basic mode to be extended.
d8496bc to
61821f3
Compare
What this branch does
A rework of how extensions and modes are built, distributed, and loaded, so plugins can live outside the monorepo:
.rspack/pluginExternals.jsis the single canonical list of packages the host shares with plugins at runtime; per-package builds, scaffolded templates, and the runtime loader all derive from it, with parity tests (platform/create-ohif/tests/externals-parity.test.mjs) enforcing that template externals, host-provided globals, and template peerDependencies stay in sync..webpackconfig dirs are renamed to.rspack, rsbuild is upgraded to 2.x, and production and dev builds converge on a single repo-rootrsbuild.config.tspipeline (fonts as native asset modules, e2e coverage instrumentation restored, singleton aliases deduped, Tailwind made plugin-aware).window.config.extensions[]load through runtime plugin descriptors with host-shared globals and an audit trail; dynamic loading is gated, invalidpluginConfig.jsonfails fast against a JSON schema, anddangerouslyUseDynamicConfigrequires an explicit regex.pnpm create ohiftemplates for extensions, modes, workspaces, and deployment, verified end to end by a scaffold smoke harness (scaffold, install, build, UMD global contract, in-scaffold tests).doctorcheck; the legacy OHIF CLI is removed and docs repointed at the pluginConfig flow.@ohif/core,@ohif/ui-next,@ohif/i18n,@ohif/extension-default,@ohif/extension-cornerstone) remain publishable; the rest of the workspace is marked private.Merge order
This branch overlaps with the rsbuild work in #6164 (React 19 + rsbuild production build) and should land after #6164; the build-pipeline commits here will need a follow-up reconcile once #6164 merges.
Testing
platform/create-ohifsuite and the app contract suites pass locally.node platform/create-ohif/scripts/scaffold-smoke.mjsis the documented manual end-to-end gate for the scaffolding flow.Summary by CodeRabbit
New Features
create-ohiftool for scaffolding workspaces, extensions, modes, and deployments, plus migration support for older plugins.Security
Documentation