ai-engineering-init 1.2.9 → 1.3.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.
@@ -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/README.md CHANGED
@@ -49,12 +49,18 @@ cd ai-engineering-init
49
49
  | OpenAI Codex | `--tool codex` | `.codex/` 目录 + `AGENTS.md` |
50
50
  | 全部 | `--tool all` | 以上全部 |
51
51
 
52
- ## 选项
52
+ ## 命令与选项
53
53
 
54
- ```
54
+ ```bash
55
+ # 命令
56
+ npx ai-engineering-init # 交互式初始化(安装到当前项目)
57
+ npx ai-engineering-init update # 更新已安装的框架文件
58
+ npx ai-engineering-init global # 全局安装到 ~/.claude 等,对所有项目生效
59
+
60
+ # 选项
55
61
  --tool, -t <工具> 指定工具: claude | cursor | codex | all
56
- --dir, -d <目录> 目标目录(默认:当前目录)
57
- --force,-f 强制覆盖已有文件
62
+ --dir, -d <目录> 目标目录(默认:当前目录,仅 init/update 有效)
63
+ --force,-f 强制覆盖(init 覆盖已有文件;update/global 同时更新保留文件)
58
64
  --help, -h 显示帮助
59
65
  ```
60
66
 
@@ -237,11 +243,31 @@ npx ai-engineering-init@latest update --force
237
243
 
238
244
  > **注意**:不加 `@latest` 会使用 npx 本地缓存的旧版本,源文件不是最新的。
239
245
 
246
+ ## 全局安装(v1.3.0+)
247
+
248
+ 一次安装,所有项目自动生效:
249
+
250
+ ```bash
251
+ # 全局安装所有工具(~/.claude + ~/.cursor + ~/.codex)
252
+ npx ai-engineering-init@latest global
253
+
254
+ # 只全局安装指定工具
255
+ npx ai-engineering-init@latest global --tool claude
256
+ npx ai-engineering-init@latest global --tool cursor
257
+
258
+ # 强制覆盖已有全局文件
259
+ npx ai-engineering-init@latest global --force
260
+ ```
261
+
262
+ > **说明**:全局安装将 Skills/Commands/Hooks 安装到 `~/.claude` / `~/.cursor` / `~/.codex`。`settings.json`、`mcp.json` 采用合并策略,不覆盖用户已有配置。项目级配置优先级高于全局配置,两者可共存。
263
+
240
264
  ## 更新日志
241
265
 
242
266
  查看完整更新历史:[CHANGELOG.md](./CHANGELOG.md)
243
267
 
244
- **v1.2.6 修复**:Cursor stop hook 自包含,不再依赖 Claude Code 安装;修复完成音效无法触发的问题。
268
+ **v1.3.0 新增**:`global` 命令,支持系统级全局安装,一次安装对所有项目生效。
269
+ **v1.2.7 修复**:Cursor `beforeSubmitPrompt` hook 输出格式改为 JSON,修复技能注入失效。
270
+ **v1.2.6 修复**:Cursor stop hook 自包含,不再依赖 Claude Code 安装。
245
271
 
246
272
  ## License
247
273
 
package/bin/index.js CHANGED
@@ -190,16 +190,15 @@ 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, rewritePrefix: '.claude/' },
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',
@@ -208,7 +207,7 @@ const GLOBAL_RULES = {
208
207
  { src: '.cursor/skills', dest: 'skills', label: 'Skills(全局技能库)', isDir: true },
209
208
  { src: '.cursor/agents', dest: 'agents', label: 'Agents(全局子代理)', isDir: true },
210
209
  { src: '.cursor/hooks', dest: 'hooks', label: 'Hooks(全局钩子脚本)', isDir: true },
211
- { src: '.cursor/hooks.json', dest: 'hooks.json', label: 'hooks.json(Hooks 触发配置)' },
210
+ { src: '.cursor/hooks.json', dest: 'hooks.json', label: 'hooks.json(Hooks 触发配置)', rewritePrefix: '.cursor/' },
212
211
  { src: '.cursor/mcp.json', dest: 'mcp.json', label: 'mcp.json(MCP 服务器配置)', merge: true },
213
212
  ],
214
213
  preserve: [],
@@ -258,6 +257,34 @@ function mergeJsonFile(srcPath, destPath, label) {
258
257
  }
259
258
  }
260
259
 
260
+ /** 将 JSON 中的相对路径重写为绝对路径(递归遍历所有字符串值) */
261
+ function rewritePaths(obj, relPrefix, absPrefix) {
262
+ if (typeof obj === 'string') {
263
+ // 匹配 "node .claude/hooks/xxx" 或 ".cursor/hooks/xxx" 等相对路径
264
+ return obj.split(' ').map(part =>
265
+ part.startsWith(relPrefix) ? part.replace(relPrefix, absPrefix) : part
266
+ ).join(' ');
267
+ }
268
+ if (Array.isArray(obj)) return obj.map(item => rewritePaths(item, relPrefix, absPrefix));
269
+ if (typeof obj === 'object' && obj !== null) {
270
+ const result = {};
271
+ for (const [k, v] of Object.entries(obj)) {
272
+ result[k] = rewritePaths(v, relPrefix, absPrefix);
273
+ }
274
+ return result;
275
+ }
276
+ return obj;
277
+ }
278
+
279
+ /** 重写已写入的 JSON 文件中的相对路径为绝对路径 */
280
+ function rewriteJsonFilePaths(filePath, relPrefix, absPrefix) {
281
+ try {
282
+ let data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
283
+ data = rewritePaths(data, relPrefix, absPrefix);
284
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n');
285
+ } catch { /* 静默失败 */ }
286
+ }
287
+
261
288
  /** 全局安装单个工具 */
262
289
  function globalInstallTool(toolKey) {
263
290
  const rule = GLOBAL_RULES[toolKey];
@@ -280,6 +307,10 @@ function globalInstallTool(toolKey) {
280
307
  // merge 模式:合并 JSON 而非覆盖(保留用户已有配置)
281
308
  if (item.merge) {
282
309
  const result = mergeJsonFile(srcPath, destPath, item.label);
310
+ // merge 后路径重写
311
+ if (result >= 0 && item.rewritePrefix) {
312
+ rewriteJsonFilePaths(destPath, item.rewritePrefix, globalDest + '/');
313
+ }
283
314
  if (result >= 0) installed++; else failed++;
284
315
  continue;
285
316
  }
@@ -295,7 +326,16 @@ function globalInstallTool(toolKey) {
295
326
  installed += n;
296
327
  } else {
297
328
  fs.mkdirSync(path.dirname(destPath), { recursive: true });
298
- fs.copyFileSync(srcPath, destPath);
329
+ // 非 merge JSON 文件的路径重写
330
+ if (item.rewritePrefix && destPath.endsWith('.json')) {
331
+ try {
332
+ let data = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
333
+ data = rewritePaths(data, item.rewritePrefix, globalDest + '/');
334
+ fs.writeFileSync(destPath, JSON.stringify(data, null, 2) + '\n');
335
+ } catch { fs.copyFileSync(srcPath, destPath); }
336
+ } else {
337
+ fs.copyFileSync(srcPath, destPath);
338
+ }
299
339
  console.log(` ${fmt('green', '✓')} ${item.label}`);
300
340
  installed++;
301
341
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-engineering-init",
3
- "version": "1.2.9",
3
+ "version": "1.3.1",
4
4
  "description": "AI 工程化配置初始化工具 — 一键为 Claude Code、OpenAI Codex 等 AI 工具初始化 Skills 和项目规范",
5
5
  "keywords": [
6
6
  "claude-code",