feat: add v2 codemod draft (#1950)
This commit is contained in:
parent
4f226c1e35
commit
48251fe2cb
4 changed files with 9239 additions and 1 deletions
3
packages/codemod/batch-test/.gitignore
vendored
Normal file
3
packages/codemod/batch-test/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
repos/
|
||||
results/
|
||||
tarballs/
|
||||
102
packages/codemod/batch-test/README.md
Normal file
102
packages/codemod/batch-test/README.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# Codemod Batch Test
|
||||
|
||||
Tests the v1-to-v2 codemod against real-world repos to find bugs, missing transforms, and gaps.
|
||||
|
||||
## How it works
|
||||
|
||||
For each repo in `repos.json`, the batch test:
|
||||
|
||||
1. Clones the repo (or resets an existing clone)
|
||||
2. Installs dependencies
|
||||
3. Runs baseline checks (typecheck, build, test, lint) to confirm the repo is healthy
|
||||
4. Runs the codemod using the programmatic API
|
||||
5. Packs local SDK packages as tarballs and rewrites `package.json` deps to use them (so the test runs against the current SDK branch, not published npm versions)
|
||||
6. Re-installs dependencies
|
||||
7. Re-runs the same checks
|
||||
8. Writes structured JSON reports
|
||||
|
||||
Errors that appear in step 7 but not step 3 are codemod-introduced regressions.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Build all SDK packages first (tarballs need built dist/)
|
||||
pnpm build:all
|
||||
|
||||
# Run the batch test
|
||||
pnpm --filter @modelcontextprotocol/codemod batch-test
|
||||
|
||||
# Clean cloned repos, results, and tarballs
|
||||
pnpm --filter @modelcontextprotocol/codemod batch-test:clean
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Results are written to `batch-test/results/`:
|
||||
|
||||
- `summary.json` — overview across all repos: which passed, which failed, error counts
|
||||
- `<repo-slug>/report.json` — per-repo detail: baseline vs post-codemod check results, codemod diagnostics, change counts
|
||||
|
||||
## Repo manifest (`repos.json`)
|
||||
|
||||
An array of repo entries. Each entry specifies a GitHub repo and one or more packages within it.
|
||||
|
||||
```json
|
||||
{
|
||||
"repo": "owner/repo-name",
|
||||
"ref": "main",
|
||||
"packages": [
|
||||
{
|
||||
"dir": "packages/mcp-server",
|
||||
"sourceDir": "src",
|
||||
"checks": {
|
||||
"typecheck": "npx tsc --noEmit",
|
||||
"build": "npm run build",
|
||||
"test": "npm run test",
|
||||
"lint": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Required | Default | Description |
|
||||
| ---------------------- | -------- | -------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `repo` | yes | — | GitHub `owner/name` |
|
||||
| `ref` | no | `main` | Branch or tag to clone |
|
||||
| `packages` | no | `[{ "dir": ".", "sourceDir": "src" }]` | Package targets within the repo |
|
||||
| `packages[].dir` | yes | — | Path to package root (where `package.json` lives) |
|
||||
| `packages[].sourceDir` | no | `src` | Source directory relative to `dir` (passed to codemod) |
|
||||
| `packages[].checks` | no | auto-detect | Override check commands; set a value to `null` to skip that check |
|
||||
|
||||
When `checks` is omitted, the runner auto-detects commands from the package's `package.json` scripts (probing names like `typecheck`, `build`, `test`, `lint`). The package manager is auto-detected from the lockfile at the repo root.
|
||||
|
||||
## Analyzing results
|
||||
|
||||
`analyze-prompt.md` contains instructions for Claude Code to run the batch test and produce a categorized analysis. Each error is classified as:
|
||||
|
||||
| Category | Meaning |
|
||||
| ------------------- | -------------------------------------------------- |
|
||||
| `codemod-bug` | A transform produced incorrect output |
|
||||
| `missing-transform` | The codemod should handle this pattern but doesn't |
|
||||
| `manual-migration` | Expected — requires human judgment |
|
||||
| `repo-specific` | Unusual pattern not worth handling in the codemod |
|
||||
|
||||
## Adding a repo
|
||||
|
||||
1. Edit `repos.json` and add an entry
|
||||
2. Run `pnpm --filter @modelcontextprotocol/codemod batch-test`
|
||||
3. Check `results/<repo-slug>/report.json` for new findings
|
||||
|
||||
For monorepos, list each package that uses `@modelcontextprotocol/sdk` as a separate entry in `packages`.
|
||||
|
||||
## Iteration workflow
|
||||
|
||||
```
|
||||
1. Run the batch test
|
||||
2. Review results — identify codemod bugs / missing transforms
|
||||
3. Fix the codemod transforms
|
||||
4. Run batch-test:clean, then re-run the batch test
|
||||
5. Confirm the fixes resolved the issues
|
||||
6. Repeat
|
||||
```
|
||||
87
packages/codemod/batch-test/analyze-prompt.md
Normal file
87
packages/codemod/batch-test/analyze-prompt.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Codemod Batch Test: Analysis
|
||||
|
||||
## Context
|
||||
|
||||
The MCP TypeScript SDK is migrating from a single v1 package (`@modelcontextprotocol/sdk`) to a multi-package v2 architecture (`@modelcontextprotocol/client`, `/server`, `/core`, `/node`, `/express`). This involves renamed APIs, restructured context objects, removed modules, and
|
||||
new import paths.
|
||||
|
||||
The `@modelcontextprotocol/codemod` package automates the mechanical parts of this migration. It runs 9 ordered AST transforms via ts-morph: import path rewrites, symbol renames, McpServer API restructuring, handler registration changes, context property remapping, and more. It
|
||||
also updates `package.json` to swap v1 deps for v2.
|
||||
|
||||
The **batch test** runs this codemod against a curated list of real-world repos that use the v1 SDK. For each repo it:
|
||||
|
||||
1. Clones and installs
|
||||
2. Runs baseline checks (typecheck, build, test, lint) to confirm the repo is healthy before migration
|
||||
3. Runs the codemod
|
||||
4. Re-installs (package.json was updated with v2 deps)
|
||||
5. Re-runs the same checks
|
||||
|
||||
The goal is to find issues in the codemod itself — incorrect transforms, missing transforms, or gaps — so we can fix them.
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Build the codemod:
|
||||
|
||||
```
|
||||
pnpm --filter @modelcontextprotocol/codemod build
|
||||
```
|
||||
|
||||
2. Run the batch test:
|
||||
|
||||
```
|
||||
pnpm --filter @modelcontextprotocol/codemod batch-test
|
||||
```
|
||||
|
||||
3. Read `packages/codemod/batch-test/results/summary.json` for the overview. Note which repos have `postCodemodClean: false` and which check types have new errors.
|
||||
|
||||
4. For each repo with new errors, read its `packages/codemod/batch-test/results/<repo-slug>/report.json`. Compare `baseline` vs `postCodemod` for each check — only errors that appear in `postCodemod` but not in `baseline` are codemod-introduced.
|
||||
|
||||
5. Also review the `codemod.diagnostics` array in each report — these are warnings the codemod itself emitted about patterns it couldn't fully handle.
|
||||
|
||||
6. For each codemod-introduced error, look at the actual source file in the cloned repo (`packages/codemod/batch-test/repos/<repo-slug>/...`) to understand what the codemod produced and what it should have produced.
|
||||
|
||||
7. Categorize each finding using the categories below, then produce the output described in the Output Format section.
|
||||
|
||||
## Error Categories
|
||||
|
||||
| Category | Meaning | What to do |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `codemod-bug` | A transform produced incorrect output — the code it generated is wrong | Identify which transform is responsible and what the correct output should be. This is a bug to fix in the codemod. |
|
||||
| `missing-transform` | The codemod left v1 code untouched that it should have migrated | Identify the v1 pattern and which existing transform should handle it, or whether a new transform is needed. |
|
||||
| `manual-migration` | The error is expected — the migration guide documents this as requiring human judgment (e.g., removed APIs, architectural changes) | Verify the codemod emitted a diagnostic for it. If not, add one. |
|
||||
| `repo-specific` | An unusual pattern unique to this repo that isn't worth handling in the codemod | Note it briefly but don't suggest codemod changes. |
|
||||
|
||||
## Output Format
|
||||
|
||||
### Summary
|
||||
|
||||
- Repos tested: X
|
||||
- Repos clean after codemod: Y
|
||||
- Repos with new errors: Z
|
||||
- Total codemod-introduced errors: N
|
||||
|
||||
### Findings by Category
|
||||
|
||||
#### Codemod Bugs
|
||||
|
||||
| Repo | File:Line | Error | Transform | Root Cause | Correct Output |
|
||||
| ---- | --------- | ----- | --------- | ---------- | -------------- |
|
||||
|
||||
#### Missing Transforms
|
||||
|
||||
| Repo | File:Line | Error | v1 Pattern | Suggested Fix |
|
||||
| ---- | --------- | ----- | ---------- | ------------- |
|
||||
|
||||
#### Manual Migration (expected)
|
||||
|
||||
| Repo | File:Line | Error | Has Diagnostic? | Migration Guide Reference |
|
||||
| ---- | --------- | ----- | --------------- | ------------------------- |
|
||||
|
||||
#### Repo-Specific
|
||||
|
||||
| Repo | File:Line | Error | Why Not Worth Handling |
|
||||
| ---- | --------- | ----- | ---------------------- |
|
||||
|
||||
### Priority Fixes
|
||||
|
||||
List the top 3-5 codemod improvements that would fix the most repos, ordered by impact (number of repos affected). For each, state: what to change, in which transform, and how many repos it would fix.
|
||||
44
packages/codemod/batch-test/repos.json
Normal file
44
packages/codemod/batch-test/repos.json
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
[
|
||||
{
|
||||
"repo": "KKonstantinov/mcp-servers-fork",
|
||||
"ref": "feature/upgrade-zod-v4",
|
||||
"packages": [
|
||||
{
|
||||
"dir": "src/everything",
|
||||
"sourceDir": ".",
|
||||
"checks": {
|
||||
"typecheck": "npx tsc --noEmit",
|
||||
"build": "npm run build",
|
||||
"test": "npm run test",
|
||||
"lint": "npm run prettier:check"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "modelcontextprotocol/inspector",
|
||||
"ref": "main",
|
||||
"packages": [
|
||||
{
|
||||
"dir": "client",
|
||||
"sourceDir": "src",
|
||||
"checks": {
|
||||
"typecheck": "npx tsc --noEmit",
|
||||
"build": "npm run build",
|
||||
"test": "npm run test",
|
||||
"lint": "npm run lint"
|
||||
}
|
||||
},
|
||||
{
|
||||
"dir": "server",
|
||||
"sourceDir": "src",
|
||||
"checks": {
|
||||
"typecheck": "npx tsc --noEmit",
|
||||
"build": "npm run build",
|
||||
"test": null,
|
||||
"lint": null
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Loading…
Reference in a new issue