ai-engineering-init 1.2.8 → 1.2.9
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/bin/index.js +48 -8
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -205,15 +205,14 @@ const GLOBAL_RULES = {
|
|
|
205
205
|
label: 'Cursor',
|
|
206
206
|
targetDir: path.join(HOME_DIR, '.cursor'),
|
|
207
207
|
files: [
|
|
208
|
-
{ src: '.cursor/skills',
|
|
209
|
-
{ src: '.cursor/agents',
|
|
210
|
-
{ src: '.cursor/hooks',
|
|
208
|
+
{ src: '.cursor/skills', dest: 'skills', label: 'Skills(全局技能库)', isDir: true },
|
|
209
|
+
{ src: '.cursor/agents', dest: 'agents', label: 'Agents(全局子代理)', isDir: true },
|
|
210
|
+
{ src: '.cursor/hooks', dest: 'hooks', label: 'Hooks(全局钩子脚本)', isDir: true },
|
|
211
|
+
{ src: '.cursor/hooks.json', dest: 'hooks.json', label: 'hooks.json(Hooks 触发配置)' },
|
|
212
|
+
{ src: '.cursor/mcp.json', dest: 'mcp.json', label: 'mcp.json(MCP 服务器配置)', merge: true },
|
|
211
213
|
],
|
|
212
|
-
preserve: [
|
|
213
|
-
|
|
214
|
-
{ dest: 'hooks.json', reason: '包含用户 Hooks 配置(项目级优先)' },
|
|
215
|
-
],
|
|
216
|
-
note: `Skills/Hooks 已安装到 ~/.cursor,重启 Cursor 后在全局规则中生效`,
|
|
214
|
+
preserve: [],
|
|
215
|
+
note: `Skills/Hooks/MCP 已安装到 ~/.cursor,重启 Cursor 后生效`,
|
|
217
216
|
},
|
|
218
217
|
codex: {
|
|
219
218
|
label: 'OpenAI Codex',
|
|
@@ -226,6 +225,39 @@ const GLOBAL_RULES = {
|
|
|
226
225
|
},
|
|
227
226
|
};
|
|
228
227
|
|
|
228
|
+
/** 合并 JSON 文件:将 src 的键补充到 dest,已有的键保留不覆盖 */
|
|
229
|
+
function mergeJsonFile(srcPath, destPath, label) {
|
|
230
|
+
try {
|
|
231
|
+
const srcData = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
|
|
232
|
+
let destData = {};
|
|
233
|
+
if (fs.existsSync(destPath)) {
|
|
234
|
+
try { destData = JSON.parse(fs.readFileSync(destPath, 'utf8')); } catch { destData = {}; }
|
|
235
|
+
}
|
|
236
|
+
// 深度合并第一层对象键(如 mcpServers),已有的不覆盖
|
|
237
|
+
let added = 0;
|
|
238
|
+
for (const [key, value] of Object.entries(srcData)) {
|
|
239
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
240
|
+
if (!destData[key]) destData[key] = {};
|
|
241
|
+
for (const [subKey, subValue] of Object.entries(value)) {
|
|
242
|
+
if (!(subKey in destData[key])) {
|
|
243
|
+
destData[key][subKey] = subValue;
|
|
244
|
+
added++;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
} else if (!(key in destData)) {
|
|
248
|
+
destData[key] = value;
|
|
249
|
+
added++;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
fs.writeFileSync(destPath, JSON.stringify(destData, null, 2) + '\n');
|
|
253
|
+
console.log(` ${fmt('green', '✓')} ${label} ${fmt('magenta', `(合并 +${added} 项,已有配置保留)`)}`);
|
|
254
|
+
return added > 0 ? 1 : 0;
|
|
255
|
+
} catch (e) {
|
|
256
|
+
console.log(` ${fmt('red', '✗')} ${label} 合并失败: ${e.message}`);
|
|
257
|
+
return -1;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
229
261
|
/** 全局安装单个工具 */
|
|
230
262
|
function globalInstallTool(toolKey) {
|
|
231
263
|
const rule = GLOBAL_RULES[toolKey];
|
|
@@ -244,6 +276,14 @@ function globalInstallTool(toolKey) {
|
|
|
244
276
|
console.log(` ${fmt('yellow', '⚠')} ${item.label} 源文件不存在,跳过`);
|
|
245
277
|
continue;
|
|
246
278
|
}
|
|
279
|
+
|
|
280
|
+
// merge 模式:合并 JSON 而非覆盖(保留用户已有配置)
|
|
281
|
+
if (item.merge) {
|
|
282
|
+
const result = mergeJsonFile(srcPath, destPath, item.label);
|
|
283
|
+
if (result >= 0) installed++; else failed++;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
247
287
|
if (fs.existsSync(destPath) && !force) {
|
|
248
288
|
console.log(` ${fmt('yellow', '⚠')} ${item.label} 已存在,跳过(--force 可强制覆盖)`);
|
|
249
289
|
continue;
|