@elliemae/pui-cli 9.0.0-alpha.10 → 9.0.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/build/docs/404.html +2 -2
- package/build/docs/api/functions/loadRoutes/index.html +2 -2
- package/build/docs/api/index.html +2 -2
- package/build/docs/api/type-aliases/LIB_NAME/index.html +2 -2
- package/build/docs/api/variables/babelConfig/index.html +2 -2
- package/build/docs/api/variables/commitlintConfig/index.html +2 -2
- package/build/docs/api/variables/eslintBaseConfig/index.html +2 -2
- package/build/docs/api/variables/eslintConfig/index.html +2 -2
- package/build/docs/api/variables/eslintFlatBaseConfig/index.html +2 -2
- package/build/docs/api/variables/eslintFlatBaseConfigStrict/index.html +2 -2
- package/build/docs/api/variables/eslintFlatConfig/index.html +2 -2
- package/build/docs/api/variables/eslintFlatConfigStrict/index.html +2 -2
- package/build/docs/api/variables/jestConfig/index.html +2 -2
- package/build/docs/api/variables/jestNodeConfig/index.html +2 -2
- package/build/docs/api/variables/lintStagedConfig/index.html +2 -2
- package/build/docs/api/variables/prettierConfig/index.html +2 -2
- package/build/docs/api/variables/stylelintConfig/index.html +2 -2
- package/build/docs/api/variables/vitestConfig/index.html +2 -2
- package/build/docs/assets/js/04ee7372.2852111b.js +1 -0
- package/build/docs/assets/js/13097d8d.7877421c.js +1 -0
- package/build/docs/assets/js/4fb6949f.69e375e4.js +1 -0
- package/build/docs/assets/js/{main.00e13c37.js → main.d5acb4ca.js} +2 -2
- package/build/docs/assets/js/{runtime~main.cb214d1a.js → runtime~main.4f7cd700.js} +1 -1
- package/build/docs/eslint-rules-migration/index.html +6 -6
- package/build/docs/index.html +2 -2
- package/build/docs/pui-cli-9-migration/index.html +93 -6
- package/build/docs/ssl-certificate-setup/index.html +2 -2
- package/build/docs/stylelint-migration/index.html +2 -2
- package/build/docs/usage-guide/index.html +4 -4
- package/dist/cjs/commands/storybook.js +33 -4
- package/dist/cjs/lint-config/eslint/flat/compat.mjs +5 -5
- package/dist/cjs/skills/migrate-storybook-out-of-cjs/SKILL.md +188 -0
- package/dist/cjs/skills/migrate-to-pui-cli-9/SKILL.md +131 -18
- package/dist/cjs/testing/jest.config.cjs +5 -1
- package/dist/cjs/testing/setup-textencoder.cjs +4 -0
- package/dist/cjs/webpack/webpack.storybook.js +62 -0
- package/dist/esm/commands/storybook.js +22 -4
- package/dist/esm/lint-config/eslint/flat/compat.mjs +5 -5
- package/dist/esm/skills/migrate-storybook-out-of-cjs/SKILL.md +188 -0
- package/dist/esm/skills/migrate-to-pui-cli-9/SKILL.md +131 -18
- package/dist/esm/testing/jest.config.cjs +5 -1
- package/dist/esm/testing/setup-textencoder.cjs +4 -0
- package/dist/esm/webpack/webpack.storybook.js +61 -0
- package/dist/types/lib/commands/storybook.d.ts +1 -0
- package/dist/types/lib/lint-config/eslint/flat/compat.d.mts +1 -1
- package/dist/types/lib/testing/setup-textencoder.d.cts +1 -0
- package/dist/types/lib/webpack/webpack.storybook.d.ts +2 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/lib/lint-config/eslint/flat/compat.mjs +5 -5
- package/lib/skills/migrate-storybook-out-of-cjs/SKILL.md +188 -0
- package/lib/skills/migrate-to-pui-cli-9/SKILL.md +131 -18
- package/package.json +18 -25
- package/build/docs/assets/js/04ee7372.eaa386ed.js +0 -1
- package/build/docs/assets/js/13097d8d.c1821d28.js +0 -1
- package/build/docs/assets/js/4fb6949f.369cc1b9.js +0 -1
- /package/build/docs/assets/js/{main.00e13c37.js.LICENSE.txt → main.d5acb4ca.js.LICENSE.txt} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(globalThis.webpackChunk_elliemae_pui_cli=globalThis.webpackChunk_elliemae_pui_cli||[]).push([[5908],{4391(e,n,i){i.r(n),i.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"usage-guide","title":"Usage Guide","description":"This guide provides detailed documentation for all available commands in @elliemae/pui-cli.","source":"@site/docs/usage-guide.md","sourceDirName":".","slug":"/usage-guide","permalink":"/cli/usage-guide","draft":false,"unlisted":false,"editUrl":"https://git.elliemae.io/platform-ui/pui-cli.git/docs/usage-guide.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docsSidebar","previous":{"title":"Stylelint migration guide (pui-cli 8 \u2192 9 / Stylelint 17)","permalink":"/cli/stylelint-migration"}}');var l=i(6070),r=i(6607);const c={},d="Usage Guide",t={},o=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Build Commands",id:"build-commands",level:2},{value:"<code>pui-cli build</code>",id:"pui-cli-build",level:3},{value:"<code>pui-cli buildCDN</code>",id:"pui-cli-buildcdn",level:3},{value:"<code>pui-cli pack</code>",id:"pui-cli-pack",level:3},{value:"Development Commands",id:"development-commands",level:2},{value:"<code>pui-cli start</code>",id:"pui-cli-start",level:3},{value:"<code>pui-cli storybook</code>",id:"pui-cli-storybook",level:3},{value:"Testing Commands",id:"testing-commands",level:2},{value:"<code>pui-cli test</code>",id:"pui-cli-test",level:3},{value:"<code>pui-cli vitest</code>",id:"pui-cli-vitest",level:3},{value:"Linting Commands",id:"linting-commands",level:2},{value:"<code>pui-cli lint</code>",id:"pui-cli-lint",level:3},{value:"<code>pui-cli tscheck</code>",id:"pui-cli-tscheck",level:3},{value:"Documentation Commands",id:"documentation-commands",level:2},{value:"<code>pui-cli gendoc</code>",id:"pui-cli-gendoc",level:3},{value:"Utility Commands",id:"utility-commands",level:2},{value:"<code>pui-cli version</code>",id:"pui-cli-version",level:3},{value:"<code>pui-cli codemod</code>",id:"pui-cli-codemod",level:3},{value:"<code>pui-cli skills</code>",id:"pui-cli-skills",level:3},{value:"Advanced Usage",id:"advanced-usage",level:2},{value:"Using pui-cli in npm scripts",id:"using-pui-cli-in-npm-scripts",level:3},{value:"CI/CD Integration",id:"cicd-integration",level:3},{value:"Using Exported Configurations",id:"using-exported-configurations",level:3},{value:"Configuration Priority",id:"configuration-priority",level:2},{value:"Best Practices",id:"best-practices",level:2},{value:"Development Workflow",id:"development-workflow",level:3},{value:"Library Development Workflow",id:"library-development-workflow",level:3},{value:"Performance Tips",id:"performance-tips",level:3},{value:"Framework Chunk Splitting",id:"framework-chunk-splitting",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Build Issues",id:"build-issues",level:3},{value:"Test Issues",id:"test-issues",level:3},{value:"Linting Issues",id:"linting-issues",level:3},{value:"Additional Resources",id:"additional-resources",level:2},{value:"Need Help?",id:"need-help",level:2}];function a(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"usage-guide",children:"Usage Guide"})}),"\n",(0,l.jsxs)(n.p,{children:["This guide provides detailed documentation for all available commands in ",(0,l.jsx)(n.code,{children:"@elliemae/pui-cli"}),"."]}),"\n",(0,l.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#build-commands",children:"Build Commands"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#development-commands",children:"Development Commands"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#testing-commands",children:"Testing Commands"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#linting-commands",children:"Linting Commands"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#documentation-commands",children:"Documentation Commands"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#utility-commands",children:"Utility Commands"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"#framework-chunk-splitting",children:"Framework Chunk Splitting"})}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"build-commands",children:"Build Commands"}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-build",children:(0,l.jsx)(n.code,{children:"pui-cli build"})}),"\n",(0,l.jsx)(n.p,{children:"Builds your application for production."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli build [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-p, --prod"})," - Production build with optimizations"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Build web application (development)\npui-cli build\n\n# Build web application (production)\npui-cli build -p\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Output:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Application builds go to ",(0,l.jsx)(n.code,{children:"build/"})," or ",(0,l.jsx)(n.code,{children:"dist/"})," directory"]}),"\n",(0,l.jsx)(n.li,{children:"Creates optimized bundles with code splitting"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Bundles code using Webpack"}),"\n",(0,l.jsx)(n.li,{children:"Minifies JavaScript and CSS"}),"\n",(0,l.jsx)(n.li,{children:"Generates source maps"}),"\n",(0,l.jsx)(n.li,{children:"Optimizes assets"}),"\n",(0,l.jsx)(n.li,{children:"Creates production-ready build"}),"\n",(0,l.jsx)(n.li,{children:"Applies tree shaking for smaller bundles"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-buildcdn",children:(0,l.jsx)(n.code,{children:"pui-cli buildCDN"})}),"\n",(0,l.jsx)(n.p,{children:"Builds the application for CDN deployment."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli buildCDN\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Creates CDN-optimized builds"}),"\n",(0,l.jsx)(n.li,{children:"Generates proper asset paths for CDN"}),"\n",(0,l.jsx)(n.li,{children:"Optimizes bundle splitting"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-pack",children:(0,l.jsx)(n.code,{children:"pui-cli pack"})}),"\n",(0,l.jsx)(n.p,{children:"Packages your library for distribution with multiple output formats."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli pack [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-p, --prod"})," - Production build with minification"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-t, --target <target>"})," - Build target (default: browser, options: node, browser)"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Build library (development)\npui-cli pack\n\n# Build library (production)\npui-cli pack -p\n\n# Build for Node.js target\npui-cli pack -p -t node\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Output:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Creates ",(0,l.jsx)(n.code,{children:"dist/"})," directory with:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"dist/esm/"})," - ES Module format"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"dist/cjs/"})," - CommonJS format"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"dist/types/"})," - TypeScript declarations"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"dist/umd/"})," - UMD format (browser)"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Builds library in multiple formats (ESM, CJS, UMD)"}),"\n",(0,l.jsx)(n.li,{children:"Generates TypeScript declaration files"}),"\n",(0,l.jsx)(n.li,{children:"Minifies code in production mode"}),"\n",(0,l.jsx)(n.li,{children:"Creates source maps"}),"\n",(0,l.jsx)(n.li,{children:"Validates package.json exports"}),"\n",(0,l.jsx)(n.li,{children:"Optimized for tree-shaking"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h2,{id:"development-commands",children:"Development Commands"}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-start",children:(0,l.jsx)(n.code,{children:"pui-cli start"})}),"\n",(0,l.jsx)(n.p,{children:"Starts the development server with hot module replacement."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli start [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-p, --prod"})," - Start in production mode"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--port <number>"})," - Specify port (default: 3000)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--open"})," - Automatically open browser"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--hot"})," - Enable hot module replacement (default: true)"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Start on default port (development)\npui-cli start\n\n# Start in production mode\npui-cli start -p\n# or\npnpm start:prod\n\n# Start on custom port\npui-cli start --port 8080\n\n# Start and open browser\npui-cli start --open\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Starts Webpack dev server"}),"\n",(0,l.jsx)(n.li,{children:"Enables hot module replacement"}),"\n",(0,l.jsx)(n.li,{children:"Serves static files"}),"\n",(0,l.jsx)(n.li,{children:"Provides mock API endpoints"}),"\n",(0,l.jsx)(n.li,{children:"Auto-reloads on file changes"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Environment Variables:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-env",children:"PORT=3000\nHOST=localhost\nHTTPS=false\n"})}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-storybook",children:(0,l.jsx)(n.code,{children:"pui-cli storybook"})}),"\n",(0,l.jsx)(n.p,{children:"Runs Storybook for component development and documentation."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli storybook [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-b, --build"})," - Build static storybook"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--docs"})," - Run in documentation mode"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--port <number>"})," - Specify port (default: 6006)"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Start Storybook dev server\npui-cli storybook\n\n# Start with documentation mode\npui-cli storybook --docs\n\n# Build static Storybook\npui-cli storybook -b\n\n# Build with documentation mode\npui-cli storybook -b --docs\n\n# Run on custom port\npui-cli storybook --port 9000\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Starts Storybook development server"}),"\n",(0,l.jsx)(n.li,{children:"Provides interactive component playground"}),"\n",(0,l.jsx)(n.li,{children:"Generates component documentation"}),"\n",(0,l.jsx)(n.li,{children:"Useful for library development"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h2,{id:"testing-commands",children:"Testing Commands"}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-test",children:(0,l.jsx)(n.code,{children:"pui-cli test"})}),"\n",(0,l.jsx)(n.p,{children:"Runs Jest tests with coverage reporting."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli test [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-f, --fix"})," - Update snapshots (",(0,l.jsx)(n.code,{children:"-u"}),")"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"-p, --prod"})," - Run tests in production mode"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--watch"})," - Run tests in watch mode"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--debug"})," - Run tests in debug mode"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--coverage"})," - Generate coverage reports (default: true)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--passWithNoTests"})," - Don't fail if no tests found"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--bail"})," - Stop on first test failure"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--findRelatedTests"})," - Run tests related to changed files"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Run all tests with coverage\npui-cli test\n\n# Run tests in production mode\npui-cli test -p\n\n# Run in watch mode\npnpm test:watch\n\n# Update snapshots\npui-cli test -f\n# or\npnpm test:fix\n\n# Debug tests\npui-cli test --debug\n# or\npnpm test:debug\n\n# Run only tests related to changed files (useful for pre-commit)\npui-cli test --coverage --passWithNoTests --bail --findRelatedTests\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Executes Jest test runner"}),"\n",(0,l.jsxs)(n.li,{children:["Generates coverage reports in ",(0,l.jsx)(n.code,{children:"reports/"})," directory"]}),"\n",(0,l.jsx)(n.li,{children:"Supports React Testing Library"}),"\n",(0,l.jsx)(n.li,{children:"Provides snapshot testing"}),"\n",(0,l.jsx)(n.li,{children:"Generates HTML coverage reports"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Coverage Reports:"})}),"\n",(0,l.jsx)(n.p,{children:"After running tests, view coverage at:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"reports/index.html"})," - Overall coverage report"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"reports/lcov-report/index.html"})," - Detailed line coverage"]}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-vitest",children:(0,l.jsx)(n.code,{children:"pui-cli vitest"})}),"\n",(0,l.jsx)(n.p,{children:"Runs Vitest for modern, fast testing."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli vitest [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--watch"})," - Run in watch mode"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--ui"})," - Open Vitest UI"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--coverage"})," - Generate coverage"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Run tests\npui-cli vitest\n\n# Run with UI\npui-cli vitest --ui\n\n# Run in watch mode\npui-cli vitest --watch\n\n# Generate coverage\npui-cli vitest --coverage\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Provides fast test execution with Vite"}),"\n",(0,l.jsx)(n.li,{children:"Supports ESM natively"}),"\n",(0,l.jsx)(n.li,{children:"Offers visual test UI"}),"\n",(0,l.jsx)(n.li,{children:"Compatible with Jest syntax"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h2,{id:"linting-commands",children:"Linting Commands"}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-lint",children:(0,l.jsx)(n.code,{children:"pui-cli lint"})}),"\n",(0,l.jsx)(n.p,{children:"Lints your codebase for code quality and style issues."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli lint [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--fix"})," - Automatically fix linting issues"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--js"})," - Lint JavaScript/TypeScript files only"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--css"})," - Lint CSS/SCSS files only"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--commit"})," - Lint commit messages"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--debug"})," - Show detailed error messages"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Lint all files\npui-cli lint\n\n# Auto-fix issues\npui-cli lint --fix\n\n# Lint only JavaScript files\npui-cli lint --js\n\n# Lint only CSS files\npui-cli lint --css\n\n# Lint commit messages\npui-cli lint --commit\n\n# Show debug information\npui-cli lint --debug\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Runs ESLint on JavaScript/TypeScript files"}),"\n",(0,l.jsx)(n.li,{children:"Runs Stylelint on CSS/SCSS files"}),"\n",(0,l.jsx)(n.li,{children:"Runs Commitlint on commit messages"}),"\n",(0,l.jsx)(n.li,{children:"Enforces code style consistency"}),"\n",(0,l.jsx)(n.li,{children:"Checks for common errors and anti-patterns"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Linting Rules:"})}),"\n",(0,l.jsx)(n.p,{children:"The CLI provides pre-configured rules for:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"ESLint"}),": React, TypeScript, Jest best practices"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Stylelint"}),": CSS best practices and conventions"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Commitlint"}),": Conventional Commits format"]}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-tscheck",children:(0,l.jsx)(n.code,{children:"pui-cli tscheck"})}),"\n",(0,l.jsx)(n.p,{children:"Type-checks TypeScript files without emitting output."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli tscheck [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--files"})," - Check specific files only"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--watch"})," - Watch mode for continuous type checking"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--debug"})," - Show detailed TypeScript errors"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Check all types\npui-cli tscheck\n\n# Check with file listing\npui-cli tscheck --files\n\n# Watch for changes\npui-cli tscheck --watch\n\n# Show detailed errors\npui-cli tscheck --debug\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Runs TypeScript compiler in check mode"}),"\n",(0,l.jsx)(n.li,{children:"Reports type errors"}),"\n",(0,l.jsx)(n.li,{children:"Doesn't emit JavaScript files"}),"\n",(0,l.jsx)(n.li,{children:"Useful for CI/CD pipelines"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h2,{id:"documentation-commands",children:"Documentation Commands"}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-gendoc",children:(0,l.jsx)(n.code,{children:"pui-cli gendoc"})}),"\n",(0,l.jsx)(n.p,{children:"Generates API documentation from your code."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli gendoc\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Generates TypeDoc documentation"}),"\n",(0,l.jsx)(n.li,{children:"Extracts JSDoc comments"}),"\n",(0,l.jsx)(n.li,{children:"Creates HTML documentation"}),"\n",(0,l.jsxs)(n.li,{children:["Outputs to ",(0,l.jsx)(n.code,{children:"docs/api/"})," directory"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Example JSDoc comments:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-typescript",children:"/**\n * Adds two numbers together\n * @param a - First number\n * @param b - Second number\n * @returns The sum of a and b\n * @example\n * ```ts\n * add(2, 3) // returns 5\n * ```\n */\nexport function add(a: number, b: number): number {\n return a + b;\n}\n"})}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h2,{id:"utility-commands",children:"Utility Commands"}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-version",children:(0,l.jsx)(n.code,{children:"pui-cli version"})}),"\n",(0,l.jsx)(n.p,{children:"Manages versioning for monorepo workspaces."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli version [options]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--set <version>"})," - Set specific version for all packages"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--workspace"})," - Update workspace package versions"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Update versions in monorepo\npui-cli version --workspace\n\n# Set specific version\npui-cli version --set 2.0.0\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Updates package.json versions"}),"\n",(0,l.jsx)(n.li,{children:"Maintains version consistency in monorepos"}),"\n",(0,l.jsx)(n.li,{children:"Updates dependency versions"}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-codemod",children:(0,l.jsx)(n.code,{children:"pui-cli codemod"})}),"\n",(0,l.jsx)(n.p,{children:"Runs code transformations using jscodeshift."}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli codemod <transform>\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Arguments:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"<transform>"})," - Name of the transform to apply"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Applies automated code transformations"}),"\n",(0,l.jsx)(n.li,{children:"Useful for migrations"}),"\n",(0,l.jsx)(n.li,{children:"Batch code refactoring"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"pui-cli-skills",children:(0,l.jsx)(n.code,{children:"pui-cli skills"})}),"\n",(0,l.jsxs)(n.p,{children:["Installs bundled agent skills from ",(0,l.jsx)(n.code,{children:"@elliemae/pui-cli"})," into the current repo."]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Usage:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pui-cli skills list\npui-cli skills install [name] [--target <target>] [--force]\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Options:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"--target"})," \u2014 ",(0,l.jsx)(n.code,{children:"cursor"})," (default), ",(0,l.jsx)(n.code,{children:"claude"}),", ",(0,l.jsx)(n.code,{children:"copilot"}),", or ",(0,l.jsx)(n.code,{children:"all"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"cursor"})," \u2192 ",(0,l.jsx)(n.code,{children:".cursor/skills/"})]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"claude"})," \u2192 ",(0,l.jsx)(n.code,{children:".claude/skills/"})]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"copilot"})," \u2192 ",(0,l.jsx)(n.code,{children:".github/skills/"})]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"all"})," \u2192 all three paths (recommended for mixed teams)"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Examples:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# List bundled skills shipped with this pui-cli version\npnpm exec pui-cli skills list\n\n# Install for Cursor, Claude Code, and GitHub Copilot\npnpm exec pui-cli skills install migrate-to-pui-cli-9 --target all\n\n# Install for Cursor only (default)\npnpm exec pui-cli skills install migrate-to-pui-cli-9\n\n# Install for Claude Code only\npnpm exec pui-cli skills install migrate-to-pui-cli-9 --target claude\n\n# Overwrite an existing skill directory\npnpm exec pui-cli skills install migrate-to-pui-cli-9 --target all --force\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"What it does:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Copies ",(0,l.jsx)(n.code,{children:"lib/skills/<name>/"})," from the installed package into the target skill directories"]}),"\n",(0,l.jsxs)(n.li,{children:["Uses the shared Agent Skills ",(0,l.jsx)(n.code,{children:"SKILL.md"})," format (works across Cursor, Claude Code, and Copilot)"]}),"\n",(0,l.jsxs)(n.li,{children:["See ",(0,l.jsx)(n.a,{href:"/cli/pui-cli-9-migration",children:"pui-cli 9 migration guide"})," for the full upgrade path"]}),"\n"]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.h2,{id:"advanced-usage",children:"Advanced Usage"}),"\n",(0,l.jsx)(n.h3,{id:"using-pui-cli-in-npm-scripts",children:"Using pui-cli in npm scripts"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"package.json example:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "dev": "pui-cli start",\n "build": "pui-cli build",\n "build:lib": "pui-cli build --service",\n "test": "pui-cli test --coverage",\n "test:watch": "pui-cli test --watch",\n "test:debug": "pui-cli test --debug",\n "lint": "pui-cli lint",\n "lint:fix": "pui-cli lint --fix",\n "lint:js": "pui-cli lint --js --fix",\n "lint:css": "pui-cli lint --css --fix",\n "typecheck": "pui-cli tscheck",\n "storybook": "pui-cli storybook",\n "storybook:build": "pui-cli storybook --build",\n "gendoc": "pui-cli gendoc",\n "pack": "pui-cli pack",\n "precommit": "lint-staged"\n }\n}\n'})}),"\n",(0,l.jsx)(n.h3,{id:"cicd-integration",children:"CI/CD Integration"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Jenkins example:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-groovy",children:"pipeline {\n agent any\n stages {\n stage('Install') {\n steps {\n sh 'pnpm install'\n }\n }\n stage('Lint') {\n steps {\n sh 'pnpm lint'\n }\n }\n stage('Type Check') {\n steps {\n sh 'pnpm tscheck'\n }\n }\n stage('Test') {\n steps {\n sh 'pnpm test'\n }\n }\n stage('Build') {\n steps {\n sh 'pnpm build'\n }\n }\n }\n}\n"})}),"\n",(0,l.jsx)(n.h3,{id:"using-exported-configurations",children:"Using Exported Configurations"}),"\n",(0,l.jsx)(n.p,{children:"You can import and extend the CLI's configurations in your own config files:"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"ESLint:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-javascript",children:"import { eslintConfig } from '@elliemae/pui-cli';\n\nexport default [\n ...eslintConfig,\n {\n rules: {\n // Your custom rules\n 'no-console': 'warn',\n },\n },\n];\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Prettier:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-javascript",children:"import { prettierConfig } from '@elliemae/pui-cli';\n\nexport default {\n ...prettierConfig,\n // Your custom overrides\n printWidth: 100,\n};\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Vitest:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-typescript",children:"import { defineConfig } from 'vitest/config';\nimport { vitestConfig } from '@elliemae/pui-cli/vitest';\n\nexport default defineConfig({\n ...vitestConfig,\n test: {\n ...vitestConfig.test,\n // Your custom test config\n },\n});\n"})}),"\n",(0,l.jsx)(n.h2,{id:"configuration-priority",children:"Configuration Priority"}),"\n",(0,l.jsx)(n.p,{children:"The CLI follows this priority order for configuration:"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"Project-level configuration files"}),"\n",(0,l.jsx)(n.li,{children:"CLI's default configurations"}),"\n",(0,l.jsx)(n.li,{children:"Command-line arguments"}),"\n",(0,l.jsx)(n.li,{children:"Environment variables"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,l.jsx)(n.h3,{id:"development-workflow",children:"Development Workflow"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Start development server:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm start\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Run tests in watch mode (separate terminal):"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm test --watch\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Type check (separate terminal):"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm tscheck --watch\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Before committing:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm lint:fix\npnpm test\npnpm typecheck\n"})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"library-development-workflow",children:"Library Development Workflow"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Start Storybook:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm storybook\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Run tests in watch mode:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm test --watch\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Build library:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm build --service\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Test package:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm pack\n"})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"performance-tips",children:"Performance Tips"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Use ",(0,l.jsx)(n.code,{children:"--findRelatedTests"})," to run only relevant tests"]}),"\n",(0,l.jsxs)(n.li,{children:["Enable ",(0,l.jsx)(n.code,{children:"--watch"})," mode during development"]}),"\n",(0,l.jsxs)(n.li,{children:["Use ",(0,l.jsx)(n.code,{children:"--silent"})," in CI to reduce output"]}),"\n",(0,l.jsxs)(n.li,{children:["Run ",(0,l.jsx)(n.code,{children:"lint --js"})," and ",(0,l.jsx)(n.code,{children:"lint --css"})," separately for faster feedback"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"framework-chunk-splitting",children:"Framework Chunk Splitting"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"pui-cli"})," supports an opt-in ",(0,l.jsx)(n.strong,{children:"framework chunk"})," that separates React core libraries into a dedicated bundle. Because the framework changes far less frequently than other vendor dependencies, this improves long-term browser caching and reduces the amount of JavaScript users re-download on routine releases."]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"How it works"})}),"\n",(0,l.jsx)(n.p,{children:"When enabled, the production (and dev) Webpack build creates three vendor-level chunks instead of two:"}),"\n",(0,l.jsxs)(n.table,{children:[(0,l.jsx)(n.thead,{children:(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.th,{children:"Chunk"}),(0,l.jsx)(n.th,{children:"Contents"})]})}),(0,l.jsxs)(n.tbody,{children:[(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{children:(0,l.jsx)(n.code,{children:"emui.js"})}),(0,l.jsxs)(n.td,{children:[(0,l.jsx)(n.code,{children:"@elliemae/*"})," packages (design system, SDK, diagnostics, etc.)"]})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{children:(0,l.jsx)(n.code,{children:"framework.js"})}),(0,l.jsxs)(n.td,{children:[(0,l.jsx)(n.code,{children:"react"}),", ",(0,l.jsx)(n.code,{children:"react-dom"}),", ",(0,l.jsx)(n.code,{children:"scheduler"}),", ",(0,l.jsx)(n.code,{children:"react-router"}),", ",(0,l.jsx)(n.code,{children:"react-router-dom"}),", ",(0,l.jsx)(n.code,{children:"history"}),", ",(0,l.jsx)(n.code,{children:"react-is"})]})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{children:(0,l.jsx)(n.code,{children:"vendors.js"})}),(0,l.jsxs)(n.td,{children:["Everything else from ",(0,l.jsx)(n.code,{children:"node_modules"})]})]})]})]}),"\n",(0,l.jsxs)(n.p,{children:["Without the flag, the default two-chunk layout is preserved (",(0,l.jsx)(n.code,{children:"emui.js"})," + ",(0,l.jsx)(n.code,{children:"vendors.js"}),")."]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Enabling the flag"})}),"\n",(0,l.jsxs)(n.p,{children:["Add the following to your application's ",(0,l.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-env",children:"SPLIT_FRAMEWORK_CHUNK=true\n"})}),"\n",(0,l.jsxs)(n.p,{children:["The flag is read at build time. No changes to ",(0,l.jsx)(n.code,{children:"pui-cli"})," itself are needed."]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Required application updates"})}),"\n",(0,l.jsxs)(n.p,{children:["After enabling the flag you must update three places in your application to include ",(0,l.jsx)(n.code,{children:"framework.js"})," in the script loading order."]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsxs)(n.strong,{children:["1. ",(0,l.jsx)(n.code,{children:"index-app-loader.html"})]})}),"\n",(0,l.jsxs)(n.p,{children:["If your application uses ",(0,l.jsx)(n.code,{children:"pui-app-loader"}),", update the ",(0,l.jsx)(n.code,{children:"bodyScripts"})," array to include ",(0,l.jsx)(n.code,{children:"framework.js"})," ",(0,l.jsx)(n.strong,{children:"before"})," ",(0,l.jsx)(n.code,{children:"vendors.js"}),":"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-javascript",children:"emuiAppLoader.load({\n appId: 'loanapp',\n headScripts: [],\n bodyScripts: ['runtime~app.js', 'framework.js', 'vendors.js', 'emui.js', 'app.js'],\n styles: ['vendors.css', 'emui.css'],\n isJsModule: true,\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsxs)(n.strong,{children:["2. ",(0,l.jsx)(n.code,{children:"app.config.json"})," \u2014 ",(0,l.jsx)(n.code,{children:"microFrontendApps"})," file lists"]})}),"\n",(0,l.jsxs)(n.p,{children:["Any microapp built with the framework chunk enabled must list ",(0,l.jsx)(n.code,{children:"framework.js"})," in its ",(0,l.jsx)(n.code,{children:"development.files"})," and ",(0,l.jsx)(n.code,{children:"production.files"})," arrays. The host app's ",(0,l.jsx)(n.code,{children:"app.config.json"})," must reflect this so that ",(0,l.jsx)(n.code,{children:"app-bridge"})," loads the scripts in the correct order."]}),"\n",(0,l.jsx)(n.p,{children:"Development example:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "microFrontendApps": {\n "myapp": {\n "name": "My App",\n "hostUrl": "./myapp",\n "development": {\n "files": [\n "https://cdn.mortgagetech.q1.ice.com/pui-diagnostics@3",\n "https://cdn.mortgagetech.q1.ice.com/pui-logrocket@1",\n "js/global.js",\n "framework.js",\n "emui.js",\n "vendors.js",\n "app.js"\n ]\n }\n }\n }\n}\n'})}),"\n",(0,l.jsx)(n.p,{children:"Production example:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",children:'{\n "microFrontendApps": {\n "myapp": {\n "name": "My App",\n "hostUrl": "./myapp",\n "production": {\n "files": [\n "https://cdn.mortgagetech.q1.ice.com/pui-diagnostics@3",\n "https://cdn.mortgagetech.q1.ice.com/pui-logrocket@1",\n "js/global.js",\n "runtime~app.js",\n "framework.js",\n "emui.js",\n "vendors.js",\n "app.js",\n "emui.css",\n "vendors.css"\n ]\n }\n }\n }\n}\n'})}),"\n",(0,l.jsxs)(n.blockquote,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Load order matters."})," ",(0,l.jsx)(n.code,{children:"framework.js"})," must appear before ",(0,l.jsx)(n.code,{children:"vendors.js"})," and ",(0,l.jsx)(n.code,{children:"emui.js"})," because both depend on React."]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"3. Verify the build output"})}),"\n",(0,l.jsx)(n.p,{children:"After enabling the flag, run a production build and confirm the new chunk appears:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"pnpm build\nls build/latest/js/framework.*.js\n"})}),"\n",(0,l.jsxs)(n.p,{children:["You should see a hashed file like ",(0,l.jsx)(n.code,{children:"framework.abc123.js"})," alongside the existing ",(0,l.jsx)(n.code,{children:"emui"}),", ",(0,l.jsx)(n.code,{children:"vendors"}),", and ",(0,l.jsx)(n.code,{children:"app"})," chunks."]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Disabling the flag"})}),"\n",(0,l.jsxs)(n.p,{children:["Remove ",(0,l.jsx)(n.code,{children:"SPLIT_FRAMEWORK_CHUNK=true"})," from ",(0,l.jsx)(n.code,{children:".env"})," (or set it to ",(0,l.jsx)(n.code,{children:"false"}),"), then reverse the file-list changes above \u2014 remove ",(0,l.jsx)(n.code,{children:"framework.js"})," from ",(0,l.jsx)(n.code,{children:"index-app-loader.html"})," and ",(0,l.jsx)(n.code,{children:"app.config.json"}),". The build will revert to the default two-chunk layout."]}),"\n",(0,l.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,l.jsx)(n.h3,{id:"build-issues",children:"Build Issues"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Error: Module not found"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Clear cache and rebuild\nrm -rf node_modules dist\npnpm install\npnpm build\n"})}),"\n",(0,l.jsx)(n.h3,{id:"test-issues",children:"Test Issues"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Error: Tests timing out"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Increase timeout in jest.config\npui-cli test --debug\n"})}),"\n",(0,l.jsx)(n.h3,{id:"linting-issues",children:"Linting Issues"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Error: Too many linting errors"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Fix automatically\npnpm lint --fix\n\n# Fix only JS\npnpm lint --js --fix\n\n# Fix only CSS\npnpm lint --css --fix\n"})}),"\n",(0,l.jsx)(n.h2,{id:"additional-resources",children:"Additional Resources"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"/cli/#getting-started",children:"Getting Started Guide"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"./api/",children:"API Documentation"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://git.elliemae.io/platform-ui/pui-cli#migration-guide",children:"Migration Guide"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://git.elliemae.io/platform-ui/pui-cli",children:"GitHub Repository"})}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"need-help",children:"Need Help?"}),"\n",(0,l.jsx)(n.p,{children:"If you encounter issues or have questions:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Review the documentation"}),"\n",(0,l.jsx)(n.li,{children:"Contact the UI Platform team via ui-platform teams channel"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},6607(e,n,i){i.d(n,{R:()=>c,x:()=>d});var s=i(758);const l={},r=s.createContext(l);function c(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(globalThis.webpackChunk_elliemae_pui_cli=globalThis.webpackChunk_elliemae_pui_cli||[]).push([[5455],{2668(e,i,n){n.r(i),n.d(i,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>c,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"pui-cli-9-migration","title":"pui-cli 9 migration guide","description":"This guide helps PUI consumers upgrade apps and libraries from pui-cli 8 to pui-cli 9.","source":"@site/docs/pui-cli-9-migration.md","sourceDirName":".","slug":"/pui-cli-9-migration","permalink":"/cli/pui-cli-9-migration","draft":false,"unlisted":false,"editUrl":"https://git.elliemae.io/platform-ui/pui-cli.git/docs/pui-cli-9-migration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docsSidebar","previous":{"title":"PUI CLI Documentation","permalink":"/cli/"},"next":{"title":"Trust SSL Certificate Guide","permalink":"/cli/ssl-certificate-setup"}}');var l=n(6070),r=n(6607);const c={},t="pui-cli 9 migration guide",d={},o=[{value:"At a glance",id:"at-a-glance",level:2},{value:"Recommended rollout",id:"recommended-rollout",level:2},{value:"Step-by-step",id:"step-by-step",level:2},{value:"1. Upgrade toolchain",id:"1-upgrade-toolchain",level:3},{value:"2. Upgrade pui-cli",id:"2-upgrade-pui-cli",level:3},{value:"3. Add flat ESLint config",id:"3-add-flat-eslint-config",level:3},{value:"4. Update Stylelint config",id:"4-update-stylelint-config",level:3},{value:"5. Fix lint",id:"5-fix-lint",level:3},{value:"6. Install the migration skill (optional)",id:"6-install-the-migration-skill-optional",level:3},{value:"Temporary overrides",id:"temporary-overrides",level:2},{value:"Strict config (after cleanup)",id:"strict-config-after-cleanup",level:2},{value:"Husky 9",id:"husky-9",level:2},{value:"Vitest 4",id:"vitest-4",level:2},{value:"semantic-release 25",id:"semantic-release-25",level:2},{value:"1. Upgrade semantic-release (if pinned locally)",id:"1-upgrade-semantic-release-if-pinned-locally",level:3},{value:"2. Migrate release config to ESM",id:"2-migrate-release-config-to-esm",level:3},{value:"3. Custom plugins or overrides",id:"3-custom-plugins-or-overrides",level:3},{value:"4. Verify locally",id:"4-verify-locally",level:3},{value:"Agent-assisted migration",id:"agent-assisted-migration",level:3},{value:"CI checklist",id:"ci-checklist",level:2},{value:"Getting help",id:"getting-help",level:2}];function a(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",input:"input",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.header,{children:(0,l.jsx)(i.h1,{id:"pui-cli-9-migration-guide",children:"pui-cli 9 migration guide"})}),"\n",(0,l.jsxs)(i.p,{children:["This guide helps PUI consumers upgrade apps and libraries from ",(0,l.jsx)(i.strong,{children:"pui-cli 8"})," to ",(0,l.jsx)(i.strong,{children:"pui-cli 9"}),".\nFor ESLint rule-level detail, see ",(0,l.jsx)(i.a,{href:"/cli/eslint-rules-migration",children:"ESLint rules migration guide"}),"."]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"at-a-glance",children:"At a glance"}),"\n",(0,l.jsxs)(i.table,{children:[(0,l.jsx)(i.thead,{children:(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.th,{children:"Topic"}),(0,l.jsx)(i.th,{children:"pui-cli 8"}),(0,l.jsx)(i.th,{children:"pui-cli 9"})]})}),(0,l.jsxs)(i.tbody,{children:[(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Node.js"}),(0,l.jsx)(i.td,{children:"20"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.strong,{children:"24"})})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"pnpm"}),(0,l.jsx)(i.td,{children:"8\u201310"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.strong,{children:"11"})})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"App/library bundler"}),(0,l.jsx)(i.td,{children:"Webpack"}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.strong,{children:"Webpack"})," (unchanged)"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"ESLint"}),(0,l.jsxs)(i.td,{children:["8.x + ",(0,l.jsx)(i.code,{children:".eslintrc.cjs"})]}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.strong,{children:"10.x"})," + ",(0,l.jsx)(i.code,{children:"eslint.config.mjs"})]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Stylelint"}),(0,l.jsxs)(i.td,{children:["15.x + ",(0,l.jsx)(i.code,{children:"stylelint-config-styled-components"})]}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.strong,{children:"17.x"})," + ",(0,l.jsx)(i.code,{children:"postcss-styled-syntax"})," (styled-components rules inlined)"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsxs)(i.td,{children:["Vitest (via ",(0,l.jsx)(i.code,{children:"pui-cli vitest"}),")"]}),(0,l.jsx)(i.td,{children:"1.x"}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.strong,{children:"4.x"})," (uses Vite internally; not the app bundler)"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"TypeScript lint"}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.code,{children:"@typescript-eslint"})," v5"]}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.code,{children:"typescript-eslint"})," v8"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Exported tsconfig"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:'moduleResolution: "node"'})}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.strong,{children:(0,l.jsx)(i.code,{children:'moduleResolution: "bundler"'})})})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Shared config import"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"require('@elliemae/pui-cli').eslintConfig"})}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"import { eslintFlatConfig } from '@elliemae/pui-cli/eslint'"})})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Stylelint import"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"require('@elliemae/pui-cli').stylelintConfig"})}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.code,{children:"import { stylelintConfig } from '@elliemae/pui-cli/stylelint'"})," (or keep CJS re-export)"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"semantic-release"}),(0,l.jsxs)(i.td,{children:["21.x + ",(0,l.jsx)(i.code,{children:"release.config.cjs"})]}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.strong,{children:"25.x"})," + ",(0,l.jsx)(i.code,{children:"release.config.mjs"})," (ESM ",(0,l.jsx)(i.code,{children:"extends"})," for shareable config)"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Husky"}),(0,l.jsx)(i.td,{children:"8.x"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.strong,{children:"9.x"})})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:"Cursor skill"}),(0,l.jsx)(i.td,{children:"\u2014"}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"pui-cli skills install migrate-to-pui-cli-9 --target all"})})]})]})]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"recommended-rollout",children:"Recommended rollout"}),"\n",(0,l.jsxs)(i.p,{children:["Ship in ",(0,l.jsx)(i.strong,{children:"small PRs"})," to reduce regression risk:"]}),"\n",(0,l.jsxs)(i.ol,{children:["\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Toolchain"})," \u2014 Node 24 + pnpm 11 + CI image updates"]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Dependency bump"})," \u2014 ",(0,l.jsx)(i.code,{children:"@elliemae/pui-cli@9"})," without ESLint config change"]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"ESLint flat config"})," \u2014 add ",(0,l.jsx)(i.code,{children:"eslint.config.mjs"}),", delete legacy ESLint files, fix lint"]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Stylelint 17"})," \u2014 simplify ",(0,l.jsx)(i.code,{children:"stylelint.config.cjs"})," (remove ",(0,l.jsx)(i.code,{children:"stylelint-config-styled-components"})," overrides); optional ",(0,l.jsx)(i.code,{children:"stylelint.config.mjs"})]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Husky 9"})," \u2014 update ",(0,l.jsx)(i.code,{children:"prepare"})," script and hook files (if ",(0,l.jsx)(i.code,{children:".husky/"})," exists)"]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Vitest 4"})," \u2014 only if the repo uses ",(0,l.jsx)(i.code,{children:"pui-cli vitest"})," (see below)"]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"semantic-release 25"})," \u2014 migrate ",(0,l.jsx)(i.code,{children:"release.config.cjs"})," \u2192 ",(0,l.jsx)(i.code,{children:"release.config.mjs"})," (libraries that publish to npm)"]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Debt (optional)"})," \u2014 remove temporary rule overrides, adopt strict config"]}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["Each PR should pass: ",(0,l.jsx)(i.code,{children:"lint"}),", ",(0,l.jsx)(i.code,{children:"tscheck"}),", ",(0,l.jsx)(i.code,{children:"test"}),", ",(0,l.jsx)(i.code,{children:"build"}),"."]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"step-by-step",children:"Step-by-step"}),"\n",(0,l.jsx)(i.h3,{id:"1-upgrade-toolchain",children:"1. Upgrade toolchain"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"# .node-version\n24\n"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-json",children:'// package.json (root monorepos)\n"packageManager": "pnpm@11.x.x"\n'})}),"\n",(0,l.jsx)(i.p,{children:"Update Jenkins/docker Node images before merging."}),"\n",(0,l.jsx)(i.h3,{id:"2-upgrade-pui-cli",children:"2. Upgrade pui-cli"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm add -D @elliemae/pui-cli@9\n"})}),"\n",(0,l.jsx)(i.h3,{id:"3-add-flat-eslint-config",children:"3. Add flat ESLint config"}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.strong,{children:"React app or library:"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-js",children:"// eslint.config.mjs\nimport { eslintFlatConfig } from '@elliemae/pui-cli/eslint';\n\nexport default eslintFlatConfig;\n"})}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.strong,{children:"Node / TS service:"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-js",children:"// eslint.config.mjs\nimport { eslintFlatBaseConfig } from '@elliemae/pui-cli/eslint';\n\nexport default eslintFlatBaseConfig;\n"})}),"\n",(0,l.jsx)(i.p,{children:"Remove:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:".eslintrc.cjs"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:".eslintignore"})}),"\n"]}),"\n",(0,l.jsx)(i.h3,{id:"4-update-stylelint-config",children:"4. Update Stylelint config"}),"\n",(0,l.jsxs)(i.p,{children:["pui-cli 9 ships ",(0,l.jsx)(i.strong,{children:"Stylelint 17"})," with ",(0,l.jsx)(i.code,{children:"stylelint-config-recommended@18"})," and ",(0,l.jsx)(i.code,{children:"postcss-styled-syntax"}),". The unmaintained ",(0,l.jsx)(i.code,{children:"stylelint-config-styled-components"})," package is removed; its rules are inlined in the shared config."]}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.strong,{children:"Minimal (CJS \u2014 still supported):"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-javascript",children:"// stylelint.config.cjs\nconst { stylelintConfig } = require('@elliemae/pui-cli');\nmodule.exports = stylelintConfig;\n"})}),"\n",(0,l.jsxs)(i.p,{children:["If your repo previously filtered out ",(0,l.jsx)(i.code,{children:"stylelint-config-styled-components"})," from ",(0,l.jsx)(i.code,{children:"extends"}),", delete that workaround \u2014 the base config no longer extends it."]}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.strong,{children:"Recommended (ESM):"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-javascript",children:"// stylelint.config.mjs\nimport { stylelintConfig } from '@elliemae/pui-cli/stylelint';\n\nexport default stylelintConfig;\n"})}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.code,{children:"pui-cli lint"})," prefers ",(0,l.jsx)(i.code,{children:"stylelint.config.mjs"})," when present, otherwise falls back to ",(0,l.jsx)(i.code,{children:"stylelint.config.cjs"}),"."]}),"\n",(0,l.jsxs)(i.p,{children:["See ",(0,l.jsx)(i.a,{href:"/cli/stylelint-migration",children:"Stylelint migration guide"})," for version and rule changes."]}),"\n",(0,l.jsx)(i.h3,{id:"5-fix-lint",children:"5. Fix lint"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm exec pui-cli lint --fix\npnpm exec pui-cli lint\npnpm exec pui-cli tscheck --files\npnpm test\npnpm run build\n"})}),"\n",(0,l.jsx)(i.h3,{id:"6-install-the-migration-skill-optional",children:"6. Install the migration skill (optional)"}),"\n",(0,l.jsx)(i.p,{children:"Gives Cursor, Claude Code, and GitHub Copilot agents a step-by-step playbook in the repo:"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm exec pui-cli skills list\npnpm exec pui-cli skills install migrate-to-pui-cli-9 --target all\n"})}),"\n",(0,l.jsxs)(i.p,{children:["Skills are copied to ",(0,l.jsx)(i.code,{children:".cursor/skills/"}),", ",(0,l.jsx)(i.code,{children:".claude/skills/"}),", and ",(0,l.jsx)(i.code,{children:".github/skills/"})," (commit them if you want the whole team to share the same agent guidance)."]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"temporary-overrides",children:"Temporary overrides"}),"\n",(0,l.jsxs)(i.p,{children:["Large repos may have pre-existing ",(0,l.jsx)(i.code,{children:"any"})," usage. Legacy ESLint reported these as ",(0,l.jsx)(i.strong,{children:"warnings"}),"; flat config defaults them to ",(0,l.jsx)(i.strong,{children:"error"}),"."]}),"\n",(0,l.jsx)(i.p,{children:"Short-term override (remove in a follow-up):"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-js",children:"import { eslintFlatConfig } from '@elliemae/pui-cli/eslint';\n\nexport default [\n ...eslintFlatConfig,\n {\n rules: {\n '@typescript-eslint/no-explicit-any': 'warn',\n },\n },\n];\n"})}),"\n",(0,l.jsx)(i.p,{children:"Libraries with heavy decorator/micro-frontend typings may need additional one-off overrides \u2014 keep them minimal and tracked."}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"strict-config-after-cleanup",children:"Strict config (after cleanup)"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-js",children:"import { eslintFlatConfigStrict } from '@elliemae/pui-cli/eslint';\n\nexport default eslintFlatConfigStrict;\n"})}),"\n",(0,l.jsxs)(i.p,{children:["Strict mode elevates ",(0,l.jsx)(i.code,{children:"no-unsafe-*"})," and ",(0,l.jsx)(i.code,{children:"exhaustive-deps"})," to error."]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"husky-9",children:"Husky 9"}),"\n",(0,l.jsx)(i.p,{children:"If your repo uses Husky 8 hooks from pui-cli boilerplate:"}),"\n",(0,l.jsxs)(i.ol,{children:["\n",(0,l.jsxs)(i.li,{children:["Upgrade: ",(0,l.jsx)(i.code,{children:"pnpm add -D husky@9"})]}),"\n",(0,l.jsxs)(i.li,{children:["Update ",(0,l.jsx)(i.code,{children:"package.json"}),":","\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-diff",children:'- "prepare": "[ -n \\"$CI\\" ] || husky install"\n+ "prepare": "[ -n \\"$CI\\" ] || husky"\n'})}),"\n"]}),"\n",(0,l.jsxs)(i.li,{children:["Remove the shebang and ",(0,l.jsx)(i.code,{children:"husky.sh"})," source from each hook in ",(0,l.jsx)(i.code,{children:".husky/"}),":","\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-diff",children:'- #!/bin/sh\n- . "$(dirname "$0")/_/husky.sh"\n\npnpm -s dlx lint-staged\n'})}),"\n"]}),"\n",(0,l.jsxs)(i.li,{children:["Delete ",(0,l.jsx)(i.code,{children:".husky/.gitignore"})," if present (v9 regenerates ",(0,l.jsx)(i.code,{children:".husky/_"})," on install)."]}),"\n",(0,l.jsxs)(i.li,{children:["Remove ",(0,l.jsx)(i.code,{children:"husky-init"})," from devDependencies (use ",(0,l.jsx)(i.code,{children:"pnpm exec husky init"})," for new projects)."]}),"\n",(0,l.jsxs)(i.li,{children:["Run ",(0,l.jsx)(i.code,{children:"pnpm prepare"})," and verify with a test commit."]}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.strong,{children:"Environment variable changes:"})," ",(0,l.jsx)(i.code,{children:"HUSKY_SKIP_HOOKS"})," / ",(0,l.jsx)(i.code,{children:"HUSKY_SKIP_INSTALL"})," \u2192 ",(0,l.jsx)(i.code,{children:"HUSKY=0"}),"; ",(0,l.jsx)(i.code,{children:"HUSKY_GIT_PARAMS"})," \u2192 use ",(0,l.jsx)(i.code,{children:"$1"})," in hook scripts."]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"vitest-4",children:"Vitest 4"}),"\n",(0,l.jsxs)(i.p,{children:["Skip this section if the repo uses Jest (",(0,l.jsx)(i.code,{children:"pui-cli test"}),") only. ",(0,l.jsx)(i.strong,{children:"pui-cli 9 still builds apps and libraries with Webpack"}),"; Vite is used by Vitest (and optional ",(0,l.jsx)(i.code,{children:"pui-cli buildCDN"}),"), not for production bundling."]}),"\n",(0,l.jsxs)(i.p,{children:["After bumping ",(0,l.jsx)(i.code,{children:"@elliemae/pui-cli@9"}),", align local test dependencies with the versions pui-cli ships:"]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm add -D vitest@4 @vitest/coverage-v8@4 vite@8 @vitejs/plugin-react@6 vite-tsconfig-paths@6\npnpm remove @vitest/coverage-c8 @types/uuid # if present; uuid 14+ includes types\n"})}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.strong,{children:"Extend the shared config"})," (recommended):"]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-typescript",children:"// vitest.config.ts\nimport { defineConfig, mergeConfig } from 'vitest/config';\nimport { vitestConfig } from '@elliemae/pui-cli/vitest';\n\nexport default mergeConfig(vitestConfig, defineConfig({\n test: {\n // repo-specific overrides\n },\n}));\n"})}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsxs)(i.strong,{children:["If you spread ",(0,l.jsx)(i.code,{children:"vitestConfig"})," manually"]}),", update any Vitest 1.x options:"]}),"\n",(0,l.jsxs)(i.table,{children:[(0,l.jsx)(i.thead,{children:(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.th,{children:"pui-cli 8 / Vitest 1"}),(0,l.jsx)(i.th,{children:"pui-cli 9 / Vitest 4"})]})}),(0,l.jsxs)(i.tbody,{children:[(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"test.deps.optimizer.web"})}),(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"test.deps.optimizer.client"})})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"@vitest/coverage-c8"})}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.code,{children:"@vitest/coverage-v8"})," (coverage provider ",(0,l.jsx)(i.code,{children:"v8"}),")"]})]}),(0,l.jsxs)(i.tr,{children:[(0,l.jsx)(i.td,{children:(0,l.jsx)(i.code,{children:"import { PluginOption } from 'vite'"})}),(0,l.jsxs)(i.td,{children:[(0,l.jsx)(i.code,{children:"import type { PluginOption } from 'vite'"})," (Vite 8)"]})]})]})]}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.strong,{children:"TypeScript:"})," exported ",(0,l.jsx)(i.code,{children:"@elliemae/pui-cli/app.tsconfig.json"})," and ",(0,l.jsx)(i.code,{children:"library.tsconfig.json"})," use ",(0,l.jsx)(i.code,{children:'moduleResolution: "bundler"'}),". If your ",(0,l.jsx)(i.code,{children:"tsconfig.json"})," extends them, reinstall pui-cli and re-run ",(0,l.jsx)(i.code,{children:"tscheck"}),". Custom tsconfigs that import ",(0,l.jsx)(i.code,{children:"vitest/config"})," or ",(0,l.jsx)(i.code,{children:"vite"})," may need the same setting."]}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.strong,{children:"Vitest config import:"})," use ",(0,l.jsx)(i.code,{children:"@elliemae/pui-cli/vitest"})," (not the package root). pui-cli 9 publishes ",(0,l.jsx)(i.code,{children:"types"})," on each ",(0,l.jsx)(i.code,{children:"package.json"})," ",(0,l.jsx)(i.code,{children:"exports"})," entry so ",(0,l.jsx)(i.code,{children:"tsc"})," resolves declarations under ",(0,l.jsx)(i.code,{children:'moduleResolution: "bundler"'})," \u2014 no ",(0,l.jsx)(i.code,{children:"tsconfig"})," ",(0,l.jsx)(i.code,{children:"paths"})," workaround."]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm exec pui-cli vitest --passWithNoTests\npnpm exec pui-cli tscheck --files\n"})}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"semantic-release-25",children:"semantic-release 25"}),"\n",(0,l.jsxs)(i.p,{children:["pui-cli 9 ships ",(0,l.jsx)(i.strong,{children:"semantic-release 25"})," with an ESM shareable config at ",(0,l.jsx)(i.code,{children:"@elliemae/pui-cli/releaseConfig"}),". semantic-release 22+ loads ESM ",(0,l.jsx)(i.code,{children:"extends"})," targets via dynamic ",(0,l.jsx)(i.code,{children:"import()"})," \u2014 the old ",(0,l.jsx)(i.code,{children:"release.config.cjs"})," + ",(0,l.jsx)(i.code,{children:"require()"})," path no longer works for the shared config."]}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsxs)(i.strong,{children:["Libraries that run ",(0,l.jsx)(i.code,{children:"semantic-release"})," in CI"]})," should migrate in the same PR as the pui-cli 9 bump (or immediately after)."]}),"\n",(0,l.jsx)(i.h3,{id:"1-upgrade-semantic-release-if-pinned-locally",children:"1. Upgrade semantic-release (if pinned locally)"}),"\n",(0,l.jsxs)(i.p,{children:["Most PUI libraries inherit semantic-release from ",(0,l.jsx)(i.code,{children:"@elliemae/pui-cli"}),". If your ",(0,l.jsx)(i.code,{children:"package.json"})," pins ",(0,l.jsx)(i.code,{children:"semantic-release"})," or ",(0,l.jsx)(i.code,{children:"@semantic-release/*"})," plugins directly, align with pui-cli 9:"]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm add -D semantic-release@25 @semantic-release/changelog@6 @semantic-release/exec@7 @semantic-release/git@10\n"})}),"\n",(0,l.jsxs)(i.p,{children:["Remove explicit pins if the repo only uses ",(0,l.jsx)(i.code,{children:"pnpm release"})," and relies on pui-cli's dependency tree."]}),"\n",(0,l.jsx)(i.h3,{id:"2-migrate-release-config-to-esm",children:"2. Migrate release config to ESM"}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.strong,{children:"Before:"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-javascript",children:"// release.config.cjs\nmodule.exports = {\n extends: '@elliemae/pui-cli/releaseConfig',\n};\n"})}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.strong,{children:"After:"})}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-javascript",children:"// release.config.mjs\n/** @type {import('semantic-release').GlobalConfig} */\nexport default {\n extends: '@elliemae/pui-cli/releaseConfig',\n};\n"})}),"\n",(0,l.jsxs)(i.p,{children:["Delete ",(0,l.jsx)(i.code,{children:"release.config.cjs"})," after adding ",(0,l.jsx)(i.code,{children:"release.config.mjs"}),"."]}),"\n",(0,l.jsx)(i.h3,{id:"3-custom-plugins-or-overrides",children:"3. Custom plugins or overrides"}),"\n",(0,l.jsxs)(i.p,{children:["Keep repo-specific plugins as relative paths from the config file. ESM plugins use ",(0,l.jsx)(i.code,{children:"export default"}),":"]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-javascript",children:"// release.config.mjs\nexport default {\n extends: '@elliemae/pui-cli/releaseConfig',\n plugins: [\n '@semantic-release/commit-analyzer',\n // ...other plugins from the shared config if replacing extends entirely\n './my-custom-plugin.mjs',\n ],\n};\n"})}),"\n",(0,l.jsxs)(i.p,{children:["CJS plugins (",(0,l.jsx)(i.code,{children:".cjs"}),") still work when referenced by path."]}),"\n",(0,l.jsx)(i.h3,{id:"4-verify-locally",children:"4. Verify locally"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm exec semantic-release --dry-run\n"})}),"\n",(0,l.jsx)(i.h3,{id:"agent-assisted-migration",children:"Agent-assisted migration"}),"\n",(0,l.jsx)(i.p,{children:"Install the pui-cli 9 skill so Cursor / Copilot agents follow the full config migration playbook (ESLint, Stylelint, Vitest, Husky, and semantic-release):"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-bash",children:"pnpm exec pui-cli skills install migrate-to-pui-cli-9 --target all\n"})}),"\n",(0,l.jsx)(i.p,{children:"Then ask the agent to migrate configuration files for pui-cli 9."}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"ci-checklist",children:"CI checklist"}),"\n",(0,l.jsxs)(i.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ","Node 24 in pipeline"]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ","pnpm 11 in pipeline"]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ",(0,l.jsx)(i.code,{children:"pui-cli lint"})," (0 errors)"]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ",(0,l.jsx)(i.code,{children:"pui-cli tscheck --files"})]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ","Unit tests"]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ","Production build"]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ","lint-staged / husky hooks pass locally"]}),"\n",(0,l.jsxs)(i.li,{className:"task-list-item",children:[(0,l.jsx)(i.input,{type:"checkbox",disabled:!0})," ",(0,l.jsx)(i.code,{children:"semantic-release --dry-run"})," (libraries that publish to npm)"]}),"\n"]}),"\n",(0,l.jsx)(i.hr,{}),"\n",(0,l.jsx)(i.h2,{id:"getting-help",children:"Getting help"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Rule changes:"})," ",(0,l.jsx)(i.a,{href:"/cli/eslint-rules-migration",children:"eslint-rules-migration.md"})]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Stylelint changes:"})," ",(0,l.jsx)(i.a,{href:"/cli/stylelint-migration",children:"stylelint-migration.md"})]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Commands:"})," ",(0,l.jsx)(i.a,{href:"/cli/usage-guide",children:"usage guide"})]}),"\n",(0,l.jsxs)(i.li,{children:[(0,l.jsx)(i.strong,{children:"Platform team:"})," ",(0,l.jsx)(i.code,{children:"#pui-platform"})," or your team's platform-ui channel"]}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,l.jsx)(i,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},6607(e,i,n){n.d(i,{R:()=>c,x:()=>t});var s=n(758);const l={},r=s.createContext(l);function c(e){const i=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(i):{...i,...e}},[i,e])}function t(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),s.createElement(r.Provider,{value:i},e.children)}}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(globalThis.webpackChunk_elliemae_pui_cli=globalThis.webpackChunk_elliemae_pui_cli||[]).push([[1019],{176(e,s,n){n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>x,frontMatter:()=>c,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"eslint-rules-migration","title":"ESLint rules migration guide (legacy \u2192 ESLint 10 flat config)","description":"This document compares the previous @elliemae/pui-cli ESLint setup (ESLint 8 + .eslintrc.cjs + Airbnb) with the current setup (ESLint 10 + eslint.config.mjs + typescript-eslint v8 flat config).","source":"@site/docs/eslint-rules-migration.md","sourceDirName":".","slug":"/eslint-rules-migration","permalink":"/cli/eslint-rules-migration","draft":false,"unlisted":false,"editUrl":"https://git.elliemae.io/platform-ui/pui-cli.git/docs/eslint-rules-migration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docsSidebar","previous":{"title":"vitestConfig","permalink":"/cli/api/variables/vitestConfig"},"next":{"title":"PUI CLI Documentation","permalink":"/cli/"}}');var i=n(6070),d=n(6607);const c={},t="ESLint rules migration guide (legacy \u2192 ESLint 10 flat config)",l={},o=[{value:"At a glance",id:"at-a-glance",level:2},{value:"How to upgrade a repo",id:"how-to-upgrade-a-repo",level:2},{value:"Presets: what was removed vs added",id:"presets-what-was-removed-vs-added",level:2},{value:"Removed (no longer extended)",id:"removed-no-longer-extended",level:3},{value:"Still included (equivalent or better)",id:"still-included-equivalent-or-better",level:3},{value:"Optional (not enabled by default)",id:"optional-not-enabled-by-default",level:3},{value:"PUI custom rules \u2014 unchanged",id:"pui-custom-rules--unchanged",level:2},{value:"TypeScript (explicit, same as before)",id:"typescript-explicit-same-as-before",level:3},{value:"React (explicit, same as before)",id:"react-explicit-same-as-before",level:3},{value:"E2E specs (unchanged)",id:"e2e-specs-unchanged",level:3},{value:"Import rules: <code>import/*</code> \u2192 <code>import-x/*</code>",id:"import-rules-import--import-x",level:2},{value:"Still off (same as legacy PUI config)",id:"still-off-same-as-legacy-pui-config",level:3},{value:"Still on",id:"still-on",level:3},{value:"Formatting: removed from ESLint",id:"formatting-removed-from-eslint",level:2},{value:"New rules you may see after upgrade",id:"new-rules-you-may-see-after-upgrade",level:2},{value:"TypeScript \u2014 newly explicit in PUI config",id:"typescript--newly-explicit-in-pui-config",level:3},{value:"TypeScript \u2014 from <code>recommendedTypeChecked</code> (v8 bundle)",id:"typescript--from-recommendedtypechecked-v8-bundle",level:3},{value:"React \u2014 new in pui-cli shared config",id:"react--new-in-pui-cli-shared-config",level:3},{value:"Unused variables",id:"unused-variables",level:3},{value:"Airbnb removal \u2014 practical impact",id:"airbnb-removal--practical-impact",level:2},{value:"File-type overrides (flat config only)",id:"file-type-overrides-flat-config-only",level:2},{value:"Ignore patterns",id:"ignore-patterns",level:2},{value:"TypeScript project resolution",id:"typescript-project-resolution",level:2},{value:"Quick fix cheat sheet",id:"quick-fix-cheat-sheet",level:2},{value:"Config entry points (reference)",id:"config-entry-points-reference",level:2},{value:"Post-migration tune-ups (alpha flat config)",id:"post-migration-tune-ups-alpha-flat-config",level:2},{value:"ESLint 10 plugin compatibility",id:"eslint-10-plugin-compatibility",level:3},{value:"Config performance notes",id:"config-performance-notes",level:3},{value:"Strict exports",id:"strict-exports",level:3},{value:"Questions?",id:"questions",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"eslint-rules-migration-guide-legacy--eslint-10-flat-config",children:"ESLint rules migration guide (legacy \u2192 ESLint 10 flat config)"})}),"\n",(0,i.jsxs)(s.p,{children:["This document compares the ",(0,i.jsx)(s.strong,{children:"previous"})," ",(0,i.jsx)(s.code,{children:"@elliemae/pui-cli"})," ESLint setup (ESLint 8 + ",(0,i.jsx)(s.code,{children:".eslintrc.cjs"})," + Airbnb) with the ",(0,i.jsx)(s.strong,{children:"current"})," setup (ESLint 10 + ",(0,i.jsx)(s.code,{children:"eslint.config.mjs"})," + ",(0,i.jsx)(s.code,{children:"typescript-eslint"})," v8 flat config)."]}),"\n",(0,i.jsxs)(s.p,{children:["For the full pui-cli 9 upgrade path (Node 24, pnpm 11, CI, Cursor skills), see ",(0,i.jsx)(s.a,{href:"/cli/pui-cli-9-migration",children:"pui-cli 9 migration guide"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Use it when upgrading apps/libraries and explaining new lint failures to your team."}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"at-a-glance",children:"At a glance"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Topic"}),(0,i.jsx)(s.th,{children:"Before (legacy)"}),(0,i.jsx)(s.th,{children:"After (flat config)"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Config format"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:".eslintrc.cjs"})," + ",(0,i.jsx)(s.code,{children:".eslintignore"})]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint.config.mjs"})," (ignores built-in)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"ESLint"}),(0,i.jsx)(s.td,{children:"8.x"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.strong,{children:"10.x"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"TypeScript lint"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"@typescript-eslint"})," v5, ",(0,i.jsx)(s.code,{children:"project: true"})]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"typescript-eslint"})," v8, ",(0,i.jsx)(s.code,{children:"projectService: true"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"JS parser"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@babel/eslint-parser"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"@eslint/js"})," recommended (no Babel parser for lint)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Style presets"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"Airbnb"})," + ",(0,i.jsx)(s.strong,{children:"airbnb-typescript"})]}),(0,i.jsx)(s.td,{children:"Removed \u2014 rules re-expressed explicitly"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Import plugin"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-import"})," (",(0,i.jsx)(s.code,{children:"import/*"}),")"]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-import-x"})," (",(0,i.jsx)(s.code,{children:"import-x/*"}),")"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Prettier in ESLint"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"prettier/prettier"})," ",(0,i.jsx)(s.strong,{children:"error"})]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"Not enforced in ESLint"})," \u2014 use Prettier in ",(0,i.jsx)(s.code,{children:"lint-staged"})," / CI"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Indent in ESLint"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"indent"})," ",(0,i.jsx)(s.strong,{children:"error"})]}),(0,i.jsx)(s.td,{children:"Removed \u2014 Prettier owns formatting"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Type-aware TS"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"recommended-requiring-type-checking"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"recommendedTypeChecked"})," (v8 equivalent)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Consumer import"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"require('@elliemae/pui-cli').eslintConfig"})}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import { eslintFlatConfig } from '@elliemae/pui-cli/eslint'"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Strict import"}),(0,i.jsx)(s.td,{children:"\u2014"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslintFlatConfigStrict"})," / ",(0,i.jsx)(s.code,{children:"eslintFlatBaseConfigStrict"})]})]})]})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"how-to-upgrade-a-repo",children:"How to upgrade a repo"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-js",children:"// eslint.config.mjs \u2014 React apps / libraries\nimport { eslintFlatConfig } from '@elliemae/pui-cli/eslint';\n\nexport default eslintFlatConfig;\n"})}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-js",children:"// eslint.config.mjs \u2014 Node / TS services (non-React)\nimport { eslintFlatBaseConfig } from '@elliemae/pui-cli/eslint';\n\nexport default eslintFlatBaseConfig;\n"})}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Upgrade ",(0,i.jsx)(s.code,{children:"@elliemae/pui-cli"})," to the alpha release that ships flat config."]}),"\n",(0,i.jsxs)(s.li,{children:["Add ",(0,i.jsx)(s.code,{children:"eslint.config.mjs"})," as above."]}),"\n",(0,i.jsxs)(s.li,{children:["Delete ",(0,i.jsx)(s.code,{children:".eslintrc.cjs"})," and ",(0,i.jsx)(s.code,{children:".eslintignore"}),"."]}),"\n",(0,i.jsxs)(s.li,{children:["Run ",(0,i.jsx)(s.code,{children:"pui-cli lint"})," and ",(0,i.jsx)(s.code,{children:"pui-cli lint --fix"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"presets-what-was-removed-vs-added",children:"Presets: what was removed vs added"}),"\n",(0,i.jsx)(s.h3,{id:"removed-no-longer-extended",children:"Removed (no longer extended)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Legacy extend"}),(0,i.jsx)(s.th,{children:"Impact"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"airbnb"})," / ",(0,i.jsx)(s.code,{children:"airbnb/hooks"})]}),(0,i.jsxs)(s.td,{children:["React style rules from Airbnb (e.g. ",(0,i.jsx)(s.code,{children:"react/jsx-props-no-spreading"}),", ",(0,i.jsx)(s.code,{children:"react/no-array-index-key"}),", stricter JSX patterns) are ",(0,i.jsx)(s.strong,{children:"gone"})," unless we set them explicitly in PUI config."]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"airbnb-base"})}),(0,i.jsx)(s.td,{children:"Same for non-React JS."})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"airbnb-typescript"})," / ",(0,i.jsx)(s.code,{children:"airbnb-typescript/base"})]}),(0,i.jsx)(s.td,{children:"Airbnb + TypeScript combo rules removed."})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:prettier/recommended"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"prettier/prettier"})," is no longer an ESLint error."]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:import/recommended"})}),(0,i.jsxs)(s.td,{children:["Replaced by ",(0,i.jsx)(s.code,{children:"eslint-plugin-import-x"})," flat recommended."]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:mdx/recommended"})}),(0,i.jsx)(s.td,{children:"MDX-specific ESLint block removed from shared React config (Storybook flat config remains)."})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"still-included-equivalent-or-better",children:"Still included (equivalent or better)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Area"}),(0,i.jsx)(s.th,{children:"Legacy"}),(0,i.jsx)(s.th,{children:"Flat config"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Core JS"}),(0,i.jsx)(s.td,{children:"ESLint recommended (via Airbnb + plugins)"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"@eslint/js"})," ",(0,i.jsx)(s.strong,{children:"recommended"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"TypeScript"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"@typescript-eslint/recommended"})," + ",(0,i.jsx)(s.strong,{children:"recommended-requiring-type-checking"})]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"typescript-eslint"})," ",(0,i.jsx)(s.strong,{children:"recommendedTypeChecked"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"React"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"plugin:react/recommended"})," (via Airbnb)"]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-react"})," ",(0,i.jsx)(s.strong,{children:"recommended"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Hooks"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"react-hooks/rules-of-hooks"})," (explicit); ",(0,i.jsx)(s.strong,{children:"no"})," ",(0,i.jsx)(s.code,{children:"exhaustive-deps"})," in old pui-cli"]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"rules-of-hooks"})," ",(0,i.jsx)(s.strong,{children:"error"})," + ",(0,i.jsxs)(s.strong,{children:[(0,i.jsx)(s.code,{children:"exhaustive-deps"})," warn"]})," (new)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"a11y"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:jsx-a11y/recommended"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-jsx-a11y"})," flat ",(0,i.jsx)(s.strong,{children:"recommended"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Jest"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:jest/recommended"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-jest"})," ",(0,i.jsx)(s.strong,{children:"recommended"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Testing Library"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:testing-library/dom"})}),(0,i.jsxs)(s.td,{children:["Same (",(0,i.jsx)(s.strong,{children:"dom"})," rules only)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"WDIO"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:wdio/recommended"})}),(0,i.jsx)(s.td,{children:"Same"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Redux Saga"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:redux-saga/recommended"})}),(0,i.jsx)(s.td,{children:"Same"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Storybook"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"plugin:storybook/recommended"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-storybook"})," flat ",(0,i.jsx)(s.strong,{children:"recommended"})," (v0.12, Storybook 6\u2013compatible)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Prettier conflict"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-config-prettier"})," via ",(0,i.jsx)(s.code,{children:"plugin:prettier/recommended"})]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslint-config-prettier"})," only (disables conflicting ESLint style rules)"]})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"optional-not-enabled-by-default",children:"Optional (not enabled by default)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Preset"}),(0,i.jsx)(s.th,{children:"Status"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"typescript-eslint/strictTypeChecked"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"Not"})," enabled \u2014 optional stricter tier for a later rollout"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"typescript-eslint/stylistic*"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"Not"})," enabled \u2014 Prettier is the source of truth for formatting"]})]})]})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"pui-custom-rules--unchanged",children:"PUI custom rules \u2014 unchanged"}),"\n",(0,i.jsxs)(s.p,{children:["These explicit PUI rules are ",(0,i.jsx)(s.strong,{children:"the same"})," in spirit (same limits and overrides):"]}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsxs)(s.th,{children:["JS (",(0,i.jsx)(s.code,{children:".js"}),")"]}),(0,i.jsxs)(s.th,{children:["TS (",(0,i.jsx)(s.code,{children:".ts"}),"/",(0,i.jsx)(s.code,{children:".tsx"}),")"]})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"complexity"})}),(0,i.jsx)(s.td,{children:"max 10"}),(0,i.jsx)(s.td,{children:"max 10"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"max-depth"})}),(0,i.jsx)(s.td,{children:"max 4"}),(0,i.jsx)(s.td,{children:"max 4"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"max-nested-callbacks"})}),(0,i.jsx)(s.td,{children:"max 3"}),(0,i.jsx)(s.td,{children:"max 3"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"max-params"})}),(0,i.jsx)(s.td,{children:"max 3"}),(0,i.jsx)(s.td,{children:"max 3"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"max-statements"})}),(0,i.jsx)(s.td,{children:"max 20"}),(0,i.jsx)(s.td,{children:"max 20"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"max-lines"})}),(0,i.jsx)(s.td,{children:"120"}),(0,i.jsx)(s.td,{children:"200"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"no-console"})}),(0,i.jsx)(s.td,{children:"warn"}),(0,i.jsx)(s.td,{children:"warn"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"no-param-reassign"})}),(0,i.jsx)(s.td,{children:"props: false"}),(0,i.jsx)(s.td,{children:"props: false"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"arrow-body-style"})}),(0,i.jsx)(s.td,{children:"as-needed"}),(0,i.jsx)(s.td,{children:"as-needed"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"prefer-template"})}),(0,i.jsx)(s.td,{children:"error"}),(0,i.jsx)(s.td,{children:"error"})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"typescript-explicit-same-as-before",children:"TypeScript (explicit, same as before)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Setting"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-floating-promises"})}),(0,i.jsxs)(s.td,{children:["error, ",(0,i.jsx)(s.code,{children:"ignoreIIFE: true"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/unbound-method"})}),(0,i.jsxs)(s.td,{children:["error, ",(0,i.jsx)(s.code,{children:"ignoreStatic: true"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-use-before-define"})}),(0,i.jsx)(s.td,{children:"functions: false, classes/variables/typedefs: true"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/explicit-module-boundary-types"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/explicit-function-return-type"})}),(0,i.jsx)(s.td,{children:"off"})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"react-explicit-same-as-before",children:"React (explicit, same as before)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Setting"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react/function-component-definition"})}),(0,i.jsx)(s.td,{children:"named components: arrow-function"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react/react-in-jsx-scope"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react/prop-types"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"jsx-a11y/heading-has-content"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"jsx-a11y/label-has-associated-control"})}),(0,i.jsxs)(s.td,{children:["on, ",(0,i.jsx)(s.code,{children:"controlComponents: ['Input']"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"redux-saga/no-yield-in-race"})}),(0,i.jsx)(s.td,{children:"error"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"redux-saga/yield-effects"})}),(0,i.jsx)(s.td,{children:"error"})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"e2e-specs-unchanged",children:"E2E specs (unchanged)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Files"}),(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Setting"})]})}),(0,i.jsx)(s.tbody,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"*.func.spec.js"}),", ",(0,i.jsx)(s.code,{children:"*.visual.spec.js"})]}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"jest/valid-expect"})}),(0,i.jsx)(s.td,{children:"off"})]})})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsxs)(s.h2,{id:"import-rules-import--import-x",children:["Import rules: ",(0,i.jsx)(s.code,{children:"import/*"})," \u2192 ",(0,i.jsx)(s.code,{children:"import-x/*"})]}),"\n",(0,i.jsxs)(s.p,{children:["Update ",(0,i.jsx)(s.strong,{children:"eslint-disable"})," comments when you touch files:"]}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Legacy rule name"}),(0,i.jsx)(s.th,{children:"New rule name"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import/no-unresolved"})}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-unresolved"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import/extensions"})}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/extensions"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import/no-named-as-default"})}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-named-as-default"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"\u2026"}),(0,i.jsxs)(s.td,{children:["Prefix ",(0,i.jsx)(s.code,{children:"import/"})," \u2192 ",(0,i.jsx)(s.code,{children:"import-x/"})]})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"still-off-same-as-legacy-pui-config",children:"Still off (same as legacy PUI config)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Status"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/imports-first"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/newline-after-import"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-dynamic-require"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-extraneous-dependencies"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-named-as-default"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-webpack-loader-syntax"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/prefer-default-export"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/default"})}),(0,i.jsx)(s.td,{children:"off"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/namespace"})}),(0,i.jsx)(s.td,{children:"off"})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"still-on",children:"Still on"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Setting"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-unresolved"})}),(0,i.jsx)(s.td,{children:"error, strict casing"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/extensions"})}),(0,i.jsx)(s.td,{children:"never (json/js ignorePackages)"})]})]})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"formatting-removed-from-eslint",children:"Formatting: removed from ESLint"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Legacy"}),(0,i.jsx)(s.th,{children:"Flat config"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"prettier/prettier"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"error"})," (via ",(0,i.jsx)(s.code,{children:"plugin:prettier/recommended"}),")"]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"off"})," \u2014 run Prettier separately"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"indent"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"error"})," (2 spaces, SwitchCase: 1)"]}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.strong,{children:"removed"})})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.strong,{children:"Action:"})," Rely on ",(0,i.jsx)(s.code,{children:"prettier --write"})," / ",(0,i.jsx)(s.code,{children:"lint-staged"})," for formatting. Do not expect ESLint to fail on quote/semicolon/indent issues."]}),"\n",(0,i.jsxs)(s.p,{children:["Legacy ",(0,i.jsx)(s.code,{children:"eslint-disable prettier/prettier"})," comments still work (no-op rule registered as off)."]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"new-rules-you-may-see-after-upgrade",children:"New rules you may see after upgrade"}),"\n",(0,i.jsxs)(s.p,{children:["These are the main ",(0,i.jsx)(s.strong,{children:"new or stricter"})," checks teams notice beyond \u201csame PUI rules as before.\u201d"]}),"\n",(0,i.jsx)(s.h3,{id:"typescript--newly-explicit-in-pui-config",children:"TypeScript \u2014 newly explicit in PUI config"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Severity"}),(0,i.jsx)(s.th,{children:"What it catches"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/consistent-type-imports"})}),(0,i.jsx)(s.td,{children:"error"}),(0,i.jsxs)(s.td,{children:["Use ",(0,i.jsx)(s.code,{children:"import type { Foo }"})," for type-only imports"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-import-type-side-effects"})}),(0,i.jsx)(s.td,{children:"error"}),(0,i.jsxs)(s.td,{children:["TS 5+ ",(0,i.jsx)(s.code,{children:"import type"})," side-effect hygiene"]})]})]})]}),"\n",(0,i.jsxs)(s.h3,{id:"typescript--from-recommendedtypechecked-v8-bundle",children:["TypeScript \u2014 from ",(0,i.jsx)(s.code,{children:"recommendedTypeChecked"})," (v8 bundle)"]}),"\n",(0,i.jsxs)(s.p,{children:["Already largely covered by legacy ",(0,i.jsx)(s.code,{children:"recommended-requiring-type-checking"}),", but stricter defaults / renames may surface more issues, including:"]}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Typical issue"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-misused-promises"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"async"})," handler passed where ",(0,i.jsx)(s.code,{children:"void"})," is expected (e.g. some callbacks)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-assignment"})}),(0,i.jsxs)(s.td,{children:["Assigning ",(0,i.jsx)(s.code,{children:"any"})," to a typed variable"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-member-access"})}),(0,i.jsxs)(s.td,{children:["Property access on ",(0,i.jsx)(s.code,{children:"any"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-call"})}),(0,i.jsxs)(s.td,{children:["Calling an ",(0,i.jsx)(s.code,{children:"any"})," value"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-argument"})}),(0,i.jsxs)(s.td,{children:["Passing ",(0,i.jsx)(s.code,{children:"any"})," into a typed parameter"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-return"})}),(0,i.jsxs)(s.td,{children:["Returning ",(0,i.jsx)(s.code,{children:"any"})," from a typed function"]})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.strong,{children:"Note:"})," Test files (",(0,i.jsx)(s.code,{children:"**/*.{test,spec}.*"}),") disable the ",(0,i.jsx)(s.code,{children:"no-unsafe-*"})," and ",(0,i.jsx)(s.code,{children:"unbound-method"})," rules in the shared config to reduce noise."]}),"\n",(0,i.jsx)(s.h3,{id:"react--new-in-pui-cli-shared-config",children:"React \u2014 new in pui-cli shared config"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Severity"}),(0,i.jsx)(s.th,{children:"Notes"})]})}),(0,i.jsx)(s.tbody,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react-hooks/exhaustive-deps"})}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.strong,{children:"warn"})}),(0,i.jsxs)(s.td,{children:["Missing deps in ",(0,i.jsx)(s.code,{children:"useEffect"})," / ",(0,i.jsx)(s.code,{children:"useCallback"})," / ",(0,i.jsx)(s.code,{children:"useMemo"})," \u2014 was not in legacy pui-cli (only ",(0,i.jsx)(s.code,{children:"rules-of-hooks"}),")"]})]})})]}),"\n",(0,i.jsx)(s.h3,{id:"unused-variables",children:"Unused variables"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Legacy"}),(0,i.jsx)(s.th,{children:"Flat config"})]})}),(0,i.jsx)(s.tbody,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"no-unused-vars"})," on TS files"]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unused-vars"})," with ",(0,i.jsx)(s.code,{children:"ignoreRestSiblings"}),", ",(0,i.jsx)(s.code,{children:"argsIgnorePattern: '^_'"})]})]})})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"airbnb-removal--practical-impact",children:"Airbnb removal \u2014 practical impact"}),"\n",(0,i.jsxs)(s.p,{children:["We no longer extend Airbnb. You should ",(0,i.jsx)(s.strong,{children:"not"})," expect every Airbnb rule to have a 1:1 replacement. Common behavioral changes:"]}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"You might have relied on (Airbnb)"}),(0,i.jsx)(s.th,{children:"After migration"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Stricter React patterns (e.g. some JSX prop rules)"}),(0,i.jsxs)(s.td,{children:["Only if still in ",(0,i.jsx)(s.code,{children:"eslint-plugin-react"})," recommended or our explicit ",(0,i.jsx)(s.code,{children:"reactRules"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import/prefer-default-export"})}),(0,i.jsxs)(s.td,{children:["Still ",(0,i.jsx)(s.strong,{children:"off"})," in PUI config"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react/jsx-props-no-spreading"})}),(0,i.jsxs)(s.td,{children:["Still ",(0,i.jsx)(s.strong,{children:"off"})," in PUI config"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Many opinionated React/a11y defaults from Airbnb"}),(0,i.jsxs)(s.td,{children:["Replaced by ",(0,i.jsx)(s.strong,{children:"plugin recommended"})," sets + PUI overrides above"]})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:["If lint gets ",(0,i.jsx)(s.strong,{children:"looser"})," in some areas, that is expected. If it gets ",(0,i.jsx)(s.strong,{children:"stricter"}),", it is usually from ",(0,i.jsx)(s.strong,{children:"type-checked TypeScript"})," or ",(0,i.jsx)(s.strong,{children:(0,i.jsx)(s.code,{children:"consistent-type-imports"})}),", not from Airbnb."]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"file-type-overrides-flat-config-only",children:"File-type overrides (flat config only)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Files"}),(0,i.jsx)(s.th,{children:"Rules relaxed"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"**/*.d.ts"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"@typescript-eslint/no-explicit-any"}),", ",(0,i.jsx)(s.code,{children:"@typescript-eslint/no-empty-object-type"})," off"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"**/*.{test,spec}.{js,jsx,ts,tsx}"}),", ",(0,i.jsx)(s.code,{children:"**/__tests__/**"}),", ",(0,i.jsx)(s.code,{children:"lib/**/tests/**"}),", ",(0,i.jsx)(s.code,{children:"app/**/tests/**"}),", etc."]}),(0,i.jsxs)(s.td,{children:["Jest + Testing Library; ",(0,i.jsx)(s.code,{children:"no-unsafe-*"})," off; ",(0,i.jsx)(s.code,{children:"no-unsafe-declaration-merging"}),", ",(0,i.jsx)(s.code,{children:"no-unsafe-enum-comparison"}),", ",(0,i.jsx)(s.code,{children:"await-thenable"}),", ",(0,i.jsx)(s.code,{children:"prefer-promise-reject-errors"}),", ",(0,i.jsx)(s.code,{children:"prefer-const"}),", etc. off in tests"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"**/*.checksum*.js"}),", ",(0,i.jsx)(s.code,{children:"**/*.endpoint.js"}),", versioned ",(0,i.jsx)(s.code,{children:"tests/**/latest"})," and ",(0,i.jsx)(s.code,{children:"tests/**/X.Y"})," assets"]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"no-unused-vars"}),", ",(0,i.jsx)(s.code,{children:"no-console"}),", ",(0,i.jsx)(s.code,{children:"max-lines"}),", ",(0,i.jsx)(s.code,{children:"max-statements"}),", ",(0,i.jsx)(s.code,{children:"complexity"})," off (fixture JS only)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"**/lint-config/**"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"max-lines"})," off; some ",(0,i.jsx)(s.code,{children:"import-x"})," rules off"]})]})]})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"ignore-patterns",children:"Ignore patterns"}),"\n",(0,i.jsxs)(s.p,{children:["Legacy ",(0,i.jsx)(s.code,{children:".eslintignore"})," entries are merged into the shared flat config ",(0,i.jsx)(s.code,{children:"ignores"}),", including:"]}),"\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.code,{children:"build"}),", ",(0,i.jsx)(s.code,{children:"node_modules"}),", ",(0,i.jsx)(s.code,{children:"dist"}),", ",(0,i.jsx)(s.code,{children:"reports"}),", ",(0,i.jsx)(s.code,{children:"coverage"}),", ",(0,i.jsx)(s.code,{children:"demo"}),", ",(0,i.jsx)(s.code,{children:"docs"}),", ",(0,i.jsx)(s.code,{children:"temp"}),", ",(0,i.jsx)(s.code,{children:".tmp"}),", ",(0,i.jsx)(s.code,{children:"public"}),", ",(0,i.jsx)(s.code,{children:"webroot"}),", ",(0,i.jsx)(s.code,{children:"cdn"}),", ",(0,i.jsx)(s.code,{children:".docusaurus"}),", ",(0,i.jsx)(s.code,{children:"vendor/*.js"}),", ",(0,i.jsx)(s.code,{children:".nx"}),", ",(0,i.jsx)(s.code,{children:"pnpm-lock.yaml"}),", ",(0,i.jsx)(s.code,{children:".scannerwork"}),", ",(0,i.jsx)(s.code,{children:"stats.json"}),", ",(0,i.jsx)(s.code,{children:"jsconfig.json"}),", ",(0,i.jsx)(s.code,{children:"allure-report"}),", ",(0,i.jsx)(s.code,{children:"docs/api"})]}),"\n",(0,i.jsxs)(s.p,{children:["Repo-specific paths should still be added in ",(0,i.jsx)(s.strong,{children:"your"})," ",(0,i.jsx)(s.code,{children:"eslint.config.mjs"})," if needed:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-js",children:"import { eslintFlatConfig } from '@elliemae/pui-cli/eslint';\n\nexport default [\n ...eslintFlatConfig,\n { ignores: ['my-generated-folder/**'] },\n];\n"})}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"typescript-project-resolution",children:"TypeScript project resolution"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{}),(0,i.jsx)(s.th,{children:"Legacy"}),(0,i.jsx)(s.th,{children:"Flat config"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Option"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"parserOptions.project: true"})}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"parserOptions.projectService: true"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Root"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"tsconfigRootDir: process.cwd()"})}),(0,i.jsxs)(s.td,{children:["Same (",(0,i.jsx)(s.code,{children:"process.cwd()"})," when lint runs)"]})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:["Monorepo packages: run lint from each package root (or ensure ",(0,i.jsx)(s.code,{children:"tsconfig"})," is discoverable). Same guidance as before, but ",(0,i.jsx)(s.code,{children:"projectService"})," is faster and less brittle than ",(0,i.jsx)(s.code,{children:"project: true"}),"."]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"quick-fix-cheat-sheet",children:"Quick fix cheat sheet"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Lint message / area"}),(0,i.jsx)(s.th,{children:"What to do"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"import/..."})," rule id in comment"]}),(0,i.jsxs)(s.td,{children:["Rename to ",(0,i.jsx)(s.code,{children:"import-x/..."})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"consistent-type-imports"})}),(0,i.jsxs)(s.td,{children:["Change to ",(0,i.jsx)(s.code,{children:"import type { X }"})," or inline ",(0,i.jsx)(s.code,{children:"import { type X }"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"no-floating-promises"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"void fn()"}),", ",(0,i.jsx)(s.code,{children:".catch()"}),", or ",(0,i.jsx)(s.code,{children:"await"})," in async context"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"no-misused-promises"})}),(0,i.jsxs)(s.td,{children:["Usually fixed by shared config (",(0,i.jsx)(s.code,{children:"attributes: false"}),"); otherwise wrap handler or fix callback type"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"exhaustive-deps"})," warning"]}),(0,i.jsx)(s.td,{children:"Fix dependency array or document intentional omission"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Formatting (quotes, indent)"}),(0,i.jsx)(s.td,{children:"Run Prettier \u2014 not ESLint"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"prettier/prettier"})," in disable comment"]}),(0,i.jsx)(s.td,{children:"Harmless; rule is off in ESLint"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"no-extraneous-dependencies"})," on app or ",(0,i.jsx)(s.code,{children:".babelrc.cjs"})]}),(0,i.jsxs)(s.td,{children:["Rule is ",(0,i.jsx)(s.strong,{children:"off"})," (legacy parity; ",(0,i.jsx)(s.code,{children:"app-react-dependencies"})," meta-package)"]})]})]})]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"config-entry-points-reference",children:"Config entry points (reference)"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"App type"}),(0,i.jsx)(s.th,{children:"Legacy export"}),(0,i.jsx)(s.th,{children:"Flat export"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"React + TS"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslintConfig"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslintFlatConfig"})," / ",(0,i.jsx)(s.code,{children:"eslintFlatConfigStrict"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Non-React TS"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslintBaseConfig"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"eslintFlatBaseConfig"})," / ",(0,i.jsx)(s.code,{children:"eslintFlatBaseConfigStrict"})]})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:["Legacy ",(0,i.jsx)(s.code,{children:".eslintrc.cjs"})," exports remain in the package for one transition release but are ",(0,i.jsx)(s.strong,{children:"deprecated"}),"."]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"post-migration-tune-ups-alpha-flat-config",children:"Post-migration tune-ups (alpha flat config)"}),"\n",(0,i.jsx)(s.p,{children:"The shared flat config includes pragmatic defaults to reduce migration noise while keeping high-value checks."}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Change"}),(0,i.jsx)(s.th,{children:"Behavior"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-misused-promises"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"checksVoidReturn.attributes: false"})," \u2014 async ",(0,i.jsx)(s.code,{children:"onClick"})," / JSX handlers allowed"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-*"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"warn"})," in app code (not error); ",(0,i.jsx)(s.strong,{children:"off"})," in test globs (",(0,i.jsx)(s.code,{children:"*.{test,spec}.*"}),", ",(0,i.jsx)(s.code,{children:"lib/**/tests/**"}),", etc.)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"import-x/no-extraneous-dependencies"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"off"})," (legacy parity; apps use ",(0,i.jsx)(s.code,{children:"@elliemae/app-react-dependencies"}),")"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"JSDoc"}),(0,i.jsxs)(s.td,{children:["Full ",(0,i.jsx)(s.code,{children:"jsdoc/recommended"})," ",(0,i.jsx)(s.strong,{children:"removed"}),"; only legacy ",(0,i.jsx)(s.code,{children:"require-jsdoc: off"})," + noisy rules explicitly off"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Testing Library"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"dom"})," rules on test files; ",(0,i.jsx)(s.strong,{children:"react"})," rules on ",(0,i.jsx)(s.code,{children:"*.{test,spec}.{tsx,jsx}"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"WDIO"}),(0,i.jsxs)(s.td,{children:["Globals + rules on ",(0,i.jsx)(s.code,{children:"*.func.spec.js"}),", ",(0,i.jsx)(s.code,{children:"*.visual.spec.js"}),", ",(0,i.jsx)(s.code,{children:"*e2e*"}),", and ",(0,i.jsx)(s.code,{children:"**/e2e/**"})," (page-objects, etc.)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Storybook"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"react/jsx-props-no-spreading"})," off (React config); ",(0,i.jsx)(s.code,{children:"eslint-plugin-storybook@0.12"})," shimmed in ",(0,i.jsx)(s.code,{children:"compat.mjs"})," until Storybook 10"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslint.config.*"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"import-x/no-unresolved"})," off"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"scripts/**"}),", ",(0,i.jsx)(s.code,{children:"ci_cd/**"})]}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"no-console"}),", ",(0,i.jsx)(s.code,{children:"max-lines"}),", ",(0,i.jsx)(s.code,{children:"complexity"})," off"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react-hooks/exhaustive-deps"})}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"warn"})," (not error) until repos are clean"]})]})]})]}),"\n",(0,i.jsx)(s.h3,{id:"eslint-10-plugin-compatibility",children:"ESLint 10 plugin compatibility"}),"\n",(0,i.jsxs)(s.p,{children:["Only plugins that still call removed ",(0,i.jsx)(s.code,{children:"context.getFilename()"})," / ",(0,i.jsx)(s.code,{children:"getScope()"})," APIs are wrapped via ",(0,i.jsx)(s.code,{children:"@eslint/compat"})," v2 ",(0,i.jsx)(s.code,{children:"fixupPluginRules"})," / ",(0,i.jsx)(s.code,{children:"fixupConfigRules"})," in ",(0,i.jsx)(s.code,{children:"lib/lint-config/eslint/flat/compat.mjs"}),":"]}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Plugin"}),(0,i.jsx)(s.th,{children:"Wrapped?"}),(0,i.jsx)(s.th,{children:"Reason"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslint-plugin-react"})}),(0,i.jsx)(s.td,{children:"Yes"}),(0,i.jsxs)(s.td,{children:["Uses legacy context APIs (",(0,i.jsx)(s.code,{children:"display-name"}),", etc.)"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslint-plugin-redux-saga"})}),(0,i.jsx)(s.td,{children:"Yes"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"no-yield-in-race"})," uses ",(0,i.jsx)(s.code,{children:"getScope()"})]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslint-plugin-storybook"})}),(0,i.jsx)(s.td,{children:"Yes"}),(0,i.jsx)(s.td,{children:"Flat preset rules use legacy context APIs"})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslint-plugin-wdio"})}),(0,i.jsx)(s.td,{children:"No"}),(0,i.jsxs)(s.td,{children:["Use nested plugin from ",(0,i.jsx)(s.code,{children:"flat/recommended"})," (see ",(0,i.jsx)(s.code,{children:"presets.mjs"}),")"]})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.code,{children:"typescript-eslint"}),", ",(0,i.jsx)(s.code,{children:"import-x"}),", ",(0,i.jsx)(s.code,{children:"jest"}),", ",(0,i.jsx)(s.code,{children:"react-hooks"}),", ",(0,i.jsx)(s.code,{children:"jsx-a11y"}),", ",(0,i.jsx)(s.code,{children:"testing-library"})]}),(0,i.jsx)(s.td,{children:"No"}),(0,i.jsx)(s.td,{children:"ESLint 10\u2013compatible; no shim overhead"})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:["Use ",(0,i.jsx)(s.code,{children:"@eslint/compat"})," ",(0,i.jsx)(s.strong,{children:"v2+"})," with ESLint 10. v1 ",(0,i.jsx)(s.code,{children:"fixupPluginRules"})," lacks ESLint 10 context patches."]}),"\n",(0,i.jsx)(s.h3,{id:"config-performance-notes",children:"Config performance notes"}),"\n",(0,i.jsx)(s.p,{children:"The shared flat config is structured for faster lint runs:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Preset rule spreads are computed once in ",(0,i.jsx)(s.code,{children:"presets.mjs"})," (not per factory call)."]}),"\n",(0,i.jsx)(s.li,{children:"Jest and Testing Library plugins apply only to test-like file globs (not all source files)."}),"\n",(0,i.jsx)(s.li,{children:"WDIO plugin applies only to e2e / visual / func spec files."}),"\n",(0,i.jsxs)(s.li,{children:["Unused ",(0,i.jsx)(s.code,{children:"eslint-plugin-prettier"})," and ",(0,i.jsx)(s.code,{children:"eslint-plugin-jsdoc"})," were removed (Prettier stays in ",(0,i.jsx)(s.code,{children:"lint-staged"}),"; no JSDoc rules enforced)."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"eslint-plugin-eslint-comments"})," was removed (incompatible with ESLint 10; rules were low-value)."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Lint toolchain (pui-cli 9 alpha):"})," ESLint 10, Prettier 3, Stylelint 17, ",(0,i.jsx)(s.code,{children:"eslint-plugin-react-hooks"})," 7, ",(0,i.jsx)(s.code,{children:"typescript-eslint"})," 8.56+, Commitlint 21, lint-staged 17."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.code,{children:"createBaseFlatConfigs()"})," caches the two variants (default + strict)."]}),"\n"]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h3,{id:"strict-exports",children:"Strict exports"}),"\n",(0,i.jsx)(s.p,{children:"Use when the default config is clean and you want full type-safety enforcement:"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"App type"}),(0,i.jsx)(s.th,{children:"Export"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"React + TS"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslintFlatConfigStrict"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:"Non-React TS"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"eslintFlatBaseConfigStrict"})})]})]})]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-js",children:"import { eslintFlatConfigStrict } from '@elliemae/pui-cli/eslint';\n\nexport default eslintFlatConfigStrict;\n"})}),"\n",(0,i.jsx)(s.p,{children:"Compared to the default flat config, strict mode:"}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{children:"Rule"}),(0,i.jsx)(s.th,{children:"Default"}),(0,i.jsx)(s.th,{children:"Strict"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"@typescript-eslint/no-unsafe-*"})}),(0,i.jsx)(s.td,{children:"warn in app code"}),(0,i.jsx)(s.td,{children:(0,i.jsx)(s.strong,{children:"error"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{children:(0,i.jsx)(s.code,{children:"react-hooks/exhaustive-deps"})}),(0,i.jsx)(s.td,{children:"warn"}),(0,i.jsxs)(s.td,{children:[(0,i.jsx)(s.strong,{children:"error"})," (React config only)"]})]})]})]}),"\n",(0,i.jsxs)(s.p,{children:["Tests, Storybook, and other file overrides are unchanged. Strict does ",(0,i.jsx)(s.strong,{children:"not"})," enable ",(0,i.jsx)(s.code,{children:"typescript-eslint/strictTypeChecked"})," (can be added per-repo later)."]}),"\n",(0,i.jsx)(s.hr,{}),"\n",(0,i.jsx)(s.h2,{id:"questions",children:"Questions?"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Channel:"})," ui-platform-chat"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Source of truth in repo:"})," ",(0,i.jsx)(s.code,{children:"lib/lint-config/eslint/flat/"})]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Legacy reference:"})," ",(0,i.jsx)(s.code,{children:"lib/lint-config/eslint/*.cjs"})," (frozen snapshot of old behavior)"]}),"\n"]})]})}function x(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},6607(e,s,n){n.d(s,{R:()=>c,x:()=>t});var r=n(758);const i={},d=r.createContext(i);function c(e){const s=r.useContext(d);return r.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),r.createElement(d.Provider,{value:s},e.children)}}}]);
|
|
File without changes
|