ai-engineering-init 1.1.1-test.0 → 1.2.0
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/.claude/hooks/skill-forced-eval.js +1 -0
- package/.claude/skills/leniu-brainstorm/SKILL.md +651 -0
- package/.claude/skills/leniu-java-export/SKILL.md +23 -22
- package/.claude/skills/leniu-java-total-line/SKILL.md +20 -19
- package/.codex/skills/leniu-brainstorm/SKILL.md +651 -0
- package/.cursor/hooks/cursor-pre-tool-use.js +122 -0
- package/.cursor/hooks/cursor-skill-eval.js +355 -0
- package/.cursor/hooks.json +39 -0
- package/AGENTS.md +1 -0
- package/README.md +18 -0
- package/package.json +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* preToolUse Hook - 工具使用前触发 (Cursor 版本)
|
|
4
|
+
* 功能:
|
|
5
|
+
* 1. 阻止危险命令
|
|
6
|
+
* 2. 提醒敏感操作
|
|
7
|
+
* 3. 自动修正常见错误
|
|
8
|
+
*
|
|
9
|
+
* Cursor vs Claude 差异:
|
|
10
|
+
* - Cursor Shell 工具名: "Shell"(Claude 是 "Bash")
|
|
11
|
+
* - 输出格式兼容: { decision: "block", reason: "..." }
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
|
|
16
|
+
// 从 stdin 读取输入
|
|
17
|
+
let inputData = '';
|
|
18
|
+
try {
|
|
19
|
+
inputData = fs.readFileSync(0, 'utf8');
|
|
20
|
+
} catch {
|
|
21
|
+
console.log(JSON.stringify({ continue: true }));
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let input;
|
|
26
|
+
try {
|
|
27
|
+
input = JSON.parse(inputData);
|
|
28
|
+
} catch {
|
|
29
|
+
console.log(JSON.stringify({ continue: true }));
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const toolName = input.tool_name || input.toolName || '';
|
|
34
|
+
const toolInput = input.tool_input || input.toolInput || {};
|
|
35
|
+
|
|
36
|
+
// Shell/Bash 命令检查(兼容 Cursor 的 "Shell" 和 Claude 的 "Bash")
|
|
37
|
+
if (toolName === 'Shell' || toolName === 'Bash') {
|
|
38
|
+
const command = toolInput.command || toolInput.cmd || '';
|
|
39
|
+
|
|
40
|
+
// 检测 > nul 错误用法(Windows 会创建名为 nul 的文件)
|
|
41
|
+
const nulPattern = /[12]?\s*>\s*nul\b/i;
|
|
42
|
+
if (nulPattern.test(command)) {
|
|
43
|
+
const output = {
|
|
44
|
+
decision: 'block',
|
|
45
|
+
reason: `🚫 **命令被阻止**:检测到 \`> nul\`\n\n**问题**:Windows 下某些 Shell 会创建名为 \`nul\` 的文件\n\n**解决方案**:\n- 移除输出重定向,或\n- 使用 \`> /dev/null 2>&1\`(跨平台)\n\n原命令: \`${command}\``
|
|
46
|
+
};
|
|
47
|
+
console.log(JSON.stringify(output));
|
|
48
|
+
process.exit(2);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 危险命令模式 - 直接阻止
|
|
52
|
+
const dangerousPatterns = [
|
|
53
|
+
{ pattern: /rm\s+-rf\s+\/(?!\w)/, reason: '删除根目录' },
|
|
54
|
+
{ pattern: /rm\s+-rf\s+\*/, reason: '删除所有文件' },
|
|
55
|
+
{ pattern: /drop\s+database/i, reason: '删除数据库' },
|
|
56
|
+
{ pattern: /truncate\s+table/i, reason: '清空表数据' },
|
|
57
|
+
{ pattern: /git\s+push\s+--force\s+(origin\s+)?(main|master)/i, reason: '强制推送到主分支' },
|
|
58
|
+
{ pattern: /git\s+reset\s+--hard\s+HEAD~\d+/, reason: '硬重置多个提交' },
|
|
59
|
+
{ pattern: />\s*\/dev\/sd[a-z]/, reason: '直接写入磁盘设备' },
|
|
60
|
+
{ pattern: /mkfs\./, reason: '格式化文件系统' },
|
|
61
|
+
{ pattern: /:(){ :|:& };:/, reason: 'Fork 炸弹' },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
for (const { pattern, reason } of dangerousPatterns) {
|
|
65
|
+
if (pattern.test(command)) {
|
|
66
|
+
const output = {
|
|
67
|
+
decision: 'block',
|
|
68
|
+
reason: `⚠️ **危险操作被阻止**\n\n命令: \`${command}\`\n原因: ${reason}\n\n如确需执行,请手动在终端运行`
|
|
69
|
+
};
|
|
70
|
+
console.log(JSON.stringify(output));
|
|
71
|
+
process.exit(2);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 警告但不阻止的命令
|
|
76
|
+
const warningPatterns = [
|
|
77
|
+
{ pattern: /git\s+push\s+--force/, warning: 'Force push 可能覆盖他人代码' },
|
|
78
|
+
{ pattern: /npm\s+publish/, warning: '即将发布到 npm' },
|
|
79
|
+
{ pattern: /docker\s+system\s+prune/, warning: '将清理所有未使用的 Docker 资源' },
|
|
80
|
+
{ pattern: /brew\s+upgrade/, warning: '升级所有 Homebrew 包可能影响环境' },
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
for (const { pattern, warning } of warningPatterns) {
|
|
84
|
+
if (pattern.test(command)) {
|
|
85
|
+
const output = {
|
|
86
|
+
continue: true,
|
|
87
|
+
systemMessage: `⚠️ **注意**: ${warning}`
|
|
88
|
+
};
|
|
89
|
+
console.log(JSON.stringify(output));
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Write 工具检查
|
|
96
|
+
if (toolName === 'Write' || toolName === 'CreateFile' || toolName === 'EditFile') {
|
|
97
|
+
const filePath = toolInput.file_path || toolInput.path || toolInput.filePath || '';
|
|
98
|
+
|
|
99
|
+
// 检查是否写入敏感配置文件
|
|
100
|
+
const sensitiveFiles = [
|
|
101
|
+
'.env.production',
|
|
102
|
+
'application-prod.yml',
|
|
103
|
+
'credentials.json',
|
|
104
|
+
'secrets.json',
|
|
105
|
+
'.env.prod'
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
for (const sensitive of sensitiveFiles) {
|
|
109
|
+
if (filePath.endsWith(sensitive)) {
|
|
110
|
+
const output = {
|
|
111
|
+
continue: true,
|
|
112
|
+
systemMessage: `⚠️ **敏感文件**: 正在写入 \`${sensitive}\`\n\n请确保不要提交敏感信息到 Git`
|
|
113
|
+
};
|
|
114
|
+
console.log(JSON.stringify(output));
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 默认:允许继续
|
|
121
|
+
console.log(JSON.stringify({ continue: true }));
|
|
122
|
+
process.exit(0);
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* beforeSubmitPrompt Hook - 强制技能评估 (Cursor 版本)
|
|
4
|
+
* 功能: 开发场景下,检测用户意图并注入相关技能文档引导
|
|
5
|
+
*
|
|
6
|
+
* Cursor 与 Claude 的差异:
|
|
7
|
+
* - Claude 用 Skill() 工具调用技能
|
|
8
|
+
* - Cursor 通过读取 .cursor/skills/[name]/SKILL.md 获取技能知识
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
|
|
13
|
+
// 从 stdin 读取用户输入
|
|
14
|
+
let inputData = '';
|
|
15
|
+
try {
|
|
16
|
+
inputData = fs.readFileSync(0, 'utf8');
|
|
17
|
+
} catch {
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let input;
|
|
22
|
+
try {
|
|
23
|
+
input = JSON.parse(inputData);
|
|
24
|
+
} catch {
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const prompt = (input.prompt || '').trim();
|
|
29
|
+
|
|
30
|
+
// 检测是否是恢复会话(防止上下文溢出死循环)
|
|
31
|
+
const skipPatterns = [
|
|
32
|
+
'continued from a previous conversation',
|
|
33
|
+
'ran out of context',
|
|
34
|
+
'No code restore',
|
|
35
|
+
'Conversation compacted',
|
|
36
|
+
'commands restored',
|
|
37
|
+
'context window',
|
|
38
|
+
'session is being continued'
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const isRecoverySession = skipPatterns.some(pattern =>
|
|
42
|
+
prompt.toLowerCase().includes(pattern.toLowerCase())
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
if (isRecoverySession) {
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 技能关键词映射(技能名 → 触发关键词列表)
|
|
50
|
+
const skillMap = [
|
|
51
|
+
// ========== leniu 专项技能 ==========
|
|
52
|
+
{
|
|
53
|
+
name: 'leniu-crud-development',
|
|
54
|
+
keywords: ['leniu-CRUD', 'leniu-增删改查', 'leniu-新建模块', 'leniu-Entity', 'leniu-Service',
|
|
55
|
+
'leniu-Mapper', 'leniu-Controller', 'LeRequest', 'PageDTO', 'net.xnzn', 'leniu-yunshitang',
|
|
56
|
+
'云食堂CRUD', '云食堂模块']
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'leniu-api-development',
|
|
60
|
+
keywords: ['leniu-API', 'leniu-接口', 'LeResult', '云食堂接口', '云食堂API', 'leniu-RESTful',
|
|
61
|
+
'leniu-Controller']
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'leniu-database-ops',
|
|
65
|
+
keywords: ['leniu-数据库', 'leniu-SQL', 'leniu-建表', 'leniu-双库', 'leniu-商户库', 'leniu-系统库',
|
|
66
|
+
'leniu-Entity']
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'leniu-java-entity',
|
|
70
|
+
keywords: ['leniu-Entity', 'leniu-VO', 'leniu-DTO', 'leniu-Param', 'leniu-实体类',
|
|
71
|
+
'leniu-@TableName', 'leniu-@TableField']
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'leniu-java-mybatis',
|
|
75
|
+
keywords: ['leniu-MyBatis', 'leniu-MyBatisPlus', 'leniu-Mapper', 'leniu-LambdaQueryWrapper',
|
|
76
|
+
'leniu-XML', 'leniu-BaseMapper']
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'leniu-java-code-style',
|
|
80
|
+
keywords: ['leniu-代码风格', 'leniu-命名规范', 'leniu-类命名', 'leniu-方法命名', 'leniu-包结构']
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'leniu-java-concurrent',
|
|
84
|
+
keywords: ['leniu-并发', 'leniu-CompletableFuture', 'leniu-线程池', 'leniu-分布式锁']
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'leniu-java-export',
|
|
88
|
+
keywords: ['leniu-导出', 'leniu-Export', 'leniu-Excel导出', 'leniu-异步导出', 'leniu-@ExcelProperty']
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'leniu-java-logging',
|
|
92
|
+
keywords: ['leniu-日志', 'leniu-@Slf4j', 'leniu-log.info', 'leniu-log.error']
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'leniu-java-mq',
|
|
96
|
+
keywords: ['leniu-消息队列', 'leniu-MQ', 'leniu-MqUtil', 'leniu-@MqConsumer', 'leniu-延迟消息']
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'leniu-java-task',
|
|
100
|
+
keywords: ['leniu-定时任务', 'leniu-XXL-Job', 'leniu-@XxlJob', 'leniu-TenantLoader']
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'leniu-java-total-line',
|
|
104
|
+
keywords: ['leniu-合计行', 'leniu-totalLine', 'leniu-报表合计', 'leniu-SUM合计', 'leniu-ReportBaseTotalVO']
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'leniu-java-amount-handling',
|
|
108
|
+
keywords: ['leniu-金额', 'leniu-分转元', 'leniu-元转分', 'leniu-Long金额', 'amountFen', 'amountYuan']
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'leniu-java-report-query-param',
|
|
112
|
+
keywords: ['leniu-报表查询', 'leniu-Param类', 'leniu-分页参数', 'leniu-时间范围', 'ReportBaseParam']
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'leniu-error-handler',
|
|
116
|
+
keywords: ['leniu-异常', 'leniu-LeException', 'leniu-全局异常', 'leniu-参数校验', 'leniu-错误码',
|
|
117
|
+
'leniu-I18n', 'leniu-国际化', 'LeException']
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'leniu-backend-annotations',
|
|
121
|
+
keywords: ['leniu-注解', 'leniu-@RequiresAuthentication', 'leniu-@RequiresGuest',
|
|
122
|
+
'leniu-@Validated', 'leniu-@Api', 'leniu-@ApiOperation', 'leniu-分组校验']
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'leniu-utils-toolkit',
|
|
126
|
+
keywords: ['leniu-工具类', 'leniu-BeanUtil', 'leniu-StrUtil', 'leniu-CollUtil',
|
|
127
|
+
'leniu-RedisUtil', 'leniu-JacksonUtil', 'leniu-LeBeanUtil']
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'leniu-architecture-design',
|
|
131
|
+
keywords: ['leniu-架构', '云食堂架构', '双库架构', '商户库', '系统库', 'pigx框架']
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'leniu-security-guard',
|
|
135
|
+
keywords: ['leniu-安全', 'leniu-认证', 'leniu-授权', 'leniu-权限', 'leniu-加密']
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'leniu-redis-cache',
|
|
139
|
+
keywords: ['leniu-缓存', 'leniu-Redis', 'leniu-@Cacheable', 'leniu-@CacheEvict', 'leniu-RedisUtil']
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'leniu-data-permission',
|
|
143
|
+
keywords: ['leniu-数据权限', 'leniu-DataScope', 'leniu-行级权限', '部门权限']
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'leniu-code-patterns',
|
|
147
|
+
keywords: ['leniu-规范', 'leniu-禁止', 'leniu-命名', 'leniu-Git提交', 'leniu-代码风格']
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'leniu-marketing-price-rule-customizer',
|
|
151
|
+
keywords: ['营销计费', '计费规则', 'price规则', '折扣规则', '满减规则']
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'leniu-marketing-recharge-rule-customizer',
|
|
155
|
+
keywords: ['营销充值', '充值规则', 'recharge规则', '满赠规则']
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'leniu-mealtime',
|
|
159
|
+
keywords: ['餐次', '早餐', '午餐', '下午茶', '晚餐', '夜宵', 'mealtimeTypes']
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// ========== OpenSpec 工作流 ==========
|
|
163
|
+
{
|
|
164
|
+
name: 'openspec-new-change',
|
|
165
|
+
keywords: ['新建变更', '开始新功能', 'opsx:new', 'openspec new', '创建变更']
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'openspec-ff-change',
|
|
169
|
+
keywords: ['快速推进', '快速生成所有制品', 'opsx:ff', 'openspec ff', 'fast-forward']
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'openspec-apply-change',
|
|
173
|
+
keywords: ['实现任务', '开始实现', 'opsx:apply', 'openspec apply', '执行变更']
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'openspec-continue-change',
|
|
177
|
+
keywords: ['继续变更', '创建下一个制品', 'opsx:continue', 'openspec continue']
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'openspec-archive-change',
|
|
181
|
+
keywords: ['归档变更', '完成变更', 'opsx:archive', 'openspec archive', '归档']
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: 'openspec-bulk-archive-change',
|
|
185
|
+
keywords: ['批量归档', '批量完成', 'opsx:bulk-archive']
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'openspec-explore',
|
|
189
|
+
keywords: ['探索模式', '思维伙伴', 'opsx:explore', 'openspec explore', '探索问题']
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'openspec-sync-specs',
|
|
193
|
+
keywords: ['同步规格', '同步spec', 'opsx:sync', 'openspec sync', 'delta同步']
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'openspec-verify-change',
|
|
197
|
+
keywords: ['验证变更', '检查实现', 'opsx:verify', 'openspec verify', '验证规格']
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
// ========== 通用技能 ==========
|
|
201
|
+
{
|
|
202
|
+
name: 'crud-development',
|
|
203
|
+
keywords: ['CRUD', '增删改查', 'Entity', 'Service', 'Controller', '业务模块开发']
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'api-development',
|
|
207
|
+
keywords: ['API设计', 'RESTful', '接口规范', 'Swagger', 'OpenAPI']
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'database-ops',
|
|
211
|
+
keywords: ['数据库', 'SQL', '建表', '字典', '菜单配置']
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: 'backend-annotations',
|
|
215
|
+
keywords: ['@RateLimiter', '@DataScope', '@RepeatSubmit', '@Sensitive', '@EncryptField']
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'utils-toolkit',
|
|
219
|
+
keywords: ['MapstructUtils', 'StreamUtils', 'TreeBuildUtils', 'DateUtils']
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: 'file-oss-management',
|
|
223
|
+
keywords: ['文件上传', 'OSS', '云存储', 'MinIO', '预签名URL']
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: 'bug-detective',
|
|
227
|
+
keywords: ['Bug', '报错', '异常', '不工作', '500', '404', 'NullPointerException']
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
name: 'error-handler',
|
|
231
|
+
keywords: ['异常处理', 'ServiceException', '全局异常', '参数校验异常']
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: 'performance-doctor',
|
|
235
|
+
keywords: ['性能', '慢查询', '优化', '接口慢', 'N+1', '批量优化']
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: 'data-permission',
|
|
239
|
+
keywords: ['数据权限', '@DataPermission', 'DataScope', '行级权限']
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: 'security-guard',
|
|
243
|
+
keywords: ['Sa-Token', '认证授权', '加密', 'XSS', 'SQL注入', '数据脱敏']
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'architecture-design',
|
|
247
|
+
keywords: ['架构设计', '模块划分', '重构', '技术栈']
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: 'code-patterns',
|
|
251
|
+
keywords: ['规范', '禁止', '命名规范', 'Git提交', '代码风格']
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'project-navigator',
|
|
255
|
+
keywords: ['项目结构', '文件在哪', '定位代码', '模块职责']
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: 'git-workflow',
|
|
259
|
+
keywords: ['git', 'commit', '提交', '分支', '合并', 'push', 'pull', '冲突']
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'task-tracker',
|
|
263
|
+
keywords: ['任务跟踪', '记录进度', '继续任务', '跨会话']
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: 'tech-decision',
|
|
267
|
+
keywords: ['技术选型', '方案对比', '哪个好', '优缺点']
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: 'brainstorm',
|
|
271
|
+
keywords: ['头脑风暴', '方案设计', '怎么设计', '有什么办法', '创意']
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
name: 'workflow-engine',
|
|
275
|
+
keywords: ['工作流', '审批流', 'Flowable', '流程定义', 'WarmFlow']
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: 'test-development',
|
|
279
|
+
keywords: ['单元测试', '@Test', 'JUnit5', 'Mockito', '集成测试']
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: 'json-serialization',
|
|
283
|
+
keywords: ['JSON', '序列化', '反序列化', 'JsonUtils', '日期格式', 'BigDecimal精度']
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: 'redis-cache',
|
|
287
|
+
keywords: ['Redis', '缓存', '@Cacheable', '@CacheEvict', 'RedisUtils', '分布式锁', 'RLock']
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: 'scheduled-jobs',
|
|
291
|
+
keywords: ['定时任务', 'SnailJob', '@Scheduled', '@JobExecutor', '任务调度', '重试机制']
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: 'websocket-sse',
|
|
295
|
+
keywords: ['WebSocket', 'SSE', '实时推送', '消息通知', '在线状态', '双向通信']
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'sms-mail',
|
|
299
|
+
keywords: ['短信', '邮件', 'SMS', '验证码', '通知', 'MailUtils', '邮件发送']
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
name: 'social-login',
|
|
303
|
+
keywords: ['第三方登录', '微信登录', 'QQ登录', 'OAuth', 'JustAuth', '扫码登录']
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'tenant-management',
|
|
307
|
+
keywords: ['多租户', '租户隔离', 'TenantEntity', 'TenantHelper', 'tenantId', '跨租户', 'SaaS']
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: 'ui-pc',
|
|
311
|
+
keywords: ['Element UI', '前端组件', 'el-table', 'el-form', '管理页面']
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: 'store-pc',
|
|
315
|
+
keywords: ['Vuex', 'store', 'mapState', 'mapActions', '状态管理']
|
|
316
|
+
}
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
// 匹配技能
|
|
320
|
+
const promptLower = prompt.toLowerCase();
|
|
321
|
+
const matchedSkills = [];
|
|
322
|
+
|
|
323
|
+
for (const skill of skillMap) {
|
|
324
|
+
const matched = skill.keywords.some(kw =>
|
|
325
|
+
promptLower.includes(kw.toLowerCase())
|
|
326
|
+
);
|
|
327
|
+
if (matched) {
|
|
328
|
+
matchedSkills.push(skill.name);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// 无匹配技能,直接通过
|
|
333
|
+
if (matchedSkills.length === 0) {
|
|
334
|
+
process.exit(0);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// 构建技能文档路径列表
|
|
338
|
+
const skillPaths = matchedSkills.map(name => `.cursor/skills/${name}/SKILL.md`);
|
|
339
|
+
|
|
340
|
+
const instructions = `## 技能知识库引导
|
|
341
|
+
|
|
342
|
+
检测到当前任务匹配以下技能,**请在回答前阅读对应技能文档**:
|
|
343
|
+
|
|
344
|
+
${matchedSkills.map((name, i) => `- **${name}**: \`${skillPaths[i]}\``).join('\n')}
|
|
345
|
+
|
|
346
|
+
### 执行步骤
|
|
347
|
+
|
|
348
|
+
1. **阅读技能文档**(必须):依次读取上述 SKILL.md 文件获取规范指导
|
|
349
|
+
2. **理解项目规范**:根据文档中的规范、禁令和示例代码制定实现方案
|
|
350
|
+
3. **实现功能**:严格按照技能文档的规范实现,不得违反禁令
|
|
351
|
+
|
|
352
|
+
> 注意:SKILL.md 文档包含本项目特定的实现规范,必须优先参考,不得使用通用写法替代。`;
|
|
353
|
+
|
|
354
|
+
console.log(instructions);
|
|
355
|
+
process.exit(0);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"beforeSubmitPrompt": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node .cursor/hooks/cursor-skill-eval.js"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"preToolUse": [
|
|
15
|
+
{
|
|
16
|
+
"matcher": "Shell|Write|CreateFile|EditFile",
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "node .cursor/hooks/cursor-pre-tool-use.js",
|
|
21
|
+
"timeout": 5000
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"stop": [
|
|
27
|
+
{
|
|
28
|
+
"matcher": "",
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "node .claude/hooks/stop.js",
|
|
33
|
+
"timeout": 10000
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
package/AGENTS.md
CHANGED
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
|---------|---------|
|
|
81
81
|
| `leniu-crud-development` | leniu-CRUD/leniu-增删改查/leniu-新建模块/leniu-Entity/leniu-DTO/leniu-VO/leniu-Service/leniu-Mapper/LeRequest/PageDTO/net.xnzn/leniu-yunshitang |
|
|
82
82
|
| `leniu-api-development` | leniu-API开发/云食堂接口/leniu-Controller/LeResult/leniu-yunshitang/net.xnzn |
|
|
83
|
+
| `leniu-brainstorm` | leniu头脑风暴/云食堂方案/leniu怎么设计/云食堂讨论/leniu创意/leniu方案探索/leniu功能规划 |
|
|
83
84
|
| `leniu-architecture-design` | leniu-架构/云食堂架构/双库架构/商户库/系统库/net.xnzn/pigx框架 |
|
|
84
85
|
| `leniu-database-ops` | leniu-数据库/leniu-SQL/leniu-建表/leniu-双库/leniu-商户库/leniu-系统库/net.xnzn/leniu-yunshitang |
|
|
85
86
|
| `leniu-utils-toolkit` | leniu-工具类/leniu-BeanUtil/leniu-StrUtil/leniu-CollUtil/leniu-ObjectUtil/leniu-RedisUtil/net.xnzn/leniu-yunshitang |
|
package/README.md
CHANGED
|
@@ -74,6 +74,8 @@ cd ai-engineering-init
|
|
|
74
74
|
| `skills/`(68个) | 与 `.claude/skills/` 完全同步,支持 `@技能名` 手动调用或 Agent 自动委托 |
|
|
75
75
|
| `agents/`(2个) | Subagents:`code-reviewer`(`readonly: true`)、`project-manager` |
|
|
76
76
|
| `mcp.json` | MCP 服务器配置:`sequential-thinking`、`context7`、`github` |
|
|
77
|
+
| `hooks.json` | Hooks 配置:技能文档引导(beforeSubmitPrompt)、危险命令拦截(preToolUse)、完成音效(stop) |
|
|
78
|
+
| `hooks/` | Hooks 脚本:`cursor-skill-eval.js`、`cursor-pre-tool-use.js` |
|
|
77
79
|
|
|
78
80
|
### OpenAI Codex(`.codex/`)
|
|
79
81
|
|
|
@@ -185,6 +187,22 @@ cd ai-engineering-init
|
|
|
185
187
|
|
|
186
188
|
## 更新日志
|
|
187
189
|
|
|
190
|
+
### v1.2.0(2026-03-01)
|
|
191
|
+
|
|
192
|
+
- 新增 **Cursor Hooks 支持**(`.cursor/hooks.json` + `.cursor/hooks/`)
|
|
193
|
+
- `beforeSubmitPrompt`:检测用户意图,自动注入相关技能文档路径引导 Agent 阅读(对应 Claude 的 `UserPromptSubmit`)
|
|
194
|
+
- `preToolUse`:拦截危险 Shell 命令(`rm -rf /`、`drop database` 等),兼容 Cursor `Shell` 工具名
|
|
195
|
+
- `stop`:复用 Claude 的 `stop.js`,支持 nul 文件清理和完成音效
|
|
196
|
+
- 修复 **leniu-java-export** 技能示例代码:移除错误的 `Executors.readInSystem()` 包装(业务查询默认在商户库执行)
|
|
197
|
+
- 修复 **leniu-java-total-line** 技能:同步修正双库架构说明,`Executors.doInSystem()` 仅用于访问系统库
|
|
198
|
+
|
|
199
|
+
### v1.1.1(2026-02-24)
|
|
200
|
+
|
|
201
|
+
- 优化 **npm 发布流程**
|
|
202
|
+
- 预发布版本(含 `-`)自动发布到 `test` 标签
|
|
203
|
+
- 正式版本自动发布到 `latest` 标签
|
|
204
|
+
- GitHub Release 自动标记预发布版本(`prerelease: true`)
|
|
205
|
+
|
|
188
206
|
### v1.1.0(2026-02-24)
|
|
189
207
|
|
|
190
208
|
- 新增 **Cursor** 工具支持(`.cursor/` 目录)
|