Conversation
Adds @skillsoft/gamut-codemods, a jscodeshift-based CLI for moving consumers from @Codecademy/gamut* to @skillsoft/gamut*: npx @skillsoft/gamut-codemods scope-swap . The scope-swap preset rewrites imports, mocks, `declare module`, and package-name strings; moves Video/VideoProps to @skillsoft/gamut/Video; maps /dist/ deep imports to public entry points; replaces gamut-kit in package.json and Module Federation shared config; and updates the ESLint plugin prefix. It refuses to run on a dirty tree, and ends with a leftovers report plus a checklist built from what fired. Structure: presets (one per upgrade) hold a data manifest and an ordered list of reusable migrations. String swaps are splice edits on the original text rather than recast prints, since recast reprinted neighbouring code in semicolon-less files and changed JSX whitespace. Also adds gamut-codemods, gamut-illustrations, and gamut-tests to the changesets fixed group so every consumer-facing package shares a version, which the preset uses for its target versions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lets the @skillsoft/gamut-codemods PR, which targets cass-gmt-1795, publish installable pkg.pr.new previews. Revert this commit before either branch ships to main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@skillsoft/eslint-plugin-gamut
@skillsoft/gamut
@skillsoft/gamut-agent-tools
@skillsoft/gamut-codemods
@skillsoft/gamut-icons
@skillsoft/gamut-illustrations
@skillsoft/gamut-patterns
@skillsoft/gamut-styles
@skillsoft/gamut-tests
@skillsoft/variance
commit: |
…the root Ships the rename upstream GMT-1740 held back (Codecademy/gamut 009aa43, "move Menu/elements and IconOptionComponent renames to a separate PR"): - Menu/elements: List* -> MenuList* (List, ListProps, ListItem, ListItemProps, ListLink, ListLinkProps, ListButton), and Menu/index now re-exports './elements'. MenuToolTipWrapper becomes public too. - Form/SelectDropdown: the IconOption component -> IconOptionComponent, exported from the barrel. The IconOption type is unchanged. The names changed because List and IconOption collide with the public List component and IconOption type once they're on the root. The scope-swap codemod maps both deep imports to the root with the new names, keeping local bindings (`import { MenuList as List }`), and its manifest test now type-checks those names against the built package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd .yarnrc.yml From a scope-swap run against mono: - package-json no longer overwrites a new package that's already listed. Expanding gamut-kit re-added @codecademy/* names and the rename step then replaced hand-added @skillsoft/* preview URLs with ^0.0.1, which isn't published for most packages, so yarn install 404'd. Expansion now checks for the new name too, and existing entries win. - A `*` peer range stays `*` instead of narrowing to the target version. - New mdx-imports migration: runs the source migrations over ESM import/export statements in .mdx files, skipping fenced code. Stories get the scope rename, Video split, and deep-import rewrites. - New yarnrc migration: renames old names in .yarnrc.yml list items, or drops them when a scope glob like '@skillsoft/*' covers the new name. Quotes the result, since a YAML plain scalar can't start with `@`. The source-migration runner moves to lib/run-source.ts so file migrations can reuse it through a `transformSource` helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nalStyles For custom inputs that should look like Input, such as third-party hosted payment fields; mono's Recurly fields import all three from dist/Form/styles today. The rest of Form/styles stays internal. The scope-swap codemod now rewrites Form/styles deep imports to the root when every imported name is one of the three, via a new `onlyNames` manifest field, and warns otherwise. Deep-import rewrites inside mocks now always warn, since mocking the root covers the whole package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arget exports From a type-checked scope-swap run against mono (15 errors left after the consumer-side fixes, all from these): gamut - Add a Video/package.json stub (and ship it) so `@skillsoft/gamut/Video` resolves under TypeScript's node10 resolution and bundlers that ignore `exports`, the same way upstream does. Drop attw's `no-resolution` ignore, which was hiding exactly this. - Export the HTMLToReactNode and ButtonBaseProps types from the root; mono deep-imports both. gamut-codemods - Five deep-import rows were sending every name to the root even though only some are public there (Box/props, Button/shared, Markdown/libs/overrides, SelectDropdown/elements, gamut-icons/props). They now list their public names in `onlyNames`, and manifest.test.ts fails if any row could send a name its target doesn't export. - New tsconfig-dom report: warns on `lib` without "dom", which Video used to supply through the root import, with a matching next-steps item. - The gamut-kit next step mentions gamut-styles' stylis peer dependency. - README: how to test against pkg.pr.new previews (resolutions to avoid duplicate copies). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A consumer now needs react, react-dom, @emotion/react, and @emotion/styled alongside @skillsoft/gamut, down from also installing @emotion/cache, lodash, stylis, and typescript by hand. Verified by installing packed tarballs into a fresh yarn project: the only peer warning left is yarn's implicit @types/react. - gamut-styles: stylis, lodash, @emotion/cache peer -> dependency. stylis only feeds the cache's prefixer, and @emotion/cache already ships its own copy, so nothing needs to be shared with the host. - gamut-icons: drop the lodash peer; nothing imports it. - variance: mark the typescript peer optional; no runtime import. - Sibling @SkillSoft deps use ^ ranges instead of exact pins, so a consumer on a slightly different patch shares one gamut-styles (one theme context) instead of getting two. - gamut-tests: component-test-setup * -> ^0.3.1. - gamut: @types/marked -> devDependencies; no published .d.ts uses it. Third-party exact pins (react-aria-components and friends) stay exact: loosening them re-resolved react-aria-components 1.7.1 -> 1.21.1, which is an upgrade to test on its own. The scope-swap checklist drops its now-unneeded stylis note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #18 (
cass-gmt-1795).Warning
b1b91a74faddscass-gmt-1795topreview.yml'spull_request.branchesso this PR can publish a pkg.pr.new preview. It's temporary. Revert it before either branch ships tomain.What this adds
@skillsoft/gamut-codemods, a jscodeshift CLI for moving consumers from@codecademy/gamut*to@skillsoft/gamut*:npx @skillsoft/gamut-codemods scope-swap .The
scope-swappreset:require,import(),jest.mock/vi.mock,declare module, andimport('x').T, plus exact package-name strings liketranspilePackages, with one warning per fileVideo/VideoPropsimports to@skillsoft/gamut/Video/dist/deep imports to public entry points, and warns where there isn't one@codecademy/gamut-kitinpackage.jsonand in Module Federationsharedconfig.eslintrc(.json)It refuses to run on a dirty tree unless you pass
--force. It ends with a leftovers report and a next-steps checklist built from what actually fired.The package README covers usage and how to contribute.
Structure
{title} - {description}became{title}- {description}).manifest.test.tstype-checks every export a manifest points at against the built packages. It also checks that the target versions match the changesetsfixedgroup.Also in here
gamut-codemods,gamut-illustrations, andgamut-testsare added to the changesetsfixedgroup, so every consumer-facing package shares one version. All of them are currently on0.0.1.@skillsoft/gamut-codemodsminor. Because of thefixedgroup, that bumps the whole group.This branch intentionally includes breaking changes. In
d0693b15e,@skillsoft/gamutships the Menu and SelectDropdown renames that upstream GMT-1740 held back (Codecademy/gamut009aa43f6, "move Menu/elements and IconOptionComponent renames to a separate PR"):dist/Menu/elements,dist/Form/SelectDropdown/elements)@skillsoft/gamutroot)List,ListPropsMenuList,MenuListPropsListItem,ListItemPropsMenuListItem,MenuListItemPropsListLink,ListLinkPropsMenuListLink,MenuListLinkPropsListButtonMenuListButtonIconOption(the component)IconOptionComponentMenuToolTipWrapperalso becomes public.IconOptiontype is unchanged.ListandIconOptionwould collide with the publicListcomponent andIconOptiontype on the root.minor, following CONTRIBUTING's 0.x rule, and includes a migration table.The scope-swap codemod handles this for consumers. It keeps local names (
import { List }becomesimport { MenuList as List }), andmanifest.test.tstype-checks the new names against the built package.ButtonBasestays private. That was a separate decision in GMT-1740, not a rename, so the codemod still warns ondist/ButtonBase/ButtonBasedeep imports.Fixes from a type-checked run against mono
These come from a test run of the
@28preview against mono (8f6f3ee5c,1bebf4340,658a4df14).@skillsoft/gamut:@skillsoft/gamut/Videofailed under TypeScript'smoduleResolution: "node". AVideo/package.jsonstub fixes it, the same approach upstream uses. attw'sno-resolutionignore, which was hiding the problem, is removed.formFieldStyles,formFieldPaddingStyles, andconditionalStyles(mono's Recurly fields use them), plus theHTMLToReactNodeandButtonBasePropstypes. The rest ofForm/stylesstays internal.Codemod:
package-jsonno longer overwrites@skillsoft/*entries that are already listed, such as preview URLs. It had been writing^0.0.1, which 404s.*peer ranges now stay*.onlyNames). A new test fails if any row could rewrite a name its target doesn't export.mdx-imports: import/export statements in Storybook.mdxfiles.yarnrc:.yarnrc.ymlpackage lists.tsconfig-dom: a warning whenlibhas no"dom". Video used to supply the DOM types through the root import.resolutionsto avoid duplicate copies.Easier install (
46ad288ed)Consumers now need only
react,react-dom,@emotion/react, and@emotion/styledalongside@skillsoft/gamut. Before, they also had to add@emotion/cache,lodash,stylis, andtypescriptby hand.I checked this by installing packed tarballs into a fresh yarn project. The only peer warning left is yarn's implicit
@types/react.What changed:
gamut-styles:stylis,lodash, and@emotion/cacheare dependencies instead of peers.gamut-icons: the unusedlodashpeer is gone.variance: thetypescriptpeer is optional.@skillsoftpackages depend on each other with^ranges, so installs share onegamut-styles(one theme context).gamut-tests:component-test-setupis^0.3.1instead of*.gamut:@types/markedmoved to devDependencies.Third-party exact pins stay as they are. Loosening them re-resolved
react-aria-componentsfrom 1.7.1 to 1.21.1, and that upgrade should be tested separately.Verification
yarn nx test gamut: 1,276 tests pass, with the export snapshot updated.yarn nx test gamut-codemods: 33 tests pass, including fixture-driven tests with an idempotence check and the manifest type-check against built dist.nx verify(tsc),verify-package(publint), prettier, and eslint pass.yarn dedupe --checkstill fails, but that's already true on the base branch: it reports 129 packages there. I deduped the 13 that jscodeshift added, so this PR is back to that same 129.git archivesnapshots of mono (3,443 files changed) and platform (1,056), with 0 parse errors. The dirty-tree guard refused a dirty snapshot. platform'srspack.config.tscame out with six real singletons.@skillsoft/*into the snapshots or runtscthere.🤖 Generated with Claude Code