@fredwsw/frontend-rules 1.0.0 → 1.0.1

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 (2) hide show
  1. package/README.md +26 -276
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,302 +1,52 @@
1
- # `@sanshui/frontend-rules` 使用说明
1
+ # frontend-rules
2
2
 
3
- 本文档说明如何把当前仓库的规则模板打包成一个可执行 npm 包,并通过 `pnpm dlx` 在其他项目一键同步到项目根目录。
3
+ 一个用于将最新 `.cursor` 规则同步到当前项目根目录的小工具。
4
4
 
5
- ## 目标
5
+ ## 快速开始
6
6
 
7
- - 发布一个包:`@sanshui/frontend-rules`
8
- - 在任意项目根目录执行:
7
+ 在你的项目根目录执行:
9
8
 
10
9
  ```bash
11
- pnpm dlx @sanshui/frontend-rules@latest
10
+ pnpm dlx @fredwsw/frontend-rules@latest
12
11
  ```
13
12
 
14
- - 自动将包内模板按需同步到当前项目根目录:
15
- - 规则和技能同步到 `.cursor`
16
- - 组件库文档同步到 `docs`
13
+ ## 使用前提
17
14
 
18
- ---
15
+ - 已安装 Node.js `>=18`
16
+ - 已安装 `pnpm`
17
+ - 当前命令行所在目录是你希望应用规则的项目根目录
19
18
 
20
- ## 一、建议的包结构
19
+ ## 执行后会发生什么
21
20
 
22
- 新建一个用于发布的仓库(或就在当前仓库整理),结构建议如下:
21
+ - 工具会引导你选择需要的规则模板
22
+ - 将选中的规则文件写入当前项目(通常是 `.cursor/rules` 相关目录)
23
+ - 如果目标文件已存在,按工具提示处理覆盖或更新
23
24
 
