{"_id":"@cordwainer/cw-migrate","_rev":"5-b67e048aec3e12e118e0cb9af6304946","name":"@cordwainer/cw-migrate","dist-tags":{"latest":"1.0.1","alpha":"1.0.0-alpha.0"},"versions":{"0.1.0":{"name":"@cordwainer/cw-migrate","version":"0.1.0","keywords":["cordwainer","shoelace","migration","codemod","cli","web components"],"author":{"name":"Matt Hand"},"license":"MIT","_id":"@cordwainer/cw-migrate@0.1.0","maintainers":[{"name":"matthand","email":"npm@matthand.us"}],"homepage":"https://cordwainer.dev/tooling/cw-migrate","bugs":{"url":"https://gitlab.com/cordwainer/cw-migrate/-/work_items"},"bin":{"cw-migrate":"dist/cli.js"},"dist":{"shasum":"4eff0011fe8855379beb98c35b383a6c669c3b93","tarball":"https://registry.npmjs.org/@cordwainer/cw-migrate/-/cw-migrate-0.1.0.tgz","fileCount":45,"integrity":"sha512-bmBChA56sl42a6u7jNgCY1HSoLgxyHt5OnBqzpEhR2Z3GKMy1Le4GvV8xBYDNrPmAshPeR1P2idnJeIxVW8C1w==","signatures":[{"sig":"MEQCIC2/nu9Dh0zjYLJPTES4AofMkflkiComu/JfrGtp9kR3AiAJoWOa1T6IEo32VJM5XGTU1AccAPRRUKt4vVhgPJUmWA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43878},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"72ad470691981645f0987f9beaf0fdd20905f720","scripts":{"lint":"eslint src --max-warnings 0","test":"vitest run","build":"tsc","clean":"node ./scripts/clean.js","lint:fix":"eslint src --max-warnings 0 --fix","prebuild":"npm run clean","prettier":"prettier --write --log-level=warn .","test:watch":"vitest","prepublishOnly":"npm run build","prettier:check":"prettier --check --log-level=warn ."},"_npmUser":{"name":"matthand","email":"npm@matthand.us"},"repository":{"url":"git+https://gitlab.com/cordwainer/cw-migrate.git","type":"git"},"_npmVersion":"11.16.0","description":"CLI for migrating Shoelace projects to Cordwainer Elements, and for running codemods across Cordwainer Elements major-version upgrades.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"chalk":"^5.3.0","globby":"^16.2.4","parse5":"^8.0.1","postcss":"^8.5.28","ts-morph":"^28.0.0","commander":"^15.0.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.51.0","vitest":"^5.0.0","prettier":"^3.9.6","typescript":"^5.7.2","@types/node":"^22.20.2","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/cw-migrate_0.1.0_1789083942107_0.03424535246831506","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@cordwainer/cw-migrate","version":"0.2.0","keywords":["cordwainer","shoelace","migration","codemod","cli","web components"],"author":{"name":"Matt Hand"},"license":"MIT","_id":"@cordwainer/cw-migrate@0.2.0","maintainers":[{"name":"matthand","email":"npm@matthand.us"}],"homepage":"https://cordwainer.dev/tooling/cw-migrate","bugs":{"url":"https://gitlab.com/cordwainer/cw-migrate/-/work_items"},"bin":{"cw-migrate":"dist/cli.js"},"dist":{"shasum":"8380f20fc328f251874bb4daa6a24500550a42ac","tarball":"https://registry.npmjs.org/@cordwainer/cw-migrate/-/cw-migrate-0.2.0.tgz","fileCount":45,"integrity":"sha512-1jCbkuF+90XjZbOYK32trHXS9jY4eNX3zYe40pl0e5jV0/kRDDV8PwBjFHLe516+mOys8C4BVk+NlGEO0T5UCA==","signatures":[{"sig":"MEUCIQDJG62tY+1DuAtbQ5W4TB9q8rwYeZde0o1guktTE67V8AIgH+k3c+eo6wEANhz3eaJKJ0v7HZc8OFhRuMmI8WlTWmM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47483},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"c685f6c7ec6e1c71e69dad892e22ef0b7332869c","scripts":{"lint":"eslint src --max-warnings 0","test":"vitest run","build":"tsc","clean":"node ./scripts/clean.js","lint:fix":"eslint src --max-warnings 0 --fix","prebuild":"npm run clean","prettier":"prettier --write --log-level=warn .","test:watch":"vitest","prepublishOnly":"npm run build","prettier:check":"prettier --check --log-level=warn ."},"_npmUser":{"name":"GitLab CI/CD","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"gitlab","oidcConfigId":"oidc:8ef6346b-a78c-4474-842b-c83218f7ccd3"}},"repository":{"url":"git+https://gitlab.com/cordwainer/cw-migrate.git","type":"git"},"_npmVersion":"11.19.0","description":"CLI for migrating Shoelace projects to Cordwainer Elements, and for running codemods across Cordwainer Elements major-version upgrades.","directories":{},"_nodeVersion":"24.21.0","dependencies":{"chalk":"^5.3.0","globby":"^16.2.4","parse5":"^8.0.1","postcss":"^8.5.28","ts-morph":"^28.0.0","commander":"^15.0.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.51.0","vitest":"^5.0.0","prettier":"^3.9.6","typescript":"^5.7.2","@types/node":"^22.20.2","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/cw-migrate_0.2.0_1789163486396_0.3412750514838414","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cordwainer/cw-migrate","version":"0.3.0","keywords":["cordwainer","shoelace","migration","codemod","cli","web components"],"author":{"name":"Matt Hand"},"license":"MIT","_id":"@cordwainer/cw-migrate@0.3.0","maintainers":[{"name":"matthand","email":"npm@matthand.us"}],"homepage":"https://cordwainer.dev/tooling/cw-migrate","bugs":{"url":"https://gitlab.com/cordwainer/cw-migrate/-/work_items"},"bin":{"cw-migrate":"dist/cli.js"},"dist":{"shasum":"9fd6463d3c3149841151fdb68b13ca987a708ed8","tarball":"https://registry.npmjs.org/@cordwainer/cw-migrate/-/cw-migrate-0.3.0.tgz","fileCount":45,"integrity":"sha512-SustlZ5EYTtkPmZjBKxG/G4KQxYc//64018K3cn+8hF2kXvV1fnBLX+h85kzi07wA11L+EimGl+cUU/UG44MHA==","signatures":[{"sig":"MEUCIGIxZFJ47Lhu2kh8W3Ot4qwZwkfnoVGPMswBWjmeTYokAiEA1tZf5w/lG2ICZfpRlEfXn5AURg3N+gPL0mCWWb8h86w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58518},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"f66f403a18e4e611d695434eff2b56df3d6a2983","scripts":{"lint":"eslint src --max-warnings 0","test":"vitest run","build":"tsc","clean":"node ./scripts/clean.js","lint:fix":"eslint src --max-warnings 0 --fix","prebuild":"npm run clean","prettier":"prettier --write --log-level=warn .","test:watch":"vitest","prepublishOnly":"npm run build","prettier:check":"prettier --check --log-level=warn ."},"_npmUser":{"name":"GitLab CI/CD","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"gitlab","oidcConfigId":"oidc:8ef6346b-a78c-4474-842b-c83218f7ccd3"}},"repository":{"url":"git+https://gitlab.com/cordwainer/cw-migrate.git","type":"git"},"_npmVersion":"11.19.0","description":"CLI for migrating Shoelace projects to Cordwainer Elements, and for running codemods across Cordwainer Elements major-version upgrades.","directories":{},"_nodeVersion":"24.21.0","dependencies":{"chalk":"^5.3.0","globby":"^16.2.4","parse5":"^8.0.1","postcss":"^8.5.28","ts-morph":"^28.0.0","commander":"^15.0.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.51.0","vitest":"^5.0.0","prettier":"^3.9.6","typescript":"^5.7.2","@types/node":"^22.20.2","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/cw-migrate_0.3.0_1789164594715_0.19253206902224584","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-alpha.0":{"name":"@cordwainer/cw-migrate","version":"1.0.0-alpha.0","keywords":["cordwainer","shoelace","migration","codemod","cli","web components"],"author":{"name":"Matt Hand"},"license":"MIT","_id":"@cordwainer/cw-migrate@1.0.0-alpha.0","maintainers":[{"name":"matthand","email":"npm@matthand.us"}],"homepage":"https://cordwainer.dev/tooling/cw-migrate","bugs":{"url":"https://gitlab.com/cordwainer/cw-migrate/-/work_items"},"bin":{"cw-migrate":"dist/cli.js"},"dist":{"shasum":"d2c8bc6e61b756a42bfb39523cc89b03ef32d5ff","tarball":"https://registry.npmjs.org/@cordwainer/cw-migrate/-/cw-migrate-1.0.0-alpha.0.tgz","fileCount":45,"integrity":"sha512-r9GEJL+7XqfsAj1x4L9yvPu4bMf6ryQfD2f7tZa4+DFETpsmqFMCn8WJlhXEXXneJms6ZmAXxReXzHNeb0AC9g==","signatures":[{"sig":"MEUCIQDz2nEZvqc/5ck3fGUEZn8/js2QrDiOwFZUAm3IMmqUkgIgJto820iRButisaAaJi3O6gIEChKX6CqTqGyybJngUu8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69953},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"5994d94a080b5db6e21b33e44ab032458a66bd92","scripts":{"lint":"eslint src --max-warnings 0","test":"vitest run","build":"tsc","clean":"node ./scripts/clean.js","lint:fix":"eslint src --max-warnings 0 --fix","prebuild":"npm run clean","prettier":"prettier --write --log-level=warn .","test:watch":"vitest","prepublishOnly":"npm run build","prettier:check":"prettier --check --log-level=warn ."},"_npmUser":{"name":"GitLab CI/CD","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"gitlab","oidcConfigId":"oidc:8ef6346b-a78c-4474-842b-c83218f7ccd3"}},"repository":{"url":"git+https://gitlab.com/cordwainer/cw-migrate.git","type":"git"},"_npmVersion":"11.19.0","description":"CLI for migrating Shoelace projects to Cordwainer Elements, and for running codemods across Cordwainer Elements major-version upgrades.","directories":{},"_nodeVersion":"24.21.0","dependencies":{"chalk":"^5.3.0","globby":"^16.2.4","parse5":"^8.0.1","postcss":"^8.5.28","ts-morph":"^28.0.0","commander":"^15.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"eslint":"^8.51.0","vitest":"^5.0.0","prettier":"^3.9.6","typescript":"^5.7.2","@types/node":"^22.20.2","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/eslint-plugin":"^7.18.0"},"_npmOperationalInternal":{"tmp":"tmp/cw-migrate_1.0.0-alpha.0_1789166235074_0.22663678565662893","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@cordwainer/cw-migrate","description":"CLI for migrating Shoelace projects to Cordwainer Elements, and for running codemods across Cordwainer Elements major-version upgrades.","version":"1.0.1","homepage":"https://cordwainer.dev/tooling/cw-migrate","author":{"name":"Matt Hand"},"license":"MIT","type":"module","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.js","bin":{"cw-migrate":"dist/cli.js"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"keywords":["cordwainer","shoelace","migration","codemod","cli","web components"],"repository":{"type":"git","url":"git+https://gitlab.com/cordwainer/cw-migrate.git"},"bugs":{"url":"https://gitlab.com/cordwainer/cw-migrate/-/work_items"},"scripts":{"build":"tsc","clean":"node ./scripts/clean.js","prebuild":"npm run clean","prepublishOnly":"npm run build","test":"vitest run","test:watch":"vitest","lint":"eslint src --max-warnings 0","lint:fix":"eslint src --max-warnings 0 --fix","prettier":"prettier --write --log-level=warn .","prettier:check":"prettier --check --log-level=warn ."},"engines":{"node":">=20.0.0"},"dependencies":{"chalk":"^5.3.0","commander":"^15.0.0","globby":"^16.2.4","parse5":"^8.0.1","postcss":"^8.5.28","ts-morph":"^28.0.0"},"devDependencies":{"@types/node":"^22.20.2","@typescript-eslint/eslint-plugin":"^7.18.0","@typescript-eslint/parser":"^7.18.0","eslint":"^8.51.0","prettier":"^3.9.6","typescript":"^5.7.2","vitest":"^5.0.0"},"gitHead":"571a886de3bc80e5b62d01e99aef5e6eb1bd6bce","_id":"@cordwainer/cw-migrate@1.0.1","_nodeVersion":"24.21.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-Y2ZlM2UyxObhDERUMTvcO3BLW2w2RqjP0mc0FWraP0rJG/Amb+O4iSL1yyms9LJ2+pQNxfNzLbEpTHy5TX179g==","shasum":"eed6724c09daa6fe5a1a1656ec0a314f1e4c9f02","tarball":"https://registry.npmjs.org/@cordwainer/cw-migrate/-/cw-migrate-1.0.1.tgz","fileCount":47,"unpackedSize":90984,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCmTx/pM5nak54ck3xhti9CTFCKVV7qDxPGCzrdcPcvRQIgH9JbhRUW11a8UoZzSzIyyErFZQZfXi4wP88/zW+wkZ0="}]},"_npmUser":{"name":"GitLab CI/CD","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"gitlab","oidcConfigId":"oidc:8ef6346b-a78c-4474-842b-c83218f7ccd3"}},"directories":{},"maintainers":[{"name":"matthand","email":"npm@matthand.us"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cw-migrate_1.0.1_1789241225675_0.011540391010125939"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-10T23:45:41.937Z","modified":"2026-09-12T19:27:05.988Z","0.1.0":"2026-09-10T23:45:42.242Z","0.2.0":"2026-09-11T21:51:26.523Z","0.3.0":"2026-09-11T22:09:54.858Z","1.0.0-alpha.0":"2026-09-11T22:37:15.210Z","1.0.1":"2026-09-12T19:27:05.808Z"},"bugs":{"url":"https://gitlab.com/cordwainer/cw-migrate/-/work_items"},"author":{"name":"Matt Hand"},"license":"MIT","homepage":"https://cordwainer.dev/tooling/cw-migrate","keywords":["cordwainer","shoelace","migration","codemod","cli","web components"],"repository":{"type":"git","url":"git+https://gitlab.com/cordwainer/cw-migrate.git"},"description":"CLI for migrating Shoelace projects to Cordwainer Elements, and for running codemods across Cordwainer Elements major-version upgrades.","maintainers":[{"name":"matthand","email":"npm@matthand.us"}],"readme":"# Cordwainer Migrate\n\nA CLI for migrating [Shoelace](https://shoelace.style) projects to [Cordwainer Elements](https://cordwainer.dev) — and, going forward, for running codemods across Cordwainer Elements' own major-version upgrades.\n\n> ✅ **Feature-complete and real-world tested.** Every command below is implemented and has been run end-to-end against a production Shoelace + Lit codebase — see [Real-world testing](#real-world-testing) and [Status](#status) for the release plan.\n\n- 🔍 Detects every Shoelace element, token, event, and TypeScript reference before touching anything\n- ✍️ Rewrites using real parsers per domain (`parse5`, PostCSS, `ts-morph`) — not find-and-replace\n- 🧵 Understands Lit `html\\`\\`` / `css\\`\\`` tagged templates, not just literal markup — tags, custom properties, type selectors, and `style=\"...\"` attributes are all reachable inside template-literal text in plain `.ts`/`.js` files\n- 🧪 `--dry-run` reports what would change without writing anything\n- 🛡️ Refuses to run against a dirty working tree unless `--force` — git is the assumed safety net\n- 🧩 Each rewrite domain is also runnable on its own, for incremental conversion\n\nThis module was built for Cordwainer Elements, but — like [`@cordwainer/cw-animations`](https://gitlab.com/cordwainer/cw-animations) and [`@cordwainer/cw-localize`](https://gitlab.com/cordwainer/cw-localize) — it ships as its own standalone package with its own release cadence.\n\n---\n\nDocumentation: [cordwainer.dev/tooling/cw-migrate](https://cordwainer.dev/tooling/cw-migrate)\n\nSource: [gitlab.com/cordwainer/cw-migrate](https://gitlab.com/cordwainer/cw-migrate)\n\nnpm: [@cordwainer/cw-migrate](https://www.npmjs.com/package/@cordwainer/cw-migrate)\n\n---\n\n## Why this exists\n\nCordwainer Elements is a rename-and-retheme fork of Shoelace: same component shapes and attributes, different tag names (`sl-` → `cw-`), CSS custom property namespace (`--sl-` → `--cw-`), custom event names (`sl-` → `cw-`), and TypeScript class/type names (`Sl*` → `Cw*`) — including for anyone who's built their own components on top of Shoelace's. Adopting Cordwainer in an existing Shoelace project means finding and renaming all four by hand, across every file type in the project. This tool automates it.\n\nNaive find-and-replace isn't safe here — `sl-button` and `sl-button-group` need to be told apart, and a closing tag has to match its opener. Each command below uses a real parser for its own domain instead of regex, so it understands the file it's rewriting rather than pattern-matching text.\n\n## Usage\n\nThis is a tool you run directly against a project you're migrating — it's not meant to become a dependency of that project. The usual way to run it is with `npx`, with no separate install step:\n\n```bash\nnpx @cordwainer/cw-migrate <path>\n```\n\nRun with no subcommand, `cw-migrate` acts as an orchestrator: it runs `detect` first, then every rewrite domain in order, and prints a summary of what changed. `package-json` is the one exception — it needs an explicit `--target-version` decision, so it's always run as its own separate step.\n\n```bash\n# Preview every change without writing anything\nnpx @cordwainer/cw-migrate ./my-project --dry-run\n\n# Actually rewrite the project (requires a clean working tree)\nnpx @cordwainer/cw-migrate ./my-project\n```\n\n### Commands\n\nEach rewrite domain is also runnable on its own, for anyone who wants to convert incrementally rather than all at once.\n\n| Command | What it does |\n| --- | --- |\n| `cw-migrate detect <path>` | Scans the project and reports every Shoelace element, token, event, and TypeScript class/type reference found, with file/line references. Writes nothing. Always run first — the other commands consume its scan output rather than re-scanning. |\n| `cw-migrate elements <path>` | Renames custom element tags (`<sl-button>` → `<cw-button>`, opening _and_ closing tags) across plain HTML, JSX/TSX, Vue SFC templates, Angular templates, and Svelte files — plus Lit `html\\`\\``/`svg\\`\\`` tagged templates in `.ts`/`.js`. Also renames `sl-*` CSS type selectors (`sl-button { ... }` → `cw-button { ... }`) in stylesheets and `css\\`\\``/styled-components template literals, and `sl-*` selector strings passed to `.querySelector(...)`/`.querySelectorAll(...)`/`.closest(...)`/`.matches(...)`. |\n| `cw-migrate tokens <path>` | Renames CSS custom properties (`--sl-color-primary-600` → `--cw-color-primary-600`, etc.) across CSS/SCSS/LESS files, inline `style=\"...\"` attributes (HTML/Vue/Svelte, and Lit `html\\`\\``/`svg\\`\\`` tagged templates in `.ts`/`.js`), JSX `style={{...}}` object props, and `styled-components`/emotion template literals (`styled.*`, `styled(...)`, `css\\`\\``). Vue/Svelte's own bound style expressions (`:style=\"{...}\"`) aren't covered yet — those are JavaScript, not a literal string or a JSX object. |\n| `cw-migrate events <path>` | Renames custom event names (`sl-change` → `cw-change`) in `addEventListener` calls and framework event bindings (`@sl-change` in Vue, `(slChange)` in Angular, `onSlChange` props in the React wrapper). |\n| `cw-migrate typescript-refs <path>` | Renames Shoelace-exported class/type identifiers (`SlButton` → `CwButton`, `SlChangeEvent` → `CwChangeEvent`, etc.) everywhere they're _referenced_ — `extends` clauses on your own composite components, type annotations, generic constraints, and the ambient `HTMLElementTagNameMap`/`JSX.IntrinsicElements` global augmentation these libraries ship. Covers `.ts`, `.tsx`, and `.d.ts` files. |\n| `cw-migrate imports <path>` | Updates JS/TS import specifiers, CDN `<script>`/`<link>` URLs, and framework wrapper package imports. |\n| `cw-migrate package-json <path> [--target-version <version>]` | Swaps the `@shoelace-style/shoelace` dependency for `@cordwainer/cw-elements` at the target version (`--target-version`, not `--version` — that's reserved for the CLI's own `cw-migrate --version`). |\n| `cw-migrate <path>` | Orchestrator — runs every rewrite domain above except `package-json` (which needs an explicit `--target-version`) in order. Supports `--dry-run`. |\n\n### Flags\n\n- `--dry-run` — reports what would change without writing anything. Works on any command, including the orchestrator.\n- `--force` — required to run against a dirty working tree. By default, `cw-migrate` refuses to run at all if the target project has uncommitted changes, since git is the assumed rollback path if something looks wrong afterward.\n\n## Beyond the Shoelace migration\n\nOnce the initial wave of Shoelace-to-Cordwainer conversions is done, this package doesn't go away — it becomes the permanent home for codemods that ship alongside future **Cordwainer Elements** major-version bumps (a renamed attribute, a restructured slot, a removed component), the same role tools like `react-codemod` or Angular's `ng update` schematics play for their own ecosystems. That's also why this package is named `@cordwainer/cw-migrate` rather than something Shoelace-specific. The command shape for version-targeted codemods hasn't been designed yet — there's no breaking Cordwainer change to design against until one is actually planned.\n\n## Real-world testing\n\ncw-migrate has been run end-to-end against [GoogleChrome/chromium-dashboard](https://github.com/GoogleChrome/chromium-dashboard) (chromestatus.com) — a production Lit + TypeScript app with 80 Shoelace-referencing files — as its first real-world validation, ahead of this stable release. Sample migration branch and write-up: [matthandus/chromium-dashboard-migrate-shoelace-to-cordwainer#1](https://github.com/matthandus/chromium-dashboard-migrate-shoelace-to-cordwainer/pull/1).\n\nThat test surfaced and fixed four gaps in the tool itself, all now shipped:\n\n- `elements` wasn't scanning `.ts`/`.js` files at all, so `sl-*` tags inside Lit `html\\`\\`` tagged templates — the majority of this project's Shoelace usage — went untouched. `detect`'s element-match count went from 2 to 1102 after the fix.\n- No command renamed `sl-*` CSS type selectors (`sl-button { ... }`), only `--sl-*` custom properties — left as-is, this would have silently broken component styling post-migration.\n- Plain `style=\"...\"` attributes inside Lit templates weren't covered by the custom-property rewrite.\n- `sl-*` selector strings passed to `.querySelector(...)`/`.querySelectorAll(...)`/`.closest(...)`/`.matches(...)` weren't renamed, which would have left tests silently querying for elements that no longer exist.\n\nPost-fix, the migrated result installs and builds cleanly (`npm install`, `tsc`, `rollup`), with zero Shoelace tag/token/event/import/type references remaining in source.\n\n## Status\n\n**`1.0.0` is the current stable release.** Every command below is implemented, and the tool has been real-world tested against a production codebase (see [Real-world testing](#real-world-testing) above) before this release.\n\n- ✅ `detect`, `elements`, `tokens`, `events`, `typescript-refs`, `imports`, `package-json` are all implemented\n- The no-subcommand orchestrator (`cw-migrate <path>`) runs every rewrite domain except `package-json`, which stays a deliberate separate step since it needs an explicit `--target-version`\n- Beyond v1: the command shape for future Cordwainer major-version codemods (see [Beyond the Shoelace migration](#beyond-the-shoelace-migration)) is still undesigned\n\n## Developers\n\nYou'll need Node >= 20 to build and run this project locally.\n\n```bash\nnpm run build   # compile with tsc\nnpm test        # run the vitest suite\n```\n\nPlease report all bugs and suggestions to [the issue tracker](https://gitlab.com/cordwainer/cw-migrate/-/work_items).\n\n## License\n\nCordwainer Migrate is developed by Matt Hand. It's available under the terms of the MIT license.\n","readmeFilename":"README.md"}