diff --git a/README.md b/README.md index 6563ee1..d4be2d4 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,14 @@ description: A concise summary of the page content for SEO and AI consumption. ## Rsdoctor skills +### rsdoctor-migrate-v2 + +```bash +npx skills add rstackjs/agent-skills --skill rsdoctor-migrate-v2 +``` + +Upgrade Rspack projects from Rsdoctor 1.x to 2.0, including runtime and bundler compatibility, package and ESM changes, configuration replacements, Agent CLI migration, and report validation. + ### rsdoctor-analysis ```bash diff --git a/skills/rsdoctor-analysis/SKILL.md b/skills/rsdoctor-analysis/SKILL.md index 3a3b938..9bcbf58 100644 --- a/skills/rsdoctor-analysis/SKILL.md +++ b/skills/rsdoctor-analysis/SKILL.md @@ -43,22 +43,28 @@ Decision rules: ## Generation gate -Identify `pluginName` (`@rsdoctor/rspack-plugin` or `@rsdoctor/webpack-plugin`) and determine `pluginVersion` from local files first: `package.json`, lockfile, then `node_modules//package.json`; use `pnpm why` / `npm ls` only as fallback. +Identify the project's bundler first. For webpack, follow the separate [webpack 1.x generation guide](references/install-rsdoctor-webpack.md); do not apply the Rspack 2.x gate below. For Rspack, check `@rsdoctor/core` and `@rsdoctor/rspack-plugin` in `package.json`, the lockfile, then installed package metadata. Use `pnpm why` / `npm ls` only as fallback. Resolve actual versions rather than inferring the major version from a dependency range, and stop if the selected plugin's peer dependency excludes the installed bundler. Check direct dependencies and active plugin registration separately from framework-owned transitive packages. `@rsdoctor/core` 1.x may be present for custom rules without providing the build plugin. -Use this exact if/else decision tree; do not merge branches: +For Rspack, use this exact if/else decision tree; do not merge branches: ```text -if pluginName is missing: - install/register the matching Rsdoctor plugin, then configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -else if pluginVersion is unknown: - resolve pluginVersion first; if still unknown, configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -else if pluginVersion >= 1.5.11: +if Rspack actively registers both @rsdoctor/core 2.x and @rsdoctor/rspack-plugin 1.x: + stop and report mixed plugins; do not install or build +else if Rspack has @rsdoctor/core 2.x: + use or register the v2 plugin; configure output.mode='brief' and include 'json' in output.options.type; build with RSDOCTOR=true only +else if @rsdoctor/rspack-plugin is installed but its version is unknown: + resolve its version first; if still unknown, configure output.mode='brief' and include 'json' in output.options.type; build with RSDOCTOR=true only +else if an installed @rsdoctor/rspack-plugin 1.x version is >= 1.5.11: do not edit plugin config just for JSON; build with RSDOCTOR_OUTPUT=json and RSDOCTOR=true if needed -else: # pluginVersion < 1.5.11 - MUST configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only +else if an installed @rsdoctor/rspack-plugin 1.x version is older: + configure output.mode='brief' and include 'json' in output.options.type; build with RSDOCTOR=true only +else: # no build plugin installed + choose a compatible Rspack plugin, then configure brief JSON output and build with RSDOCTOR=true only ``` -Preflight every build command: `RSDOCTOR_OUTPUT=json` is allowed only in the `pluginVersion >= 1.5.11` branch. For missing, unknown, or `< 1.5.11`, it is forbidden. For `< 1.5.11`, generating `rsdoctor-data.json` requires the plugin config below: +For an Rspack 2.x project without a plugin, install a compatible `@rsdoctor/core` 2.x version; do not install `@rsdoctor/rspack-plugin`. For Rspack 1.x, keep the compatible 1.x plugin. If installed versions or bundler compatibility cannot be determined, stop before installing. Check the plugin import path only when the package versions and active configuration appear inconsistent. + +For Rspack builds, `RSDOCTOR_OUTPUT=json` is allowed only for a known 1.x plugin version `>= 1.5.11`. It is forbidden for 2.x, missing, unknown, or older plugin versions. When explicit JSON configuration is required, add `'json'` to an existing brief output type rather than removing HTML; if changing a normal report temporarily, restore its previous output settings after generating data: ```ts output: { diff --git a/skills/rsdoctor-analysis/references/install-rsdoctor-common.md b/skills/rsdoctor-analysis/references/install-rsdoctor-common.md index ca63919..be50384 100644 --- a/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +++ b/skills/rsdoctor-analysis/references/install-rsdoctor-common.md @@ -17,28 +17,9 @@ For repeated analysis in the same repository, use a lightweight project-local ca When the runtime supports parallel execution, run independent local initialization checks concurrently: common path checks, bounded `rg --files` lookup, and local plugin-version file reads. Do not run `rsdoctor-agent` CLI checks until a real `rsdoctor-data.json` path exists. Treat plugin-version results as speculative until the data file is confirmed missing; never let parallel plugin checks trigger generation by themselves. -If you cannot find the file, ask the user to provide the path to `rsdoctor-data.json`. If the file truly does not exist and generation/setup is required, check the installed `@rsdoctor/rspack-plugin` or `@rsdoctor/webpack-plugin` version before changing config or running a build. The `@rsdoctor/agent-cli` version does not prove plugin support for `RSDOCTOR_OUTPUT=json`. - -Required version gate (use exactly this if/else order): - -1. Identify `pluginName`: `@rsdoctor/rspack-plugin` or `@rsdoctor/webpack-plugin`. -2. Determine `pluginVersion` from local files first: dependency declarations in `package.json`, lockfile entries, then installed `node_modules//package.json`. Use package-manager output such as `pnpm why @rsdoctor/rspack-plugin` / `npm ls @rsdoctor/rspack-plugin` only as a fallback. -3. Choose one branch; do not merge branches: - -```text -if pluginName is missing: - install/register the matching Rsdoctor plugin, then MUST configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -else if pluginVersion is unknown: - resolve pluginVersion first; if still unknown, MUST configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -else if pluginVersion >= 1.5.11: - do not modify plugin config just for JSON; build with RSDOCTOR_OUTPUT=json and RSDOCTOR=true if needed -else: # pluginVersion < 1.5.11 - MUST configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -``` - -Preflight every build command: `RSDOCTOR_OUTPUT=json` is allowed only in the `pluginVersion >= 1.5.11` branch. For missing, unknown, or `< 1.5.11` versions, a command such as `RSDOCTOR_OUTPUT=json RSDOCTOR=true pnpm run build:rspack` is incorrect. +If you cannot find the file, ask the user to provide its path. If generation/setup is required, follow the [Rspack Generation Gate](../SKILL.md#generation-gate) for Rspack projects or the separate [webpack 1.x guide](install-rsdoctor-webpack.md) for webpack projects before changing config or running a build. The `@rsdoctor/agent-cli` version does not prove which plugin or JSON generation method the project supports. -The file is typically generated in the same directory as your build output (e.g., `dist`, `output`, `static`). For plugin versions < `1.5.11`, configure a custom output directory using the `output.reportDir` option: +The file is typically generated in the same directory as your build output (e.g., `dist`, `output`, `static`). When explicit brief JSON configuration is needed, configure a custom output directory using the `output.reportDir` option if necessary: ```js // Example for Rspack: use RsdoctorRspackPlugin diff --git a/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md b/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md index 36b1937..271770b 100644 --- a/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +++ b/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md @@ -8,45 +8,31 @@ This guide covers installation for Rspack-based projects, including: - Rslib - Rspress -## Step 1: install dependencies +## Step 1: Check the Plugin Version -For projects based on Rspack, such as Rsbuild or Rslib: +Follow the [Generation Gate](../SKILL.md#generation-gate) before installation or build. Rspack 2.x uses `@rsdoctor/core` 2.x; existing Rspack 1.x integrations use `@rsdoctor/rspack-plugin` 1.x. Do not add the legacy plugin to a 2.x project. A standalone `@rsdoctor/core` 1.x dependency may exist for custom rules and does not identify the active plugin. -**Note:** Prefer using the latest versions of the above dependencies when available. +If no plugin is installed, select a version compatible with the project's Rspack version and install it with the project's package manager. If both 2.x and 1.x plugins are actively registered, report the mixed setup instead of installing another package. A framework-owned transitive 1.x package alone does not establish that its plugin is active. -```bash -npm add @rsdoctor/rspack-plugin -D -pnpm add @rsdoctor/rspack-plugin -D -``` - -## Step 2: register plugin +## Step 2: Register Plugin and Generate JSON -After the dependency installation, check the installed `@rsdoctor/rspack-plugin` version before changing config or running a build. Do not infer plugin capabilities from `@rsdoctor/agent-cli --version`. +For `@rsdoctor/core` 2.x, preserve the project's existing plugin registration point and use this import and output configuration when generating analysis data: -Required version gate (use exactly this if/else order): +```ts +import { RsdoctorRspackPlugin } from '@rsdoctor/core'; -1. Set `pluginName = '@rsdoctor/rspack-plugin'`. -2. Determine `pluginVersion` from local files first: dependency declarations in `package.json`, lockfile entries, then `node_modules/@rsdoctor/rspack-plugin/package.json` if installed. Use `pnpm why @rsdoctor/rspack-plugin` / `npm ls @rsdoctor/rspack-plugin` only as a fallback. When repeating analysis, reuse a valid `.rsdoctor-analysis-cache.json` plugin entry before re-reading files; invalidate it if `package.json`, lock files, or the plugin package file modification time changed. -3. Choose one branch; do not merge branches: - -```text -if @rsdoctor/rspack-plugin is missing: - install/register @rsdoctor/rspack-plugin, then configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -else if pluginVersion is unknown: - resolve pluginVersion first; if still unknown, configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only -else if pluginVersion >= 1.5.11: - do not modify plugin config just for JSON; build with RSDOCTOR_OUTPUT=json and RSDOCTOR=true if needed -else: # pluginVersion < 1.5.11 - MUST configure output.mode='brief' and output.options.type=['json']; build with RSDOCTOR=true only +new RsdoctorRspackPlugin({ + disableClientServer: true, + output: { + mode: 'brief', + options: { type: ['json'] }, + }, +}); ``` -Preflight every build command: `RSDOCTOR_OUTPUT=json` is allowed only in the `pluginVersion >= 1.5.11` branch. For missing, unknown, or `< 1.5.11`, `RSDOCTOR_OUTPUT=json` is forbidden. For example, when `@rsdoctor/rspack-plugin` is `1.5.7`, this command is incorrect: - -```bash -RSDOCTOR_OUTPUT=json RSDOCTOR=true pnpm run build:rspack -``` +Add `'json'` alongside `'html'` when an existing brief report needs both. If normal report settings are changed temporarily, restore them after generating the data. Build with `RSDOCTOR=true`; do not use `RSDOCTOR_OUTPUT=json` for this 2.x branch. -Below are configuration examples for old Rspack plugin versions, unknown versions, missing plugins, or projects that still need to register the plugin: +The following examples apply to the legacy `@rsdoctor/rspack-plugin` 1.x branch when explicit JSON configuration is needed (version below `1.5.11` or unknown): ### Rspack CLI diff --git a/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md b/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md index 4698708..14cf6ff 100644 --- a/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +++ b/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md @@ -1,16 +1,16 @@ # Install Rsdoctor plugin for webpack projects -This guide covers installation for Webpack projects (webpack >= 5). +This guide covers Rsdoctor 1.x installation for webpack projects (webpack >= 5). Rsdoctor 2.x does not support webpack; keep the existing 1.x integration when the project remains on webpack. ## Step 1: install dependencies Rsdoctor only supports webpack >= 5. -For projects based on webpack: +Only if the plugin is missing, install the 1.x package with the project's package manager: ```bash -npm add @rsdoctor/webpack-plugin -D -pnpm add @rsdoctor/webpack-plugin -D +npm add @rsdoctor/webpack-plugin@1 -D +pnpm add @rsdoctor/webpack-plugin@1 -D ``` ## Step 2: register plugin diff --git a/skills/rsdoctor-migrate-v2/SKILL.md b/skills/rsdoctor-migrate-v2/SKILL.md new file mode 100644 index 0000000..685b0b3 --- /dev/null +++ b/skills/rsdoctor-migrate-v2/SKILL.md @@ -0,0 +1,68 @@ +--- +name: rsdoctor-migrate-v2 +description: Upgrade Rspack projects from Rsdoctor 1.x to 2.0. Use when replacing legacy Rsdoctor packages, converting Rsdoctor setup to ESM, updating removed or deprecated options, moving MCP workflows to Agent CLI, or validating Node.js and Rspack compatibility for an Rsdoctor 2.0 upgrade. +--- + +# Upgrade Rsdoctor to v2 + +Upgrade with the smallest behavior-preserving diff. Treat the official migration guides and the installed package exports as the source of truth: + +- https://rsdoctor.rs/guide/start/migration-v2 +- https://rsdoctor.rs/config/options/options-v2 + +## Workflow + +1. **Audit the current integration** + - Read `package.json`, the lockfile, Node.js version files, and the build scripts. + - Determine the installed Rsdoctor package versions from the lockfile or package metadata, and check which package provides the active `RsdoctorRspackPlugin`. Migrate a 1.x `@rsdoctor/rspack-plugin` integration, including any partially migrated setup that still imports it. If `@rsdoctor/core` 2.x already provides the active plugin, validate the integration instead of migrating it again. `@rsdoctor/core` alone does not prove a 2.x integration because 1.x projects may use it for custom rules. Distinguish direct integration from framework-owned transitive 1.x dependencies. + - Locate Rspack, Rsbuild, and Rsdoctor configuration files. Preserve any environment condition that enables Rsdoctor only for selected builds. + - Search source, scripts, and editor configuration for `@rsdoctor/`, `RsdoctorRspackPlugin`, legacy options, MCP setup, and report-output assumptions. + - Record the current build command and expected report formats before editing. + +2. **Pass the compatibility gate** + - Require Node.js `^20.19.0 || >=22.12.0` and verify that the installed Rspack version satisfies the selected `@rsdoctor/core` peer dependency. Check the selected package's `engines` and peer dependencies if they differ. + - For webpack projects, stop the Rsdoctor upgrade. Keep Rsdoctor 1.x or migrate the project to Rspack as a separate task first. + - Update only Rsdoctor dependencies and preserve the existing Rspack and framework versions. If a framework supplies Rspack, do not add `@rspack/core` directly. Report a compatibility issue separately only when the installed version does not satisfy Rsdoctor's peer dependency. + +3. **Plan only applicable changes** + - Read [references/migration-map.md](references/migration-map.md). + - List the package, import, module-format, configuration, and AI-workflow changes that apply to this project. + - Choose one Rsdoctor 2.x target version. Keep `@rsdoctor/core` and `@rsdoctor/cli` on the same version; version `@rsdoctor/agent-cli` independently. + +4. **Migrate packages and imports** + - Replace `@rsdoctor/rspack-plugin` with `@rsdoctor/core` and import `RsdoctorRspackPlugin` from `@rsdoctor/core`. + - Convert Rsdoctor `require()` calls to ESM imports. When the project remains CommonJS, move only the affected build config to a supported ESM extension such as `.mjs` instead of changing the entire package module type without need. + - Do not mechanically rename imports from removed low-level packages. Resolve every imported symbol against the public 2.x exports, then type-check it. + - Use the project's existing package manager and avoid unrelated dependency or lockfile updates. + - Do not remove framework-owned transitive 1.x dependencies merely because they remain in the lockfile; verify whether the framework still activates its old plugin. + +5. **Migrate configuration without changing report intent** + - Replace each removed or deprecated field using the mapping reference. + - Preserve whether the project needs HTML, JSON, or both, and preserve intentional code-source omission from lite reports. + - Delete `experiments.enableNativePlugin` and `supports.banner`; both options were removed in 2.0, and the Rspack native plugin is always enabled. + - If Rspack reports that `experiments.RsdoctorPlugin` is unavailable, report the compatibility issue instead of changing Rspack or framework dependencies as part of the Rsdoctor upgrade. + +6. **Migrate AI workflows when present** + - Remove `@rsdoctor/mcp-server`, its editor MCP entries, and scripts that start it. + - Add `@rsdoctor/agent-cli`, generate a fresh `rsdoctor-data.json`, and invoke `rsdoctor-agent` against that file. + - Rewrite automation to consume structured CLI output. Agent CLI is not an MCP-compatible or drop-in API replacement. Do not carry over MCP ports or assume its compiler-selection syntax applies; for multi-compiler data, select a compiler using Agent CLI's `--compiler `. + +7. **Validate the migration** + - Reinstall dependencies and run the production build under the project's supported Node.js version. + - Confirm the expected Rsdoctor report is generated and open the overview, compilation, and bundle-analysis pages used by the project. + - If JSON output or Agent CLI is used, validate a newly generated data file with one representative command. + - Run the relevant tests and type checks, then search again for removed packages and legacy options. + - Report what changed, commands run, and any validation that could not be completed. Do not claim success from dependency installation alone. + +## Output language + +- Write all user-facing explanations, plans, progress updates, and migration summaries in Chinese. +- Keep package names, API names, configuration fields, commands, file paths, and error messages in their original form; explain their meaning in Chinese when needed. + +## Guardrails + +- Do not install Rsdoctor 2.x into a webpack-only project. +- Do not activate 1.x and 2.x plugins together to work around migration errors. Investigate framework-owned transitive 1.x packages separately. +- Do not silently change report formats, filenames, server ports, or source-code visibility. +- Do not replace MCP configuration with an invented Agent CLI service configuration. +- Do not remove compatibility code until the replacement build and report have been verified. diff --git a/skills/rsdoctor-migrate-v2/references/migration-map.md b/skills/rsdoctor-migrate-v2/references/migration-map.md new file mode 100644 index 0000000..9e83071 --- /dev/null +++ b/skills/rsdoctor-migrate-v2/references/migration-map.md @@ -0,0 +1,116 @@ +# Rsdoctor 2.0 Migration Map + +Read only the sections that match the audited project. + +## Compatibility + +| Area | Rsdoctor 2.0 requirement | Migration action | +| ------------- | ------------------------ | -------------------------------------------------------------------------------------- | +| Node.js | `^20.19.0 || >=22.12.0` | Update local, CI, and deployment runtimes before installing 2.x. | +| Bundler | Rspack 2.0 or later | Upgrade Rspack first. If a framework owns Rspack, upgrade through the framework. | +| webpack | Unsupported | Stay on maintained Rsdoctor 1.x or migrate to Rspack in a separate change. | +| Module format | ESM-only packages | Replace Rsdoctor `require()` calls with imports and use an ESM-compatible config file. | + +## Packages and imports + +| Rsdoctor 1.x usage | Rsdoctor 2.x action | +| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `@rsdoctor/rspack-plugin` | Replace with `@rsdoctor/core`. Import `RsdoctorRspackPlugin` from `@rsdoctor/core`. | +| `@rsdoctor/cli` | Keep when the `rsdoctor` command or Node.js API is used. Match its version to `@rsdoctor/core`. | +| `@rsdoctor/mcp-server` | Remove and migrate the workflow to `@rsdoctor/agent-cli`; this is a workflow migration, not an import rename. | +| `@rsdoctor/webpack-plugin` | No 2.x replacement. Keep the project on Rsdoctor 1.x or migrate the bundler first. | +| `@rsdoctor/sdk`, `@rsdoctor/graph`, `@rsdoctor/types`, `@rsdoctor/utils`, or `@rsdoctor/components` | These standalone packages are removed. Resolve each used symbol against documented public exports from `@rsdoctor/core` or `@rsdoctor/shared`; there is no safe package-wide search-and-replace. | + +Basic plugin import: + +```ts +// Before +import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'; + +// After +import { RsdoctorRspackPlugin } from '@rsdoctor/core'; +``` + +If the old config uses CommonJS, migrate the config itself to ESM: + +```ts +import { RsdoctorRspackPlugin } from '@rsdoctor/core'; + +export default { + plugins: [new RsdoctorRspackPlugin()], +}; +``` + +When renaming `rspack.config.js` or `rspack.config.cjs` to `.mjs` or `.mts`, update build scripts that pass the config path explicitly. + +## Configuration options + +| Rsdoctor 1.x option | Status in 2.x | Replacement | +| ------------------------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------- | +| `experiments.enableNativePlugin` | Removed | Delete it; the native plugin is always enabled. | +| top-level `mode: 'normal'` | Removed and ignored | `output.mode: 'normal'` | +| top-level `mode: 'brief'` | Removed and ignored | `output.mode: 'brief'` | +| top-level `mode: 'lite'` | Removed and ignored | `output.mode: 'normal'` plus `output.reportCodeType: 'noCode'` or `'noAssetsAndModuleSource'` | +| `brief` | Deprecated | `output.mode: 'brief'`, `output.options.type: ['html']`, and `output.options.htmlOptions` | +| `brief.writeDataJson` or `output.options.htmlOptions.writeDataJson` | Removed | Include both formats with `output.options.type: ['html', 'json']` | +| `output.compressData` | Removed and ignored | `output.mode: 'brief'` plus `output.options.type: ['json']` | +| top-level `port` | Deprecated | `server.port` | +| `supports.generateTileGraph` | Deprecated and unnecessary | Delete it; tree-map data is generated by default. | +| `supports.banner` | Removed | Delete it; no replacement is needed. | + +Brief HTML and JSON output: + +```ts +new RsdoctorRspackPlugin({ + output: { + mode: 'brief', + options: { + type: ['html', 'json'], + htmlOptions: { + reportHtmlName: 'rsdoctor-report.html', + }, + }, + }, + server: { + port: 9966, + }, +}); +``` + +Lite-equivalent output without module source code: + +```ts +new RsdoctorRspackPlugin({ + output: { + mode: 'normal', + reportCodeType: 'noCode', + }, +}); +``` + +Both `features: { lite: true }` and `features: ['lite']` remain supported. Leave them unchanged unless the project benefits from expressing the equivalent behavior explicitly with `output.reportCodeType`. + +## AI workflow + +Remove MCP entries from files such as `.cursor/mcp.json` and `.vscode/mcp.json`, and remove automation that starts `npx @rsdoctor/mcp-server`. + +Generate JSON data with Rsdoctor 2.x, then invoke Agent CLI directly: + +```bash +rsdoctor-agent bundle optimize --data-file ./dist/rsdoctor-data.json +rsdoctor-agent query packages_duplicates --data-file ./dist/rsdoctor-data.json +# For a report with multiple compilers, choose the intended compiler: +rsdoctor-agent build summary --data-file ./dist/rsdoctor-data.json --compiler client +``` + +Update agents and automation to parse the structured command output. The data file replaces the long-running MCP connection, so MCP-only server ports do not carry over. For multi-compiler data, Agent CLI requires `--compiler `; use a compiler name from its `COMPILER_REQUIRED` response or the report metadata. + +## Final search + +Use a bounded search after the migration: + +```bash +rg '@rsdoctor/(rspack-plugin|webpack-plugin|sdk|graph|types|utils|components|mcp-server)|enableNativePlugin|compressData|generateTileGraph|writeDataJson|supports\.banner|banner\s*:' +``` + +Review every match; documentation, snapshots, intentionally retained Rsdoctor 1.x examples, or framework-owned transitive packages may be valid. Check whether any old plugin is still active.