@luxkit/cli 1.1.2 → 1.1.4

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.
@@ -1,67 +1,248 @@
1
1
  # Custom Preset Configuration
2
2
 
3
- > ⚠️ **Always use `lux init --preset` to initialize presets.** Running `lux fmt` / `lux vscode` directly generates config files in cwd and requires `package.json` only use in real project directories.
3
+ Presets are stored at `~/.lux/preset/` (i.e. `os.homedir()/.lux/preset/`). Override with `LUX_HOME` env var.
4
4
 
5
- ## Quick Start
5
+ ```
6
+ ~/.lux/preset/
7
+ ├── fmt/ # fmt presets (web-vue, web-react, electron-vue, uniapp, node, nest)
8
+ └── vscode/ # vscode presets (same + go)
9
+ ```
10
+
11
+ > ⚠️ **Always use `lux init --preset` to initialize all built-in presets.**
12
+
13
+ ## Built-in presets File Reference
14
+
15
+ ### fmt preset
16
+
17
+ | File | Description |
18
+ | :--------------------- | :-------------------------------------------- |
19
+ | `eslint.config.mjs` | ESLint flat config |
20
+ | `.prettierrc` | Prettier JSON config |
21
+ | `.prettierignore` | Prettier ignore rules |
22
+ | `stylelint.config.mjs` | Stylelint config |
23
+ | `.stylelintignore` | Stylelint ignore rules |
24
+ | `cspell.json` | CSpell dictionary config |
25
+ | `.editorconfig` | EditorConfig config |
26
+ | `.lintstagedrc.json` | lint-staged config (enables `--lint-staged`) |
27
+ | `package.json` | Template with `devDependencies` and `scripts` |
28
+
29
+ ### vscode preset
30
+
31
+ | File | Description |
32
+ | :---------------- | :------------------------------- |
33
+ | `settings.json` | VSCode workspace settings |
34
+ | `extensions.json` | VSCode extension recommendations |
35
+
36
+ ## Customize built-in presets
6
37
 
7
38
  ```bash
8
- lux init --preset # materialize all built-in presets to ~/.lux/preset/
39
+ lux init --preset # init all built-in presets
9
40
  ```
10
41
 
11
- After materialization, edit files under `~/.lux/preset/<type>/<preset-name>/` to customize. Changes take effect on the next `lux fmt` / `lux vscode` run.
42
+ After init, edit files under `~/.lux/preset/<type>/<preset-name>/` to customize — e.g. `package.json`, `eslint.config.mjs`, etc. You can also add your own lint files like `your-file-lint-config`. Changes take effect on the next `lux fmt` / `lux vscode` run.
43
+
44
+ To reset a customized built-in preset, re-run `lux init --preset` to overwrite, or use `lux fmt <name> --reset` / `lux vscode <name> --reset` (deletes local preset dir only; re-generated from built-in on next run).
12
45
 
13
- `lux init --preset` can be run repeatedly — each run overwrites with built-in defaults. To reset a single preset, use `lux fmt <name> --reset` or `lux vscode <name> --reset` (deletes local preset dir only; re-generated from built-in on next run).
46
+ ## Customize your own presets
14
47
 
15
- ## Storage Location
48
+ ### fmt
16
49
 
17
- `~/.lux/preset/` (i.e. `os.homedir()/.lux/preset/`). Override with `LUX_HOME` env var.
50
+ Create a directory under `~/.lux/preset/fmt/<your-fmt-preset-name>/` with config files and a `package.json`:
18
51
 
52
+ ```bash
53
+ # 1. Create the preset directory
54
+ mkdir -p ~/.lux/preset/fmt/[your-custom-fmt-preset-name]
55
+
56
+ # 2. Add config files
57
+ # Required: package.json (with devDependencies/dependencies and/or scripts)
58
+ # Recommended: include ALL tool configs so --stylelint / --cspell / --editorconfig flags can take effect
59
+ # Config files: eslint.config.mjs, .prettierrc, .prettierignore,
60
+ # stylelint.config.mjs, .stylelintignore,
61
+ # Config files: eslint.config.mjs, .prettierrc, .prettierignore,
62
+ # stylelint.config.mjs, .stylelintignore,
63
+ # cspell.json, .editorconfig, .lintstagedrc.json, etc.
64
+ #
65
+ # ⚠️ Only configs present in the preset can be controlled by flags. See "Flag-based filtering" below.
19
66
  ```