24
- ```text
25
- frontend-rules/
26
- bin/
27
- cli.js
28
- template/
29
- rules/
30
- common.mdc
31
- uv-ui-docs.mdc
32
- ...
33
- docs/
34
- uv-ui-docs/
35
- ...
36
- skills/
37
- ...
38
- package.json
39
- README.md
40
- ```
41
-
42
- 说明:
43
-
44
- - `template/rules`:规则文件模板。
45
- - `template/docs`:组件库文档模板,按用户选择复制。
46
- - `template/skills`:技能模板。
47
- - `bin/cli.js`:`pnpm dlx` 实际执行入口。
48
-
49
- ---
50
-
51
- ## 二、`package.json` 示例
52
-
53
- > 包名改成你的正式名:`@sanshui/frontend-rules`
54
-
55
- ```json
56
- {
57
- "name": "@sanshui/frontend-rules",
58
- "version": "1.0.0",
59
- "description": "Sync latest .cursor rules into project root",
60
- "type": "module",
61
- "bin": {
62
- "frontend-rules": "./bin/cli.js"
63
- },
64
- "files": [
65
- "bin",
66
- "template",
67
- "README.md"
68
- ],
69
- "engines": {
70
- "node": ">=18"
71
- },
72
- "dependencies": {
73
- "@inquirer/prompts": "^7.8.4",
74
- "fs-extra": "^11.2.0"
75
- },
76
- "license": "MIT"
77
- }
78
- ```
79
-
80
- ---
81
-
82
- ## 三、`bin/cli.js` 示例
83
-
84
- > 作用:基础规则与技能始终复制到 `.cursor`,组件库文档支持交互多选后按需复制到项目根目录 `docs`。支持 `--dry-run`。
85
-
86
- ```js
87
- #!/usr/bin/env node
88
- import path from "node:path";
89
- import process from "node:process";
90
- import { fileURLToPath } from "node:url";
91
- import fs from "fs-extra";
92
- import { checkbox } from "@inquirer/prompts";
93
-
94
- const cwd = process.cwd();
95
- const __filename = fileURLToPath(import.meta.url);
96
- const __dirname = path.dirname(__filename);
97
- const root = path.resolve(__dirname, "..");
98
- const sourceDir = path.join(root, "template");
99
- const cursorTargetDir = path.join(cwd, ".cursor");
100
- const docsTargetRootDir = path.join(cwd, "docs");
101
- const args = new Set(process.argv.slice(2));
102
- const dryRun = args.has("--dry-run");
103
- const allLibs = args.has("--all-libs");
104
- const libsArg = [...args].find((arg) => arg.startsWith("--libs="));
105
-
106
- function parseLibsArg() {
107
- if (!libsArg) {
108
- return null;
109
- }
110
- const value = libsArg.slice("--libs=".length).trim();
111
- if (!value) {
112
- return [];
113
- }
114
- return value.split(",").map((item) => item.trim()).filter(Boolean);
115
- }
116
-
117
- async function getLibraryOptions() {
118
- const docsRoot = path.join(sourceDir, "docs");
119
- const exists = await fs.pathExists(docsRoot);
120
- if (!exists) {
121
- return [];
122
- }
123
- const entries = await fs.readdir(docsRoot, { withFileTypes: true });
124
- return entries.filter((entry) => entry.isDirectory()).map((entry) => {
125
- const docsDirName = entry.name;
126
- return {
127
- key: docsDirName.replace(/-docs$/i, ""),
128
- docsDirName,
129
- docsSourcePath: path.join(docsRoot, docsDirName),
130
- ruleFileName: `${docsDirName}.mdc`,
131
- ruleSourcePath: path.join(sourceDir, "rules", `${docsDirName}.mdc`),
132
- };
133
- });
134
- }
135
-
136
- async function promptLibraries(options) {
137
- if (options.length === 0) {
138
- return [];
139
- }
140
- if (!process.stdin.isTTY) {
141
- return options;
142
- }
143
- const selectedKeys = await checkbox({
144
- message: "请选择组件库(方向键移动,空格勾选,回车确认)",
145
- choices: options.map((option) => ({ name: option.key, value: option.key })),
146
- });
147
- if (!selectedKeys || selectedKeys.length === 0) {
148
- return [];
149
- }
150
- return options.filter((option) => new Set(selectedKeys).has(option.key));
151
- }
25
+ ## 推荐用法
152
26
 
153
- async function resolveSelectedLibraries(options) {
154
- if (allLibs) {
155
- return options;
156
- }
157
- const parsedLibKeys = parseLibsArg();
158
- if (parsedLibKeys !== null) {
159
- return options.filter((option) => new Set(parsedLibKeys).has(option.key));
160
- }
161
- return promptLibraries(options);
162
- }
163
-
164
- async function copyWithDryRun(from, to) {
165
- if (dryRun) {
166
- console.log("[frontend-rules] copy:", from, "->", to);
167
- return;
168
- }
169
- await fs.copy(from, to, { overwrite: true, recursive: true });
170
- }
171
-
172
- async function main() {
173
- await fs.ensureDir(cursorTargetDir);
174
- await fs.ensureDir(docsTargetRootDir);
175
-
176
- await copyWithDryRun(path.join(sourceDir, "rules", "common.mdc"), path.join(cursorTargetDir, "rules", "common.mdc"));
177
- await copyWithDryRun(path.join(sourceDir, "skills"), path.join(cursorTargetDir, "skills"));
178
-
179
- const options = await getLibraryOptions();
180
- const selectedLibraries = await resolveSelectedLibraries(options);
181
- for (const library of selectedLibraries) {
182
- await copyWithDryRun(library.docsSourcePath, path.join(docsTargetRootDir, library.docsDirName));
183
- if (await fs.pathExists(library.ruleSourcePath)) {
184
- await copyWithDryRun(library.ruleSourcePath, path.join(cursorTargetDir, "rules", library.ruleFileName));
185
- }
186
- }
187
- }
188
-
189
- main();
190
- ```
191
-
192
- ---
193
-
194
- ## 四、本地联调
195
-
196
- 在包仓库目录执行:
27
+ 每次想同步最新规则时,直接重复执行:
197
28
 
198
29
  ```bash
199
- pnpm install
200
- node ./bin/cli.js --dry-run
201
- node ./bin/cli.js
30
+ pnpm dlx @fredwsw/frontend-rules@latest
202
31
  ```
203
32
 
