@elliemae/pui-cli 9.0.0-alpha.7 → 9.0.0-alpha.9

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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/app.tsconfig.json +1 -1
  3. package/dist/cjs/cli.js +2 -14
  4. package/dist/cjs/commands/build.js +1 -2
  5. package/dist/cjs/commands/buildcdn.js +1 -2
  6. package/dist/cjs/commands/codemod.js +1 -12
  7. package/dist/cjs/commands/gendoc.js +1 -2
  8. package/dist/cjs/commands/lint.js +11 -9
  9. package/dist/cjs/commands/pack.js +1 -2
  10. package/dist/cjs/commands/skills.js +1 -2
  11. package/dist/cjs/commands/start.js +1 -2
  12. package/dist/cjs/commands/storybook.js +1 -12
  13. package/dist/cjs/commands/test.js +1 -12
  14. package/dist/cjs/commands/tscheck.js +1 -2
  15. package/dist/cjs/commands/utils.js +12 -8
  16. package/dist/cjs/commands/version.js +1 -12
  17. package/dist/cjs/commands/vitest.js +1 -12
  18. package/dist/cjs/index.cjs +1 -1
  19. package/dist/cjs/index.js +2 -2
  20. package/dist/cjs/lint-config/eslint/flat/compat.mjs +10 -3
  21. package/dist/cjs/lint-config/eslint/flat/react.mjs +2 -3
  22. package/dist/cjs/lint-config/stylelint/config.mjs +27 -0
  23. package/dist/cjs/lint-config/stylelint/export.mjs +1 -0
  24. package/dist/cjs/lint-config/stylelint.config.cjs +3 -19
  25. package/dist/cjs/monorepo/utils.cjs +15 -7
  26. package/dist/cjs/monorepo/utils.js +5 -8
  27. package/dist/cjs/skills/migrate-to-pui-cli-9/SKILL.md +115 -11
  28. package/dist/cjs/testing/vitest.config.js +2 -1
  29. package/dist/esm/cli.js +2 -14
  30. package/dist/esm/commands/build.js +1 -2
  31. package/dist/esm/commands/buildcdn.js +1 -2
  32. package/dist/esm/commands/codemod.js +1 -2
  33. package/dist/esm/commands/gendoc.js +1 -2
  34. package/dist/esm/commands/lint.js +11 -9
  35. package/dist/esm/commands/pack.js +1 -2
  36. package/dist/esm/commands/skills.js +1 -2
  37. package/dist/esm/commands/start.js +1 -2
  38. package/dist/esm/commands/storybook.js +1 -2
  39. package/dist/esm/commands/test.js +1 -2
  40. package/dist/esm/commands/tscheck.js +1 -2
  41. package/dist/esm/commands/utils.js +13 -9
  42. package/dist/esm/commands/version.js +1 -2
  43. package/dist/esm/commands/vitest.js +1 -2
  44. package/dist/esm/index.cjs +1 -1
  45. package/dist/esm/index.js +1 -1
  46. package/dist/esm/lint-config/eslint/flat/compat.mjs +10 -3
  47. package/dist/esm/lint-config/eslint/flat/react.mjs +2 -3
  48. package/dist/esm/lint-config/stylelint/config.mjs +27 -0
  49. package/dist/esm/lint-config/stylelint/export.mjs +1 -0
  50. package/dist/esm/lint-config/stylelint.config.cjs +3 -19
  51. package/dist/esm/monorepo/utils.cjs +15 -7
  52. package/dist/esm/monorepo/utils.js +5 -8
  53. package/dist/esm/skills/migrate-to-pui-cli-9/SKILL.md +115 -11
  54. package/dist/esm/testing/vitest.config.js +2 -1
  55. package/dist/types/lib/commands/build.d.ts +1 -1
  56. package/dist/types/lib/commands/buildcdn.d.ts +1 -1
  57. package/dist/types/lib/commands/codemod.d.ts +1 -1
  58. package/dist/types/lib/commands/gendoc.d.ts +1 -1
  59. package/dist/types/lib/commands/lint.d.ts +1 -1
  60. package/dist/types/lib/commands/pack.d.ts +1 -1
  61. package/dist/types/lib/commands/skills.d.ts +1 -1
  62. package/dist/types/lib/commands/start.d.ts +1 -1
  63. package/dist/types/lib/commands/storybook.d.ts +1 -1
  64. package/dist/types/lib/commands/test.d.ts +1 -1
  65. package/dist/types/lib/commands/tscheck.d.ts +1 -1
  66. package/dist/types/lib/commands/utils.d.ts +43 -2
  67. package/dist/types/lib/commands/version.d.ts +1 -1
  68. package/dist/types/lib/commands/vitest.d.ts +1 -1
  69. package/dist/types/lib/index.d.cts +1 -1
  70. package/dist/types/lib/index.d.ts +1 -1
  71. package/dist/types/lib/lint-config/eslint/flat/compat.d.mts +7 -2
  72. package/dist/types/lib/lint-config/stylelint/config.d.mts +3 -0
  73. package/dist/types/lib/lint-config/stylelint/export.d.mts +1 -0
  74. package/dist/types/lib/lint-config/stylelint.config.d.cts +2 -10
  75. package/dist/types/tsconfig.tsbuildinfo +1 -1
  76. package/lib/lint-config/eslint/flat/compat.mjs +10 -3
  77. package/lib/lint-config/eslint/flat/react.mjs +2 -3
  78. package/lib/lint-config/stylelint/config.mjs +27 -0
  79. package/lib/lint-config/stylelint/export.mjs +1 -0
  80. package/lib/lint-config/stylelint.config.cjs +3 -19
  81. package/lib/skills/migrate-to-pui-cli-9/SKILL.md +115 -11
  82. package/library.tsconfig.json +1 -1
  83. package/package.json +21 -21
@@ -32,20 +32,17 @@ __export(utils_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(utils_exports);
34
34
  var import_node_path = __toESM(require("node:path"), 1);
35
- var import_child_process = require("child_process");
35
+ var import_find_up = require("find-up");
36
36
  const WORKSPACE_DIR_ENV_VAR = "NPM_CONFIG_WORKSPACE_DIR";
37
37
  const WORKSPACE_MANIFEST_FILENAME = "pnpm-workspace.yaml";
38
38
  const getPNPMWorkspaceLocation = (cwd) => {
39
- let location = null;
40
39
  for (const fileName of [WORKSPACE_MANIFEST_FILENAME, "pnpm-workspace.yml"]) {
41
- try {
42
- const result = (0, import_child_process.execSync)(`npx find-up ${fileName}`, { cwd });
43
- location = result.toString().trim();
44
- break;
45
- } catch {
40
+ const location = (0, import_find_up.findUpSync)(fileName, { cwd });
41
+ if (location) {
42
+ return location;
46
43
  }
47
44
  }
48
- return location;
45
+ return null;
49
46
  };
50
47
  const findMonoRepoRoot = (cwd = process.cwd()) => {
51
48
  const workspaceManifestDirEnvVar = process.env[WORKSPACE_DIR_ENV_VAR] ?? process.env[WORKSPACE_DIR_ENV_VAR.toLowerCase()];
@@ -1,15 +1,17 @@
1
1
  ---
2
2
  name: migrate-to-pui-cli-9
3
3
  description: >-
4
- Migrate a PUI app or library to pui-cli 9 (Node 24, pnpm 11, ESLint 9 flat config).
5
- Use when upgrading @elliemae/pui-cli, migrating from .eslintrc.cjs to eslint.config.mjs,
6
- fixing ESLint 9 lint failures, or adopting the shared flat config from pui-cli.
4
+ Migrate a PUI app or library to pui-cli 9 (Node 24, pnpm 11, ESLint 10 flat config, Stylelint 17,
5
+ Husky 9, Vitest 4). Use when upgrading @elliemae/pui-cli, migrating from .eslintrc.cjs to
6
+ eslint.config.mjs, upgrading Husky 8 hooks, fixing Vitest 4 / coverage-v8 breakages, or adopting
7
+ shared configs from pui-cli. App/library production builds stay on Webpack.
7
8
  ---
8
9
 
9
10
  # Migrate to pui-cli 9
10
11
 
11
12
  Upgrades a PUI repo from pui-cli 8 (ESLint 8 + `.eslintrc.cjs`) to pui-cli 9
12
- (ESLint 9 + `eslint.config.mjs` + Node 24 + pnpm 11).
13
+ (ESLint 10 + `eslint.config.mjs` + Node 24 + pnpm 11). Production bundling remains Webpack;
14
+ Vitest 4 uses Vite only as the test runner when you run `pui-cli vitest`.
13
15
 
14
16
  ## Pre-flight: Toolchain
15
17
 
@@ -42,7 +44,7 @@ pnpm add -D @elliemae/pui-cli@9
42
44
 
43
45
  Re-run install and smoke-test build/test without ESLint changes yet if the bump is large.
44
46
 
45
- ### Phase 3 — ESLint 9 flat config
47
+ ### Phase 3 — ESLint 10 flat config
46
48
 
47
49
  **React apps and libraries:**
48
50
 
@@ -95,13 +97,111 @@ export default [
95
97
 
96
98
  Remove overrides in a follow-up debt PR. Do not copy Airbnb or legacy `.eslintrc` rules.
97
99
 
98
- ### Phase 5 — Verify
100
+ ### Phase 5 — Husky 9 (if `.husky/` exists)
101
+
102
+ Skip this phase if the repo has no git hooks. Most PUI apps/libs copied hooks from pui-cli boilerplate and still use Husky 8.
103
+
104
+ 1. Upgrade and remove deprecated package:
105
+
106
+ ```bash
107
+ pnpm add -D husky@9
108
+ pnpm remove husky-init # if present
109
+ ```
110
+
111
+ 2. Update `package.json` `prepare` script:
112
+
113
+ ```diff
114
+ - "prepare": "[ -n \"$CI\" ] || husky install"
115
+ + "prepare": "[ -n \"$CI\" ] || husky"
116
+ ```
117
+
118
+ 3. Simplify each hook in `.husky/` — remove the shebang and `husky.sh` source. Keep only the command(s):
119
+
120
+ **`.husky/pre-commit`** (typical PUI repo):
121
+
122
+ ```sh
123
+ pnpm -s dlx lint-staged
124
+ ```
125
+
126
+ **`.husky/commit-msg`** (if commitlint is enabled):
127
+
128
+ ```sh
129
+ pnpm exec commitlint --edit $1
130
+ ```
131
+
132
+ ```diff
133
+ - #!/bin/sh
134
+ - . "$(dirname "$0")/_/husky.sh"
135
+ -
136
+ pnpm -s dlx lint-staged
137
+ ```
138
+
139
+ 4. Delete `.husky/.gitignore` if present (Husky 9 regenerates `.husky/_` on install).
140
+
141
+ 5. Run `pnpm prepare`, then verify hooks with a test commit.
142
+
143
+ **Environment variable changes (Husky 9):**
144
+
145
+ | Husky 8 | Husky 9 |
146
+ | ----------------------------------------- | ------------- |
147
+ | `HUSKY_SKIP_HOOKS` / `HUSKY_SKIP_INSTALL` | `HUSKY=0` |
148
+ | `HUSKY_GIT_PARAMS` in commit-msg hooks | `$1`, `$2`, … |
149
+
150
+ Reference hooks: [pui-cli/.husky](https://git.elliemae.io/platform-ui/pui-cli/tree/master/.husky)
151
+
152
+ ### Phase 6 — Stylelint 17 (if CSS / styled-components)
153
+
154
+ 1. Simplify `stylelint.config.cjs` — remove `stylelint-config-styled-components` workarounds.
155
+ 2. Optional ESM: `stylelint.config.mjs` importing `@elliemae/pui-cli/stylelint`.
156
+ 3. Run `pnpm exec pui-cli lint` (CSS pass).
157
+
158
+ See [stylelint-migration.md](https://docs.pui.mortgagetech.q1.ice.com/cli/stylelint-migration) in pui-cli docs.
159
+
160
+ ### Phase 7 — Vitest 4 (if using `pui-cli vitest`)
161
+
162
+ Skip if the repo uses Jest (`pui-cli test`) only.
163
+
164
+ 1. Align devDependencies with pui-cli 9 (Vitest 4 stack):
165
+
166
+ ```bash
167
+ pnpm add -D vitest@4 @vitest/coverage-v8@4 vite@8 @vitejs/plugin-react@6 vite-tsconfig-paths@6
168
+ pnpm remove @vitest/coverage-c8 @types/uuid # when upgrading uuid to 14+
169
+ ```
170
+
171
+ 2. Prefer extending shared config:
172
+
173
+ ```typescript
174
+ import { defineConfig, mergeConfig } from 'vitest/config';
175
+ import { vitestConfig } from '@elliemae/pui-cli/vitest';
176
+
177
+ export default mergeConfig(
178
+ vitestConfig,
179
+ defineConfig({
180
+ test: {
181
+ /* overrides */
182
+ },
183
+ }),
184
+ );
185
+ ```
186
+
187
+ 3. Update custom Vitest 1.x options:
188
+
189
+ | Old | New |
190
+ | ------------------------- | ---------------------------- |
191
+ | `test.deps.optimizer.web` | `test.deps.optimizer.client` |
192
+ | `@vitest/coverage-c8` | `@vitest/coverage-v8` |
193
+
194
+ 4. If `tsconfig.json` extends `@elliemae/pui-cli/app.tsconfig.json` or `library.tsconfig.json`, ensure pui-cli 9 is installed — shared tsconfigs use `moduleResolution: "bundler"`. Custom tsconfigs importing `vitest/config` may need the same.
195
+
196
+ 5. Smoke-test: `pnpm exec pui-cli vitest --passWithNoTests`
197
+
198
+ ### Phase 8 — Verify
99
199
 
100
200
  - [ ] `pnpm exec pui-cli lint` — 0 errors
101
201
  - [ ] `pnpm exec pui-cli tscheck --files`
102
- - [ ] `pnpm test`
103
- - [ ] `pnpm run build` (or `pui-cli build`)
104
- - [ ] Pre-commit / lint-staged passes
202
+ - [ ] `pnpm test` (or `pui-cli vitest` if applicable)
203
+ - [ ] `pnpm run build` (or `pui-cli build`) — Webpack, unchanged
204
+ - [ ] Pre-commit / lint-staged passes (after Husky 9 migration if applicable)
105
205
  - [ ] CI green on the target branch
106
206
 
107
207
  ## Common lint fixes after upgrade
@@ -114,6 +214,9 @@ Remove overrides in a follow-up debt PR. Do not copy Airbnb or legacy `.eslintrc
114
214
  | Stale `eslint-disable` comments | Remove disables for rules no longer in config |
115
215
  | Test/fixture files flagged | Shared config includes `lib/**/tests/**` globs — ensure pui-cli 9.0.0+ |
116
216
  | `.d.ts` files | pui-cli turns off `no-explicit-any` for `**/*.d.ts` |
217
+ | Cannot find module `vite` in tscheck | Set `moduleResolution: "bundler"` or extend pui-cli 9 tsconfig |
218
+ | Vitest `optimizer.web` unknown | Rename to `test.deps.optimizer.client` (Vitest 4) |
219
+ | Coverage fails after upgrade | Remove `@vitest/coverage-c8`; use `@vitest/coverage-v8@4` |
117
220
 
118
221
  Full rule comparison: [eslint-rules-migration.md](https://docs.pui.mortgagetech.q1.ice.com/cli/eslint-rules-migration) (also at `docs/eslint-rules-migration.md` in pui-cli).
119
222
 
@@ -130,11 +233,12 @@ Skills are copied to `.cursor/skills/`, `.claude/skills/`, and `.github/skills/`
130
233
  ## What NOT to change
131
234
 
132
235
  - Application business logic — migration is tooling/config only
133
- - Webpack/babel config unless pui-cli 9 release notes require it
134
- - Prettier / Stylelint / commitlint configs unless pui-cli 9 bumps those presets
236
+ - Webpack/babel production build config pui-cli 9 does not migrate apps to Vite for bundling
237
+ - Prettier / commitlint configs unless pui-cli 9 bumps those presets
135
238
 
136
239
  ## Additional resources
137
240
 
138
241
  - [pui-cli 9 migration guide](https://docs.pui.mortgagetech.q1.ice.com/cli/pui-cli-9-migration)
139
242
  - [ESLint rules migration guide](https://docs.pui.mortgagetech.q1.ice.com/cli/eslint-rules-migration)
243
+ - [Stylelint migration guide](https://docs.pui.mortgagetech.q1.ice.com/cli/stylelint-migration)
140
244
  - Reference one-liner: `pui-react-boilerplate/eslint.config.mjs`
@@ -48,11 +48,12 @@ const vitestConfig = (0, import_config.defineConfig)({
48
48
  include: ["./{app,lib}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
49
49
  exclude: [...import_config.configDefaults.exclude, ".idea", ".git", ".cache", "e2e"],
50
50
  coverage: {
51
+ provider: "v8",
51
52
  reportsDirectory: "./reports/coverage"
52
53
  },
53
54
  deps: {
54
55
  optimizer: {
55
- web: {
56
+ client: {
56
57
  include: ["app.config.json", "@elliemae/pui-app-sdk"]
57
58
  }
58
59
  }
package/dist/esm/cli.js CHANGED
@@ -19,21 +19,9 @@ import { tscheckCmd } from "./commands/tscheck.js";
19
19
  import { buildCDNCmd } from "./commands/buildcdn.js";
20
20
  import { skillsCmd } from "./commands/skills.js";
21
21
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
- envConfig();
22
+ envConfig({ quiet: true });
23
23
  process.env.PATH += path.delimiter + path.join(__dirname, "..", "node_modules", ".bin");
24
24
  (async () => {
25
- await yargs(hideBin(process.argv)).command(buildCmd).help().argv;
26
- await yargs(hideBin(process.argv)).command(packCmd).help().argv;
27
- await yargs(hideBin(process.argv)).command(startCmd).help().argv;
28
- await yargs(hideBin(process.argv)).command(testCmd).help().argv;
29
- await yargs(hideBin(process.argv)).command(lintCmd).help().argv;
30
- await yargs(hideBin(process.argv)).command(gendocCmd).help().argv;
31
- await yargs(hideBin(process.argv)).command(codemodCmd).help().argv;
32
- await yargs(hideBin(process.argv)).command(storybookCmd).help().argv;
33
- await yargs(hideBin(process.argv)).command(vitestCmd).help().argv;
34
- await yargs(hideBin(process.argv)).command(versionCmd).help().argv;
35
- await yargs(hideBin(process.argv)).command(tscheckCmd).help().argv;
36
- await yargs(hideBin(process.argv)).command(buildCDNCmd).help().argv;
37
- await yargs(hideBin(process.argv)).command(skillsCmd).help().argv;
25
+ await yargs(hideBin(process.argv)).command(buildCmd).command(packCmd).command(startCmd).command(testCmd).command(lintCmd).command(gendocCmd).command(codemodCmd).command(storybookCmd).command(vitestCmd).command(versionCmd).command(tscheckCmd).command(buildCDNCmd).command(skillsCmd).help().parseAsync();
38
26
  await notifyUpdates();
39
27
  })();
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- import yargs from "yargs";
4
3
  import {
5
4
  exec,
6
5
  logInfo,
@@ -50,7 +49,7 @@ const buildCmd = {
50
49
  logSuccess("Build completed");
51
50
  } catch (err) {
52
51
  logError("Build failed", err);
53
- yargs().exit(-1, err);
52
+ process.exit(1);
54
53
  }
55
54
  },
56
55
  command: "build",
@@ -1,7 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import fg from "fast-glob";
4
- import yargs from "yargs";
5
4
  import { exec, logInfo, logError, logSuccess } from "./utils.js";
6
5
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
6
  const buildCDN = async () => {
@@ -31,7 +30,7 @@ const buildCDNCmd = {
31
30
  logSuccess("CDN Build completed");
32
31
  } catch (err) {
33
32
  logError("Build failed", err);
34
- yargs().exit(-1, err);
33
+ process.exit(1);
35
34
  }
36
35
  },
37
36
  command: "buildCDN",
@@ -1,4 +1,3 @@
1
- import yargs from "yargs";
2
1
  import { exec, logInfo, logError, logSuccess } from "./utils.js";
3
2
  const transform = async (argv) => {
4
3
  logInfo("Code modification in-progress...");
@@ -11,7 +10,7 @@ const codemodCmd = {
11
10
  logSuccess("Code modifications completed. ");
12
11
  } catch (err) {
13
12
  logError("Code modifications failed", err);
14
- yargs().exit(-1, err);
13
+ process.exit(1);
15
14
  }
16
15
  },
17
16
  command: "codemod <transform>",
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- import yargs from "yargs";
4
3
  import { exec, logInfo, logSuccess, logError } from "./utils.js";
5
4
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
5
  const generateDocs = async () => {
@@ -14,7 +13,7 @@ const gendocCmd = {
14
13
  logSuccess("Document generation completed. ");
15
14
  } catch (err) {
16
15
  logError("Document generation failed", err);
17
- yargs().exit(-1, err);
16
+ process.exit(1);
18
17
  }
19
18
  },
20
19
  command: "gendoc",
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
+ import fs from "node:fs";
2
3
  import { inspect } from "node:util";
3
- import yargs from "yargs";
4
4
  import {
5
5
  exec,
6
6
  logInfo,
@@ -9,21 +9,23 @@ import {
9
9
  getCIEnv,
10
10
  isTypeScriptEnabled
11
11
  } from "./utils.js";
12
+ const resolveStylelintConfigPath = () => {
13
+ const mjsPath = path.join(process.cwd(), "stylelint.config.mjs");
14
+ if (fs.existsSync(mjsPath)) return mjsPath;
15
+ return path.join(process.cwd(), "stylelint.config.cjs");
16
+ };
12
17
  const lintCSS = async (args) => {
13
18
  const fixIssues = args.fix ? "--fix" : "";
19
+ const configPath = resolveStylelintConfigPath();
14
20
  if (args.debug) {
15
- const configPath = path.join(process.cwd(), "stylelint.config.cjs");
16
21
  const config = await import(configPath);
17
22
  logInfo("stylelint version:");
18
23
  await exec(`stylelint ./{lib,app}/**/*.{js,jsx,ts,tsx} --version`);
19
24
  logInfo("stylelint config:");
20
- logInfo(inspect(config, { depth: null }));
25
+ logInfo(inspect(config.default ?? config, { depth: null }));
21
26
  }
22
27
  await exec(
23
- `stylelint ./{lib,app}/**/*.{js,jsx,ts,tsx} ${fixIssues} ${!getCIEnv() ? "--color" : "--no-color"} --allow-empty-input --config ${path.join(
24
- process.cwd(),
25
- "stylelint.config.cjs"
26
- )}`
28
+ `stylelint ./{lib,app}/**/*.{js,jsx,ts,tsx} ${fixIssues} ${!getCIEnv() ? "--color" : "--no-color"} --allow-empty-input --config ${configPath}`
27
29
  );
28
30
  };
29
31
  const lintJS = async (args) => {
@@ -67,7 +69,7 @@ const lintCmd = {
67
69
  } catch (err) {
68
70
  logError("JS linting failed");
69
71
  if (argv.debug) logError(err);
70
- yargs().exit(-1, err);
72
+ process.exit(1);
71
73
  return;
72
74
  }
73
75
  }
@@ -79,7 +81,7 @@ const lintCmd = {
79
81
  } catch (err) {
80
82
  logError("CSS linting failed");
81
83
  if (argv.debug) logError(err);
82
- yargs().exit(-1, err);
84
+ process.exit(1);
83
85
  }
84
86
  }
85
87
  },
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- import yargs from "yargs";
4
3
  import {
5
4
  exec,
6
5
  logInfo,
@@ -73,7 +72,7 @@ const packCmd = {
73
72
  logSuccess("Build completed");
74
73
  } catch (err) {
75
74
  logError("Build failed", err);
76
- yargs().exit(-1, err);
75
+ process.exit(1);
77
76
  }
78
77
  },
79
78
  command: "pack",
@@ -3,7 +3,6 @@ import { fileURLToPath } from "node:url";
3
3
  import { createRequire } from "node:module";
4
4
  import { access, copyFile, mkdir, readdir, stat } from "node:fs/promises";
5
5
  import { constants } from "node:fs";
6
- import yargs from "yargs";
7
6
  import { logError, logInfo, logSuccess, logWarning } from "./utils.js";
8
7
  const SKILL_TARGETS = ["cursor", "claude", "copilot", "all"];
9
8
  const TARGET_RELATIVE_DIRS = {
@@ -167,7 +166,7 @@ const skillsCmd = {
167
166
  await runInstall(argv.name, Boolean(argv.force), argv.target);
168
167
  } catch (err) {
169
168
  logError(err.message);
170
- yargs().exit(-1, err);
169
+ process.exit(1);
171
170
  }
172
171
  }
173
172
  };
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- import yargs from "yargs";
4
3
  import { exec, logError, logSuccess, isApp } from "./utils.js";
5
4
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
5
  const startProdServer = async () => {
@@ -38,7 +37,7 @@ const startCmd = {
38
37
  logSuccess("Server started");
39
38
  } catch (err) {
40
39
  logError("Server start failed", err);
41
- yargs().exit(-1, err);
40
+ process.exit(1);
42
41
  }
43
42
  },
44
43
  command: "start [options]",
@@ -1,4 +1,3 @@
1
- import yargs from "yargs";
2
1
  import { exec, logInfo, logError, logSuccess } from "./utils.js";
3
2
  const buildStoryBook = async (outputDir = "demo", isDoc = false) => {
4
3
  const additionalParams = isDoc ? `--docs -o ${outputDir}/docs` : `-o ${outputDir}`;
@@ -39,7 +38,7 @@ const storybookCmd = {
39
38
  }
40
39
  } catch (err) {
41
40
  logError("Storybook execution failed", err);
42
- yargs().exit(-1, err);
41
+ process.exit(1);
43
42
  }
44
43
  },
45
44
  command: "storybook [options]",
@@ -1,4 +1,3 @@
1
- import yargs from "yargs";
2
1
  import { exec, logError, logSuccess, getCIEnv } from "./utils.js";
3
2
  const test = async (commandOptions) => {
4
3
  await exec(`cross-env NODE_ENV=test jest ${commandOptions}`);
@@ -61,7 +60,7 @@ const testCmd = {
61
60
  logSuccess("Unit test execution completed");
62
61
  } catch (err) {
63
62
  logError("Unit test execution failed", err);
64
- yargs().exit(-1, err);
63
+ process.exit(1);
65
64
  }
66
65
  },
67
66
  command: "test [options]",
@@ -1,6 +1,5 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
- import yargs from "yargs";
4
3
  import { exec, logInfo, logError } from "./utils.js";
5
4
  const randomChars = () => Math.random().toString(36).slice(2);
6
5
  const validateTypescript = async (files = []) => {
@@ -52,7 +51,7 @@ const tscheckCmd = {
52
51
  logInfo("Typescript validation completed");
53
52
  } catch (err) {
54
53
  logError("Typescript validation failed", err);
55
- yargs().exit(-1, err);
54
+ process.exit(1);
56
55
  }
57
56
  },
58
57
  command: "tscheck [options]",
@@ -12,7 +12,7 @@ import {
12
12
  import { createGzip, createBrotliCompress } from "node:zlib";
13
13
  import { pipeline } from "node:stream";
14
14
  import { promisify } from "node:util";
15
- import { execaCommand } from "execa";
15
+ import { $ } from "execa";
16
16
  import chalk from "chalk";
17
17
  import fg from "fast-glob";
18
18
  import {
@@ -30,7 +30,8 @@ const browsersMapping = {
30
30
  safari: "Safari",
31
31
  samsung: "Samsung Internet"
32
32
  };
33
- const exec = async (command, options = { stdio: "inherit" }) => execaCommand(command, options);
33
+ const $shell = $({ shell: true });
34
+ const exec = async (command, options) => $shell({ stdio: "inherit", ...options })`${command}`;
34
35
  const logInfo = console.log;
35
36
  const logWarning = (...args) => console.log(chalk.yellow(...args));
36
37
  const logSuccess = (...args) => console.log(chalk.green(...args));
@@ -50,13 +51,16 @@ const getSupportedBrowsers = async () => {
50
51
  const { stdout } = await exec("npx --no-install browserslist", {
51
52
  stdout: "pipe"
52
53
  });
53
- const browserVersions = stdout?.toString()?.split("\n") || [];
54
- return browserVersions.reduce((acc, nameVersion) => {
55
- const [name, version] = nameVersion.split(" ");
56
- const versionRange = version.split("-");
57
- acc[browsersMapping[name]] = versionRange && versionRange[0] || version;
58
- return acc;
59
- }, {});
54
+ const browserVersions = String(stdout ?? "").split("\n");
55
+ return browserVersions.reduce(
56
+ (acc, nameVersion) => {
57
+ const [name, version] = nameVersion.split(" ");
58
+ const versionRange = version.split("-");
59
+ acc[browsersMapping[name]] = versionRange && versionRange[0] || version;
60
+ return acc;
61
+ },
62
+ {}
63
+ );
60
64
  };
61
65
  const getModulesInfo = async () => {
62
66
  try {
@@ -1,4 +1,3 @@
1
- import yargs from "yargs";
2
1
  import { exec, logError } from "./utils.js";
3
2
  import { setWorkspaceVersion } from "../monorepo/set-workspace-version.js";
4
3
  import { setRegistryVersion } from "../monorepo/set-registry-version.js";
@@ -40,7 +39,7 @@ const versionCmd = {
40
39
  }
41
40
  } catch (err) {
42
41
  logError("Monorepo versioning failed", err);
43
- yargs().exit(-1, err);
42
+ process.exit(1);
44
43
  }
45
44
  },
46
45
  command: "version [options]",
@@ -1,4 +1,3 @@
1
- import yargs from "yargs";
2
1
  import { exec, logError, logSuccess, getCIEnv } from "./utils.js";
3
2
  const test = async (commandOptions) => {
4
3
  await exec(`vitest ${commandOptions}`);
@@ -46,7 +45,7 @@ const vitestCmd = {
46
45
  logSuccess("Unit test execution completed");
47
46
  } catch (err) {
48
47
  logError("Unit test execution failed", err);
49
- yargs().exit(-1, err);
48
+ process.exit(1);
50
49
  }
51
50
  },
52
51
  command: "vitest [options]",
@@ -13,7 +13,7 @@ const {
13
13
  const {
14
14
  esReactConfig: eslintConfig,
15
15
  } = require('./lint-config/eslint/react.cjs');
16
- const { stylelintConfig } = require('./lint-config/stylelint.config.cjs');
16
+ const { stylelintConfig } = require('./lint-config/stylelint/export.mjs');
17
17
  const { prettierConfig } = require('./lint-config/prettier.config.cjs');
18
18
  const { commitlintConfig } = require('./lint-config/commitlint.config.cjs');
19
19
  const { jestConfig } = require('./testing/jest.config.cjs');
package/dist/esm/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  } from "./lint-config/eslint/flat/react-export.mjs";
10
10
  import { esConfig } from "./lint-config/eslint/non-react.cjs";
11
11
  import { esReactConfig } from "./lint-config/eslint/react.cjs";
12
- import { stylelintConfig } from "./lint-config/stylelint.config.cjs";
12
+ import { stylelintConfig } from "./lint-config/stylelint/export.mjs";
13
13
  import { prettierConfig } from "./lint-config/prettier.config.cjs";
14
14
  import { commitlintConfig } from "./lint-config/commitlint.config.cjs";
15
15
  import { jestConfig } from "./testing/jest.config.cjs";
@@ -1,8 +1,9 @@
1
1
  /**
2
- * ESLint 10 removed deprecated context APIs (e.g. getSourceCode).
3
- * Wrap legacy plugins until their maintainers publish compatible releases.
2
+ * ESLint 10 removed deprecated context APIs (e.g. getSourceCode, getScope, getFilename).
3
+ * Wrap legacy plugins via @eslint/compat v2 (ESLint 10–aware fixupPluginRules).
4
4
  */
5
5
  import { fixupConfigRules, fixupPluginRules } from '@eslint/compat';
6
+ import react from 'eslint-plugin-react';
6
7
  import reduxSaga from 'eslint-plugin-redux-saga';
7
8
  import storybook from 'eslint-plugin-storybook';
8
9
 
@@ -11,10 +12,16 @@ const storybookFlat =
11
12
  storybook.configs.recommended ??
12
13
  [];
13
14
 
15
+ /** React — uses context.getFilename / getScope (eslint-plugin-react@7). */
16
+ /** @type {import('eslint').ESLint.Plugin} */
17
+ export const reactPlugin = fixupPluginRules(react);
18
+
19
+ /** Redux-saga — uses context.getScope in no-yield-in-race. */
14
20
  /** @type {import('eslint').ESLint.Plugin} */
15
21
  export const reduxSagaPlugin = fixupPluginRules(reduxSaga);
16
22
 
17
- /** Storybook flat presets with ESLint 10 compatibility shims applied. */
23
+ /** Storybook flat presets uses legacy context APIs (eslint-plugin-storybook@0.12). */
24
+ /** @type {import('eslint').Linter.Config[]} */
18
25
  export const storybookFlatConfigs = fixupConfigRules(
19
26
  Array.isArray(storybookFlat) ? storybookFlat : [storybookFlat],
20
27
  );
@@ -1,9 +1,8 @@
1
1
  import { defineConfig } from 'eslint/config';
2
2
  import jsxA11y from 'eslint-plugin-jsx-a11y';
3
- import react from 'eslint-plugin-react';
4
3
  import reactHooks from 'eslint-plugin-react-hooks';
5
4
  import { baseFlatConfigs, baseFlatConfigsStrict } from './common.mjs';
6
- import { reduxSagaPlugin } from './compat.mjs';
5
+ import { reactPlugin, reduxSagaPlugin } from './compat.mjs';
7
6
  import {
8
7
  reactPresetRules,
9
8
  storybookFiles,
@@ -13,7 +12,7 @@ import { reactRules, reactStrictRules } from './rules.mjs';
13
12
 
14
13
  const reactPluginBlock = {
15
14
  plugins: {
16
- react,
15
+ react: reactPlugin,
17
16
  'react-hooks': reactHooks,
18
17
  'jsx-a11y': jsxA11y,
19
18
  'redux-saga': reduxSagaPlugin,
@@ -0,0 +1,27 @@
1
+ /** @type {import('stylelint').Config} */
2
+ export const stylelintConfig = {
3
+ ignoreFiles: [
4
+ '/dist/**/*',
5
+ '/coverage/**/*',
6
+ '/build/**/*',
7
+ '/reports/**/*',
8
+ '/temp/**/*',
9
+ '/docs/**/*',
10
+ '/demo/**/*',
11
+ '/node_modules/**/*',
12
+ '/vendor/**/*',
13
+ ],
14
+ customSyntax: 'postcss-styled-syntax',
15
+ extends: ['stylelint-config-recommended'],
16
+ rules: {
17
+ 'selector-type-no-unknown': null,
18
+ 'function-no-unknown': null,
19
+ // Formerly from stylelint-config-styled-components (unmaintained; references
20
+ // removed rules like no-missing-end-of-source-newline in Stylelint 17).
21
+ 'value-no-vendor-prefix': true,
22
+ 'property-no-vendor-prefix': true,
23
+ 'no-empty-source': null,
24
+ },
25
+ };
26
+
27
+ export default stylelintConfig;
@@ -0,0 +1 @@
1
+ export { stylelintConfig, default } from './config.mjs';
@@ -1,19 +1,3 @@
1
- exports.stylelintConfig = {
2
- ignoreFiles: [
3
- "/dist/**/*",
4
- "/coverage/**/*",
5
- "/build/**/*",
6
- "/reports/**/*",
7
- "/temp/**/*",
8
- "/docs/**/*",
9
- "/demo/**/*",
10
- "/node_modules/**/*",
11
- "/vendor/**/*",
12
- ],
13
- customSyntax: "postcss-styled-syntax",
14
- extends: [
15
- "stylelint-config-recommended",
16
- "stylelint-config-styled-components",
17
- ],
18
- rules: { "selector-type-no-unknown": null, "function-no-unknown": null },
19
- };
1
+ const { stylelintConfig } = require('./stylelint/export.mjs');
2
+
3
+ exports.stylelintConfig = stylelintConfig;