20
- ~/.lux/preset/
21
- ├── fmt/ # fmt presets (web-vue, web-react, electron-vue, uniapp, node, nest)
22
- └── vscode/ # vscode presets (same + go)
67
+
68
+ Minimum `package.json` example:
69
+
70
+ ```json
71
+ {
72
+ "devDependencies": {
73
+ "eslint": "<latest>",
74
+ "prettier": "<latest>"
75
+ },
76
+ "scripts": {
77
+ "lint": "<pm> eslint .",
78
+ "lint:fix": "<pm> eslint . --fix --cache --cache-location node_modules/.cache/.eslintcache",
79
+ "cspell": "<pm> cspell \"**\""
80
+ }
81
+ }
23
82
  ```
24
83
 
25
- ## File Reference
84
+ Then run `lux fmt list` to verify — check if `<your-fmt-preset-name>` appears in the list.
26
85
 
27
- ### fmt preset
86
+ ```bash
87
+ lux fmt <your-fmt-preset-name> # applies your custom preset
88
+ lux fmt <your-fmt-preset-name> --force # overwrite existing config files
89
+ lux fmt <your-fmt-preset-name> --dry-run # preview without writing
90
+ lux fmt <your-fmt-preset-name> --stylelint # applies your custom preset (includes stylelint config)
91
+ ```
28
92
 
29
- | File | Description |
30
- | :--------------------- | :--------------------------------------------- |
31
- | `eslint.config.mjs` | ESLint flat config |
32
- | `.prettierrc` | Prettier JSON config |
33
- | `.prettierignore` | Prettier ignore rules |
34
- | `stylelint.config.mjs` | Stylelint config |
35
- | `.stylelintignore` | Stylelint ignore rules |
36
- | `cspell.json` | CSpell dictionary config |
37
- | `.editorconfig` | EditorConfig config |
38
- | `package.json` | Template with `devDependencies` and `scripts` |
93
+ Notes:
39
94
 
40
- ### vscode preset
95
+ - `lux fmt list` shows custom presets after built-in ones, marked with `(custom)`
96
+ - `lux fmt <name> --reset` warns and aborts for custom presets — there is no built-in source to restore
97
+ - Unknown preset names fuzzy-match against all available presets (builtin + custom combined)
98
+ - `lux fmt` returns exit code **1** when a preset is not found (safe for CI/CD)
99
+ - `lux fmt <name> --stylelint/--editorconfig/--cspell/--husky/--lint-staged` warns when the flag has no effect (preset has no matching config or dependencies)
41
100
 
42
- | File | Description |
43
- | :---------------- | :-------------------------- |
44
- | `settings.json` | VSCode workspace settings |
45
- | `extensions.json` | VSCode extension recommendations |
101
+ > For general flag behavior (`--force`, `--dry-run`, `--no-install`, `--reset`), see `skill.md`. The sections below only cover behaviors specific to custom preset interaction.
46
102
 
47
- ## Template Placeholders (fmt preset)
103
+ ### vscode
48
104
 
49
- | Placeholder | Replaced with |
50
- | :---------- | :------------ |
51
- | `<pm>` | Package manager prefix (`bun run` / `pnpm run` / `npm run`) |
52
- | `<lockfile>` | Project lockfile name (`bun.lock` / `pnpm-lock.yaml` etc.) |
53
- | `"<latest>"` | Resolved to latest version at install time, or pin like `"3.3.0"` |
105
+ Custom vscode presets are not yet supported. To customize VSCode settings, use the built-in preset customization flow:
54
106
 
55
- ## Workflow
107
+ ```bash
108
+ lux init --preset # materialize built-in presets
109
+ # Edit files under ~/.lux/preset/vscode/<preset-name>/
110
+ # - settings.json (VSCode workspace settings)
111
+ # - extensions.json (extension recommendations)
112
+ lux vscode web-vue # applies your customized preset
113
+ ```
114
+
115
+ ## Fmt presets · package.json rules
116
+
117
+ Use `<latest>` placeholder for `devDependencies` and `dependencies` to get the latest version, or pin a specific version. Use `<pm>` placeholder in `scripts` to let lux auto-detect the package manager.
118
+
119
+ ```jsonc
120
+ {
121
+ "devDependencies": {
122
+ // latest version
123
+ "prettier": "<latest>",
124
+ // pinned version
125
+ "cspell": "10.0.0",
126
+ },
127
+ "scripts": {
128
+ "lint": "<pm> eslint .",
129
+ "lint:fix": "<pm> eslint . --fix --cache --cache-location node_modules/.cache/.eslintcache",
130
+ "cspell": "<pm> cspell \"**\"",
131
+ },
132
+ }
133
+ ```
134
+
135
+ ## Flag-based filtering (`--stylelint`, `--cspell`, `--editorconfig`, `--husky`, `--lint-staged`)
136
+
137
+ The `--stylelint`/`--cspell`/`--editorconfig`/`--husky`/`--lint-staged` flags control **strip/inject** behavior. For these flags to work with your custom preset, you must include **all** relevant config files and dependencies in the preset directory — lux can only strip what already exists; it cannot inject what is missing.
138
+
139
+ ### Three-layer filtering
140
+
141
+ When a flag is **not** passed (default), lux skips the corresponding files, deps, and scripts. When a flag **is** passed, those items are preserved.
142
+
143
+ | Layer | Matching rule | Examples |
144
+ | :------------ | :----------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------- |
145
+ | **Files** | Exact filename match | `stylelint.config.mjs`, `.stylelintignore`, `cspell.json`, `.editorconfig`, `.lintstagedrc.json` |
146
+ | **Deps** | stylelint: predefined set match; editorconfig: `includes('editorconfig')`; cspell: `dep === 'cspell'`; husky: `dep === 'husky'`; lint-staged: `dep === 'lint-staged'` | `stylelint`, `postcss-html`, `cspell`, `editorconfig-checker`, `husky`, `lint-staged` |
147
+ | **Script keys** | **Case-sensitive** `key.includes(keyword)` match + inline command segment stripping | See detailed rules below |
148
+
149
+ ### Script naming convention (important)
150
+
151
+ lux checks whether a script **key** contains a specific keyword to decide if it should be filtered:
152
+
153
+ | Script key example | Filtered by `--stylelint`? | Reason |
154
+ | :------------------------------ | :------------------------- | :-------------------------------------------- |
155
+ | `stylelint:check` | ✅ Yes | key contains `stylelint` (all lowercase) |
156
+ | `stylelint` | ✅ Yes | key contains `stylelint` |
157
+ | `Stylelint:check` | ❌ No | uppercase `S`, case-sensitive mismatch |
158
+ | `style:check` | ❌ No | key does not contain the full word `stylelint` |
159
+ | `lintX:check` | ❌ No | key does not contain any known keyword |
160
+
161
+ The same rules apply to `cspell` and `editorconfig`:
162
+
163
+ | Keyword | Matching key examples | Non-matching key examples |
164
+ | :-------------- | :---------------------------- | :------------------------------ |
165
+ | `stylelint` | `stylelint:check`, `stylelint` | `Stylelint:*`, `style:*` |
166
+ | `cspell` | `cspell`, `cspell:check` | `Cspell:*`, `spell:*` |
167
+ | `editorconfig` | `editorconfig:check` | `Editorconfig:*`, `editor:*` |
168
+ | `lint-staged` | `lint-staged`, `lint-staged:check` | `Lint-staged:*` (case-sensitive) |
56
169
 
170
+ **Non-matching script keys are copied as-is** to the target project — lux does not process them.
171
+
172
+ ### Inline command segment stripping
173
+
174
+ lux also strips inline tool invocation segments from **composite scripts**:
175
+
176
+ ```jsonc
177
+ {
178
+ "scripts": {
179
+ // Original: composite script with stylelint and cspell
180
+ "lint": "<pm> eslint . && stylelint \"src/**/*.{css,scss,vue}\" && cspell --gitignore \"src/**/*\"",
181
+
182
+ // When --stylelint and --cspell are NOT passed, both segments are stripped
183
+ // Result: "lint": "<pm> eslint ."
184
+ }
185
+ }
57
186
  ```
58
- lux init --preset
59
- → materialize all built-in presets to ~/.lux/preset/ (no cwd writes)
60
187
 
61
- lux fmt web-vue (in target project)
62
- → local preset exists → use local version (with custom edits)
63
- → local preset missing → generate from built-in + materialize (also writes to cwd)
188
+ Inline stripping matches `&& stylelint "..."` and `&& cspell ...` patterns in command text.
64
189
 
