Skip to content

feat(cli-modules): add Rsdoctor CLI module and workspace - #4898

Open
christoph-jerolimov wants to merge 5 commits into
redhat-developer:mainfrom
christoph-jerolimov:cli-modules-with-rsdoctor-command
Open

christoph-jerolimov wants to merge 5 commits into
redhat-developer:mainfrom
christoph-jerolimov:cli-modules-with-rsdoctor-command

Conversation

@christoph-jerolimov

Copy link
Copy Markdown
Member

Summary

  • Scaffold a new workspaces/cli-modules workspace (CODEOWNERS entry included) for Backstage CLI modules.
  • Add @red-hat-developer-hub/cli-module-rsdoctor, which registers an rsdoctor command group on backstage-cli (build, start, analyze, check, diff) by injecting RsdoctorRspackPlugin into the frontend bundler without forking the CLI config.
  • Support gzip size budgets (rsdoctor.budgets.json), baseline growth checks, and CI-friendly brief reports; include an rsdoctor-test frontend plugin for exercising the module.

Test plan

  • In workspaces/cli-modules, run yarn install and yarn workspace @red-hat-developer-hub/backstage-plugin-rsdoctor-test build:rsdoctor (or the equivalent package script) and confirm a report/sizes.json is written under .rsdoctor/
  • Run backstage-cli rsdoctor check against that build with the plugin’s rsdoctor.budgets.json and confirm budget pass/fail behaves as expected
  • Run backstage-cli rsdoctor analyze to reopen a saved report, and rsdoctor diff --baseline … against a second build
  • Run yarn test for cli-module-rsdoctor (budget/options unit tests)
  • Confirm .rsdoctor/ remains gitignored and workspace lint/prettier still pass

Made with Cursor

@christoph-jerolimov
christoph-jerolimov requested review from a team as code owners September 21, 2026 10:07
@github-actions

Copy link
Copy Markdown
Contributor

This pull request adds a new top-level directory under workspaces/. Please follow Submitting a Pull Request for a New Workspace in CONTRIBUTING.md.

@rhdh-gh-app

rhdh-gh-app Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/cli-module-rsdoctor workspaces/cli-modules/packages/cli-module-rsdoctor none v0.1.0
@red-hat-developer-hub/backstage-plugin-rsdoctor-test workspaces/cli-modules/plugins/rsdoctor-test none v0.1.0

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

PR Summary by Qodo

Add Rsdoctor CLI commands and bundle-size checks workspace

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add a Backstage CLI module for Rsdoctor-enabled builds, dev servers, and saved-report analysis.
• Add gzip size budgets and baseline comparisons that can fail builds in CI.
• Scaffold a CLI-modules workspace with a test frontend plugin, documentation, and unit tests.
Diagram

