jinzd-ai-cli 0.1.32 → 0.1.37

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.md CHANGED
@@ -45,7 +45,7 @@ src/
45
45
  │ ├── dev-state.ts # 开发状态交接(provider/model 切换时快照生成、save/load/clear)
46
46
  │ ├── setup-wizard.ts # @inquirer/prompts 首次运行交互式设置
47
47
  │ └── commands/
48
- │ └── index.ts # CommandRegistry + 26个命令(/help /about /provider /model /clear /compact /plan /session /system /context /status /search /undo /export /copy /cost /init /skill /tools /plugins /mcp /config /checkpoint /review /commands /exit)
48
+ │ └── index.ts # CommandRegistry + 32个命令(/help /about /provider /model /clear /compact /plan /session /system /context /status /search /undo /export /copy /cost /init /skill /tools /plugins /mcp /config /checkpoint /review /commands /test /scaffold /add-dir /memory /doctor /bug /exit)
49
49
  │ ├── custom-commands.ts # CustomCommandManager(~/.aicli/commands/*.md 用户自定义命令)
50
50
  ├── skills/
51
51
  │ ├── types.ts # Skill/SkillMeta 接口、parseSkillFile(YAML frontmatter 解析)
@@ -343,6 +343,168 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
343
343
  - [x] **web_fetch DNS 解析时 SSRF 防护**(v0.1.25):新增 `resolveAndCheck()` 函数,用 `dns.promises.lookup()` 预解析域名,检查结果 IP 是否为私有地址。初始 URL 和 redirect 目标均校验。
344
344
  - [ ] **`persistentCwd` 全局状态**:bash 工具的当前工作目录是模块级全局变量,多 session 并发时可能串扰。现阶段单 session REPL 无影响,GUI 多会话扩展时需重构为 per-session 状态。
345
345
 
346
+ ## 本轮开发完成记录(2026-03-05,v0.1.34 → v0.1.36)
347
+
348
+ ### v0.1.35 — P0 功能缺口 + P1 前三项
349
+
350
+ **P0:并行工具调用**(`src/tools/executor.ts`)
351
+ - `executeAll()` 的 safe 级别工具从顺序 `for` 循环改为 `Promise.all()` 并行执行,批量 safe 工具整体耗时降至最慢单个工具的时间
352
+
353
+ **P0:`/add-dir` 动态目录上下文**(`src/repl/repl.ts` + `src/repl/commands/index.ts`)
354
+ - `Repl` 新增 `extraContextDirs` 数组 + `scanDirContent()`(目录树 + 文件内容,总限 40K 字符,单文件限 4K)
355
+ - `addExtraContextDir()` / `removeExtraContextDir()`:解析绝对路径,校验目录存在,存入数组
356
+ - `buildCurrentSystemPrompt()` 在 skill 段之前注入 `# Added Directory Context: <dir>` 段落
357
+ - `/add-dir <路径>`:添加目录;`/add-dir remove <路径>`:移除;`/add-dir`(无参):列出所有已添加目录
358
+
359
+ **启动参数:`--allowed-tools` / `--blocked-tools`**(`src/index.ts` + `src/repl/repl.ts`)
360
+ - CLI 新增两个选项,逗号分隔工具名,转为 `Set<string>` 传入 `Repl` 构造函数
361
+ - `handleChatWithTools()` 在 plan/skill 过滤之后叠加应用 allowedTools / blockedTools 过滤
362
+
363
+ **P1:`/memory` 命令**(`src/repl/commands/index.ts`)
364
+ - `show`:打印 memory.md 内容;`add <内容>`:`appendFileSync` 追加带时间戳条目;`clear`:清空文件(需确认);`path`:显示文件路径
365
+
366
+ **P1:`/doctor` 健康检查**(`src/repl/commands/index.ts`)
367
+ - 扫描所有 configured provider 的 API Key 状态(✓/✗)
368
+ - 检查 config.json 文件是否存在
369
+ - 调用 `getMcpManager().getStatus()` 显示 MCP 服务器连接状态
370
+ - 显示当前 session 消息数 + 估算 context 占用率(绿/黄/红)
371
+
372
+ **文档与版本**
373
+ - `src/repl/commands/index.ts`:`CommandContext` 新增 `addContextDir` / `removeContextDir` / `listContextDirs` 三个回调
374
+ - `src/repl/renderer.ts`:命令计数 28 → 31,添加 `/add-dir` `/memory` `/doctor`,新增 5 条特性条目
375
+ - VERSION `0.1.34` → `0.1.35`,`package.json` 同步
376
+
377
+ ---
378
+
379
+ ### v0.1.36 — P1 剩余三项全部完成
380
+
381
+ **P1:`/bug` 反馈命令**(`src/repl/commands/index.ts`)
382
+ - 生成 Markdown 格式 Bug 报告模板,自动填入 VERSION / OS(`platform()`)/ Node.js 版本 / 当前 Provider / 当前 Model
383
+ - `--copy` 参数调用已有 `copyToClipboard()` 复制到剪贴板
384
+ - 无 `--copy` 时打印报告并显示提交链接(`REPO_URL/issues`)
385
+ - 新增 `VERSION` + `REPO_URL` 到 constants.ts import
386
+
387
+ **P1:流式 JSON 输出**(`src/index.ts`)
388
+ - 新增 `--output-format <format>` CLI 选项,支持 `text`(默认)和 `streaming-json`
389
+ - `streaming-json` 模式:调用 `provider.chatStream()`,每个 delta 输出一行 NDJSON:
390
+ - `{"type":"delta","text":"..."}` —— 每个 chunk
391
+ - `{"type":"done","content":"...","provider":"...","model":"...","usage":{...}}` —— 最终行
392
+ - `--json` 和 `streaming-json` 均强制不走普通 `useStream` 分支
393
+
394
+ **P1:桌面通知**
395
+ - 新文件 `src/repl/notify.ts`:`sendNotification(title, body)` 跨平台非阻塞后台 spawn
396
+ - macOS:`osascript -e 'display notification "..." with title "..."'`
397
+ - Windows:PowerShell `System.Windows.Forms.NotifyIcon`(5 行脚本,`ShowBalloonTip(3000)`)
398
+ - Linux:`notify-send <title> <body>`
399
+ - 失败静默忽略(`try/catch` 包裹,不影响主流程)
400
+ - `src/config/schema.ts`:`ui` 对象新增 `notificationThreshold: z.number().default(10_000)`(单位 ms,0 = 禁用)
401
+ - `src/repl/repl.ts`:导入 `sendNotification`;`handleChat()` 在 `handleChatSimple`/`handleChatWithTools` 调用前记录 `t0 = Date.now()`,完成后对比阈值发送通知
402
+
403
+ **文档与版本**
404
+ - `src/repl/commands/index.ts`:`/help` 新增 `/bug [--copy]` 条目
405
+ - `src/repl/renderer.ts`:命令计数 31 → 32,命令行列表加入 `/bug`,新增 3 条特性
406
+ - 新增 `USAGE.md`:21 章节完整用户使用说明文档(CLI / REPL 命令 / 工具 / 配置 / 各高级特性)
407
+ - VERSION `0.1.35` → `0.1.36`,`package.json` 同步
408
+ - 构建验证:`npm run build` 零错误(ESM + CJS 双产物)
409
+
410
+ ### 本轮变更文件汇总
411
+
412
+ | 文件 | 变更类型 | 说明 |
413
+ |------|---------|------|
414
+ | `src/core/constants.ts` | 修改 | VERSION 0.1.34 → 0.1.36 |
415
+ | `src/config/schema.ts` | 修改 | `ui.notificationThreshold` 新增字段 |
416
+ | `src/tools/executor.ts` | 修改 | safe 工具并行执行(Promise.all) |
417
+ | `src/repl/repl.ts` | 修改 | extraContextDirs、allowedTools/blockedTools、sendNotification 集成 |
418
+ | `src/repl/notify.ts` | 新增 | 跨平台桌面通知实现 |
419
+ | `src/repl/commands/index.ts` | 修改 | /add-dir /memory /doctor /bug 四个命令 + /help 更新 |
420
+ | `src/repl/renderer.ts` | 修改 | /about 命令数 28→32,新增特性条目 |
421
+ | `src/index.ts` | 修改 | --allowed-tools / --blocked-tools / --output-format 三个新参数 |
422
+ | `package.json` | 修改 | version 0.1.34 → 0.1.36 |
423
+ | `USAGE.md` | 新增 | 21 章节完整用户使用说明文档 |
424
+
425
+ ### 下一步建议(P2 优先)
426
+ 1. **项目级 `.mcp.json`**:项目根目录独立 MCP 配置,优先全局 config
427
+ 2. **`--resume <id>` 启动参数**:命令行直接恢复指定会话(`aicli --resume abc12345`)
428
+ 3. **Word wrap 配置**:终端输出折行宽度可配置(`config.ui.wordWrap`)
429
+ 4. **主题/颜色自定义**:dark/light/custom 主题支持
430
+ 5. **L1 低危**:`run-tests.ts` 的 `JSON.parse(package.json)` 细粒度错误处理
431
+
432
+ ---
433
+
434
+ ## 本轮开发完成记录(2026-03-03,v0.1.32 → v0.1.33)
435
+
436
+ ### 高危安全修复:H1–H4 全部修复
437
+
438
+ **H1 — MCP pendingRequests 内存泄漏**(`src/mcp/client.ts`):
439
+ `sendRequest()` 重构——resolve/reject 回调内含统一 `cleanup()` 函数(`pendingRequests.delete(id)` + `clearTimeout(timer)`),任何 Promise 完成路径都即时释放资源。`handleMessage()` 简化——不再重复调用 delete/clearTimeout(由回调内部处理)。
440
+
441
+ **H2 — readline 竞态条件**(`src/tools/executor.ts`):
442
+ `confirm()` 和 `batchConfirm()` 中 `completed` 布尔守卫从外部变量统一移入 `cleanup()` 函数内部(单一检查点模式)。`rl.once('line')` 注册用 `try/catch` 包裹,极端情况下(readline 已关闭)确保 `confirming` 标志不会卡死。
443
+
444
+ **H3 — 工具执行错误语义混淆**(`src/tools/executor.ts`):
445
+ 所有用户取消/拒绝路径的 `content` 增加语义前缀:
446
+ - `[User cancelled]` — 用户在 confirm 对话框中按 N 或 Ctrl+C
447
+ - `[User rejected]` — 用户在 batchConfirm 中拒绝特定文件
448
+ - `[Permission denied]` — 权限规则阻止
449
+ 所有前缀后附 "Do not retry without asking." 指示,防止 AI 无意义重试。
450
+
451
+ **H4 — MCP 断开后无恢复机制**:
452
+ - `src/mcp/client.ts`:新增 `reconnect()` 方法——清理旧状态(rejectAllPending + killProcess + 重置缓冲区)后重新执行完整 `connect()` 流程
453
+ - `src/mcp/manager.ts`:新增 `reconnectServer(serverId)` 和 `reconnectAll()` 方法;`wrapMcpTool` 的 execute 函数在检测到断线时自动尝试一次重连,成功后继续调用
454
+ - `src/repl/commands/index.ts`:`/mcp reconnect [serverId]` 子命令——手动重连指定服务器或所有断开的服务器,成功后刷新 ToolRegistry 中的 MCP 工具
455
+
456
+ **版本与收尾**
457
+ - `src/core/constants.ts`:VERSION `0.1.30` → `0.1.33`
458
+ - `package.json`:version `0.1.32` → `0.1.33`
459
+
460
+ ---
461
+
462
+ ## 本轮开发完成记录(2026-03-03,v0.1.33 → v0.1.34)
463
+
464
+ ### 中危安全修复:M5–M12 全面排查
465
+
466
+ 对审计报告中 8 个中危问题逐一排查,发现 **M6–M11 已在先前版本修复或确认安全**,仅 **M5** 和 **M12** 需要新代码修复。
467
+
468
+ **M5 — bash `persistentCwd` 指向已删除目录**(`src/tools/builtin/bash.ts`):
469
+ - 问题:`persistentCwd` 模块级变量记住上次 `cd` 目标,但该目录可能在后续操作中被删除(如 `rm -rf`),导致下一次 bash 调用 `execSync` 报 `ENOENT`
470
+ - 修复:`execute()` 开头新增 `existsSync(persistentCwd)` 检查,不存在时自动回退到 `process.cwd()` 并打印 stderr 警告
471
+
472
+ **M12 — MCP 工具 schema 嵌套结构丢失**(`src/mcp/manager.ts` + `src/tools/types.ts` + 三个 provider):
473
+ - 问题:MCP 工具的 JSON Schema 含嵌套 object/array 时,`convertDefinition()` 扁平化为简单类型,AI 生成的参数结构与实际 schema 不匹配导致调用失败
474
+ - 修复:
475
+ - `src/tools/types.ts`:`ToolParameterSchema` 新增 `properties?: Record<string, ToolParameterSchema>` 字段;`items` 类型从 `{ type: ToolParameterType }` 扩展为完整 `ToolParameterSchema`;新增 `schemaToJsonSchema()` 公共递归转换函数
476
+ - `src/mcp/manager.ts`:新增 `convertSchema()` 私有递归方法,替代原有扁平转换
477
+ - `src/providers/openai-compatible.ts`、`claude.ts`、`gemini.ts`:统一使用 `schemaToJsonSchema()` 构建 API 请求的工具参数 schema
478
+
479
+ **M6–M11 排查结论**(无需修改):
480
+ | # | 结论 |
481
+ |---|------|
482
+ | M6 | web-fetch 手动 redirect 循环每一跳均做 SSRF 检查,已安全 |
483
+ | M7 | run-interactive `write()` 返回 false 时已有 `once('drain')` 背压处理 |
484
+ | M8 | session-manager `catch` 中已有 `stderr.write` 含文件名和错误信息 |
485
+ | M9 | mcp/client `killProcess()` 已有 `removeAllListeners()`(H4 修复附带) |
486
+ | M10 | permissions.ts 使用 `.includes()` 子串匹配而非正则,无 ReDoS 风险 |
487
+ | M11 | repl.ts 上下文加载已有 `resolve()` + `startsWith(cwd)` 路径穿越校验 |
488
+
489
+ **版本与收尾**
490
+ - `src/core/constants.ts`:VERSION `0.1.33` → `0.1.34`
491
+ - `package.json`:version `0.1.33` → `0.1.34`
492
+ - 代码审查报告表格全部更新为已修复/已确认安全状态
493
+ - 构建通过:`npm run build` 零错误
494
+
495
+ ### 安全审计完结状态
496
+ - **高危 H1–H4**:全部已修复(v0.1.33)
497
+ - **中危 M5–M12**:全部已修复或确认安全(v0.1.34)
498
+ - **低危 L1–L7**:L2–L7 已在 v0.1.30 修复/确认,L1 待后续改进
499
+ - **安全债务已清零**,可安全进入功能开发阶段
500
+
501
+ ### 下一步建议
502
+ 1. **P0 功能缺口**:并行工具调用、`/add-dir` 命令
503
+ 2. **P1 功能缺口**:`/memory` 命令、`/doctor` 健康检查、`/bug` 反馈
504
+ 3. **L1 低危**:`run-tests.ts` 的 `JSON.parse(package.json)` 细粒度错误处理
505
+
506
+ ---
507
+
346
508
  ## 本轮开发完成记录(2026-03-01,v0.1.26 → v0.1.30)
347
509
 
348
510
  ### 安全修复续篇:低危 L2–L7
@@ -886,40 +1048,40 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
886
1048
 
887
1049
  > 全面扫描 src/ 目录 35+ 个 TypeScript 源文件,共发现 **4 高危 + 8 中危 + 7 低危** 问题。
888
1050
 
889
- ### 🔴 高危问题(立即修复)
1051
+ ### 🔴 高危问题(全部已修复 v0.1.33)
890
1052
 
891
- **H1 — MCP pendingRequests 内存泄漏**
1053
+ **H1 — MCP pendingRequests 内存泄漏**
892
1054
  - **文件**:`src/mcp/client.ts`
893
- - **描述**:进程崩溃时 `pendingRequests.delete(id)` 可能不触发,timer 未清理;长期运行时内存持续增长
894
- - **修复**:在 `sendRequest` 中用 `finally` 确保 `pendingRequests.delete(id)` + `clearTimeout(timer)` 总被执行
895
-
896
- **H2 — readline 竞态条件:`confirming` 标志失效**
897
- - **文件**:`src/tools/executor.ts`(行 58, 155, 307, 320-356)
898
- - **描述**:`batchConfirm()` 提前返回 `'none'` 时 `confirming = true` 与实际状态不匹配;`once('line')` edge case 下可能触发两次,误消费用户输入;`ask_user` 工具的 `askUserContext.prompting` 存在同样问题
899
- - **修复**:使用 `completed` 布尔标志防止二次触发,或改用 Promise-based 状态机
900
-
901
- **H3 — 工具执行错误语义混淆(isError 混用)**
902
- - **文件**:`src/tools/executor.ts`(行 128, 160, 170)
903
- - **描述**:权限 deny 和用户取消均返回 `{ isError: false }`,AI 无法区分"用户拒绝"与"工具正常返回",可能产生错误推理
904
- - **修复**:统一为 `isError: true`,内容前缀加 `[User cancelled]` 或 `[Permission denied]`
905
-
906
- **H4 — MCP 断开后无恢复机制**
907
- - **文件**:`src/mcp/client.ts` + `src/mcp/manager.ts`
908
- - **描述**:服务器子进程意外退出后,客户端对象仍留在 Map 中;工具列表可见但调用时 silent failure;用户需重启 CLI 才能恢复
909
- - **修复**:`callTool()` 中检测 `isConnected`,返回友好错误提示;可选:实现指数退避自动重连
910
-
911
- ### 🟠 中危问题(近期修复)
912
-
913
- | # | 文件 | 问题描述 | 修复方向 |
914
- |---|------|---------|---------|
915
- | M5 | `src/tools/builtin/bash.ts:76-86` | `cwd` 指向不存在目录时不报错,AI 误判 cd 成功 | `existsSync` 校验后再设置 `effectiveCwd` |
916
- | M6 | `src/tools/builtin/web-fetch.ts` | SSRF:重定向链中间 URL 不检查(仅检查首尾) | 对每个中间重定向 URL 均调用 `resolveAndCheck()` |
917
- | M7 | `src/tools/builtin/run-interactive.ts:131-144` | stdin 写入无背压处理,大量输入可能溢出 | 监听 `drain` 事件,写满后暂停直到缓冲区释放 |
918
- | M8 | `src/session/session-manager.ts` | 会话 JSON 损坏时错误被吞噬,无日志,用户无法诊断 | `catch` 中输出 `stderr` 警告含文件名和错误信息 |
919
- | M9 | `src/mcp/client.ts` | `close()` 时事件监听器未移除,长期运行积累僵尸监听器 | `killProcess()` 中调用 `removeAllListeners()` |
920
- | M10 | `src/tools/permissions.ts` | `pathPattern` 直接 `new RegExp()`,恶意配置可触发 ReDoS | 加 try/catch 包裹正则编译,或限制正则复杂度 |
921
- | M11 | `src/repl/repl.ts`(上下文加载) | `contextFile` 设为相对路径可能遍历项目外目录 | `resolve()` 后校验路径以项目目录为前缀 |
922
- | M12 | `src/mcp/manager.ts` | MCP 工具 schema 扁平化时丢失嵌套结构,AI 传参可能失败 | `convertDefinition()` 支持递归转换嵌套 object/array |
1055
+ - **描述**:`withTimeout` 外层超时后,`sendRequest` 内部的 pending 条目和 timer 滞留到内部超时才释放
1056
+ - **修复**:`sendRequest` resolve/reject 回调内含统一 `cleanup()` 函数,任何路径(正常响应/内部超时/写入错误/外部 reject)都即时释放资源
1057
+
1058
+ **H2 — readline 竞态条件:`confirming` 标志失效**
1059
+ - **文件**:`src/tools/executor.ts`、`src/tools/builtin/ask-user.ts`
1060
+ - **描述**:`confirm()`/`batchConfirm()`/`ask_user` `once('line')` 在极端 edge case 下可能二次触发
1061
+ - **修复**:`completed` 布尔守卫统一移入 `cleanup()` 内部(单一检查点);`try/catch` 包裹 `rl.once()` 注册防止 readline 已关闭时 `confirming` 卡死
1062
+
1063
+ **H3 — 工具执行错误语义混淆(isError 混用)**
1064
+ - **文件**:`src/tools/executor.ts`
1065
+ - **描述**:用户取消和权限拒绝的 content 缺少语义前缀,AI 难以区分取消/拒绝/真实错误
1066
+ - **修复**:所有取消/拒绝路径 content `[User cancelled]`/`[User rejected]`/`[Permission denied]` 前缀 + "Do not retry without asking" 提示
1067
+
1068
+ **H4 — MCP 断开后无恢复机制**
1069
+ - **文件**:`src/mcp/client.ts` + `src/mcp/manager.ts` + `src/repl/commands/index.ts`
1070
+ - **描述**:服务器子进程意外退出后,工具可见但调用时 silent failure,需重启 CLI
1071
+ - **修复**:`McpClient.reconnect()` 清理旧状态后重新执行完整连接流程;`wrapMcpTool` execute 断线时自动尝试一次重连;`McpManager.reconnectServer()/reconnectAll()`;`/mcp reconnect [serverId]` 命令手动重连
1072
+
1073
+ ### 🟠 中危问题(全部已修复或确认安全 v0.1.34)
1074
+
1075
+ | # | 状态 | 文件 | 说明 |
1076
+ |---|------|------|------|
1077
+ | M5 | ✅ v0.1.34 | `bash.ts` | `persistentCwd` 指向已删除目录时自动回退 `process.cwd()` |
1078
+ | M6 | ✅ 已修复 | `web-fetch.ts` | 手动 redirect loop 每一跳均做 SSRF 检查 |
1079
+ | M7 | ✅ 已修复 | `run-interactive.ts` | `write()` 返回 false `once('drain')` 背压处理 |
1080
+ | M8 | ✅ 已修复 | `session-manager.ts` | `catch` `stderr.write` 含文件名和错误信息 |
1081
+ | M9 | ✅ H4 附带 | `mcp/client.ts` | `killProcess()` 已有 `removeAllListeners()` |
1082
+ | M10 | ✅ 非问题 | `permissions.ts` | 使用 `.includes()` 子串匹配,非正则,无 ReDoS 风险 |
1083
+ | M11 | ✅ 已修复 | `repl.ts` | `resolve()` + `startsWith(cwd)` 路径穿越校验 |
1084
+ | M12 | ✅ v0.1.34 | `mcp/manager.ts` | `convertSchema()` 递归转换嵌套 schema;`schemaToJsonSchema()` 供三 provider 统一使用 |
923
1085
 
924
1086
  ### 🟡 低危问题(后续改进)
925
1087
 
@@ -950,17 +1112,17 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
950
1112
  #### P0 — 核心竞争力缺口
951
1113
  - [x] **中断生成**(v0.1.30):`Escape` 键或 `Ctrl+C` 立即停止 AI 流式输出,不退出程序,显示 `[interrupted]` 后恢复提示符;已生成内容保留到 session
952
1114
  - [x] **多模态输入(图片)**(v0.1.30):`@image.png 描述这张图` 语法发送图片;Claude/Gemini/OpenAI 兼容格式自动转换;10MB 大小限制;`getVisionModelHint()` 正确识别 Claude/Gemini 原生支持视觉
953
- - [ ] **`/add-dir` 命令**:运行时动态添加目录到上下文
954
- - [ ] **并行工具调用**:AI 一次返回多个工具同时执行(当前为分组串行)
955
-
956
- #### P1 — 重要差距
957
- - [ ] **`/memory` 命令**:查看/编辑/清理 memory.md 内容(当前只能由工具写入)
958
- - [ ] **`/doctor` 健康检查**:诊断 API Key、网络、配置问题
959
- - [ ] **`/bug` 反馈命令**:一键提交 bug 报告
960
- - [ ] **Vim 编辑模式**:命令行输入支持 vim 键绑定
961
- - [ ] **桌面通知**:长任务完成时发送系统通知
962
- - [ ] **`--allowedTools` / `--blockedTools` 启动参数**:启动时动态限制工具集
963
- - [ ] **流式 JSON 输出**:`--output-format streaming-json` 逐行输出(当前仅支持一次性 `--json`)
1115
+ - [x] **`/add-dir` 命令**(v0.1.35):运行时动态添加目录到上下文(目录树 + 文件内容,限 40K 字符)
1116
+ - [x] **并行工具调用**(v0.1.35):safe 级别工具改为 `Promise.all()` 并行执行
1117
+
1118
+ #### P1 — 重要差距(已全部完成 v0.1.36,Vim 模式跳过)
1119
+ - [x] **`/memory` 命令**(v0.1.35):查看/手动追加/清空 memory.md,`/memory show|add|clear|path`
1120
+ - [x] **`/doctor` 健康检查**(v0.1.35):诊断 API Key 状态、配置文件、MCP 连接、context 占用率
1121
+ - [x] **`/bug` 反馈命令**(v0.1.36):生成含系统信息的 Bug 报告模板,`--copy` 复制到剪贴板
1122
+ - [ ] **Vim 编辑模式**:命令行输入支持 vim 键绑定(已跳过,优先级低)
1123
+ - [x] **桌面通知**(v0.1.36):`src/repl/notify.ts` 跨平台通知(osascript/PowerShell/notify-send),耗时超阈值自动触发,`config.ui.notificationThreshold`(默认 10000ms)
1124
+ - [x] **`--allowed-tools` / `--blocked-tools` 启动参数**(v0.1.35):启动时白名单/黑名单限制 AI 可用工具
1125
+ - [x] **流式 JSON 输出**(v0.1.36):`--output-format streaming-json`,NDJSON 每 chunk 一行 `{"type":"delta","text":"..."}` + 最终 `{"type":"done",...}`
964
1126
 
965
1127
  #### P2 — 体验增强
966
1128
  - [ ] **项目级 `.mcp.json`**:项目根目录独立 MCP 配置,优先全局 config
@@ -8,7 +8,7 @@ import { platform } from "os";
8
8
  import chalk from "chalk";
9
9
 
10
10
  // src/core/constants.ts
11
- var VERSION = "0.1.30";
11
+ var VERSION = "0.1.37";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -22,6 +22,7 @@ var MEMORY_MAX_CHARS = 1e4;
22
22
  var DEV_STATE_FILE_NAME = "dev-state.md";
23
23
  var DEFAULT_MAX_TOKENS = 8192;
24
24
  var MCP_TOOL_PREFIX = "mcp__";
25
+ var MCP_PROJECT_CONFIG_NAME = ".mcp.json";
25
26
  var MCP_CONNECT_TIMEOUT = 3e4;
26
27
  var MCP_CALL_TIMEOUT = 6e4;
27
28
  var MCP_PROTOCOL_VERSION = "2024-11-05";
@@ -75,6 +76,7 @@ var TEST_TIMEOUT = 3e5;
75
76
  var AUTHOR = "\u664B\u6B63\u4E1C";
76
77
  var AUTHOR_EMAIL = "zhengdong.jin@gmail.com";
77
78
  var DESCRIPTION = "\u8DE8\u5E73\u53F0 REPL \u98CE\u683C AI \u5BF9\u8BDD\u5DE5\u5177\uFF0C\u652F\u6301\u591A Provider \u4E0E Agentic \u5DE5\u5177\u8C03\u7528";
79
+ var REPO_URL = "https://gitee.com/jinzhengdong/ai-courses";
78
80
 
79
81
  // src/tools/builtin/run-tests.ts
80
82
  var IS_WINDOWS = platform() === "win32";
@@ -369,6 +371,7 @@ export {
369
371
  DEV_STATE_FILE_NAME,
370
372
  DEFAULT_MAX_TOKENS,
371
373
  MCP_TOOL_PREFIX,
374
+ MCP_PROJECT_CONFIG_NAME,
372
375
  MCP_CONNECT_TIMEOUT,
373
376
  MCP_CALL_TIMEOUT,
374
377
  MCP_PROTOCOL_VERSION,
@@ -381,6 +384,7 @@ export {
381
384
  AUTHOR,
382
385
  AUTHOR_EMAIL,
383
386
  DESCRIPTION,
387
+ REPO_URL,
384
388
  executeTests,
385
389
  runTestsTool
386
390
  };