Skip to content

feat(gamut-codemods): add the codemods CLI and an empty scope-swap preset - #38

Open
dreamwasp wants to merge 2 commits into
mainfrom
cass-gmt-1790-scaffold
Open

dreamwasp wants to merge 2 commits into
mainfrom
cass-gmt-1790-scaffold

Conversation

@dreamwasp

@dreamwasp dreamwasp commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Overview

First PR in the split of #28. Adds the @skillsoft/gamut-codemods package with an empty scope-swap preset. Each breaking change brings its own migration in a stacked PR.

Stack (split from #28, merge in order):

  1. feat(gamut-codemods): add the codemods CLI and an empty scope-swap preset #38 Scaffold, based on main 👈 this PR
  2. feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39 Package scope rename and gamut-kit removal, based on feat(gamut-codemods): add the codemods CLI and an empty scope-swap preset #38
  3. feat(gamut-codemods): move Video imports and add Markdown video overrides #40 Video and Markdown, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  4. feat(gamut)!: promote deep imports to the root, renaming Menu and SelectDropdown elements #41 Deep imports and Menu/SelectDropdown renames, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  5. feat(gamut-codemods): rename the ESLint plugin prefix in scope-swap #42 ESLint plugin prefix, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  6. feat(gamut-codemods): warn about esmExternals: false in next.config #43 Next.js esmExternals warning, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  7. build(deps): make @skillsoft packages easier to install #44 Simpler dependencies (independent), based on main
  8. feat(gamut-agent-tools): add the gamut-scope-swap skill #45 gamut-scope-swap skill (open last), based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39, includes feat(gamut-codemods): move Video imports and add Markdown video overrides #40–feat(gamut-codemods): warn about esmExternals: false in next.config #43
  • CLI: npx @skillsoft/gamut-codemods <preset> <path...>, plus list. Supports --dry, --only=a,b, --no-report, and --force. It refuses to write outside git or into a dirty tree, so git checkout . always undoes a run.
  • Runner: three migration kinds: ast (recast reprints), splice (offset edits on the original text), and file (raw text for package.json, configs, .mdx). validatePreset enforces that every ast migration comes before any splice one.
  • Shared helpers: finding every place a file names a module, the leftovers report, version-range checks, and flat ESLint config detection.
  • Preset: the scope-swap manifest has the package rename map and the ESLint plugin prefix, but no migrations. A run reports every line that still names an old package and prints next steps.
  • Tests: the fixture harness (<case>.input / .output / .warnings.json, plus an idempotence check), CLI tests, and manifest.test.ts. manifest.test.ts type-checks manifest rows against the built packages.
  • Versioning: gamut-codemods, gamut-illustrations, and gamut-tests join the changesets fixed group.

PR Checklist

  • Related to designs: N/A
  • Related to JIRA ticket: GMT-1790
  • Changeset added
  • I have run this code to verify it works
  • This PR includes unit tests for the code change
  • This PR includes testing instructions for the code change
  • Package previews from this PR are passing end-to-end tests in all relevant consuming repositories

Testing Instructions

  1. yarn nx test gamut-codemods. Expect 48 tests to pass.

  2. Build the CLI and run it on a throwaway repo:

    yarn nx build gamut-codemods
    mkdir -p /tmp/swap && cd /tmp/swap && git init -q
    printf "import { Box } from '@codecademy/gamut';\n" > a.tsx
    echo '{ "dependencies": { "@codecademy/gamut": "^73.0.0" } }' > package.json
    git add -A && git commit -qm init
    node <repo>/packages/gamut-codemods/dist/bin.js scope-swap .

    Nothing is rewritten. The leftovers list should show a.tsx:1 and package.json:1, followed by the three standing next steps.

  3. Edit a.tsx without committing, then rerun. It should refuse and mention --force.

  4. node <repo>/packages/gamut-codemods/dist/bin.js list prints scope-swap.

PR Links and Envs

Repository PR Link
Mono N/A

🤖 Generated with Claude Code

…eset

Adds @skillsoft/gamut-codemods: the CLI (clean-tree guard, --dry, --only,
--no-report, --force), the runner for ast, splice, and file migrations,
the shared helpers (module-string finder, leftovers report, version-range
checks, flat ESLint config detection), the preset registry, and the
fixture harness.

The scope-swap preset has its package map but no migrations yet, so a run
only reports the lines that still name an old package. Each breaking
change lands its migration in its own PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pkg-pr-new

pkg-pr-new Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@skillsoft/eslint-plugin-gamut

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/eslint-plugin-gamut@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/eslint-plugin-gamut@38.tgz

@skillsoft/gamut

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut@38.tgz

@skillsoft/gamut-agent-tools

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-agent-tools@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-agent-tools@38.tgz

@skillsoft/gamut-codemods

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-codemods@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-codemods@38.tgz

@skillsoft/gamut-icons

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-icons@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-icons@38.tgz

@skillsoft/gamut-illustrations

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-illustrations@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-illustrations@38.tgz

@skillsoft/gamut-patterns

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-patterns@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-patterns@38.tgz

@skillsoft/gamut-styles

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-styles@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-styles@38.tgz

@skillsoft/gamut-tests

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-tests@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/gamut-tests@38.tgz

@skillsoft/variance

npm i https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/variance@38
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/variance@38.tgz

commit: e6923f5

@codecov

codecov Bot commented Oct 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.96677% with 63 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@b3b7251). Learn more about missing BASE report.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/gamut-codemods/src/cli.ts 76.63% 25 Missing ⚠️
packages/gamut-codemods/src/lib/run-source.ts 47.05% 18 Missing ⚠️
packages/gamut-codemods/src/lib/manifest.ts 70.00% 9 Missing ⚠️
packages/gamut-codemods/src/transform.ts 70.00% 6 Missing ⚠️
packages/gamut-codemods/src/lib/module-strings.ts 85.71% 5 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main      #38   +/-   ##
=======================================
  Coverage        ?   80.96%           
=======================================
  Files           ?       11           
  Lines           ?      331           
  Branches        ?       94           
=======================================
  Hits            ?      268           
  Misses          ?       63           
  Partials        ?        0           
Flag Coverage Δ
pull-request 80.96% <80.96%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

Comment thread packages/gamut-codemods/src/cli.ts Outdated
const files = fs.statSync(root).isDirectory() ? walk(root) : [root];
for (const file of files) {
for (const migration of active) {
if (!migration.match(file)) continue;
CodeQL read `migration.match(file)` in cli.ts as String.prototype.match
on a command-line argument and flagged js/regex-injection. Nothing builds
a regex from the path; the method just had the same name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dreamwasp
dreamwasp marked this pull request as ready for review October 20, 2026 15:21
@dreamwasp
dreamwasp requested a review from a team as a code owner October 20, 2026 15:21

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants