fg-devkit 1.14.3 → 1.14.5

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.
@@ -11,6 +11,13 @@ alwaysApply: true
11
11
  - Avoid unrelated refactors in the same task.
12
12
  - Preserve existing behavior unless a behavior change is requested.
13
13
 
14
+ ## Code comments
15
+
16
+ - Do not add comments in code unless the user explicitly asks for them.
17
+ - Prefer self-explanatory naming and structure over inline comments.
18
+ - When updating existing code, do not add new comments or expand existing ones unless requested.
19
+ - Exception: update comments only when they are required to keep an existing comment accurate after a behavior change in the same task.
20
+
14
21
  ## Communication efficiency
15
22
 
16
23
  - Do not waste tokens: keep responses concise, high-signal, and scoped to the request.
@@ -33,7 +40,7 @@ alwaysApply: true
33
40
  - Keep TypeScript and Vue template typing strict (`strict: true`, `strictTemplates: true`).
34
41
  - Do not introduce `any`; use `unknown` for unsafe input and narrow before use.
35
42
  - Type API boundaries explicitly (request payloads, response DTOs, mutation variables, callback contracts).
36
- - Prefer named reusable types (for example under `src/types`) for shared domain shapes.
43
+ - Prefer named reusable types under `src/types/<domain>/` for shared domain shapes; re-export from `src/types/index.ts`. Do not keep shared interfaces in views, stores, or query files.
37
44
  - Avoid non-null assertions unless guarded by `enabled` checks or equivalent runtime guarantees.
38
45
 
39
46
  ## API boundaries
@@ -44,9 +51,10 @@ alwaysApply: true
44
51
 
45
52
  ## State-management boundaries
46
53
 
47
- - Use TanStack Query (or the project’s chosen data library) for server state and caching.
48
- - Use Pinia/Vuex only for client/app state that is not owned by the server.
49
- - Do not duplicate the same state across the query cache and global stores unless the project explicitly documents that pattern.
54
+ - Use TanStack Query for server state and caching. Do not add Vuex for new work.
55
+ - Use Pinia only for client/app state that is not owned by the server (for example `src/pinia/*`).
56
+ - Do not duplicate the same state across the query cache and Pinia unless the project explicitly documents that pattern.
57
+ - When a project is migrating Vuex → Query/Pinia, follow that repo’s local migration rules (if present) instead of expanding Vuex.
50
58
 
51
59
  ## TanStack Query server-state conventions
52
60
 
@@ -85,6 +93,7 @@ alwaysApply: true
85
93
  ## FDS-first component usage
86
94
 
87
95
  - Use `fds-vue-core` components as the default choice for UI building blocks.
96
+ - Multi-step wizards use `FdsWizard` from `fds-vue-core`. Follow the project’s wizard rule file when one exists (for example `.cursor/rules/fds-wizard.md`).
88
97
  - Before adding custom UI, check whether an FDS component already solves the use case.
89
98
  - Prefer extending composition around FDS components over re-implementing design-system behavior.
90
99
  - Keep visual consistency by matching FDS variants, spacing patterns, and interaction styles.
@@ -113,6 +122,7 @@ alwaysApply: true
113
122
  - Keep spacing and typography explicit in class names; avoid hidden styling in deep selectors.
114
123
  - Use `!` utility overrides sparingly and only when a component default cannot be changed safely.
115
124
  - For Tailwind v4 important modifiers, use postfix-important utility syntax (for example `grid-cols-1!`) instead of prefix syntax (for example `!grid-cols-1`).
125
+ - Stack repeated items with parent `flex flex-col gap-*` (or `space-y-*`). Do not use `mb-* last:mb-0` or `last-of-type:mb-*` — those variants often miss the last `v-for` item (extra Vue/FDS nodes) and trip Tailwind conflict lint.
116
126
 
117
127
  ## Figma MCP implementation workflow
118
128
 
@@ -166,9 +176,11 @@ alwaysApply: true
166
176
 
167
177
  ## Testing expectations
168
178
 
169
- - For non-trivial logic changes, add or update automated tests close to the affected feature.
170
- - Validate critical flows for changed views: loading, empty, error, and success states.
179
+ - Do not add new automated tests unless the user explicitly asks for them.
180
+ - Update existing tests when your change requires it (for example broken assertions, renamed APIs, or changed behavior covered by current tests).
181
+ - When new tests are requested, add them close to the affected feature.
171
182
  - Keep tests behavior-focused and avoid brittle implementation-detail assertions.
183
+ - When no new tests are requested, rely on lint, typecheck, and manual verification of critical flows where practical.
172
184
 
173
185
  ## CI/CD
174
186
 
@@ -178,7 +190,8 @@ alwaysApply: true
178
190
 
179
191
  ## Quality checks before finishing
180
192
 
181
- - Run relevant checks for touched code (lint, typecheck, or tests when practical).
193
+ - Run relevant checks for touched code (lint and typecheck when practical).
194
+ - Run and update existing tests when your change affects them; add new tests only when the user explicitly requests them.
182
195
  - Fix issues introduced by your change before handing off.
183
196
  - Call out anything you could not verify.
184
197
 
package/README.md CHANGED
@@ -63,13 +63,6 @@ pnpm exec fgd fallow dead-code --json
63
63
 
64
64
  When you run `fgd sync-tooling-configs` (or `fgd sync-project-configs`), fg-devkit also writes a shared `.fallowrc.json` to the consuming repo.
65
65
 
66
- To remove redundant tooling dependencies from a consuming repo:
67
-
68
- ```bash
69
- pnpm exec fgd prune-consumer-deps
70
- pnpm install
71
- ```
72
-
73
66
  To sync standard consumer scripts to `fgd` commands:
74
67
 
75
68
  ```bash
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "toolchain": {
3
- "packageManager": "pnpm@11.21.0",
3
+ "packageManager": "pnpm@11.22.0",
4
4
  "node": {
5
5
  "nvmrc": "22",
6
6
  "engines": ">=22.13.0",
@@ -33,7 +33,7 @@
33
33
  "content-disposition-header": "0.6.0",
34
34
  "date-fns": "4.4.0",
35
35
  "element-plus": "2.14.4",
36
- "fds-vue-core": "8.4.3",
36
+ "fds-vue-core": "8.5.1",
37
37
  "imask": "7.6.1",
38
38
  "leaflet": "1.9.4",
39
39
  "lexical": "0.49.0",
@@ -59,15 +59,15 @@
59
59
  "devDependencies": {
60
60
  "@chromatic-com/storybook": "5.3.0",
61
61
  "@eslint/js": "9.39.1",
62
- "@intlify/unplugin-vue-i18n": "11.2.4",
62
+ "@intlify/unplugin-vue-i18n": "11.2.5",
63
63
  "@playwright/test": "1.62.1",
64
- "@storybook/addon-a11y": "10.5.7",
65
- "@storybook/addon-docs": "10.5.7",
66
- "@storybook/addon-vitest": "10.5.7",
67
- "@storybook/vue3": "10.5.7",
68
- "@storybook/vue3-vite": "10.5.7",
64
+ "@storybook/addon-a11y": "10.5.8",
65
+ "@storybook/addon-docs": "10.5.8",
66
+ "@storybook/addon-vitest": "10.5.8",
67
+ "@storybook/vue3": "10.5.8",
68
+ "@storybook/vue3-vite": "10.5.8",
69
69
  "@tanstack/vue-query-devtools": "6.1.38",
70
- "@tsconfig/node22": "22.0.5",
70
+ "@tsconfig/node22": "22.0.6",
71
71
  "@types/lodash-es": "4.17.12",
72
72
  "@types/node": "22.16.5",
73
73
  "@vitest/browser": "4.1.10",
@@ -77,13 +77,13 @@
77
77
  "@vue/test-utils": "2.4.11",
78
78
  "arg": "5.0.2",
79
79
  "babel-eslint": "10.1.0",
80
- "eslint-plugin-storybook": "10.5.7",
80
+ "eslint-plugin-storybook": "10.5.8",
81
81
  "globals": "15.11.0",
82
82
  "jsdom": "26.1.0",
83
83
  "sass": "1.102.0",
84
- "storybook": "10.5.7",
84
+ "storybook": "10.5.8",
85
85
  "tsx": "4.23.12",
86
- "vega": "6.3.1",
86
+ "vega": "6.4.0",
87
87
  "vite-plugin-dts": "4.5.4",
88
88
  "vite-plugin-vue-devtools": "8.2.1",
89
89
  "vitest": "4.1.10",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fg-devkit",
3
- "version": "1.14.3",
3
+ "version": "1.14.5",
4
4
  "description": "Shared configs, scripts, and DX tooling for Vue / TypeScript frontend repos",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -27,7 +27,6 @@
27
27
  "./scripts/sync-project-configs.mjs": "./scripts/sync-project-configs.mjs",
28
28
  "./scripts/sync-consumer-scripts.mjs": "./scripts/sync-consumer-scripts.mjs",
29
29
  "./scripts/sync-consumer-lefthook.mjs": "./scripts/sync-consumer-lefthook.mjs",
30
- "./scripts/prune-consumer-deps.mjs": "./scripts/prune-consumer-deps.mjs",
31
30
  "./scripts/policy-outdated.mjs": "./scripts/policy-outdated.mjs",
32
31
  "./scripts/policy-vulns.mjs": "./scripts/policy-vulns.mjs",
33
32
  "./scripts/repo-vulns.mjs": "./scripts/repo-vulns.mjs",
@@ -124,7 +123,7 @@
124
123
  "tsx": "4.23.12",
125
124
  "typescript": "5.9.3",
126
125
  "vue-eslint-parser": "10.4.1",
127
- "vue-tsc": "3.3.9"
126
+ "vue-tsc": "3.3.10"
128
127
  },
129
128
  "devDependencies": {
130
129
  "cz-git": "1.13.2",
@@ -21,7 +21,7 @@
21
21
  "content-disposition-header": "0.6.0",
22
22
  "date-fns": "4.4.0",
23
23
  "dotenv": "16.4.5",
24
- "fds-vue-core": "8.4.3",
24
+ "fds-vue-core": "8.5.1",
25
25
  "pinia": "3.0.4",
26
26
  "qrcode.vue": "3.10.0",
27
27
  "vue": "3.5.41",
@@ -29,16 +29,16 @@
29
29
  "vue-router": "4.6.3"
30
30
  },
31
31
  "devDependencies": {
32
- "@intlify/unplugin-vue-i18n": "11.2.4",
32
+ "@intlify/unplugin-vue-i18n": "11.2.5",
33
33
  "@tanstack/vue-query-devtools": "6.1.38",
34
34
  "@types/node": "22.16.5",
35
35
  "@vitejs/plugin-vue": "6.0.8",
36
- "fg-devkit": "1.14.3",
36
+ "fg-devkit": "1.14.5",
37
37
  "tailwindcss": "4.3.3",
38
38
  "tsx": "4.23.12",
39
39
  "vite": "7.3.5"
40
40
  },
41
- "packageManager": "pnpm@11.21.0",
41
+ "packageManager": "pnpm@11.22.0",
42
42
  "engines": {
43
43
  "node": ">=22.13.0"
44
44
  }
@@ -23,7 +23,6 @@
23
23
  * pnpm exec fg-devkit sync-core-coding-standards
24
24
  * pnpm exec fg-devkit sync-consumer-scripts
25
25
  * pnpm exec fg-devkit setup-lefthook
26
- * pnpm exec fg-devkit prune-consumer-deps [--dry-run]
27
26
  * pnpm exec fg-devkit full-consumer-setup
28
27
  * pnpm exec fg-devkit create-release [release|candidate] [patch|minor|major] [--skip-release-notes]
29
28
  * pnpm exec fg-devkit generate-release-notes [--tag=vX.Y.Z]
@@ -145,7 +144,6 @@ function runSetupLefthook() {
145
144
 
146
145
  /**
147
146
  * Full consumer setup flow:
148
- * - Step 7: remove unnecessary deps
149
147
  * - Sync required consumer scripts for fgd commands
150
148
  * - Setup lefthook and migrate from husky/lint-staged
151
149
  * - Step 3: sync project configs
@@ -155,9 +153,6 @@ function runSetupLefthook() {
155
153
  function runFullConsumerSetup() {
156
154
  console.log('[fg-devkit] Running full consumer sync and setup')
157
155
 
158
- const step7 = runNode('prune-consumer-deps.mjs')
159
- if (step7 !== 0) return step7
160
-
161
156
  const scriptsStep = runNode('sync-consumer-scripts.mjs')
162
157
  if (scriptsStep !== 0) return scriptsStep
163
158
 
@@ -487,7 +482,6 @@ const DIRECT_COMMANDS = {
487
482
  'generate-release-notes': 'generate-release-notes.mjs',
488
483
  'verify-release-notes': 'verify-release-notes.mjs',
489
484
  'setup-lefthook': 'setup-lefthook',
490
- 'prune-consumer-deps': 'prune-consumer-deps.mjs',
491
485
  'sync-scaffold-vue-deps': 'sync-scaffold-vue-deps.mjs',
492
486
  'poeditor-download': 'poeditor-download.mjs',
493
487
  'poeditor-upload': 'poeditor-upload.mjs',
@@ -546,8 +540,7 @@ Commands:
546
540
  sync-core-coding-standards Copy .cursor core coding standards with consumer package name
547
541
  sync-consumer-scripts Enforce standard fgd scripts in consumer package.json
548
542
  setup-lefthook Setup lefthook and migrate from husky/lint-staged
549
- prune-consumer-deps [--dry-run] Remove consumer tooling deps bundled by fg-devkit
550
- full-consumer-setup Run: step 7 -> scripts -> lefthook -> step 3 -> step 2 -> pnpm install
543
+ full-consumer-setup Run: scripts -> lefthook -> step 3 -> step 2 -> pnpm install
551
544
  create-release [release|candidate] [patch|minor|major] [--skip-release-notes]
552
545
  Stable release or candidate (X.Y.Z-rc.N); omit = interactive menu
553
546
  (alias: createRelease)
@@ -1,101 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Removes tooling dependencies from a consuming repo that are now bundled by fg-devkit.
4
- *
5
- * By default this script edits package.json in the current working directory and removes
6
- * known ESLint/Prettier/TypeScript/cz-git tooling packages from dependencies/devDependencies.
7
- *
8
- * Usage:
9
- * node node_modules/fg-devkit/scripts/prune-consumer-deps.mjs
10
- * pnpm exec fg-devkit prune-consumer-deps
11
- * pnpm exec fg-devkit prune-consumer-deps --dry-run
12
- */
13
-
14
- import fs from 'node:fs'
15
- import path from 'node:path'
16
-
17
- const BUNDLED_TOOLING_PACKAGES = new Set([
18
- '@intlify/eslint-plugin-vue-i18n',
19
- '@typescript-eslint/eslint-plugin',
20
- '@typescript-eslint/parser',
21
- '@vitest/eslint-plugin',
22
- '@vue/eslint-config-prettier',
23
- '@vue/eslint-config-typescript',
24
- '@vue/tsconfig',
25
- '@rushstack/eslint-patch',
26
- 'commitizen',
27
- 'cz-git',
28
- 'czg',
29
- 'eslint',
30
- 'eslint-plugin-prettier',
31
- 'eslint-plugin-vue',
32
- 'husky',
33
- 'jsonc-eslint-parser',
34
- 'lint-staged',
35
- 'lefthook',
36
- 'prettier',
37
- 'typescript',
38
- 'yaml-eslint-parser',
39
- 'vue-eslint-parser',
40
- 'vue-tsc',
41
- ])
42
-
43
- function readPackageJson(packageJsonPath) {
44
- if (!fs.existsSync(packageJsonPath)) {
45
- console.error(`[prune-consumer-deps] No package.json found at ${packageJsonPath}`)
46
- process.exit(1)
47
- }
48
- try {
49
- return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
50
- } catch (err) {
51
- console.error(`[prune-consumer-deps] Failed to parse package.json: ${err.message}`)
52
- process.exit(1)
53
- }
54
- }
55
-
56
- function removeFromSection(pkg, sectionName, removed) {
57
- const section = pkg[sectionName]
58
- if (!section || typeof section !== 'object') {
59
- return
60
- }
61
- for (const name of Object.keys(section)) {
62
- if (BUNDLED_TOOLING_PACKAGES.has(name)) {
63
- removed.push(`${sectionName}.${name}@${section[name]}`)
64
- delete section[name]
65
- }
66
- }
67
- if (Object.keys(section).length === 0) {
68
- delete pkg[sectionName]
69
- }
70
- }
71
-
72
- function main() {
73
- const dryRun = process.argv.includes('--dry-run')
74
- const projectRoot = process.cwd()
75
- const packageJsonPath = path.join(projectRoot, 'package.json')
76
- const pkg = readPackageJson(packageJsonPath)
77
-
78
- const removed = []
79
- removeFromSection(pkg, 'dependencies', removed)
80
- removeFromSection(pkg, 'devDependencies', removed)
81
-
82
- if (removed.length === 0) {
83
- console.log('[prune-consumer-deps] No bundled tooling dependencies found to remove.')
84
- return
85
- }
86
-
87
- console.log('[prune-consumer-deps] Removed entries:')
88
- for (const line of removed) {
89
- console.log(` - ${line}`)
90
- }
91
-
92
- if (dryRun) {
93
- console.log('\n[prune-consumer-deps] Dry run only; package.json was not modified.')
94
- return
95
- }
96
-
97
- fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`, 'utf8')
98
- console.log('\n[prune-consumer-deps] Updated package.json. Run pnpm install to refresh lockfile.')
99
- }
100
-
101
- main()