65
- lux vscode web-vue (in target project)
66
- → same as above
190
+ ### Full custom preset example (all flags supported)
191
+
192
+ To make `--stylelint`, `--cspell`, `--editorconfig`, `--husky`, and `--lint-staged` all functional, your custom preset should include configs for **every tool**:
193
+
194
+ ```
195
+ ~/.lux/preset/fmt/my-full-preset/
196
+ ├── eslint.config.mjs # ESLint config
197
+ ├── .prettierrc # Prettier config
198
+ ├── .prettierignore # Prettier ignore rules
199
+ ├── stylelint.config.mjs # ← enables --stylelint
200
+ ├── .stylelintignore # ← enables --stylelint
201
+ ├── cspell.json # ← enables --cspell
202
+ ├── .editorconfig # ← enables --editorconfig
203
+ ├── .lintstagedrc.json # ← enables --lint-staged
204
+ └── package.json # with all devDependencies and scripts
205
+ ```
206
+
207
+ The `package.json` should include corresponding deps and scripts:
208
+
209
+ ```jsonc
210
+ {
211
+ "devDependencies": {
212
+ "eslint": "<latest>",
213
+ "prettier": "<latest>",
214
+ // ← enables --stylelint
215
+ "stylelint": "<latest>",
216
+ "stylelint-config-standard-scss": "<latest>",
217
+ "stylelint-order": "<latest>",
218
+ "postcss-html": "<latest>",
219
+ // ← enables --cspell
220
+ "cspell": "<latest>",
221
+ // ← enables --husky
222
+ "husky": "<latest>",
223
+ // ← enables --lint-staged
224
+ "lint-staged": "<latest>"
225
+ },
226
+ "scripts": {
227
+ "lint": "<pm> eslint .",
228
+ "lint:fix": "<pm> eslint . --fix --cache --cache-location node_modules/.cache/.eslintcache",
229
+ // ← key contains "stylelint", controllable by --stylelint
230
+ "stylelint:check": "<pm> stylelint \"src/**/*.{css,scss,vue}\"",
231
+ // ← key contains "cspell", controllable by --cspell
232
+ "cspell": "<pm> cspell \"**\"",
233
+ // ← key contains "lint-staged", controllable by --lint-staged
234
+ "lint-staged": "lint-staged"
235
+ }
236
+ }
237
+ ```
238
+
239
+ Usage:
240
+
241
+ ```bash
242
+ lux fmt my-full-preset # ESLint + Prettier only
243
+ lux fmt my-full-preset --stylelint # + Stylelint
244
+ lux fmt my-full-preset --stylelint --cspell # + Stylelint + CSpell
245
+ lux fmt my-full-preset --stylelint --cspell --editorconfig # + Stylelint + CSpell + EditorConfig
246
+ lux fmt my-full-preset --lint-staged # + lint-staged + husky
247
+ lux fmt my-full-preset --stylelint --cspell --lint-staged # all tools
67
248
  ```
@@ -6,34 +6,58 @@ description: Use when setting up ESLint, Prettier, CSpell, Stylelint, EditorConf
6
6
  ## fmt — generate lint/format configs
7
7
 
8
8
  ```bash
9
- lux fmt <preset> [--stylelint] [--editorconfig]
9
+ lux fmt <preset> [--stylelint] [--editorconfig] [--cspell] [--husky] [--lint-staged]
10
10
  lux fmt list
11
11
  ```
12
12
 
13
- - `--force` overwrite existing config files (default: skip)
14
- - `--dry-run` — preview what would be generated, write nothing
15
- - `--no-install` — write deps to package.json but skip install
16
- - `--reset` — reset local preset, re-materialize from built-in defaults
13
+ built-in presets: `web-vue` `web-react` `electron-vue` `uniapp` `node` `nest`
17
14
 
18
- Presets: `web-vue` `web-react` `electron-vue` `uniapp` `node` `nest`
15
+ ### Opt-in flags
16
+
17
+ Only ESLint + Prettier are generated by default. Add flags to include additional tools:
18
+
19
+ - `--stylelint` — generate stylelint config + deps + scripts
20
+ - `--editorconfig` — generate .editorconfig + deps
21
+ - `--cspell` — generate cspell.json + deps + scripts
22
+ - `--husky` — initialize husky for Git hooks (creates `.husky/pre-commit`, injects init script, executes once)
23
+ - `--lint-staged` — generate `.lintstagedrc.json` + deps + scripts (implies `--husky`)
24
+
25
+ Each flag controls three layers of filtering — **files** (exact filename), **deps** (set/exact match), **script keys** (`key.includes(keyword)`, case-sensitive). See `references/custom-preset-setting.md` for details.
26
+
27
+ ### Control flags
28
+
29
+ - `--force` — overwrite existing config files **and** scripts. Default behavior skips existing files and package.json scripts. `--force` does not affect deps — deps are always additive (missing only, no version overwrite).
30
+ - `--dry-run` — preview mode, write nothing. Outputs `[dry-run]` prefixed messages showing what would happen.
31
+ - `--no-install` — write deps to package.json but **skip** `bun/npm install`. Useful for CI or manual install control.
32
+ - `--reset` — reset local preset. For built-in presets: deletes `~/.lux/preset/fmt/<name>/` and re-materializes from built-in template. For custom presets: **aborts immediately** with a warning (no built-in source to restore).
33
+
34
+ ### list
35
+
36
+ `lux fmt list` — Built-in presets first, custom presets last, marked with **(custom)**.
19
37
 
20
38
  ## vscode — generate editor settings
21
39
 
22
40
  ```bash
23
- lux vscode <preset> [--dry-run]
41
+ lux vscode <preset> [--stylelint]
24
42
  lux vscode list
25
43
  ```
26
44
 
27
- - `--force` overwrite existing settings (default: skip)
28
- - `--dry-run` — preview what would be generated, write nothing
29
- - `--reset` — reset local preset, re-materialize from built-in defaults
45
+ built-in presets: `web-vue` `web-react` `electron-vue` `uniapp` `node` `nest` `go`
46
+
47
+ ### Opt-in flags
48
+
49
+ - `--stylelint` — include Stylelint VSCode settings and extension recommendation
50
+
51
+ ### Control flags
30
52
 
31
- Presets: `web-vue` `web-react` `electron-vue` `uniapp` `node` `nest` `go`
53
+ - `--force` overwrite existing .vscode/settings.json and .vscode/extensions.json (default: skip)
54
+ - `--dry-run` — preview mode
55
+ - `--reset` — reset local vscode preset (built-in presets only)
32
56
 
33
57
  ## init — initialize skills or presets
34
58
 
35
59
  ```bash
36
- lux init # interactively select AI tool, copy skill files to project
60
+ lux init # interactively select AI tool, copy skill files to AI Agent
37
61
  lux init --preset # materialize all built-in presets to ~/.lux/preset/ (no cwd writes, no package.json required)
38
62
  ```
39
63
 
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@luxkit/cli",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "One-click project formatting & VSCode config CLI",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "lux": "dist/index.js"
8
8
  },
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "README_Zh.md"
11
12
  ],
12
13
  "publishConfig": {
13
14
  "access": "public"
@@ -21,7 +22,9 @@
21
22
  "prepublishOnly": "cross-env NODE_ENV=production bun run build",
22
23
  "test": "vitest run",
23
24
  "test:watch": "vitest",
24
- "test:coverage": "vitest run --coverage"
25
+ "test:coverage": "vitest run --coverage",
26
+ "code:check": "bun run lint && bun run format:check",
27
+ "prepare": "husky"
25
28
  },
26
29
  "keywords": [
27
30
  "cli",
@@ -42,6 +45,12 @@
42
45
  "chalk": "5",
43
46
  "commander": "^14.0.3"
44
47
  },
48
+ "lint-staged": {
49
+ "src/**/*.{ts,js,json}": [
50
+ "eslint --fix",
51
+ "prettier --write"
52
+ ]
53
+ },
45
54
  "devDependencies": {
46
55
  "@eslint/js": "10.0.1",
47
56
  "@types/node": "^25.5.2",
@@ -51,6 +60,8 @@
51
60
  "eslint": "10.2.0",
52
61
  "eslint-config-prettier": "10.1.8",
53
62
  "eslint-plugin-prettier": "5.5.5",
63
+ "husky": "^9.1.7",
64
+ "lint-staged": "^17.0.4",
54
65
  "prettier": "3.8.1",
55
66
  "tsup": "^8.5.1",
56
67
  "typescript": "^6.0.2",