ai-engineering-init 1.2.8 → 1.3.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.
@@ -37,11 +37,5 @@
37
37
  }
38
38
  ]
39
39
  },
40
- "mcpServers": {
41
- "codex": {
42
- "command": "/Users/xujiajun/.nvm/versions/node/v20.19.6/bin/codex",
43
- "args": ["mcp-server"],
44
- "description": "OpenAI Codex CLI - 代码分析/算法实现/代码审查"
45
- }
46
- }
40
+ "mcpServers": {}
47
41
  }
package/bin/index.js CHANGED
@@ -190,30 +190,28 @@ const GLOBAL_RULES = {
190
190
  label: 'Claude Code',
191
191
  targetDir: path.join(HOME_DIR, '.claude'),
192
192
  files: [
193
- { src: '.claude/skills', dest: 'skills', label: 'Skills(全局技能库)', isDir: true },
194
- { src: '.claude/commands', dest: 'commands', label: 'Commands(全局命令)', isDir: true },
195
- { src: '.claude/agents', dest: 'agents', label: 'Agents(全局子代理)', isDir: true },
196
- { src: '.claude/hooks', dest: 'hooks', label: 'Hooks(全局钩子)', isDir: true },
193
+ { src: '.claude/skills', dest: 'skills', label: 'Skills(全局技能库)', isDir: true },
194
+ { src: '.claude/commands', dest: 'commands', label: 'Commands(全局命令)', isDir: true },
195
+ { src: '.claude/agents', dest: 'agents', label: 'Agents(全局子代理)', isDir: true },
196
+ { src: '.claude/hooks', dest: 'hooks', label: 'Hooks(全局钩子)', isDir: true },
197
197
  { src: '.claude/framework-config.json', dest: 'framework-config.json', label: 'framework-config.json' },
198
+ { src: '.claude/settings.json', dest: 'settings.json', label: 'settings.json(Hooks + MCP 配置)', merge: true },
198
199
  ],
199
- preserve: [
200
- { dest: 'settings.json', reason: '包含用户 MCP 配置和权限设置' },
201
- ],
202
- note: `Skills/Commands/Hooks 已安装到 ~/.claude,对所有项目自动生效`,
200
+ preserve: [],
201
+ note: `Skills/Commands/Hooks/Settings 已安装到 ~/.claude,对所有项目自动生效`,
203
202
  },
204
203
  cursor: {
205
204
  label: 'Cursor',
206
205
  targetDir: path.join(HOME_DIR, '.cursor'),
207
206
  files: [
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 },
207
+ { src: '.cursor/skills', dest: 'skills', label: 'Skills(全局技能库)', isDir: true },
208
+ { src: '.cursor/agents', dest: 'agents', label: 'Agents(全局子代理)', isDir: true },
209
+ { src: '.cursor/hooks', dest: 'hooks', label: 'Hooks(全局钩子脚本)', isDir: true },
210
+ { src: '.cursor/hooks.json', dest: 'hooks.json', label: 'hooks.json(Hooks 触发配置)' },
211
+ { src: '.cursor/mcp.json', dest: 'mcp.json', label: 'mcp.json(MCP 服务器配置)', merge: true },
211
212
  ],
212
- preserve: [
213
- { dest: 'mcp.json', reason: '包含用户 MCP 服务器配置' },
214
- { dest: 'hooks.json', reason: '包含用户 Hooks 配置(项目级优先)' },
215
- ],
216
- note: `Skills/Hooks 已安装到 ~/.cursor,重启 Cursor 后在全局规则中生效`,
213
+ preserve: [],
214
+ note: `Skills/Hooks/MCP 已安装到 ~/.cursor,重启 Cursor 后生效`,
217
215
  },
218
216
  codex: {
219
217
  label: 'OpenAI Codex',
@@ -226,6 +224,39 @@ const GLOBAL_RULES = {
226
224
  },
227
225
  };
228
226
 
227
+ /** 合并 JSON 文件:将 src 的键补充到 dest,已有的键保留不覆盖 */
228
+ function mergeJsonFile(srcPath, destPath, label) {
229
+ try {
230
+ const srcData = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
231
+ let destData = {};
232
+ if (fs.existsSync(destPath)) {
233
+ try { destData = JSON.parse(fs.readFileSync(destPath, 'utf8')); } catch { destData = {}; }
234
+ }
235
+ // 深度合并第一层对象键(如 mcpServers),已有的不覆盖
236
+ let added = 0;
237
+ for (const [key, value] of Object.entries(srcData)) {
238
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
239
+ if (!destData[key]) destData[key] = {};
240
+ for (const [subKey, subValue] of Object.entries(value)) {
241
+ if (!(subKey in destData[key])) {
242
+ destData[key][subKey] = subValue;
243
+ added++;
244
+ }
245
+ }
246
+ } else if (!(key in destData)) {
247
+ destData[key] = value;
248
+ added++;
249
+ }
250
+ }
251
+ fs.writeFileSync(destPath, JSON.stringify(destData, null, 2) + '\n');
252
+ console.log(` ${fmt('green', '✓')} ${label} ${fmt('magenta', `(合并 +${added} 项,已有配置保留)`)}`);
253
+ return added > 0 ? 1 : 0;
254
+ } catch (e) {
255
+ console.log(` ${fmt('red', '✗')} ${label} 合并失败: ${e.message}`);
256
+ return -1;
257
+ }
258
+ }
259
+
229
260
  /** 全局安装单个工具 */
230
261
  function globalInstallTool(toolKey) {
231
262
  const rule = GLOBAL_RULES[toolKey];
@@ -244,6 +275,14 @@ function globalInstallTool(toolKey) {
244
275
  console.log(` ${fmt('yellow', '⚠')} ${item.label} 源文件不存在,跳过`);
245
276
  continue;
246
277
  }
278
+
279
+ // merge 模式:合并 JSON 而非覆盖(保留用户已有配置)
280
+ if (item.merge) {
281
+ const result = mergeJsonFile(srcPath, destPath, item.label);
282
+ if (result >= 0) installed++; else failed++;
283
+ continue;
284
+ }
285
+
247
286
  if (fs.existsSync(destPath) && !force) {
248
287
  console.log(` ${fmt('yellow', '⚠')} ${item.label} 已存在,跳过(--force 可强制覆盖)`);
249
288
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-engineering-init",
3
- "version": "1.2.8",
3
+ "version": "1.3.0",
4
4
  "description": "AI 工程化配置初始化工具 — 一键为 Claude Code、OpenAI Codex 等 AI 工具初始化 Skills 和项目规范",
5
5
  "keywords": [
6
6
  "claude-code",