Skip to content

feat(gamut)!: promote deep imports to the root, renaming Menu and SelectDropdown elements - #41

Merged
dreamwasp merged 16 commits into
mainfrom
cass-gmt-1790-deep-imports
Oct 28, 2026
Merged

dreamwasp merged 16 commits into
mainfrom
cass-gmt-1790-deep-imports

Conversation

@dreamwasp

@dreamwasp dreamwasp commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Breaking change: /dist/ deep imports that have a public replacement are promoted to the package root. Menu's list elements and SelectDropdown's option component are renamed along the way, so they don't collide with the public List component and IconOption type.

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
  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 👈 this PR
  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

@skillsoft/gamut

Old (dist/Menu/elements, dist/Form/SelectDropdown/elements) New (@skillsoft/gamut)
List, ListProps MenuList, MenuListProps
ListItem, ListItemProps MenuListItem, MenuListItemProps
ListLink, ListLinkProps MenuListLink, MenuListLinkProps
ListButton MenuListButton
IconOption (the component) IconOptionComponent
  • Also exported from the root: MenuToolTipWrapper, formFieldStyles, formFieldPaddingStyles, conditionalStyles, and the HTMLToReactNode and ButtonBaseProps types. The rest of Form/styles stays internal.
  • Snapshot: the root export snapshot gains 9 runtime names.

Codemod

  • deep-imports rewrites known /dist/ paths to the root and merges them into an existing import from the same package.
  • Local names are kept: import { List } from '.../dist/Menu/elements' becomes import { MenuList as List } from '@skillsoft/gamut'.
  • Warnings:
    • names that stayed internal (for example, the rest of Form/styles)
    • ButtonBase, which has no public replacement
    • unknown deep imports
    • deep paths in mocks or require()
  • Manifest rows come from the GMT-1740 deep-import inventory. manifest.test.ts fails if a row could send a name to a target that doesn't export it.

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 73 tests to pass, including manifest.test.ts against the built dist.

  2. yarn nx test gamut. The export snapshot is updated, and Menu and SelectDropdown tests pass with the renames.

  3. yarn nx run gamut:verify.

  4. Build and run 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';\nimport { List } from '@codecademy/gamut/dist/Menu/elements';\nimport { ButtonBase } from '@codecademy/gamut/dist/ButtonBase/ButtonBase';\n" > a.tsx
    git add -A && git commit -qm init
    node <repo>/packages/gamut-codemods/dist/bin.js scope-swap .

    Expect import { Box, MenuList as List } from '@skillsoft/gamut';, and a [deep-imports] warning that ButtonBase is not public.

  5. Storybook: Menu and SelectDropdown stories look and behave as before.

PR Links and Envs

Repository PR Link
Mono N/A

🤖 Generated with Claude Code

dreamwasp and others added 3 commits October 20, 2026 10:07
…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>
…swap

scope-rename swaps @Codecademy/gamut* and eslint-plugin-gamut for their
@SkillSoft names in every module position and in comments. package-json,
mdx-imports, and yarnrc cover dependencies, MDX ESM blocks, and
.yarnrc.yml lists.

@codecademy/gamut-kit has no replacement, so package-json and mf-shared
expand it into the packages it bundled. In Module Federation config that
makes Gamut a real singleton, which the checklist calls out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ectDropdown elements

Exports formFieldStyles, formFieldPaddingStyles, conditionalStyles,
ButtonBaseProps, HTMLToReactNode, MenuToolTipWrapper, and Menu's list
elements from the root. The list elements and SelectDropdown's option
component are renamed (MenuList*, MenuListButton, IconOptionComponent) so
they don't collide with the public List component and IconOption type.

The deep-imports codemod rewrites known /dist/ paths to the root, keeps
local names across renames, merges into existing imports, and warns on
paths with no public replacement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dreamwasp and others added 7 commits October 20, 2026 11:10
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>
…migrations

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The package-json warning already names each range that's newer than the
fork point, so the extra next step only repeated it.

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

@LinKCoding LinKCoding left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

running scope-swap prints:

All done. 
Results: 
0 errors
0 unmodified
1 skipped
1 ok
Time elapsed: 0.759seconds 

— package.json and .eslintrc —
0 file(s) changed

— leftovers (0) —

— next steps —
1. Run your formatter and lint autofix (prettier --write, then eslint --fix). Split imports come out in recast style, `@skillsoft` sorts differently from `@codecademy` for import-order rules like simple-import-sort, and the shorter scope lets some wrapped imports fit on one line.
2. Reinstall (yarn), then type-check and run your tests.
3. Work through the warnings above and the leftovers list.

and checked SelectDD's icon and Menu stories and they load and working just as intended

import { ListItem } from '@codecademy/gamut/dist/Menu/elements';
import type { BoxProps } from '@codecademy/gamut';
import type { PopoverContainerProps } from '@codecademy/gamut/dist/PopoverContainer/types';
import { Box as Again } from '@codecademy/gamut/dist/Box/props';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious, why are we testing this?

my main gripe is that this repo is re-importing Box, where it seems like there should be a warning about that.

I guess if this is already done in practice, in order for the codemod to not break the code, then this is the path of least resistance. However, it still seems like a warning would be nice here (although I doubt it'd be hit, or I so really hope it doesn't get hit lol)

Base automatically changed from cass-gmt-1790-scope-rename to main October 28, 2026 12:47
Keep this branch's deep-imports migration and manifest rows alongside
main's Video work (moved-exports, markdown-video-overrides, tsconfig-dom)
and the codemods tests and changesets.

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

pkg-pr-new Bot commented Oct 28, 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@41
yarn add https://pkg.pr.new/Codecademy/skillsoft-gamut/@skillsoft/eslint-plugin-gamut@41.tgz

@skillsoft/gamut

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

@skillsoft/gamut-agent-tools

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

@skillsoft/gamut-codemods

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

@skillsoft/gamut-icons

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

@skillsoft/gamut-illustrations

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

@skillsoft/gamut-patterns

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

@skillsoft/gamut-styles

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

@skillsoft/gamut-tests

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

@skillsoft/variance

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

commit: dbf3e57

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

@dreamwasp
dreamwasp merged commit 1a63454 into main Oct 28, 2026
11 checks passed
@dreamwasp
dreamwasp deleted the cass-gmt-1790-deep-imports branch October 28, 2026 14:26
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