@qilitt-mickey/vue3-temp-skill 1.0.8
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 +229 -0
- package/SKILL.md +621 -0
- package/bin/cli.js +579 -0
- package/package.json +46 -0
- package/references/advanced-ui.md +302 -0
- package/references/api-check.md +272 -0
- package/references/base-code-dict.md +48 -0
- package/references/build-optim.md +282 -0
- package/references/code-quality.md +235 -0
- package/references/crud-pages.md +316 -0
- package/references/data-compare.md +501 -0
- package/references/data-mapping.md +213 -0
- package/references/data-screen.md +79 -0
- package/references/data-writeback.md +104 -0
- package/references/detail-page.md +99 -0
- package/references/directives-advanced.md +93 -0
- package/references/download-export.md +68 -0
- package/references/feedback-loading.md +60 -0
- package/references/feedback-ui.md +111 -0
- package/references/file-management.md +132 -0
- package/references/flowchart-g6.md +244 -0
- package/references/form-advanced.md +137 -0
- package/references/graph-relation.md +253 -0
- package/references/http-api.md +188 -0
- package/references/layout-theme.md +540 -0
- package/references/mobile-h5.md +271 -0
- package/references/permission-auth.md +235 -0
- package/references/project-inventory.md +326 -0
- package/references/qrcode-barcode.md +92 -0
- package/references/rich-text.md +73 -0
- package/references/seamless-scroll.md +38 -0
- package/references/tree-table.md +111 -0
- package/references/ui-components.md +161 -0
- package/references/verify-captcha.md +96 -0
- package/references/vue-core.md +209 -0
- package/references/websocket-realtime.md +176 -0
- package/references/workflow-bpmn.md +206 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* vue3-temp-skill CLI
|
|
5
|
+
*
|
|
6
|
+
* 将 Vue 3 项目开发规范技能安装到指定 AI 工具
|
|
7
|
+
*
|
|
8
|
+
* 用法:
|
|
9
|
+
* vue3-temp-skill install <target> [options] 安装到指定 AI 工具
|
|
10
|
+
* vue3-temp-skill update [target] [options] 更新已安装的技能(默认更新全部已安装目标)
|
|
11
|
+
* vue3-temp-skill uninstall [target] [options] 卸载已安装的技能(默认卸载全部)
|
|
12
|
+
* vue3-temp-skill list 查看已安装的目标
|
|
13
|
+
* vue3-temp-skill --help 帮助
|
|
14
|
+
* vue3-temp-skill --version 版本号
|
|
15
|
+
*
|
|
16
|
+
* 通过 npx / pnpx 使用时自动下载最新版本:
|
|
17
|
+
* npx @qilitt/vue3-temp-skill@latest install cursor
|
|
18
|
+
* npx @qilitt/vue3-temp-skill@latest update
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const fs = require("fs");
|
|
22
|
+
const path = require("path");
|
|
23
|
+
const os = require("os");
|
|
24
|
+
const { execSync } = require("child_process");
|
|
25
|
+
|
|
26
|
+
const HOME = os.homedir();
|
|
27
|
+
// bin/cli.js → 上一级即包根目录
|
|
28
|
+
const SKILL_DIR = path.resolve(__dirname, "..");
|
|
29
|
+
const SKILL_NAME = "vue3-temp-skill";
|
|
30
|
+
const TRACK_FILE = path.join(HOME, ".vue3-temp-skill.json");
|
|
31
|
+
|
|
32
|
+
// ============================================================
|
|
33
|
+
// 版本
|
|
34
|
+
// ============================================================
|
|
35
|
+
const PKG_VERSION = require(path.join(SKILL_DIR, "package.json")).version;
|
|
36
|
+
|
|
37
|
+
// ============================================================
|
|
38
|
+
// AI 工具配置
|
|
39
|
+
// ============================================================
|
|
40
|
+
const TARGETS = {
|
|
41
|
+
cursor: {
|
|
42
|
+
name: "Cursor",
|
|
43
|
+
dir: (p) => (p ? path.join(p, ".cursor/rules") : path.join(HOME, ".cursor/rules")),
|
|
44
|
+
type: "rules",
|
|
45
|
+
},
|
|
46
|
+
qoder: {
|
|
47
|
+
name: "Qoder",
|
|
48
|
+
dir: (p) => (p ? path.join(p, ".qoder/skills") : path.join(HOME, ".qoderworkcn/skills")),
|
|
49
|
+
type: "skills",
|
|
50
|
+
},
|
|
51
|
+
copilot: {
|
|
52
|
+
name: "GitHub Copilot",
|
|
53
|
+
file: (p) => path.join(p || ".", ".github/copilot-instructions.md"),
|
|
54
|
+
type: "merge",
|
|
55
|
+
},
|
|
56
|
+
windsurf: {
|
|
57
|
+
name: "Windsurf",
|
|
58
|
+
dir: (p) => (p ? path.join(p, ".windsurf/rules") : path.join(HOME, ".windsurf/rules")),
|
|
59
|
+
type: "rules",
|
|
60
|
+
},
|
|
61
|
+
gemini: {
|
|
62
|
+
name: "Gemini CLI",
|
|
63
|
+
file: (p) => path.join(p || ".", "GEMINI.md"),
|
|
64
|
+
type: "merge",
|
|
65
|
+
},
|
|
66
|
+
trae: {
|
|
67
|
+
name: "Trae",
|
|
68
|
+
dir: (p) => (p ? path.join(p, ".trae/rules") : path.join(HOME, ".trae/rules")),
|
|
69
|
+
type: "rules",
|
|
70
|
+
},
|
|
71
|
+
claude: {
|
|
72
|
+
name: "Claude Code",
|
|
73
|
+
dir: (p) => (p ? path.join(p, ".claude/skills") : path.join(HOME, ".claude/skills")),
|
|
74
|
+
type: "skills",
|
|
75
|
+
},
|
|
76
|
+
universal: {
|
|
77
|
+
name: "Universal",
|
|
78
|
+
dir: (p) => path.join(p || ".", ".agents/skills"),
|
|
79
|
+
type: "skills",
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// ============================================================
|
|
84
|
+
// 样式
|
|
85
|
+
// ============================================================
|
|
86
|
+
const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
|
|
87
|
+
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
88
|
+
const red = (s) => `\x1b[31m${s}\x1b[0m`;
|
|
89
|
+
const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
|
|
90
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
91
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
92
|
+
|
|
93
|
+
// ============================================================
|
|
94
|
+
// 工具函数
|
|
95
|
+
// ============================================================
|
|
96
|
+
|
|
97
|
+
function ensureDir(dir) {
|
|
98
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 复制单个文件
|
|
103
|
+
*/
|
|
104
|
+
function copyFile(src, dest) {
|
|
105
|
+
if (fs.existsSync(src)) {
|
|
106
|
+
fs.copyFileSync(src, dest);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 复制目录(仅用于 references/ 等已知安全的小目录)
|
|
112
|
+
*/
|
|
113
|
+
function copyDir(src, dest) {
|
|
114
|
+
ensureDir(dest);
|
|
115
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
116
|
+
if (entry.name.startsWith(".") || entry.isSymbolicLink()) continue;
|
|
117
|
+
const s = path.join(src, entry.name);
|
|
118
|
+
const d = path.join(dest, entry.name);
|
|
119
|
+
if (entry.isDirectory()) copyDir(s, d);
|
|
120
|
+
else fs.copyFileSync(s, d);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function removeDir(dir) {
|
|
125
|
+
if (!fs.existsSync(dir)) return;
|
|
126
|
+
try {
|
|
127
|
+
if (process.platform === "win32") {
|
|
128
|
+
// Windows: rd /s /q 使用系统 API 删除,不受 Node.js 调用栈限制
|
|
129
|
+
execSync(`rd /s /q "${dir}"`, { stdio: "ignore" });
|
|
130
|
+
} else {
|
|
131
|
+
execSync(`rm -rf "${dir}"`, { stdio: "ignore" });
|
|
132
|
+
}
|
|
133
|
+
} catch {
|
|
134
|
+
// 兜底:尝试 Node.js 原生方法
|
|
135
|
+
try {
|
|
136
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
137
|
+
} catch {
|
|
138
|
+
// 静默失败,目录可能已被删除
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 读取技能完整内容:SKILL.md + references/*.md
|
|
145
|
+
*/
|
|
146
|
+
function readFullSkill() {
|
|
147
|
+
let content = "";
|
|
148
|
+
|
|
149
|
+
const skillMd = path.join(SKILL_DIR, "SKILL.md");
|
|
150
|
+
if (fs.existsSync(skillMd)) content += fs.readFileSync(skillMd, "utf-8");
|
|
151
|
+
|
|
152
|
+
const refsDir = path.join(SKILL_DIR, "references");
|
|
153
|
+
if (fs.existsSync(refsDir)) {
|
|
154
|
+
for (const f of fs.readdirSync(refsDir).filter((f) => f.endsWith(".md")).sort()) {
|
|
155
|
+
content += `\n\n---\n\n${fs.readFileSync(path.join(refsDir, f), "utf-8")}`;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return content;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ============================================================
|
|
162
|
+
// 安装记录(用于 update / list / uninstall)
|
|
163
|
+
// ============================================================
|
|
164
|
+
|
|
165
|
+
function readTrack() {
|
|
166
|
+
try {
|
|
167
|
+
return JSON.parse(fs.readFileSync(TRACK_FILE, "utf-8"));
|
|
168
|
+
} catch {
|
|
169
|
+
return { installed: [], version: "" };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function writeTrack(data) {
|
|
174
|
+
fs.writeFileSync(TRACK_FILE, JSON.stringify(data, null, 2), "utf-8");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function recordInstall(targetKey, projectDir) {
|
|
178
|
+
const track = readTrack();
|
|
179
|
+
const key = projectDir ? `${targetKey}@${projectDir}` : targetKey;
|
|
180
|
+
if (!track.installed.includes(key)) {
|
|
181
|
+
track.installed.push(key);
|
|
182
|
+
}
|
|
183
|
+
track.version = PKG_VERSION;
|
|
184
|
+
track.updatedAt = new Date().toISOString();
|
|
185
|
+
writeTrack(track);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function recordUninstall(targetKey, projectDir) {
|
|
189
|
+
const track = readTrack();
|
|
190
|
+
const key = projectDir ? `${targetKey}@${projectDir}` : targetKey;
|
|
191
|
+
track.installed = track.installed.filter((k) => k !== key);
|
|
192
|
+
writeTrack(track);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ============================================================
|
|
196
|
+
// 安装逻辑
|
|
197
|
+
// ============================================================
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* rules 类型:Cursor / Windsurf / Trae
|
|
201
|
+
*/
|
|
202
|
+
function installRules(targetKey, projectDir) {
|
|
203
|
+
const cfg = TARGETS[targetKey];
|
|
204
|
+
const targetDir = cfg.dir(projectDir);
|
|
205
|
+
ensureDir(targetDir);
|
|
206
|
+
|
|
207
|
+
const content = readFullSkill();
|
|
208
|
+
const ext = targetKey === "cursor" ? ".mdc" : ".md";
|
|
209
|
+
|
|
210
|
+
const ruleContent =
|
|
211
|
+
targetKey === "cursor"
|
|
212
|
+
? `---\ndescription: ${SKILL_NAME}\nglobs: **/*.vue,**/*.ts,**/*.js,**/*.tsx,**/*.jsx\nalwaysApply: true\n---\n\n${content}\n`
|
|
213
|
+
: content;
|
|
214
|
+
|
|
215
|
+
const file = path.join(targetDir, `${SKILL_NAME}${ext}`);
|
|
216
|
+
fs.writeFileSync(file, ruleContent, "utf-8");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* skills 类型:Qoder / Claude / Universal
|
|
221
|
+
*/
|
|
222
|
+
function installSkills(targetKey, projectDir) {
|
|
223
|
+
const cfg = TARGETS[targetKey];
|
|
224
|
+
const targetDir = cfg.dir(projectDir);
|
|
225
|
+
const dest = path.join(targetDir, SKILL_NAME);
|
|
226
|
+
|
|
227
|
+
// 先清理旧版本
|
|
228
|
+
if (fs.existsSync(dest)) {
|
|
229
|
+
removeDir(dest);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// 只复制必要文件,不复制整个包目录(避免缓存目录中的无关文件导致递归)
|
|
233
|
+
ensureDir(dest);
|
|
234
|
+
copyFile(path.join(SKILL_DIR, "SKILL.md"), path.join(dest, "SKILL.md"));
|
|
235
|
+
copyFile(path.join(SKILL_DIR, "README.md"), path.join(dest, "README.md"));
|
|
236
|
+
|
|
237
|
+
const refsSrc = path.join(SKILL_DIR, "references");
|
|
238
|
+
if (fs.existsSync(refsSrc)) {
|
|
239
|
+
copyDir(refsSrc, path.join(dest, "references"));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* merge 类型:Copilot / Gemini
|
|
245
|
+
*/
|
|
246
|
+
function installMerge(targetKey, projectDir) {
|
|
247
|
+
const cfg = TARGETS[targetKey];
|
|
248
|
+
const targetFile = cfg.file(projectDir);
|
|
249
|
+
ensureDir(path.dirname(targetFile));
|
|
250
|
+
|
|
251
|
+
const content = readFullSkill();
|
|
252
|
+
fs.writeFileSync(targetFile, content, "utf-8");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function installTarget(targetKey, projectDir) {
|
|
256
|
+
const cfg = TARGETS[targetKey];
|
|
257
|
+
if (cfg.type === "rules") installRules(targetKey, projectDir);
|
|
258
|
+
else if (cfg.type === "skills") installSkills(targetKey, projectDir);
|
|
259
|
+
else if (cfg.type === "merge") installMerge(targetKey, projectDir);
|
|
260
|
+
|
|
261
|
+
recordInstall(targetKey, projectDir);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ============================================================
|
|
265
|
+
// 卸载逻辑
|
|
266
|
+
// ============================================================
|
|
267
|
+
|
|
268
|
+
function uninstallTarget(targetKey, projectDir) {
|
|
269
|
+
const cfg = TARGETS[targetKey];
|
|
270
|
+
|
|
271
|
+
if (cfg.type === "rules") {
|
|
272
|
+
const targetDir = cfg.dir(projectDir);
|
|
273
|
+
const ext = targetKey === "cursor" ? ".mdc" : ".md";
|
|
274
|
+
const file = path.join(targetDir, `${SKILL_NAME}${ext}`);
|
|
275
|
+
if (fs.existsSync(file)) fs.unlinkSync(file);
|
|
276
|
+
} else if (cfg.type === "skills") {
|
|
277
|
+
const targetDir = cfg.dir(projectDir);
|
|
278
|
+
const dest = path.join(targetDir, SKILL_NAME);
|
|
279
|
+
if (fs.existsSync(dest)) removeDir(dest);
|
|
280
|
+
} else if (cfg.type === "merge") {
|
|
281
|
+
const targetFile = cfg.file(projectDir);
|
|
282
|
+
if (fs.existsSync(targetFile)) fs.unlinkSync(targetFile);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
recordUninstall(targetKey, projectDir);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ============================================================
|
|
289
|
+
// CLI 命令
|
|
290
|
+
// ============================================================
|
|
291
|
+
|
|
292
|
+
function showHelp() {
|
|
293
|
+
console.log(`
|
|
294
|
+
${bold("vue3-temp-skill")} v${PKG_VERSION}
|
|
295
|
+
Vue 3 企业级中后台项目开发规范技能包
|
|
296
|
+
|
|
297
|
+
${bold("用法:")}
|
|
298
|
+
vue3-temp-skill <command> [target] [options]
|
|
299
|
+
|
|
300
|
+
${bold("命令:")}
|
|
301
|
+
install <target> 安装技能到指定 AI 工具
|
|
302
|
+
update [target] 更新已安装的技能(默认更新全部已安装目标)
|
|
303
|
+
uninstall [target] 卸载技能(默认卸载全部已安装目标)
|
|
304
|
+
list 查看已安装的目标和版本
|
|
305
|
+
|
|
306
|
+
${bold("目标 (target):")}
|
|
307
|
+
cursor → Cursor
|
|
308
|
+
qoder → Qoder
|
|
309
|
+
copilot → GitHub Copilot
|
|
310
|
+
windsurf → Windsurf
|
|
311
|
+
gemini → Gemini CLI
|
|
312
|
+
trae → Trae
|
|
313
|
+
claude → Claude Code
|
|
314
|
+
universal → 通用标准 (.agents/skills/)
|
|
315
|
+
all → 安装到所有支持的工具
|
|
316
|
+
|
|
317
|
+
${bold("选项:")}
|
|
318
|
+
--project <dir> 安装到指定项目目录(默认全局安装)
|
|
319
|
+
--help, -h 显示帮助
|
|
320
|
+
--version, -v 显示版本号
|
|
321
|
+
|
|
322
|
+
${bold("示例:")}
|
|
323
|
+
${dim("# 安装到 Cursor")}
|
|
324
|
+
npx @qilitt/vue3-temp-skill install cursor
|
|
325
|
+
|
|
326
|
+
${dim("# 安装到 Qoder(指定项目)")}
|
|
327
|
+
npx @qilitt/vue3-temp-skill install qoder --project ./my-app
|
|
328
|
+
|
|
329
|
+
${dim("# 更新所有已安装的目标(搭配 @latest 拉取最新版)")}
|
|
330
|
+
npx @qilitt/vue3-temp-skill@latest update
|
|
331
|
+
|
|
332
|
+
${dim("# 查看已安装情况")}
|
|
333
|
+
npx @qilitt/vue3-temp-skill list
|
|
334
|
+
|
|
335
|
+
${dim("# 卸载")}
|
|
336
|
+
npx @qilitt/vue3-temp-skill uninstall cursor
|
|
337
|
+
`);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function showVersion() {
|
|
341
|
+
console.log(PKG_VERSION);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function cmdInstall(target, projectDir) {
|
|
345
|
+
if (!target) {
|
|
346
|
+
console.error(red("✗ 请指定安装目标,例如: vue3-temp-skill install cursor"));
|
|
347
|
+
console.error("运行 vue3-temp-skill --help 查看所有支持的目标");
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (target === "all") {
|
|
352
|
+
const total = Object.keys(TARGETS).length;
|
|
353
|
+
let success = 0;
|
|
354
|
+
const failed = [];
|
|
355
|
+
for (const key of Object.keys(TARGETS)) {
|
|
356
|
+
try {
|
|
357
|
+
installTarget(key, projectDir);
|
|
358
|
+
success++;
|
|
359
|
+
} catch (err) {
|
|
360
|
+
failed.push(TARGETS[key].name);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (failed.length === 0) {
|
|
364
|
+
console.log(green(`✓ 已安装到全部 ${total} 个工具 (v${PKG_VERSION})`));
|
|
365
|
+
} else {
|
|
366
|
+
console.log(yellow(`✓ 安装完成: ${success}/${total} 成功`));
|
|
367
|
+
console.log(red(` ✗ 失败: ${failed.join(", ")}`));
|
|
368
|
+
}
|
|
369
|
+
} else if (TARGETS[target]) {
|
|
370
|
+
try {
|
|
371
|
+
installTarget(target, projectDir);
|
|
372
|
+
console.log(green(`✓ 已安装到 ${TARGETS[target].name} (v${PKG_VERSION})`));
|
|
373
|
+
} catch (err) {
|
|
374
|
+
console.error(red(`✗ 安装失败: ${err.message}`));
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
} else {
|
|
378
|
+
console.error(red(`✗ 未知目标: ${target}`));
|
|
379
|
+
console.error("运行 vue3-temp-skill --help 查看支持的目标");
|
|
380
|
+
process.exit(1);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function cmdUpdate(target, projectDir) {
|
|
385
|
+
const track = readTrack();
|
|
386
|
+
|
|
387
|
+
if (track.installed.length === 0) {
|
|
388
|
+
console.log(yellow("当前没有已安装的目标,请先运行 install 命令"));
|
|
389
|
+
process.exit(0);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// 如果指定了目标,只更新该目标
|
|
393
|
+
if (target) {
|
|
394
|
+
if (target !== "all" && !TARGETS[target]) {
|
|
395
|
+
console.error(red(`✗ 未知目标: ${target}`));
|
|
396
|
+
process.exit(1);
|
|
397
|
+
}
|
|
398
|
+
const targets = target === "all" ? Object.keys(TARGETS) : [target];
|
|
399
|
+
let success = 0;
|
|
400
|
+
const failed = [];
|
|
401
|
+
for (const key of targets) {
|
|
402
|
+
try {
|
|
403
|
+
installTarget(key, projectDir);
|
|
404
|
+
success++;
|
|
405
|
+
} catch (err) {
|
|
406
|
+
failed.push(TARGETS[key].name);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (failed.length === 0) {
|
|
410
|
+
console.log(green(`✓ 已更新到 v${PKG_VERSION}`));
|
|
411
|
+
} else {
|
|
412
|
+
console.log(yellow(`✓ 更新完成: ${success}/${targets.length} 成功`));
|
|
413
|
+
console.log(red(` ✗ 失败: ${failed.join(", ")}`));
|
|
414
|
+
}
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// 默认更新全部已安装目标
|
|
419
|
+
let success = 0;
|
|
420
|
+
const failed = [];
|
|
421
|
+
for (const entry of track.installed) {
|
|
422
|
+
const [targetKey, projDir] = entry.includes("@")
|
|
423
|
+
? [entry.split("@")[0], entry.split("@").slice(1).join("@")]
|
|
424
|
+
: [entry, null];
|
|
425
|
+
|
|
426
|
+
if (!TARGETS[targetKey]) continue;
|
|
427
|
+
|
|
428
|
+
try {
|
|
429
|
+
installTarget(targetKey, projDir || projectDir);
|
|
430
|
+
success++;
|
|
431
|
+
} catch (err) {
|
|
432
|
+
failed.push(TARGETS[targetKey].name);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (failed.length === 0) {
|
|
436
|
+
console.log(green(`✓ 已更新 ${success} 个工具到 v${PKG_VERSION}`));
|
|
437
|
+
} else {
|
|
438
|
+
console.log(yellow(`✓ 更新完成: ${success}/${track.installed.length} 成功`));
|
|
439
|
+
console.log(red(` ✗ 失败: ${failed.join(", ")}`));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function cmdUninstall(target, projectDir) {
|
|
444
|
+
const track = readTrack();
|
|
445
|
+
|
|
446
|
+
if (target) {
|
|
447
|
+
if (target !== "all" && !TARGETS[target]) {
|
|
448
|
+
console.error(red(`✗ 未知目标: ${target}`));
|
|
449
|
+
process.exit(1);
|
|
450
|
+
}
|
|
451
|
+
const targets = target === "all" ? Object.keys(TARGETS) : [target];
|
|
452
|
+
let success = 0;
|
|
453
|
+
const failed = [];
|
|
454
|
+
for (const key of targets) {
|
|
455
|
+
try {
|
|
456
|
+
uninstallTarget(key, projectDir);
|
|
457
|
+
success++;
|
|
458
|
+
} catch (err) {
|
|
459
|
+
failed.push(TARGETS[key].name);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (target === "all") {
|
|
463
|
+
if (failed.length === 0) {
|
|
464
|
+
console.log(green(`✓ 已卸载全部 ${success} 个工具`));
|
|
465
|
+
} else {
|
|
466
|
+
console.log(yellow(`✓ 卸载完成: ${success}/${targets.length} 成功`));
|
|
467
|
+
console.log(red(` ✗ 失败: ${failed.join(", ")}`));
|
|
468
|
+
}
|
|
469
|
+
} else {
|
|
470
|
+
if (failed.length === 0) {
|
|
471
|
+
console.log(green(`✓ 已卸载 ${TARGETS[target].name}`));
|
|
472
|
+
} else {
|
|
473
|
+
console.error(red(`✗ 卸载失败: ${failed.join(", ")}`));
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// 默认卸载全部
|
|
480
|
+
if (track.installed.length === 0) {
|
|
481
|
+
console.log(yellow("当前没有已安装的目标"));
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
let success = 0;
|
|
486
|
+
for (const entry of track.installed) {
|
|
487
|
+
const [targetKey, projDir] = entry.includes("@")
|
|
488
|
+
? [entry.split("@")[0], entry.split("@").slice(1).join("@")]
|
|
489
|
+
: [entry, null];
|
|
490
|
+
|
|
491
|
+
if (TARGETS[targetKey]) {
|
|
492
|
+
try {
|
|
493
|
+
uninstallTarget(targetKey, projDir || projectDir);
|
|
494
|
+
success++;
|
|
495
|
+
} catch {
|
|
496
|
+
// 静默
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
writeTrack({ installed: [], version: "", updatedAt: "" });
|
|
501
|
+
console.log(green(`✓ 已卸载全部 ${success} 个工具`));
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function cmdList() {
|
|
505
|
+
const track = readTrack();
|
|
506
|
+
|
|
507
|
+
console.log(bold(`\nvue3-temp-skill v${track.version || "未安装"}`));
|
|
508
|
+
console.log(dim(`记录文件: ${TRACK_FILE}\n`));
|
|
509
|
+
|
|
510
|
+
if (track.installed.length === 0) {
|
|
511
|
+
console.log(yellow("当前没有已安装的目标"));
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
console.log(bold("已安装的目标:"));
|
|
516
|
+
for (const entry of track.installed) {
|
|
517
|
+
const [targetKey, projDir] = entry.includes("@")
|
|
518
|
+
? [entry.split("@")[0], entry.split("@").slice(1).join("@")]
|
|
519
|
+
: [entry, null];
|
|
520
|
+
|
|
521
|
+
const cfg = TARGETS[targetKey];
|
|
522
|
+
const name = cfg ? cfg.name : targetKey;
|
|
523
|
+
const scope = projDir ? ` (项目: ${projDir})` : " (全局)";
|
|
524
|
+
console.log(` ${green("•")} ${name}${scope}`);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (track.updatedAt) {
|
|
528
|
+
console.log(dim(`\n最后更新: ${track.updatedAt}`));
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// ============================================================
|
|
533
|
+
// 入口
|
|
534
|
+
// ============================================================
|
|
535
|
+
|
|
536
|
+
function main() {
|
|
537
|
+
const args = process.argv.slice(2);
|
|
538
|
+
|
|
539
|
+
if (!args.length || args.includes("--help") || args.includes("-h")) {
|
|
540
|
+
showHelp();
|
|
541
|
+
process.exit(0);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
545
|
+
showVersion();
|
|
546
|
+
process.exit(0);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const command = args[0];
|
|
550
|
+
const target = args[1];
|
|
551
|
+
const projectIdx = args.indexOf("--project");
|
|
552
|
+
const projectDir = projectIdx !== -1 ? path.resolve(args[projectIdx + 1]) : null;
|
|
553
|
+
|
|
554
|
+
switch (command) {
|
|
555
|
+
case "install":
|
|
556
|
+
cmdInstall(target, projectDir);
|
|
557
|
+
break;
|
|
558
|
+
case "update":
|
|
559
|
+
cmdUpdate(target === "--project" ? null : target, projectDir);
|
|
560
|
+
break;
|
|
561
|
+
case "uninstall":
|
|
562
|
+
cmdUninstall(target === "--project" ? null : target, projectDir);
|
|
563
|
+
break;
|
|
564
|
+
case "list":
|
|
565
|
+
cmdList();
|
|
566
|
+
break;
|
|
567
|
+
default:
|
|
568
|
+
// 兼容旧用法:直接传 target 名当作 install
|
|
569
|
+
if (TARGETS[command] || command === "all") {
|
|
570
|
+
cmdInstall(command, projectDir);
|
|
571
|
+
} else {
|
|
572
|
+
console.error(red(`✗ 未知命令: ${command}`));
|
|
573
|
+
console.error("运行 vue3-temp-skill --help 查看帮助");
|
|
574
|
+
process.exit(1);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qilitt-mickey/vue3-temp-skill",
|
|
3
|
+
"version": "1.0.8",
|
|
4
|
+
"description": "Vue 3 企业级中后台项目开发规范技能包 — 让 AI 编程助手按照团队规范生成代码,并自动审查代码质量",
|
|
5
|
+
"bin": {
|
|
6
|
+
"vue3-temp-skill": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"registry": "https://registry.npmjs.org",
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"references/",
|
|
15
|
+
"SKILL.md",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22.12.0"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"release": "node release.js",
|
|
23
|
+
"release:minor": "node release.js minor",
|
|
24
|
+
"release:major": "node release.js major",
|
|
25
|
+
"postpublish": "echo 'Published @qilitt-mickey/vue3-temp-skill to npmjs.org'"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"vue3",
|
|
29
|
+
"skill",
|
|
30
|
+
"ai",
|
|
31
|
+
"code-generation",
|
|
32
|
+
"enterprise",
|
|
33
|
+
"typescript",
|
|
34
|
+
"element-plus",
|
|
35
|
+
"vant",
|
|
36
|
+
"pinia",
|
|
37
|
+
"vite"
|
|
38
|
+
],
|
|
39
|
+
"author": "qilitt",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://gitee.com/ai-skills-collection/vue3-temp-skill"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://gitee.com/ai-skills-collection/vue3-temp-skill#readme"
|
|
46
|
+
}
|