204
- 然后检查当前目录是否生成/更新了:
205
-
206
- - `.cursor/rules`
207
- - `.cursor/skills`
208
- - `docs/<组件库>-docs`
33
+ 这样无需全局安装,始终使用最新版本。
209
34
 
210
- ---
35
+ ## 常见问题
211
36
 
212
- ## 五、发布到 npm
37
+ ### 1) 提示 `pnpm` 命令不存在
213
38
 
214
- 1. 登录 npm(首次)
39
+ 请先安装 pnpm:
215
40
 
216
41
  ```bash
217
- npm login
42
+ npm i -g pnpm
218
43
  ```
219
44
 
220
- 2. 发布(Scoped 包通常建议公开)
221
-
222
- ```bash
223
- npm publish --access public
224
- ```
225
-
226
- 3. 后续更新流程
227
-
228
- ```bash
229
- # 修改 template/.cursor 内容后
230
- npm version patch
231
- npm publish --access public
232
- ```
233
-
234
- ---
235
-
236
- ## 六、在其他项目中使用
237
-
238
- 进入目标项目根目录,执行:
239
-
240
- ```bash
241
- pnpm dlx @sanshui/frontend-rules@latest
242
- ```
243
-
244
- 常用变体:
245
-
246
- ```bash
247
- # 只预览,不落盘(若你实现了 --dry-run 参数)
248
- pnpm dlx @sanshui/frontend-rules@latest --dry-run
249
-
250
- # 不交互,直接选择全部组件库
251
- pnpm dlx @sanshui/frontend-rules@latest --all-libs
252
-
253
- # 不交互,指定组件库(可多选,逗号分隔)
254
- pnpm dlx @sanshui/frontend-rules@latest --libs=uv-ui,first-ui
255
- ```
256
-
257
- ---
258
-
259
- ## 七、推荐约定(团队协作)
260
-
261
- - 把 `.cursor` 规则维护统一放在 `@sanshui/frontend-rules`,业务仓库不各自散改。
262
- - 每次规则更新都发版,业务仓库按需执行 `pnpm dlx ...@latest` 同步。
263
- - 若业务仓库存在少量本地特化,可约定放在单独文件并在同步后手动合并。
264
-
265
- ---
266
-
267
- ## 八、常见问题
268
-
269
- ### 1)`pnpm dlx` 没拿到最新版本?
270
-
271
- - 显式指定 `@latest`:
272
-
273
- ```bash
274
- pnpm dlx @sanshui/frontend-rules@latest
275
- ```
276
-
277
- - 确认刚发布版本已在 npm 可见。
278
-
279
- ### 2)会不会覆盖本地 `.cursor`?
280
-
281
- - 当前示例是覆盖策略(`overwrite: true`)。
282
- - 如果你想保守一点,可扩展参数:
283
- - `--force` 才覆盖
284
- - 默认仅拷贝不存在文件
285
- - 或执行前先备份到 `.cursor.bak-时间戳`
286
-
287
- ### 3)如何控制复制哪些组件库文档?
288
-
289
- - 交互模式下支持方向键上下移动、空格勾选、回车确认(基于 `@inquirer/prompts`)。
290
- - 非交互可用 `--libs=uv-ui,first-ui`。
291
- - 全量组件库可用 `--all-libs`。
292
-
293
- ---
45
+ ### 2) 提示 Node 版本过低
294
46
 
295
- ## 九、最小执行清单
47
+ 请升级 Node.js 到 `18` 或更高版本后重试。
296
48
 
297
- 1. 准备 `template/rules`、`template/docs`、`template/skills` 模板目录。
298
- 2. 写好 `bin/cli.js` 复制逻辑。
299
- 3. 配置 `package.json` 的 `name`、`bin`、`files`。
300
- 4. `npm publish --access public`。
301
- 5. 在业务项目运行:`pnpm dlx @sanshui/frontend-rules@latest`,按提示多选组件库。
49
+ ### 3) 我应该在什么目录执行命令?
302
50
 
51
+ 在你要应用规则的项目根目录执行命令。
52
+ 例如你的业务项目目录,而不是这个工具包源码目录。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fredwsw/frontend-rules",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Sync latest .cursor rules into project root",
5
5
  "type": "module",
6
6
  "bin": {