graph TD
  Test["Test frontend"] --> Config["Rspack config"]
  CLI["Backstage CLI"] --> Module["Rsdoctor commands"] --> Config --> Plugin["Rsdoctor plugin"] --> Artifacts[("Saved reports")]
  Config --> Checks["Size checks"] --> Artifacts
  Artifacts --> Offline["Check and diff"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Add an upstream Backstage bundler extension point
  • ➕ Would avoid depending on internal module paths and runtime replacement of createConfig.
  • ➖ Requires an upstream Backstage change and cannot provide the command group immediately.
2. Maintain a separate Rspack build configuration
  • ➕ Avoids patching Backstage CLI internals.
  • ➖ Can drift from the CLI's entry points, chunk splitting, and production output.

Recommendation: The runtime wrapper is a pragmatic way to analyze the same bundles Backstage builds today, rather than maintaining a divergent configuration. Its dependency on private CLI paths is the principal maintenance risk; prefer an upstream extension point if one becomes available.

Files changed (56) +24716 / -4

Enhancement (17) +2006 / -0
backstage-cli-module-rsdoctorAdd standalone CLI-module executable +32/-0

Add standalone CLI-module executable

• Runs the registered module through Backstage's CLI runner, enabling the TypeScript transform for local source.

workspaces/cli-modules/packages/cli-module-rsdoctor/bin/backstage-cli-module-rsdoctor

index.cjsLoad the CLI module from source or distribution +26/-0

Load the CLI module from source or distribution

• Exposes a CommonJS entry point that loads local TypeScript source or the built distribution.

workspaces/cli-modules/packages/cli-module-rsdoctor/index.cjs

analyze.tsOpen saved Rsdoctor reports +64/-0

Open saved Rsdoctor reports

• Implements report profile, browser, and port options and keeps the report server alive until interrupted.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/analyze.ts

build.tsBuild frontend packages with Rsdoctor +95/-0

Build frontend packages with Rsdoctor

• Resolves Rsdoctor and budget options, enables instrumentation, and invokes Backstage's package build command. Plugin packages default to module federation builds.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/build.ts

check.tsCheck saved build sizes against budgets +95/-0

Check saved build sizes against budgets

• Loads a previous sizes.json, reports static and optional baseline checks, and fails on violations without rebuilding.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/check.ts

diff.tsCompare saved bundle-size reports +145/-0

Compare saved bundle-size reports

• Prints gzip-size deltas and optional baseline violations. It can also request Rsdoctor HTML, JSON, or served bundle diffs.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts

start.tsStart instrumented frontend development builds +53/-0

Start instrumented frontend development builds

• Enables Rsdoctor for supported frontend roles and forwards remaining arguments to Backstage's package start command.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/start.ts

index.tsRegister five Rsdoctor CLI subcommands +60/-0

Register five Rsdoctor CLI subcommands

• Registers build, start, analyze, check, and diff as lazily loaded Backstage CLI commands.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/index.ts

budgetRule.tsSurface static budget violations in Rsdoctor +78/-0

Surface static budget violations in Rsdoctor

• Defines a custom Rsdoctor bundle rule that evaluates asset sizes and reports static budget violations in the report UI.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgetRule.ts

budgets.tsImplement gzip budgets and growth limits +468/-0

Implement gzip budgets and growth limits

• Evaluates totals, chunk sizes and counts, named and wildcard limits, and baseline growth. It also matches assets across builds using stable keys.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts

checks.tsResolve budget, baseline, and summary settings +99/-0

Resolve budget, baseline, and summary settings

• Loads package budget files and optional baseline reports, applying command flags and CI summary defaults.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/checks.ts

enableRsdoctor.tsAttach Rsdoctor and build checks to Backstage's bundler +226/-0

Attach Rsdoctor and build checks to Backstage's bundler

• Wraps Backstage's internal Rspack createConfig function to attach report generation and size checks. It adjusts dev source maps, skips the public bundle, and handles Rsdoctor findings on CI.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/enableRsdoctor.ts

options.tsResolve Rsdoctor settings and forwarded arguments +136/-0

Resolve Rsdoctor settings and forwarded arguments

• Applies command, environment, and CI defaults for report options and separates module flags from arguments forwarded to Backstage.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/options.ts

packageRole.tsRestrict instrumented commands to frontend roles +45/-0

Restrict instrumented commands to frontend roles

• Reads the current package's Backstage role and rejects unsupported package types.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/packageRole.ts

rsdoctorCli.tsWrap saved-report CLI operations +37/-0

Wrap saved-report CLI operations

• Calls Rsdoctor's analyze and bundle-diff operations and provides interrupt handling for served reports.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/rsdoctorCli.ts

sizes.tsCollect and persist emitted asset sizes +235/-0

Collect and persist emitted asset sizes

• Measures raw and gzipped JS and CSS assets, records initial chunks, and writes versioned sizes.json reports with hash-stable asset keys.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts

summary.tsFormat size summaries and build diffs +112/-0

Format size summaries and build diffs

• Produces console summaries of bundle totals, largest assets, Rsdoctor findings, and per-file gzip changes.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/summary.ts

Tests (6) +468 / -0
budgets.test.tsTest budget parsing and baseline comparisons +253/-0

Test budget parsing and baseline comparisons

• Covers size units, wildcard matching, static limits, hash-stable diffs, and new-file baseline policies.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.test.ts

options.test.tsTest CLI argument partitioning +69/-0

Test CLI argument partitioning

• Verifies that module-specific flags are parsed while unrelated Backstage build flags retain their order and values.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/options.test.ts

TodoList.test.tsxTest todo-table rendering +43/-0

Test todo-table rendering

• Checks that supplied tasks and creator details appear in the test plugin's table.

workspaces/cli-modules/plugins/rsdoctor-test/src/components/TodoList/TodoList.test.tsx

TodoPage.test.tsxTest fetched and fallback todo data +65/-0

Test fetched and fallback todo data

• Mocks successful and failed backend responses to verify the example page's rendering behavior.

workspaces/cli-modules/plugins/rsdoctor-test/src/components/TodoPage/TodoPage.test.tsx

plugin.test.tsTest frontend-plugin export +22/-0

Test frontend-plugin export

• Checks that the test plugin is defined.

workspaces/cli-modules/plugins/rsdoctor-test/src/plugin.test.ts

setupTests.tsEnable DOM assertions for plugin tests +16/-0

Enable DOM assertions for plugin tests

• Loads jest-dom matchers for frontend component tests.

workspaces/cli-modules/plugins/rsdoctor-test/src/setupTests.ts

Documentation (7) +479 / -0
README.mdDocument the Changesets directory +8/-0

Document the Changesets directory

• Adds the generated introduction to Changesets and its documentation.

workspaces/cli-modules/.changeset/README.md

README.mdAdd scaffolded workspace README +28/-0

Add scaffolded workspace README

• Introduces the workspace with generated Backstage setup instructions and placeholder plugin descriptions.

workspaces/cli-modules/README.md

README.mdDocument Rsdoctor commands and budget policies +301/-0

Document Rsdoctor commands and budget policies

• Explains build, start, analyze, check, and diff usage, report formats, CI behavior, gzip budgets, and the internal bundler integration.

workspaces/cli-modules/packages/cli-module-rsdoctor/README.md

report.api.mdRecord the CLI module's public API +13/-0

Record the CLI module's public API

• Adds the generated API report for the default CliModule export.

workspaces/cli-modules/packages/cli-module-rsdoctor/report.api.md

README.mdDocument the workspace plugins directory +7/-0

Document the workspace plugins directory

• Adds scaffolded guidance for creating plugins within the workspace.

workspaces/cli-modules/plugins/README.md

README.mdDocument the test frontend plugin +20/-0

Document the test frontend plugin

• Adds generated guidance for running the plugin and its isolated development app.

workspaces/cli-modules/plugins/rsdoctor-test/README.md

report.api.mdRecord the test plugin's public API +102/-0

Record the test plugin's public API

• Adds the generated API report for the plugin's exported frontend extension.

workspaces/cli-modules/plugins/rsdoctor-test/report.api.md

Other (26) +21763 / -4
CODEOWNERSAssign owners to the CLI-modules workspace +6/-4

Assign owners to the CLI-modules workspace

• Adds a CODEOWNERS entry for the new workspace and reorders several existing entries.

.github/CODEOWNERS

config.jsonConfigure workspace Changesets +14/-0

Configure workspace Changesets

• Sets public access, the main base branch, internal dependency updates, and private-package behavior.

workspaces/cli-modules/.changeset/config.json

.dockerignoreExclude local files from Docker contexts +8/-0

Exclude local files from Docker contexts

• Excludes repository metadata, dependencies, plugin sources, and local configuration.

workspaces/cli-modules/.dockerignore

.eslintignoreExclude Playwright configuration from linting +1/-0

Exclude Playwright configuration from linting

• Adds an ESLint ignore entry for playwright.config.ts.

workspaces/cli-modules/.eslintignore

.eslintrc.jsReuse repository ESLint configuration +1/-0

Reuse repository ESLint configuration

• Points the workspace ESLint configuration at the repository-level configuration.

workspaces/cli-modules/.eslintrc.js

.gitignoreIgnore workspace outputs and Rsdoctor reports +57/-0

Ignore workspace outputs and Rsdoctor reports

• Excludes dependencies, build and test outputs, local credentials, and generated .rsdoctor reports.

workspaces/cli-modules/.gitignore

.prettierignoreExclude generated workspace files from formatting +6/-0

Exclude generated workspace files from formatting

• Ignores build outputs, coverage, editor configuration, and Rsdoctor reports.

workspaces/cli-modules/.prettierignore

.yarnrc.ymlConfigure approved Git repositories for Yarn +2/-0

Configure approved Git repositories for Yarn

• Allows Git repository dependencies in the new workspace's Yarn configuration.

workspaces/cli-modules/.yarnrc.yml

backstage.jsonRecord the workspace Backstage version +3/-0

Record the workspace Backstage version

• Sets the workspace's Backstage version to 1.54.6.

workspaces/cli-modules/backstage.json

catalog-info.yamlAdd scaffolded Backstage catalog metadata +13/-0

Add scaffolded Backstage catalog metadata

• Defines an experimental cli-modules catalog component with generated descriptive and ownership values.

workspaces/cli-modules/catalog-info.yaml

package.jsonDefine the CLI-modules workspace +68/-0

Define the CLI-modules workspace

• Registers package and plugin workspaces, Backstage tooling, and Rsdoctor convenience scripts. Some app-targeted scripts remain from the scaffold, although this diff adds no app package.

workspaces/cli-modules/package.json

.eslintrc.jsConfigure CLI-module linting +1/-0

Configure CLI-module linting

• Applies Backstage's package ESLint factory to the Rsdoctor CLI module.

workspaces/cli-modules/packages/cli-module-rsdoctor/.eslintrc.js

package.jsonDeclare the Rsdoctor Backstage CLI module +46/-0

Declare the Rsdoctor Backstage CLI module

• Defines the cli-module role, package scripts, entry points, and Backstage and Rsdoctor dependencies.

workspaces/cli-modules/packages/cli-module-rsdoctor/package.json

.eslintrc.jsConfigure test-plugin linting +1/-0

Configure test-plugin linting

• Uses Backstage's ESLint factory for the frontend plugin.

workspaces/cli-modules/plugins/rsdoctor-test/.eslintrc.js

index.tsxAdd an isolated frontend development app +20/-0

Add an isolated frontend development app

• Loads the test plugin into a Backstage development app.

workspaces/cli-modules/plugins/rsdoctor-test/dev/index.tsx

package.jsonDeclare the Rsdoctor test frontend plugin +67/-0

Declare the Rsdoctor test frontend plugin

• Defines its frontend-plugin role, dependencies, and scripts for Rsdoctor builds, development, and size checks.

workspaces/cli-modules/plugins/rsdoctor-test/package.json

rsdoctor.budgets.jsonProvide sample gzip size budgets +20/-0

Provide sample gzip size budgets

• Sets total, initial, per-chunk, chunk-count, and baseline growth limits for the test plugin.

workspaces/cli-modules/plugins/rsdoctor-test/rsdoctor.budgets.json

TodoList.tsxRender test-plugin tasks in a table +60/-0

Render test-plugin tasks in a table

• Defines a todo item shape and displays task titles, creators, and dates using Backstage UI components.

workspaces/cli-modules/plugins/rsdoctor-test/src/components/TodoList/TodoList.tsx

index.tsExport the todo list and item type +17/-0

Export the todo list and item type

• Provides a barrel export for the test plugin's list component and item type.

workspaces/cli-modules/plugins/rsdoctor-test/src/components/TodoList/index.ts

TodoPage.tsxAdd a lazy-loaded example page +74/-0

Add a lazy-loaded example page

• Fetches todos through Backstage's API and renders example data when the backend request fails.

workspaces/cli-modules/plugins/rsdoctor-test/src/components/TodoPage/TodoPage.tsx

index.tsExport the example page +16/-0

Export the example page

• Provides a barrel export for TodoPage.

workspaces/cli-modules/plugins/rsdoctor-test/src/components/TodoPage/index.ts

index.tsExpose the test frontend plugin +23/-0

Expose the test frontend plugin

• Exports the frontend plugin as the package's default public entry point.

workspaces/cli-modules/plugins/rsdoctor-test/src/index.ts

plugin.tsxRegister the Rsdoctor test page +42/-0

Register the Rsdoctor test page

• Creates a frontend plugin with a lazily loaded page at /rsdoctor-test.

workspaces/cli-modules/plugins/rsdoctor-test/src/plugin.tsx

routes.tsDefine the test plugin's root route +18/-0

Define the test plugin's root route

• Creates the route reference used by the frontend page extension.

workspaces/cli-modules/plugins/rsdoctor-test/src/routes.ts

tsconfig.jsonConfigure workspace TypeScript compilation +20/-0

Configure workspace TypeScript compilation

• Extends Backstage's TypeScript configuration and includes CLI-module, plugin, and development sources.

workspaces/cli-modules/tsconfig.json

yarn.lockLock new workspace dependencies +21159/-0

Lock new workspace dependencies

• Adds the Yarn lockfile for the scaffolded workspace and its CLI-module and frontend-plugin dependencies.

workspaces/cli-modules/yarn.lock

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (11) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. The new command group never loads 🐞 Bug ≡ Correctness
Description
The package's local main field points to a nonexistent root index.cjs, while the only
implemented loader is under bin/ and the comparable CLI module points to TypeScript source before
publishing. When backstage-cli resolves the workspace module before a packaged build exists,
resolution fails before any rsdoctor commands are registered.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[R7-8]

+  "main": "index.cjs",
+  "types": "src/index.ts",
Relevance

●●● Strong

Recent CLI packaging precedent accepts correcting entrypoints that do not produce or resolve the
advertised executable.

PR-#4498

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The package explicitly names index.cjs as its local main entry, and its README identifies that
root entry as the module that backstage-cli loads, but no such file was added; the only checked-in
loader instead imports ../src/index. The existing install-dynamic-plugins CLI module demonstrates
the repository convention by using src/index.ts locally and switching to dist/index.cjs.js
through publishConfig, confirming that the Rsdoctor module's local entry cannot resolve while its
packed entry is handled separately.

workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[7-12]
workspaces/cli-modules/packages/cli-module-rsdoctor/bin/backstage-cli-module-rsdoctor[25-30]
workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[295-298]
workspaces/install-dynamic-plugins/packages/install-dynamic-plugins/package.json[25-32]
workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[38-40]
workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[293-298]
workspaces/install-dynamic-plugins/packages/install-dynamic-plugins/package.json[25-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CLI module's local package entry points to a nonexistent root `index.cjs`, so Backstage CLI cannot load the workspace module and register the Rsdoctor commands before packaging.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[7-12]
- workspaces/cli-modules/packages/cli-module-rsdoctor/bin/backstage-cli-module-rsdoctor[25-30]

## Recommended Fix
Set the local `main` entry to `src/index.ts` while retaining the existing `publishConfig.main` for packed output, matching the repository's established CLI-module convention. Alternatively, add the expected root `index.cjs` loader that registers Backstage's TypeScript transform and exports `src/index.ts`; in either case, ensure both the local workspace entry and packed entry resolve.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


2. Plugin scripts cannot find rsdoctor 🐞 Bug ≡ Correctness
Description
rsdoctor-test invokes backstage-cli rsdoctor but does not declare
@red-hat-developer-hub/cli-module-rsdoctor as a dependency or devDependency. Package-local
CLI-module discovery therefore has no installed module to register the command when those scripts
run from the plugin.
Code

workspaces/cli-modules/plugins/rsdoctor-test/package.json[R20-23]

+    "start:rsdoctor": "backstage-cli rsdoctor start",
+    "build": "backstage-cli package build",
+    "build:rsdoctor": "backstage-cli rsdoctor build",
+    "check:rsdoctor": "backstage-cli rsdoctor check",
Relevance

●●● Strong

The scripts require a CLI module that is absent from the invoking package dependency graph.

PR-#4498

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added scripts call the new rsdoctor command, but the plugin's complete dependency lists omit
the separate package that declares the cli-module role and registers that command. Merely being a
sibling Yarn workspace does not make the module part of the invoking package's dependency graph.

workspaces/cli-modules/plugins/rsdoctor-test/package.json[18-29]
workspaces/cli-modules/plugins/rsdoctor-test/package.json[30-50]
workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[2-16]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/index.ts[26-57]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test plugin's Rsdoctor scripts execute a command supplied by a separate CLI-module package but do not depend on that package, so the command is not available in the plugin's dependency graph.

## Fix Focus Areas
- workspaces/cli-modules/plugins/rsdoctor-test/package.json[18-29]
- workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[2-16]

## Recommended Fix
Add `@red-hat-developer-hub/cli-module-rsdoctor` as a workspace dependency or devDependency of `rsdoctor-test` using the repository's workspace protocol/version convention, then regenerate the lockfile.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


3. Manifest-based comparisons always fail 🐞 Bug ≡ Correctness
Description
resolveReportFile accepts the target itself before checking whether it is the requested file type.
Supplying a documented manifest.json baseline makes readSizes parse that manifest as
sizes.json, while supplying sizes.json for an HTML comparison causes the sizes file to be
forwarded as the manifest.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts[R222-225]

+  const candidates = [
+    target,
+    path.join(target, fileName),
+    path.join(target, '.rsdoctor', fileName),
Relevance

●●● Strong

The resolver can parse a valid wrong-type report, directly breaking documented manifest-based
comparisons.

PR-#4020

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The resolver's first candidate is always target, and it returns any existing file without
comparing its basename to fileName. The diff command first requests sizes and later requests
manifests from the same targets, while its public flag explicitly permits manifest inputs.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts[207-213]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts[221-234]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[32-40]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[94-95]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[123-127]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Report resolution returns any directly supplied file regardless of the requested filename, breaking conversions between `manifest.json` and `sizes.json` paths.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts[221-234]
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[89-95]
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[123-127]

## Recommended Fix
When the target is a file, return it directly only if its basename matches `fileName`; otherwise search for `fileName` beside that file. Preserve the existing directory and nested `.rsdoctor` lookup behavior, and add tests covering both manifest-to-sizes and sizes-to-manifest resolution.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗



Remediation recommended

4. Users cannot install the CLI module 🐞 Bug ≡ Correctness ⭐ New
Description
The CLI module's package manifest sets private to true, which excludes it from the repository's
publish command. When the cli-modules workspace is released, the workflow's --no-private filter
skips this package despite its public publish configuration and distributable build.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[5]

+  "private": true,
Relevance

●●● Strong

The intended public CLI package is excluded from publishing by private=true despite public publish
metadata.

PR-#4011
PR-#4498

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new package declares public publish settings but is marked private; the release workflow
explicitly excludes private workspaces from publishing.

workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[2-12]
.github/workflows/release_workspace.yml[155-162]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CLI module is marked private, so the workspace release workflow skips it and users cannot install it from the registry.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/package.json[2-12]

## Recommended Fix
Remove `private: true` from the CLI module package, or set it to `false`, so the existing public publish configuration can be used.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


5. Plugin size budgets are too loose to catch growth 🐞 Bug ≡ Correctness ⭐ New
Description
The rsdoctor-test rsdoctor.budgets.json copies the whole-app budget (1.5 MB initial, 4.5 MB total,
450 chunks, main 30 KB) rather than the plugin-sized limits the README gives for a module
federation remote (85 KB initial, 300 KB total, 15 chunks). Because a plugin's remote build is a few
hundred KB at most, the plugin can grow by several megabytes and every rsdoctor build/check will
still pass, and the main/module-* keys never match a remote build, so they only show up as 'not
found' notes.
Code

workspaces/cli-modules/plugins/rsdoctor-test/rsdoctor.budgets.json[R2-5]

+  "maxInitialSize": "1.5 MB",
+  "maxTotalSize": "4.5 MB",
+  "maxChunkSize": "600 KB",
+  "maxChunks": 450,
Relevance

●●● Strong

The plugin budget contradicts its documented federation limits, making the stated growth checks
ineffective.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The plugin's budget file has the same values as the app example in the README. The README's own
'Plugin size budgets' section lists much smaller limits and chunk keys (remoteEntry.js, runtime,
__federation_expose_default_export) for plugin MF builds, and build.ts turns on
--module-federation by default for frontend-plugin roles.

workspaces/cli-modules/plugins/rsdoctor-test/rsdoctor.budgets.json[1-20]
workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[229-256]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/build.ts[62-63]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The rsdoctor-test plugin's budget file reuses the app limits, so the budget checks cannot catch real regressions in the plugin's module federation build.

## Fix Focus Areas
- workspaces/cli-modules/plugins/rsdoctor-test/rsdoctor.budgets.json[1-20]

## Recommended Fix
Run `yarn build:rsdoctor` in the plugin, measure the sizes, and set limits about 20% above them. Use MF chunk keys (`remoteEntry.js`, `runtime`, `backstage`, `vendor`, `__federation_expose_default_export`, `*`) and tighter baseline limits, following the README's plugin example.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


6. Workspace analysis scripts cannot run 🐞 Bug ≡ Correctness
Description
The root build:rsdoctor, rsdoctor:check, and rsdoctor:diff scripts target a workspace named
app and the packages/app report directory, although the only added frontend workspace is
@red-hat-developer-hub/backstage-plugin-rsdoctor-test. Invoking these advertised shortcuts asks
Yarn for a nonexistent workspace or searches a nonexistent path, preventing the Rsdoctor command
from running.
Code

workspaces/cli-modules/package.json[R16-19]

+    "build:rsdoctor": "yarn workspace app build:rsdoctor",
+    "rsdoctor:analyze": "backstage-cli rsdoctor analyze --profile packages/app/.rsdoctor/manifest.json",
+    "rsdoctor:check": "yarn workspace app backstage-cli rsdoctor check",
+    "rsdoctor:diff": "yarn workspace app backstage-cli rsdoctor diff",
Relevance

●●● Strong

Recent precedent accepts fixing workspace scripts that break advertised developer workflows.

PR-#4606

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The root shortcuts consistently reference app or packages/app, while the workspace glob includes
packages and plugins and no app workspace is added by this PR. The only new runnable frontend
package is @red-hat-developer-hub/backstage-plugin-rsdoctor-test, which already defines the
corresponding Rsdoctor scripts and report directory usage.

workspaces/cli-modules/package.json[16-19]
workspaces/cli-modules/package.json[31-34]
workspaces/cli-modules/plugins/rsdoctor-test/package.json[1-5]
workspaces/cli-modules/plugins/rsdoctor-test/package.json[18-24]
workspaces/cli-modules/plugins/rsdoctor-test/package.json[2-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The root Rsdoctor convenience scripts reference a nonexistent `app` workspace and `packages/app` report path instead of the Rsdoctor test frontend introduced by this PR, so users cannot run the advertised shortcuts.

## Fix Focus Areas
- workspaces/cli-modules/package.json[16-19]
- workspaces/cli-modules/plugins/rsdoctor-test/package.json[18-29]

## Recommended Fix
Rewrite the root scripts to target the existing `@red-hat-developer-hub/backstage-plugin-rsdoctor-test` workspace and use that plugin's `.rsdoctor` directory for analysis, checking, and comparisons. Alternatively, add the intended `app` workspace, and keep the README examples aligned with the selected target.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


View medium (3)
7. Malformed budgets silently pass 🐞 Bug ≡ Correctness
Description
parseSize accepts strings made only of dots and returns NaN because it never verifies that the
parsed result is finite. A budget such as "maxChunkSize": "." then makes every actual > max
comparison false, silently disabling that configured limit instead of rejecting the file.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts[R80-83]

+  const match = value.trim().match(/^([\d.]+)\s*([a-zA-Z]*)$/);
+  const unit = match ? UNITS[match[2].toLowerCase() || 'b'] : undefined;
+  if (!match || unit === undefined) {
+    throw new Error(
Relevance

●●● Strong

Malformed numeric configuration silently disables enforcement; repository precedent favors defensive
validation of invalid values.

PR-#3531

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The regular expression permits one or more digits or dots in any arrangement, and parseFloat('.')
produces NaN; the function returns that value without validation. Static total and chunk checks
compare actual sizes against the result with >, which is always false for NaN.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts[75-88]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts[199-207]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts[216-224]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The size parser's numeric pattern accepts malformed values that become `NaN`, causing affected budget comparisons to pass silently.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts[75-88]
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.ts[90-103]
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgets.test.ts[69-79]

## Recommended Fix
Use a strict decimal pattern and reject non-finite or negative parsed values. Apply equivalent full-string validation to percentages and add tests for `.`, repeated decimal points, malformed percentages, and valid decimal inputs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


8. Reports can show false budget failures 🐞 Bug ≡ Correctness
Description
createBudgetRule substitutes an asset's uncompressed size when gzipSize is unavailable but
still evaluates that value as gzip bytes. Under that supported fallback path, the report's bundle
alert can fail a gzip budget that the build-time check passes using an actual gzip calculation.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgetRule.ts[R61-64]

+          type,
+          size: asset.size,
+          gzip: asset.gzipSize ?? asset.size,
+        });
Relevance

●●● Strong

The fallback mixes raw and gzip units, creating inconsistent budget results and false report
violations.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The report rule assigns gzip: asset.gzipSize ?? asset.size and passes it to the gzip-budget
evaluator. The hard build check instead reads each asset's content and computes
zlib.gzipSync(content).length, so the two checks use different units when gzipSize is absent.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgetRule.ts[56-69]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts[143-162]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/enableRsdoctor.ts[88-100]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The custom report rule treats raw asset bytes as gzip bytes whenever Rsdoctor does not provide `gzipSize`, making report alerts disagree with the hard build checks.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgetRule.ts[46-69]
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts[143-173]

## Recommended Fix
Ensure the custom rule obtains a real gzip size through the same compression path used by `collectSizes`. If content is unavailable, omit the unsupported alert or clearly mark it unavailable rather than substituting raw bytes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


9. A stale default blocks valid comparisons 🐞 Bug ≡ Correctness
Description
The diff command calls resolveChecks without its already validated --baseline, allowing the
budget file's unrelated baseline.path default to be loaded. If that configured default is absent
or stale, a comparison with a valid explicit baseline fails before the supplied reports are
evaluated.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[R107-110]

+  const checks = resolveChecks(
+    { budget: flags.budget, budgetFile: flags.budgetFile },
+    targetPaths.dir,
+  );
Relevance

●●● Strong

This is a deterministic correctness bug: diff loads an unrelated configured baseline despite
requiring an explicit one.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The diff command already reads flags.baseline into baseline, but then invokes resolveChecks
with only budget flags. resolveChecks falls back to budgets.baseline.path and immediately reads
it, even though diff ignores the returned checks.baseline.

workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[86-95]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[106-112]
workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/checks.ts[76-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The diff command has already loaded its required baseline, but budget resolution independently loads the budget file's default baseline and can fail on that unused path.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/commands/diff.ts[107-112]
- workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/checks.ts[76-84]

## Recommended Fix
Add an option to resolve only budget settings without loading a baseline, and use it from `diff`; alternatively pass the explicit diff baseline through and reuse the resulting report rather than loading two independent baselines.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗



Informational

10. Module README sends users to packages that do not exist 🐞 Bug ⚙ Maintainability ⭐ New
Description
The cli-module-rsdoctor README's command examples, budget section and chunk-analysis section refer
to packages/app, @internal/backstage-plugin-example, plugins/example/rsdoctor.budgets.json and
docs/example-plugin-chunk-analysis.md. None of these exist in this workspace, which only adds the
rsdoctor-test plugin, so anyone copying the documented commands gets workspace-not-found errors.
Code

workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[R29-32]

+yarn build:rsdoctor                                            # app (= yarn workspace app build:rsdoctor)
+yarn workspace app start:rsdoctor                              # app dev server
+yarn workspace @internal/backstage-plugin-example build:rsdoctor
+yarn workspace @internal/backstage-plugin-example start:rsdoctor
Relevance

●●● Strong

Historical reviews accept correcting stale documentation paths and examples that reference
nonexistent workspace files.

PR-#3754
PR-#4144
PR-#4176

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workspace's packages are packages/cli-module-rsdoctor and plugins/rsdoctor-test. No
packages/app, plugins/example or docs/ directory is added, but the README uses them
throughout.

workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[28-38]
workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[229-233]
workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[269-284]
workspaces/cli-modules/plugins/rsdoctor-test/package.json[1-3]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The README examples refer to an app package, an example plugin and a docs file that are not in this workspace.

## Fix Focus Areas
- workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[28-38]
- workspaces/cli-modules/packages/cli-module-rsdoctor/README.md[229-284]

## Recommended Fix
Replace `@internal/backstage-plugin-example`/`plugins/example` with `@red-hat-developer-hub/backstage-plugin-rsdoctor-test`/`plugins/rsdoctor-test`. Remove or reword the `packages/app` and `docs/example-plugin-chunk-analysis.md` references.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


11. CODEOWNERS lists mcp-integrations twice 🐞 Bug ⚙ Maintainability ⭐ New
Description
The reordering adds a second /workspaces/mcp-integrations line right after the existing one, so
CODEOWNERS now has two identical rules for that path. Because the last matching rule wins, a later
edit to only one of the two lines (for example the first) will silently have no effect.
Code

.github/CODEOWNERS[34]

+/workspaces/mcp-integrations                        @redhat-developer/rhdh-plugins-maintainers @johnmcollier @gabemontero @redhat-developer/rhdh-ai
Relevance

●●● Strong

Duplicate CODEOWNERS rules are a deterministic maintainability defect and straightforward to remove.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Line 32 (context) and line 34 (added) are the same /workspaces/mcp-integrations entry.

.github/CODEOWNERS[32-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
CODEOWNERS has two identical `/workspaces/mcp-integrations` rules.

## Fix Focus Areas
- .github/CODEOWNERS[32-34]

## Recommended Fix
Delete one of the two lines, keeping the one in correct alphabetical order (after `konflux`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


Grey Divider

Context sources
✅ Compliance rules (platform): 11 rules
✅ Cross-repo context — repo relationships
Review mode: Auto: 🧠 Deep: Substantial CLI, bundler, reporting, and budget logic spans many independent paths.

Grey Divider

Tip of the day
💡 Did you know, you can turn on the rule miner and Qodo learns your standards from review history

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge Bot added documentation Improvements or additions to documentation enhancement New feature or request Tests labels Sep 21, 2026
@rhdh-qodo-merge

Copy link
Copy Markdown

Important

The /generate_labels command by Qodo is sunsetting on the 1st of October 2026 and will no longer be available. We recommend switching to the latest Qodo review capabilities. Learn more

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution!

@github-actions github-actions Bot added the stale label Oct 5, 2026
@rhdh-gh-app

rhdh-gh-app Bot commented Oct 5, 2026

Copy link
Copy Markdown

⚠️ CODEOWNERS Validation Failed

The following users are listed in CODEOWNERS but are not members of the rhdh-plugins-codeowners team:

thepetk

An org admin needs to add the missing members to the team before this PR can be merged.

christoph-jerolimov and others added 4 commits October 5, 2026 19:30
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
    Add chunk analysis for the example frontend plugin

    Documents how many JS chunks the browser fetches for
    @internal/backstage-plugin-example when it is registered synchronously
    (package discovery) versus asynchronously (feature loader), plus the
    6-chunk group behind its /example page. Adds scripts to reproduce the
    analysis from the Rspack bundle stats and to confirm it in Chromium.

    Integrate Rsdoctor for analysing the Rspack app build

    The Backstage CLI does not expose its Rspack configuration, so
    scripts/rsdoctor-cli.cjs patches the CLI's internal createConfig to
    append RsdoctorRspackPlugin to the frontend bundler config and then
    runs the regular backstage-cli command. Adds `build:rsdoctor` and
    `start:rsdoctor` scripts for packages/app, a root `build:rsdoctor`
    shortcut and `rsdoctor:analyze` to re-open a saved report.

    On CI the wrapper switches to Rsdoctor's brief mode (single HTML
    report) and keeps Rsdoctor's lint findings out of the Rspack warnings,
    since the Backstage CLI treats warnings as errors there.

    Add Rsdoctor scripts for analysing the example plugin on its own

    build:rsdoctor runs the module federation remote build of the plugin
    with Rspack so Rsdoctor can report on just the plugin and its
    dependencies; start:rsdoctor does the same for the plugin dev app.

    Add a Backstage CLI module with rsdoctor commands

    Replaces the standalone wrapper script with @internal/cli-module-rsdoctor,
    a Backstage CLI module discovered from the root package.json. It adds:

      backstage-cli rsdoctor build    Rspack build of the current package with a report
      backstage-cli rsdoctor start    dev server with a live Rsdoctor report
      backstage-cli rsdoctor analyze  re-open a saved report

    build/start wrap the CLI's own package build/start commands, appending
    RsdoctorRspackPlugin to the frontend bundler config. Inside plugin
    packages the build defaults to the module federation remote build, the
    only Rspack production build of a plugin. Flags the commands do not own
    are forwarded in order. On CI the module switches to brief mode and
    keeps Rsdoctor's lint findings out of the Rspack warnings so the build
    does not fail. The package scripts now call the CLI commands.

    Add size budgets, baseline diffs and CI summary to the rsdoctor CLI module

    rsdoctor build now writes .rsdoctor/sizes.json (gzipped size of every
    JS/CSS file with a hash-less key), prints a console summary with the
    Rsdoctor findings (on by default on CI), and checks rsdoctor.budgets.json:
    static limits for the initial JS total, the JS total, any single file
    and named chunks, plus growth limits against a baseline sizes.json.
    A violation fails the build. The same static checks run as a custom
    Rsdoctor rule so they show up under Bundle Alerts in the report, and
    --json adds a JSON report in brief mode.

    New commands: `rsdoctor check` evaluates an existing sizes.json against
    the budgets and a baseline without rebuilding; `rsdoctor diff` prints
    the per-file size changes between two builds, applies the baseline
    limits, and can generate Rsdoctor's bundle diff (--html/--json/--serve).

    packages/app ships a starting rsdoctor.budgets.json.

    Add size budgets for the example plugin build

    Adds plugins/example/rsdoctor.budgets.json with limits for the plugin's
    module federation build, check:rsdoctor scripts for the app and the
    plugin, and documents the plugin budget flow. Rsdoctor report folders
    are excluded from the Prettier check.

    Check unlisted and new chunks in size budgets

    Budget keys may now contain wildcards (module-*, static/*.chunk.js) and
    match a file's basename; the key "*" is a catch-all limit for every file
    no other key matches, so unlisted and newly appearing chunks are
    checked without naming them. maxChunks limits the number of emitted JS
    files. Baseline checks now treat files that are new compared to the
    baseline explicitly via newChunks (allow | fail | size limit) and
    maxNewChunks, and list removed files; maxChunkIncrease only applies to
    files that exist in both builds.

    The app and example plugin budgets use the catch-all and new-chunk
    limits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Christoph Jerolimov <jerolimov+git@redhat.com>
@debsmita1
debsmita1 force-pushed the cli-modules-with-rsdoctor-command branch from 892a956 to 9e9d12d Compare October 5, 2026 14:01
@rhdh-gh-app

rhdh-gh-app Bot commented Oct 5, 2026

Copy link
Copy Markdown

⚠️ CODEOWNERS Validation Failed

The following users are listed in CODEOWNERS but are not members of the rhdh-plugins-codeowners team:

thepetk

An org admin needs to add the missing members to the team before this PR can be merged.

@codecov

codecov Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.22807% with 335 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.95%. Comparing base (bd052a9) to head (7c8efaf).
⚠️ Report is 187 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4898      +/-   ##
==========================================
- Coverage   64.07%   63.95%   -0.13%     
==========================================
  Files        2719     2733      +14     
  Lines      107707   108277     +570     
  Branches    30328    30508     +180     
==========================================
+ Hits        69012    69247     +235     
- Misses      36901    37236     +335     
  Partials     1794     1794              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.77% <ø> (ø) Carriedforward from bd052a9
ai-integrations 87.24% <ø> (ø) Carriedforward from bd052a9
app-defaults 68.90% <ø> (ø) Carriedforward from bd052a9
augment 46.67% <ø> (ø) Carriedforward from bd052a9
boost 93.37% <ø> (ø) Carriedforward from bd052a9
bulk-import 73.12% <ø> (ø) Carriedforward from bd052a9
cli-modules 41.22% <41.22%> (?)
cost-management 13.56% <ø> (ø) Carriedforward from bd052a9
dcm 74.40% <ø> (ø) Carriedforward from bd052a9
e2e-adoption-insights 60.00% <ø> (ø) Carriedforward from bd052a9
e2e-extensions 62.31% <ø> (ø) Carriedforward from bd052a9
e2e-global-header 52.40% <ø> (ø) Carriedforward from bd052a9
e2e-homepage 61.11% <ø> (ø) Carriedforward from bd052a9
e2e-intelligent-assistant 45.49% <ø> (ø) Carriedforward from bd052a9
e2e-orchestrator 49.49% <ø> (ø) Carriedforward from bd052a9
e2e-orchestrator-plugin 49.48% <ø> (ø) Carriedforward from bd052a9
e2e-quickstart 54.83% <ø> (ø) Carriedforward from bd052a9
e2e-scorecard 49.77% <ø> (ø) Carriedforward from bd052a9
e2e-theme 16.43% <ø> (ø) Carriedforward from bd052a9
extensions 58.30% <ø> (ø) Carriedforward from bd052a9
global-floating-action-button 71.18% <ø> (ø) Carriedforward from bd052a9
global-header 69.10% <ø> (ø) Carriedforward from bd052a9
homepage 55.05% <ø> (ø) Carriedforward from bd052a9
install-dynamic-plugins 84.02% <ø> (ø) Carriedforward from bd052a9
intelligent-assistant 78.54% <ø> (ø) Carriedforward from bd052a9
konflux 91.98% <ø> (ø) Carriedforward from bd052a9
lightspeed 69.02% <ø> (ø) Carriedforward from bd052a9
mcp-integrations 84.46% <ø> (ø) Carriedforward from bd052a9
orchestrator 77.69% <ø> (ø) Carriedforward from bd052a9
quickstart 65.83% <ø> (ø) Carriedforward from bd052a9
sandbox 79.56% <ø> (ø) Carriedforward from bd052a9
scorecard 89.02% <ø> (ø) Carriedforward from bd052a9
theme 87.44% <ø> (ø) Carriedforward from bd052a9
translations 7.91% <ø> (ø) Carriedforward from bd052a9
x2a 78.80% <ø> (ø) Carriedforward from bd052a9

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bd052a9...7c8efaf. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@debsmita1
debsmita1 force-pushed the cli-modules-with-rsdoctor-command branch from 9e9d12d to 556bd8a Compare October 5, 2026 14:07
@rhdh-gh-app

rhdh-gh-app Bot commented Oct 5, 2026

Copy link
Copy Markdown

⚠️ CODEOWNERS Validation Failed

The following users are listed in CODEOWNERS but are not members of the rhdh-plugins-codeowners team:

thepetk

An org admin needs to add the missing members to the team before this PR can be merged.

@debsmita1
debsmita1 force-pushed the cli-modules-with-rsdoctor-command branch 3 times, most recently from aecd951 to 7371182 Compare October 5, 2026 14:27
Signed-off-by: Debsmita Santra <debsmita.santra@gmail.com>
@debsmita1
debsmita1 force-pushed the cli-modules-with-rsdoctor-command branch from 7371182 to 7c8efaf Compare October 5, 2026 14:50
@sonarqubecloud

sonarqubecloud Bot commented Oct 5, 2026

Copy link
Copy Markdown

@github-actions github-actions Bot removed the stale label Oct 5, 2026
@christoph-jerolimov
christoph-jerolimov marked this pull request as ready for review October 5, 2026 20:21
@rhdh-qodo-merge

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 7c8efaf

@debsmita1

Copy link
Copy Markdown
Member

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:12 PM UTC · Completed 3:38 PM UTC

Commit: 7c8efaf · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $9.85

@fullsend-ai-review fullsend-ai-review Bot added the risk/elevated PR risk: elevated label Oct 16, 2026
@fullsend-ai-review

Copy link
Copy Markdown

Risk Assessment: elevated (3/5)

Details

Large new workspace scaffold (56 files, 24720 lines dominated by a 21K-line yarn.lock) with four dependency files changed and a low test-file ratio (0.09), added by an established contributor with no linked issue, pushing risk above moderate despite the all-new-file nature of the change.

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

High

  • [protected-path] .github/CODEOWNERS — This PR modifies a governance file (.github/CODEOWNERS) with no linked issue providing justification. Human approval is required for protected-path changes regardless of context.
    Remediation: Link a tracking issue that authorizes the CODEOWNERS modifications, or obtain explicit human approval for the governance file change.

  • [scope-defect] .github/CODEOWNERS:34 — The /workspaces/mcp-integrations entry appears twice (lines 32 and 34) with identical owners after the alphabetical reordering. GitHub CODEOWNERS uses last-matching-pattern semantics, so the second silently overrides the first. If someone later edits only line 32, the change would be ignored.
    Remediation: Remove line 32 (the first /workspaces/mcp-integrations entry). The entry at line 34 (after konflux at line 33) is in the correct alphabetical position.

  • [naming-conventions] workspaces/cli-modules/catalog-info.yaml:4 — The catalog-info.yaml retains scaffold placeholder values throughout: name: cli-modules (convention is red-hat-developer-hub-<workspace>), description: An example of a Backstage application., type: website (should be backstage-plugin), owner: john@example.com (should be a real team), lifecycle: experimental (others use active), and all standard annotations and subcomponentOf field are absent.
    Remediation: Follow the pattern in workspaces/homepage/catalog-info.yaml: set name to red-hat-developer-hub-cli-modules, provide a real description, set type: backstage-plugin, lifecycle: active, a real owner, and add standard annotations.

  • [stale-doc] workspaces/cli-modules/README.md:3 — The workspace README retains full scaffold boilerplate: header "This is your newly scaffolded Backstage App, Good Luck!", a TODO banner, a placeholder description, and a broken link to a non-existent ./plugins/plugin-backend/README. The actual plugin is rsdoctor-test.
    Remediation: Replace the scaffold text with a real workspace description and update the plugin list to reference rsdoctor-test.

Medium

  • [architecture-coherence] .github/CODEOWNERS:25 — The file header states the workspace list is alphabetically ordered. /workspaces/cli-modules (line 25) appears after /workspaces/cost-management (line 24), but cli sorts before cos.
    Remediation: Move /workspaces/cli-modules to before /workspaces/cost-management.

  • [stale-doc] workspaces/cli-modules/packages/cli-module-rsdoctor/README.md:31 — The README uses @internal/backstage-plugin-example in multiple example commands, but this package does not exist. The actual test plugin is @red-hat-developer-hub/backstage-plugin-rsdoctor-test. Commands copied verbatim will fail.
    Remediation: Replace all occurrences of @internal/backstage-plugin-example with @red-hat-developer-hub/backstage-plugin-rsdoctor-test.

  • [stale-doc] workspaces/cli-modules/packages/cli-module-rsdoctor/README.md:231 — The "Plugin size budgets" section references plugins/example/rsdoctor.budgets.json, but the actual file is at plugins/rsdoctor-test/rsdoctor.budgets.json.
    Remediation: Change plugins/example/rsdoctor.budgets.json to plugins/rsdoctor-test/rsdoctor.budgets.json.

  • [missing-doc] workspaces/cli-modules/packages/cli-module-rsdoctor/README.md:282 — The README references docs/example-plugin-chunk-analysis.md as further reading, but this file does not exist anywhere in the workspace.
    Remediation: Either create the referenced file or remove the sentence referencing it.

  • [architecture-coherence] workspaces/cli-modules/packages/cli-module-rsdoctor/package.json:5 — The package declares "private": true alongside publishConfig with "access": "public", prepack/postpack scripts, and a files field. These are contradictory: npm blocks publishing a private package.
    Remediation: If intended for publishing, remove "private": true. If it must remain private, remove publishConfig.

  • [naming-conventions] workspaces/cli-modules/packages/cli-module-rsdoctor/bin/backstage-cli-module-rsdoctor:3 — The copyright header reads "Copyright 2026 The Backstage Authors" while every other source file uses "Copyright Red Hat, Inc."
    Remediation: Change to Copyright Red Hat, Inc.

Low

  • [architecture-coherence] workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/enableRsdoctor.ts — The implementation reaches into private internal dist paths of @backstage/cli-module-build. The README documents this limitation and the code fails fast if paths are missing.
    Remediation: File an upstream issue requesting stable extension points and document the coupling.

  • [silent-fallback] workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/sizes.ts:162 — When an asset's content cannot be read, gzip is silently set to 0 while size retains the raw value, causing budget checks to erroneously pass.
    Remediation: Skip the asset or log a warning when content is unreadable.

  • [inconsistent-measurement] workspaces/cli-modules/packages/cli-module-rsdoctor/src/lib/budgetRule.ts:63 — Uses asset.gzipSize ?? asset.size as the gzip fallback. The raw size is 2-5x larger than gzip, creating opposite-direction errors from the sizes.ts fallback.
    Remediation: Omit assets from evaluation when gzipSize is undefined, or note the approximation in violation messages.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

Comment thread .github/CODEOWNERS
/workspaces/intelligent-assistant @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-ui @redhat-developer/rhdh-ai @karthikjeeyar @rohitkrai03 @yangcao77
/workspaces/mcp-integrations @redhat-developer/rhdh-plugins-maintainers @johnmcollier @gabemontero @redhat-developer/rhdh-ai
/workspaces/konflux @redhat-developer/rhdh-plugins-maintainers @rrosatti @sahil143 @milantaky
/workspaces/mcp-integrations @redhat-developer/rhdh-plugins-maintainers @johnmcollier @gabemontero @redhat-developer/rhdh-ai

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[high] scope-defect

The /workspaces/mcp-integrations entry appears twice (lines 32 and 34) with identical owners after the alphabetical reordering. GitHub CODEOWNERS uses last-matching-pattern semantics, so the second silently overrides the first.

Suggested fix: Remove line 32 (the first /workspaces/mcp-integrations entry). The entry at line 34 (after konflux at line 33) is in the correct alphabetical position.

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: cli-modules

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[high] naming-conventions

The catalog-info.yaml retains scaffold placeholder values: name: cli-modules, description: An example of a Backstage application, type: website, owner: john@example.com, lifecycle: experimental. All standard annotations and subcomponentOf field are absent.

Suggested fix: Follow the pattern in workspaces/homepage/catalog-info.yaml: set name to red-hat-developer-hub-cli-modules, provide a real description, set type: backstage-plugin, lifecycle: active, a real owner, and add standard annotations.

@@ -0,0 +1,28 @@
# [Backstage](https://backstage.io)

This is your newly scaffolded Backstage App, Good Luck!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[high] stale-doc

The workspace README retains full scaffold boilerplate: header, TODO banner, placeholder description, and a broken link to non-existent ./plugins/plugin-backend/README. The actual plugin is rsdoctor-test.

Suggested fix: Replace the scaffold text with a real workspace description and update the plugin list to reference rsdoctor-test.

Comment thread .github/CODEOWNERS
/workspaces/app-defaults @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-ui @rohitkrai03 @christoph-jerolimov
/workspaces/bulk-import @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-plugins @rm3l @redhat-developer/rhdh-ui @debsmita1 @its-mitesh-kumar
/workspaces/cost-management @redhat-developer/rhdh-plugins-maintainers @ydayagi @mareklibra @batzionb @PreetiW @asmasarw @Aurobinda55 @r14chandra @kgaikwad
/workspaces/cli-modules @redhat-developer/rhdh-plugins-maintainers @redhat-developer/rhdh-cope @redhat-developer/rhdh-ui @christoph-jerolimov

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] architecture-coherence

The file header states the workspace list is alphabetically ordered. /workspaces/cli-modules (line 25) appears after /workspaces/cost-management (line 24), but cli sorts before cos.

Suggested fix: Move /workspaces/cli-modules to before /workspaces/cost-management.

```sh
yarn build:rsdoctor # app (= yarn workspace app build:rsdoctor)
yarn workspace app start:rsdoctor # app dev server
yarn workspace @internal/backstage-plugin-example build:rsdoctor

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] stale-doc

The README uses @internal/backstage-plugin-example in multiple example commands, but this package does not exist. The actual test plugin is @red-hat-developer-hub/backstage-plugin-rsdoctor-test.

Suggested fix: Replace all occurrences of @internal/backstage-plugin-example with @red-hat-developer-hub/backstage-plugin-rsdoctor-test.

contains and lets you drill into a chunk. The **Bundle > Treemap** view shows
which packages dominate each chunk, and the **Module Graph** answers why a
module is in the bundle at all (its import chain). For the plugin chunk
analysis in `docs/example-plugin-chunk-analysis.md`, search the Bundle Size

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] missing-doc

The README references docs/example-plugin-chunk-analysis.md as further reading, but this file does not exist anywhere in the workspace.

Suggested fix: Either create the referenced docs/example-plugin-chunk-analysis.md or remove the sentence referencing it.

"name": "@red-hat-developer-hub/cli-module-rsdoctor",
"version": "0.1.0",
"license": "Apache-2.0",
"private": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] architecture-coherence

The package declares private: true alongside publishConfig with access: public, prepack/postpack scripts, and a files field. These are contradictory: npm blocks publishing a private package.

Suggested fix: If intended for publishing, remove private: true. If it must remain private, remove publishConfig.

@@ -0,0 +1,32 @@
#!/usr/bin/env node
/*
* Copyright 2026 The Backstage Authors

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] naming-conventions

The copyright header reads Copyright 2026 The Backstage Authors while every other source file uses Copyright Red Hat, Inc.

Suggested fix: Change to Copyright Red Hat, Inc.

continue;
}
const content = readContent(asset.name);
const gzip = content ? zlib.gzipSync(content).length : 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] silent-fallback

When an asset content cannot be read, gzip is silently set to 0 while size retains the raw value, causing budget checks to erroneously pass.

Suggested fix: Skip the asset or log a warning when content is unreadable.

initial: asset.chunks.some(c => c.initial),
type,
size: asset.size,
gzip: asset.gzipSize ?? asset.size,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] inconsistent-measurement

Uses asset.gzipSize ?? asset.size as the gzip fallback. The raw size is 2-5x larger than gzip, creating opposite-direction errors from the sizes.ts fallback.

Suggested fix: Omit assets from evaluation when gzipSize is undefined, or note the approximation in violation messages.

@github-actions

Copy link
Copy Markdown
Contributor

This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request risk/elevated PR risk: elevated Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants