jinzd-ai-cli 0.1.32 → 0.1.38
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
|
@@ -42,10 +42,11 @@ src/
|
|
|
42
42
|
├── repl/
|
|
43
43
|
│ ├── repl.ts # 主 REPL 循环(MAX_TOOL_ROUNDS=20,handleChatWithTools agentic loop)
|
|
44
44
|
│ ├── renderer.ts # 终端输出(renderStream / renderResponse 均不加前置 \n)
|
|
45
|
+
│ ├── theme.ts # 集中式主题系统(dark/light/custom 主题 + 语义色槽 Proxy 导出)
|
|
45
46
|
│ ├── dev-state.ts # 开发状态交接(provider/model 切换时快照生成、save/load/clear)
|
|
46
47
|
│ ├── setup-wizard.ts # @inquirer/prompts 首次运行交互式设置
|
|
47
48
|
│ └── commands/
|
|
48
|
-
│ └── index.ts # CommandRegistry +
|
|
49
|
+
│ └── 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
50
|
│ ├── custom-commands.ts # CustomCommandManager(~/.aicli/commands/*.md 用户自定义命令)
|
|
50
51
|
├── skills/
|
|
51
52
|
│ ├── types.ts # Skill/SkillMeta 接口、parseSkillFile(YAML frontmatter 解析)
|
|
@@ -333,6 +334,10 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
|
|
|
333
334
|
- [x] **Checkpointing**(2026-02-28):`/checkpoint save/restore/list/delete`,检查点元数据随 session JSON 持久化
|
|
334
335
|
- [x] **`/review` 代码审查**(2026-02-28):读取 git diff + 上下文,AI 生成结构化审查意见(`--staged`/`--detailed`)
|
|
335
336
|
- [x] **Custom Commands**(2026-02-28):`~/.aicli/commands/*.md` 用户自定义命令,YAML frontmatter + `{{input}}/{{git-diff}}/{{git-context}}/{{file:path}}` 模板变量
|
|
337
|
+
- [x] **项目级 `.mcp.json`**(2026-03-05):项目根目录 `.mcp.json` 自动发现,与全局 `config.json` 的 `mcpServers` 合并(项目覆盖同名),`/mcp` 显示 `[global]`/`[project]` 来源标签
|
|
338
|
+
- [x] **`--resume <id>` 启动参数**(2026-03-05):命令行直接恢复指定会话(前缀匹配),找不到时显示最近 5 个 session 提示
|
|
339
|
+
- [x] **Word wrap 配置**(2026-03-05):`config.ui.wordWrap`,0=自动(终端宽度),>0=固定列宽。ANSI 转义码感知折行
|
|
340
|
+
- [x] **主题/颜色自定义**(2026-03-05):`src/repl/theme.ts` 集中式主题系统,dark/light/custom 三主题 + 10 语义色槽 + Proxy 全局导出
|
|
336
341
|
|
|
337
342
|
## 已知待改进项
|
|
338
343
|
|
|
@@ -343,6 +348,241 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
|
|
|
343
348
|
- [x] **web_fetch DNS 解析时 SSRF 防护**(v0.1.25):新增 `resolveAndCheck()` 函数,用 `dns.promises.lookup()` 预解析域名,检查结果 IP 是否为私有地址。初始 URL 和 redirect 目标均校验。
|
|
344
349
|
- [ ] **`persistentCwd` 全局状态**:bash 工具的当前工作目录是模块级全局变量,多 session 并发时可能串扰。现阶段单 session REPL 无影响,GUI 多会话扩展时需重构为 per-session 状态。
|
|
345
350
|
|
|
351
|
+
## 本轮开发完成记录(2026-03-05,v0.1.36 → v0.1.37)
|
|
352
|
+
|
|
353
|
+
### P2 四项功能全部实现
|
|
354
|
+
|
|
355
|
+
**Feature 1:项目级 `.mcp.json`**(`src/repl/repl.ts` + `src/repl/commands/index.ts` + `src/core/constants.ts`)
|
|
356
|
+
- `src/core/constants.ts`:新增 `MCP_PROJECT_CONFIG_NAME = '.mcp.json'`
|
|
357
|
+
- `src/repl/repl.ts`:
|
|
358
|
+
- 新增私有属性 `mcpServerSources = new Map<string, 'global' | 'project'>()`
|
|
359
|
+
- 新增 `loadProjectMcpConfig()` 方法:`getGitRoot(cwd)` 查找项目根 → 读取 `<root>/.mcp.json` → 基础校验(每个 server 须有 `command` 字段)→ 解析失败 stderr 警告不中断启动
|
|
360
|
+
- `start()` 中 MCP 初始化重构:先获取全局 `mcpServers`,再获取项目 `.mcp.json`,合并(项目覆盖全局同名),记录来源到 `mcpServerSources`
|
|
361
|
+
- CommandContext 注入 `getMcpServerSource`
|
|
362
|
+
- `src/repl/commands/index.ts`:`/mcp` 命令显示每个服务器的 `[global]`/`[project]` 来源标签
|
|
363
|
+
|
|
364
|
+
**Feature 2:`--resume <id>` 启动参数**(`src/index.ts` + `src/repl/repl.ts`)
|
|
365
|
+
- `src/index.ts`:新增 `--resume <id>` CLI 选项 + `startRepl` 参数传入
|
|
366
|
+
- `src/repl/repl.ts`:
|
|
367
|
+
- constructor options 扩展 `resumeSessionId?: string`
|
|
368
|
+
- `start()` 有 `resumeSessionId` 时:`listSessions()` 前缀匹配 → 未找到显示最近 5 个 session + exit(1) → 找到则 `loadSession()` 恢复
|
|
369
|
+
- welcome 后显示 `📂 Resumed session: <id> (<N> messages, "<title>")`
|
|
370
|
+
|
|
371
|
+
**Feature 3:Word wrap 配置**(`src/config/schema.ts` + `src/repl/renderer.ts` + `src/repl/repl.ts`)
|
|
372
|
+
- `src/config/schema.ts`:`ui` 对象新增 `wordWrap: z.number().int().min(0).default(0)`(0=自动,>0=固定列宽)
|
|
373
|
+
- `src/repl/renderer.ts`:
|
|
374
|
+
- 新增 `stripAnsi(s: string): string` — 去除 ANSI 转义码(正则匹配 ESC 序列)
|
|
375
|
+
- 新增 `wrapText(text: string, width: number | undefined): string` — 逐行处理,按单词边界折行,ANSI 码不计入宽度
|
|
376
|
+
- Renderer constructor 扩展 `options?: { wrapWidth?: number }`
|
|
377
|
+
- `renderResponse()` 对内容应用 `wrapText()`(流式模式不折行,由终端自然处理)
|
|
378
|
+
|
|
379
|
+
**Feature 4:主题/颜色自定义**(`src/repl/theme.ts` + `src/config/schema.ts` + 多文件迁移)
|
|
380
|
+
- `src/config/schema.ts`:`ui` 对象新增 `theme: z.enum(['dark', 'light', 'custom']).default('dark')` + `colors` 对象(10 个可选色槽)
|
|
381
|
+
- **新文件** `src/repl/theme.ts`:
|
|
382
|
+
- `ThemeColors` 接口:10 个语义色槽(prompt/info/warning/error/success/dim/accent/toolCall/toolResult/heading)→ `ChalkInstance`
|
|
383
|
+
- `DARK_THEME`:精确匹配 v0.1.36 硬编码颜色(green/cyan/yellow/red/dim/magenta 等),确保零变化升级
|
|
384
|
+
- `LIGHT_THEME`:浅色终端优化(blue/blueBright/gray 等)
|
|
385
|
+
- `resolveColor(name: string)`:支持 chalk 颜色名 + `#hex` + `bold.cyan` 组合样式
|
|
386
|
+
- `buildCustomTheme(base, overrides)`:以 base 主题为底 + 自定义覆盖
|
|
387
|
+
- `initTheme(themeId, customColors?)`:设置全局主题
|
|
388
|
+
- `theme`:Proxy 导出,始终指向当前活跃主题
|
|
389
|
+
- 迁移覆盖:
|
|
390
|
+
- `src/repl/renderer.ts`:`printWelcome`(heading/prompt/dim)、`printPrompt`(prompt)、`renderStream`(accent)、`renderResponse`(accent)、`renderError`(error)、`printInfo`(warning)、`printSuccess`(success)
|
|
391
|
+
- `src/tools/executor.ts`:`printToolCall`(toolCall/accent/dim)、`printToolResult`(error/toolResult/warning)
|
|
392
|
+
- `src/repl/repl.ts`:constructor 中调用 `initTheme()`,传入 `wrapWidth` 给 Renderer
|
|
393
|
+
|
|
394
|
+
### 版本与收尾
|
|
395
|
+
- `src/core/constants.ts`:VERSION `0.1.36` → `0.1.37`
|
|
396
|
+
- `package.json`:version 同步
|
|
397
|
+
- `src/repl/renderer.ts`:`/about` 新增 4 条特性条目(项目级 .mcp.json / --resume / Word wrap / 主题系统)
|
|
398
|
+
- 构建验证:`npm run build` 零错误
|
|
399
|
+
- 发布:`npm publish` → `jinzd-ai-cli@0.1.37`
|
|
400
|
+
|
|
401
|
+
### 本轮变更文件汇总
|
|
402
|
+
|
|
403
|
+
| 文件 | 变更类型 | 说明 |
|
|
404
|
+
|------|---------|------|
|
|
405
|
+
| `src/core/constants.ts` | 修改 | VERSION 0.1.36 → 0.1.37,新增 MCP_PROJECT_CONFIG_NAME |
|
|
406
|
+
| `src/config/schema.ts` | 修改 | `ui.wordWrap` + `ui.theme` + `ui.colors` 三个新字段 |
|
|
407
|
+
| `src/repl/theme.ts` | 新增 | 集中式主题系统(ThemeColors + DARK/LIGHT + Proxy) |
|
|
408
|
+
| `src/repl/repl.ts` | 修改 | .mcp.json 加载 + --resume + theme 初始化 + mcpServerSources |
|
|
409
|
+
| `src/repl/renderer.ts` | 修改 | stripAnsi/wrapText 辅助函数 + theme 迁移 + /about 更新 |
|
|
410
|
+
| `src/tools/executor.ts` | 修改 | theme 迁移(printToolCall/printToolResult) |
|
|
411
|
+
| `src/repl/commands/index.ts` | 修改 | getMcpServerSource + /mcp 来源标签 |
|
|
412
|
+
| `src/index.ts` | 修改 | --resume CLI 选项 |
|
|
413
|
+
| `package.json` | 修改 | version 0.1.36 → 0.1.37 |
|
|
414
|
+
|
|
415
|
+
### 下一步建议
|
|
416
|
+
1. **Extended Thinking**:Claude 3.7 深度推理模式集成
|
|
417
|
+
2. **theme 迁移扩展**:`commands/index.ts` 中 ~115 个 chalk 调用增量迁移为 theme 调用
|
|
418
|
+
3. **L1 低危**:`run-tests.ts` 的 `JSON.parse(package.json)` 细粒度错误处理
|
|
419
|
+
4. **IDE 集成**:VS Code 扩展(架构已准备就绪)
|
|
420
|
+
5. **OAuth/浏览器登录**:无需手动填 API Key
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## 本轮开发完成记录(2026-03-05,v0.1.34 → v0.1.36)
|
|
425
|
+
|
|
426
|
+
### v0.1.35 — P0 功能缺口 + P1 前三项
|
|
427
|
+
|
|
428
|
+
**P0:并行工具调用**(`src/tools/executor.ts`)
|
|
429
|
+
- `executeAll()` 的 safe 级别工具从顺序 `for` 循环改为 `Promise.all()` 并行执行,批量 safe 工具整体耗时降至最慢单个工具的时间
|
|
430
|
+
|
|
431
|
+
**P0:`/add-dir` 动态目录上下文**(`src/repl/repl.ts` + `src/repl/commands/index.ts`)
|
|
432
|
+
- `Repl` 新增 `extraContextDirs` 数组 + `scanDirContent()`(目录树 + 文件内容,总限 40K 字符,单文件限 4K)
|
|
433
|
+
- `addExtraContextDir()` / `removeExtraContextDir()`:解析绝对路径,校验目录存在,存入数组
|
|
434
|
+
- `buildCurrentSystemPrompt()` 在 skill 段之前注入 `# Added Directory Context: <dir>` 段落
|
|
435
|
+
- `/add-dir <路径>`:添加目录;`/add-dir remove <路径>`:移除;`/add-dir`(无参):列出所有已添加目录
|
|
436
|
+
|
|
437
|
+
**启动参数:`--allowed-tools` / `--blocked-tools`**(`src/index.ts` + `src/repl/repl.ts`)
|
|
438
|
+
- CLI 新增两个选项,逗号分隔工具名,转为 `Set<string>` 传入 `Repl` 构造函数
|
|
439
|
+
- `handleChatWithTools()` 在 plan/skill 过滤之后叠加应用 allowedTools / blockedTools 过滤
|
|
440
|
+
|
|
441
|
+
**P1:`/memory` 命令**(`src/repl/commands/index.ts`)
|
|
442
|
+
- `show`:打印 memory.md 内容;`add <内容>`:`appendFileSync` 追加带时间戳条目;`clear`:清空文件(需确认);`path`:显示文件路径
|
|
443
|
+
|
|
444
|
+
**P1:`/doctor` 健康检查**(`src/repl/commands/index.ts`)
|
|
445
|
+
- 扫描所有 configured provider 的 API Key 状态(✓/✗)
|
|
446
|
+
- 检查 config.json 文件是否存在
|
|
447
|
+
- 调用 `getMcpManager().getStatus()` 显示 MCP 服务器连接状态
|
|
448
|
+
- 显示当前 session 消息数 + 估算 context 占用率(绿/黄/红)
|
|
449
|
+
|
|
450
|
+
**文档与版本**
|
|
451
|
+
- `src/repl/commands/index.ts`:`CommandContext` 新增 `addContextDir` / `removeContextDir` / `listContextDirs` 三个回调
|
|
452
|
+
- `src/repl/renderer.ts`:命令计数 28 → 31,添加 `/add-dir` `/memory` `/doctor`,新增 5 条特性条目
|
|
453
|
+
- VERSION `0.1.34` → `0.1.35`,`package.json` 同步
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
### v0.1.36 — P1 剩余三项全部完成
|
|
458
|
+
|
|
459
|
+
**P1:`/bug` 反馈命令**(`src/repl/commands/index.ts`)
|
|
460
|
+
- 生成 Markdown 格式 Bug 报告模板,自动填入 VERSION / OS(`platform()`)/ Node.js 版本 / 当前 Provider / 当前 Model
|
|
461
|
+
- `--copy` 参数调用已有 `copyToClipboard()` 复制到剪贴板
|
|
462
|
+
- 无 `--copy` 时打印报告并显示提交链接(`REPO_URL/issues`)
|
|
463
|
+
- 新增 `VERSION` + `REPO_URL` 到 constants.ts import
|
|
464
|
+
|
|
465
|
+
**P1:流式 JSON 输出**(`src/index.ts`)
|
|
466
|
+
- 新增 `--output-format <format>` CLI 选项,支持 `text`(默认)和 `streaming-json`
|
|
467
|
+
- `streaming-json` 模式:调用 `provider.chatStream()`,每个 delta 输出一行 NDJSON:
|
|
468
|
+
- `{"type":"delta","text":"..."}` —— 每个 chunk
|
|
469
|
+
- `{"type":"done","content":"...","provider":"...","model":"...","usage":{...}}` —— 最终行
|
|
470
|
+
- `--json` 和 `streaming-json` 均强制不走普通 `useStream` 分支
|
|
471
|
+
|
|
472
|
+
**P1:桌面通知**
|
|
473
|
+
- 新文件 `src/repl/notify.ts`:`sendNotification(title, body)` 跨平台非阻塞后台 spawn
|
|
474
|
+
- macOS:`osascript -e 'display notification "..." with title "..."'`
|
|
475
|
+
- Windows:PowerShell `System.Windows.Forms.NotifyIcon`(5 行脚本,`ShowBalloonTip(3000)`)
|
|
476
|
+
- Linux:`notify-send <title> <body>`
|
|
477
|
+
- 失败静默忽略(`try/catch` 包裹,不影响主流程)
|
|
478
|
+
- `src/config/schema.ts`:`ui` 对象新增 `notificationThreshold: z.number().default(10_000)`(单位 ms,0 = 禁用)
|
|
479
|
+
- `src/repl/repl.ts`:导入 `sendNotification`;`handleChat()` 在 `handleChatSimple`/`handleChatWithTools` 调用前记录 `t0 = Date.now()`,完成后对比阈值发送通知
|
|
480
|
+
|
|
481
|
+
**文档与版本**
|
|
482
|
+
- `src/repl/commands/index.ts`:`/help` 新增 `/bug [--copy]` 条目
|
|
483
|
+
- `src/repl/renderer.ts`:命令计数 31 → 32,命令行列表加入 `/bug`,新增 3 条特性
|
|
484
|
+
- 新增 `USAGE.md`:21 章节完整用户使用说明文档(CLI / REPL 命令 / 工具 / 配置 / 各高级特性)
|
|
485
|
+
- VERSION `0.1.35` → `0.1.36`,`package.json` 同步
|
|
486
|
+
- 构建验证:`npm run build` 零错误(ESM + CJS 双产物)
|
|
487
|
+
|
|
488
|
+
### 本轮变更文件汇总
|
|
489
|
+
|
|
490
|
+
| 文件 | 变更类型 | 说明 |
|
|
491
|
+
|------|---------|------|
|
|
492
|
+
| `src/core/constants.ts` | 修改 | VERSION 0.1.34 → 0.1.36 |
|
|
493
|
+
| `src/config/schema.ts` | 修改 | `ui.notificationThreshold` 新增字段 |
|
|
494
|
+
| `src/tools/executor.ts` | 修改 | safe 工具并行执行(Promise.all) |
|
|
495
|
+
| `src/repl/repl.ts` | 修改 | extraContextDirs、allowedTools/blockedTools、sendNotification 集成 |
|
|
496
|
+
| `src/repl/notify.ts` | 新增 | 跨平台桌面通知实现 |
|
|
497
|
+
| `src/repl/commands/index.ts` | 修改 | /add-dir /memory /doctor /bug 四个命令 + /help 更新 |
|
|
498
|
+
| `src/repl/renderer.ts` | 修改 | /about 命令数 28→32,新增特性条目 |
|
|
499
|
+
| `src/index.ts` | 修改 | --allowed-tools / --blocked-tools / --output-format 三个新参数 |
|
|
500
|
+
| `package.json` | 修改 | version 0.1.34 → 0.1.36 |
|
|
501
|
+
| `USAGE.md` | 新增 | 21 章节完整用户使用说明文档 |
|
|
502
|
+
|
|
503
|
+
### 下一步建议(P2 优先)
|
|
504
|
+
1. ~~**项目级 `.mcp.json`**~~:✅ 已在 v0.1.37 实现
|
|
505
|
+
2. ~~**`--resume <id>` 启动参数**~~:✅ 已在 v0.1.37 实现
|
|
506
|
+
3. ~~**Word wrap 配置**~~:✅ 已在 v0.1.37 实现
|
|
507
|
+
4. ~~**主题/颜色自定义**~~:✅ 已在 v0.1.37 实现
|
|
508
|
+
5. **L1 低危**:`run-tests.ts` 的 `JSON.parse(package.json)` 细粒度错误处理
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## 本轮开发完成记录(2026-03-03,v0.1.32 → v0.1.33)
|
|
513
|
+
|
|
514
|
+
### 高危安全修复:H1–H4 全部修复
|
|
515
|
+
|
|
516
|
+
**H1 — MCP pendingRequests 内存泄漏**(`src/mcp/client.ts`):
|
|
517
|
+
`sendRequest()` 重构——resolve/reject 回调内含统一 `cleanup()` 函数(`pendingRequests.delete(id)` + `clearTimeout(timer)`),任何 Promise 完成路径都即时释放资源。`handleMessage()` 简化——不再重复调用 delete/clearTimeout(由回调内部处理)。
|
|
518
|
+
|
|
519
|
+
**H2 — readline 竞态条件**(`src/tools/executor.ts`):
|
|
520
|
+
`confirm()` 和 `batchConfirm()` 中 `completed` 布尔守卫从外部变量统一移入 `cleanup()` 函数内部(单一检查点模式)。`rl.once('line')` 注册用 `try/catch` 包裹,极端情况下(readline 已关闭)确保 `confirming` 标志不会卡死。
|
|
521
|
+
|
|
522
|
+
**H3 — 工具执行错误语义混淆**(`src/tools/executor.ts`):
|
|
523
|
+
所有用户取消/拒绝路径的 `content` 增加语义前缀:
|
|
524
|
+
- `[User cancelled]` — 用户在 confirm 对话框中按 N 或 Ctrl+C
|
|
525
|
+
- `[User rejected]` — 用户在 batchConfirm 中拒绝特定文件
|
|
526
|
+
- `[Permission denied]` — 权限规则阻止
|
|
527
|
+
所有前缀后附 "Do not retry without asking." 指示,防止 AI 无意义重试。
|
|
528
|
+
|
|
529
|
+
**H4 — MCP 断开后无恢复机制**:
|
|
530
|
+
- `src/mcp/client.ts`:新增 `reconnect()` 方法——清理旧状态(rejectAllPending + killProcess + 重置缓冲区)后重新执行完整 `connect()` 流程
|
|
531
|
+
- `src/mcp/manager.ts`:新增 `reconnectServer(serverId)` 和 `reconnectAll()` 方法;`wrapMcpTool` 的 execute 函数在检测到断线时自动尝试一次重连,成功后继续调用
|
|
532
|
+
- `src/repl/commands/index.ts`:`/mcp reconnect [serverId]` 子命令——手动重连指定服务器或所有断开的服务器,成功后刷新 ToolRegistry 中的 MCP 工具
|
|
533
|
+
|
|
534
|
+
**版本与收尾**
|
|
535
|
+
- `src/core/constants.ts`:VERSION `0.1.30` → `0.1.33`
|
|
536
|
+
- `package.json`:version `0.1.32` → `0.1.33`
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## 本轮开发完成记录(2026-03-03,v0.1.33 → v0.1.34)
|
|
541
|
+
|
|
542
|
+
### 中危安全修复:M5–M12 全面排查
|
|
543
|
+
|
|
544
|
+
对审计报告中 8 个中危问题逐一排查,发现 **M6–M11 已在先前版本修复或确认安全**,仅 **M5** 和 **M12** 需要新代码修复。
|
|
545
|
+
|
|
546
|
+
**M5 — bash `persistentCwd` 指向已删除目录**(`src/tools/builtin/bash.ts`):
|
|
547
|
+
- 问题:`persistentCwd` 模块级变量记住上次 `cd` 目标,但该目录可能在后续操作中被删除(如 `rm -rf`),导致下一次 bash 调用 `execSync` 报 `ENOENT`
|
|
548
|
+
- 修复:`execute()` 开头新增 `existsSync(persistentCwd)` 检查,不存在时自动回退到 `process.cwd()` 并打印 stderr 警告
|
|
549
|
+
|
|
550
|
+
**M12 — MCP 工具 schema 嵌套结构丢失**(`src/mcp/manager.ts` + `src/tools/types.ts` + 三个 provider):
|
|
551
|
+
- 问题:MCP 工具的 JSON Schema 含嵌套 object/array 时,`convertDefinition()` 扁平化为简单类型,AI 生成的参数结构与实际 schema 不匹配导致调用失败
|
|
552
|
+
- 修复:
|
|
553
|
+
- `src/tools/types.ts`:`ToolParameterSchema` 新增 `properties?: Record<string, ToolParameterSchema>` 字段;`items` 类型从 `{ type: ToolParameterType }` 扩展为完整 `ToolParameterSchema`;新增 `schemaToJsonSchema()` 公共递归转换函数
|
|
554
|
+
- `src/mcp/manager.ts`:新增 `convertSchema()` 私有递归方法,替代原有扁平转换
|
|
555
|
+
- `src/providers/openai-compatible.ts`、`claude.ts`、`gemini.ts`:统一使用 `schemaToJsonSchema()` 构建 API 请求的工具参数 schema
|
|
556
|
+
|
|
557
|
+
**M6–M11 排查结论**(无需修改):
|
|
558
|
+
| # | 结论 |
|
|
559
|
+
|---|------|
|
|
560
|
+
| M6 | web-fetch 手动 redirect 循环每一跳均做 SSRF 检查,已安全 |
|
|
561
|
+
| M7 | run-interactive `write()` 返回 false 时已有 `once('drain')` 背压处理 |
|
|
562
|
+
| M8 | session-manager `catch` 中已有 `stderr.write` 含文件名和错误信息 |
|
|
563
|
+
| M9 | mcp/client `killProcess()` 已有 `removeAllListeners()`(H4 修复附带) |
|
|
564
|
+
| M10 | permissions.ts 使用 `.includes()` 子串匹配而非正则,无 ReDoS 风险 |
|
|
565
|
+
| M11 | repl.ts 上下文加载已有 `resolve()` + `startsWith(cwd)` 路径穿越校验 |
|
|
566
|
+
|
|
567
|
+
**版本与收尾**
|
|
568
|
+
- `src/core/constants.ts`:VERSION `0.1.33` → `0.1.34`
|
|
569
|
+
- `package.json`:version `0.1.33` → `0.1.34`
|
|
570
|
+
- 代码审查报告表格全部更新为已修复/已确认安全状态
|
|
571
|
+
- 构建通过:`npm run build` 零错误
|
|
572
|
+
|
|
573
|
+
### 安全审计完结状态
|
|
574
|
+
- **高危 H1–H4**:全部已修复(v0.1.33)
|
|
575
|
+
- **中危 M5–M12**:全部已修复或确认安全(v0.1.34)
|
|
576
|
+
- **低危 L1–L7**:L2–L7 已在 v0.1.30 修复/确认,L1 待后续改进
|
|
577
|
+
- **安全债务已清零**,可安全进入功能开发阶段
|
|
578
|
+
|
|
579
|
+
### 下一步建议
|
|
580
|
+
1. **P0 功能缺口**:并行工具调用、`/add-dir` 命令
|
|
581
|
+
2. **P1 功能缺口**:`/memory` 命令、`/doctor` 健康检查、`/bug` 反馈
|
|
582
|
+
3. **L1 低危**:`run-tests.ts` 的 `JSON.parse(package.json)` 细粒度错误处理
|
|
583
|
+
|
|
584
|
+
---
|
|
585
|
+
|
|
346
586
|
## 本轮开发完成记录(2026-03-01,v0.1.26 → v0.1.30)
|
|
347
587
|
|
|
348
588
|
### 安全修复续篇:低危 L2–L7
|
|
@@ -886,40 +1126,40 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
|
|
|
886
1126
|
|
|
887
1127
|
> 全面扫描 src/ 目录 35+ 个 TypeScript 源文件,共发现 **4 高危 + 8 中危 + 7 低危** 问题。
|
|
888
1128
|
|
|
889
|
-
### 🔴
|
|
1129
|
+
### 🔴 高危问题(全部已修复 v0.1.33)
|
|
890
1130
|
|
|
891
|
-
**H1 — MCP pendingRequests 内存泄漏**
|
|
1131
|
+
**H1 — MCP pendingRequests 内存泄漏** ✅
|
|
892
1132
|
- **文件**:`src/mcp/client.ts`
|
|
893
|
-
-
|
|
894
|
-
-
|
|
895
|
-
|
|
896
|
-
**H2 — readline 竞态条件:`confirming` 标志失效**
|
|
897
|
-
- **文件**:`src/tools/executor.ts
|
|
898
|
-
- **描述**:`batchConfirm()`
|
|
899
|
-
-
|
|
900
|
-
|
|
901
|
-
**H3 — 工具执行错误语义混淆(isError 混用)**
|
|
902
|
-
- **文件**:`src/tools/executor.ts
|
|
903
|
-
-
|
|
904
|
-
-
|
|
905
|
-
|
|
906
|
-
**H4 — MCP 断开后无恢复机制**
|
|
907
|
-
- **文件**:`src/mcp/client.ts` + `src/mcp/manager.ts`
|
|
908
|
-
-
|
|
909
|
-
- **修复**:`
|
|
910
|
-
|
|
911
|
-
### 🟠
|
|
912
|
-
|
|
913
|
-
| # |
|
|
914
|
-
|
|
915
|
-
| M5 |
|
|
916
|
-
| M6 | `
|
|
917
|
-
| M7 | `
|
|
918
|
-
| M8 | `
|
|
919
|
-
| M9 | `
|
|
920
|
-
| M10 | `
|
|
921
|
-
| M11 | `
|
|
922
|
-
| M12 | `
|
|
1133
|
+
- **描述**:`withTimeout` 外层超时后,`sendRequest` 内部的 pending 条目和 timer 滞留到内部超时才释放
|
|
1134
|
+
- **修复**:`sendRequest` 中 resolve/reject 回调内含统一 `cleanup()` 函数,任何路径(正常响应/内部超时/写入错误/外部 reject)都即时释放资源
|
|
1135
|
+
|
|
1136
|
+
**H2 — readline 竞态条件:`confirming` 标志失效** ✅
|
|
1137
|
+
- **文件**:`src/tools/executor.ts`、`src/tools/builtin/ask-user.ts`
|
|
1138
|
+
- **描述**:`confirm()`/`batchConfirm()`/`ask_user` 的 `once('line')` 在极端 edge case 下可能二次触发
|
|
1139
|
+
- **修复**:`completed` 布尔守卫统一移入 `cleanup()` 内部(单一检查点);`try/catch` 包裹 `rl.once()` 注册防止 readline 已关闭时 `confirming` 卡死
|
|
1140
|
+
|
|
1141
|
+
**H3 — 工具执行错误语义混淆(isError 混用)** ✅
|
|
1142
|
+
- **文件**:`src/tools/executor.ts`
|
|
1143
|
+
- **描述**:用户取消和权限拒绝的 content 缺少语义前缀,AI 难以区分取消/拒绝/真实错误
|
|
1144
|
+
- **修复**:所有取消/拒绝路径 content 加 `[User cancelled]`/`[User rejected]`/`[Permission denied]` 前缀 + "Do not retry without asking" 提示
|
|
1145
|
+
|
|
1146
|
+
**H4 — MCP 断开后无恢复机制** ✅
|
|
1147
|
+
- **文件**:`src/mcp/client.ts` + `src/mcp/manager.ts` + `src/repl/commands/index.ts`
|
|
1148
|
+
- **描述**:服务器子进程意外退出后,工具可见但调用时 silent failure,需重启 CLI
|
|
1149
|
+
- **修复**:`McpClient.reconnect()` 清理旧状态后重新执行完整连接流程;`wrapMcpTool` execute 断线时自动尝试一次重连;`McpManager.reconnectServer()/reconnectAll()`;`/mcp reconnect [serverId]` 命令手动重连
|
|
1150
|
+
|
|
1151
|
+
### 🟠 中危问题(全部已修复或确认安全 v0.1.34)
|
|
1152
|
+
|
|
1153
|
+
| # | 状态 | 文件 | 说明 |
|
|
1154
|
+
|---|------|------|------|
|
|
1155
|
+
| M5 | ✅ v0.1.34 | `bash.ts` | `persistentCwd` 指向已删除目录时自动回退 `process.cwd()` |
|
|
1156
|
+
| M6 | ✅ 已修复 | `web-fetch.ts` | 手动 redirect loop 每一跳均做 SSRF 检查 |
|
|
1157
|
+
| M7 | ✅ 已修复 | `run-interactive.ts` | `write()` 返回 false 时 `once('drain')` 背压处理 |
|
|
1158
|
+
| M8 | ✅ 已修复 | `session-manager.ts` | `catch` 中 `stderr.write` 含文件名和错误信息 |
|
|
1159
|
+
| M9 | ✅ H4 附带 | `mcp/client.ts` | `killProcess()` 已有 `removeAllListeners()` |
|
|
1160
|
+
| M10 | ✅ 非问题 | `permissions.ts` | 使用 `.includes()` 子串匹配,非正则,无 ReDoS 风险 |
|
|
1161
|
+
| M11 | ✅ 已修复 | `repl.ts` | `resolve()` + `startsWith(cwd)` 路径穿越校验 |
|
|
1162
|
+
| M12 | ✅ v0.1.34 | `mcp/manager.ts` | `convertSchema()` 递归转换嵌套 schema;`schemaToJsonSchema()` 供三 provider 统一使用 |
|
|
923
1163
|
|
|
924
1164
|
### 🟡 低危问题(后续改进)
|
|
925
1165
|
|
|
@@ -944,29 +1184,31 @@ const stdinLines = Array.isArray(rawStdin) ? rawStdin.map(String)
|
|
|
944
1184
|
- Dev State 开发状态交接
|
|
945
1185
|
- Agent Skills 系统
|
|
946
1186
|
- 企业级权限规则 + Hooks 系统
|
|
1187
|
+
- 主题/颜色自定义系统(dark/light/custom + 10 语义色槽)
|
|
1188
|
+
- 项目级 MCP 配置(`.mcp.json` + 全局合并 + 来源追踪)
|
|
947
1189
|
|
|
948
1190
|
### ❌ 缺失功能路线图(新增)
|
|
949
1191
|
|
|
950
1192
|
#### P0 — 核心竞争力缺口
|
|
951
1193
|
- [x] **中断生成**(v0.1.30):`Escape` 键或 `Ctrl+C` 立即停止 AI 流式输出,不退出程序,显示 `[interrupted]` 后恢复提示符;已生成内容保留到 session
|
|
952
1194
|
- [x] **多模态输入(图片)**(v0.1.30):`@image.png 描述这张图` 语法发送图片;Claude/Gemini/OpenAI 兼容格式自动转换;10MB 大小限制;`getVisionModelHint()` 正确识别 Claude/Gemini 原生支持视觉
|
|
953
|
-
- [
|
|
954
|
-
- [
|
|
955
|
-
|
|
956
|
-
#### P1 —
|
|
957
|
-
- [
|
|
958
|
-
- [
|
|
959
|
-
- [
|
|
960
|
-
- [ ] **Vim 编辑模式**:命令行输入支持 vim
|
|
961
|
-
- [
|
|
962
|
-
- [
|
|
963
|
-
- [
|
|
964
|
-
|
|
965
|
-
#### P2 —
|
|
966
|
-
- [
|
|
1195
|
+
- [x] **`/add-dir` 命令**(v0.1.35):运行时动态添加目录到上下文(目录树 + 文件内容,限 40K 字符)
|
|
1196
|
+
- [x] **并行工具调用**(v0.1.35):safe 级别工具改为 `Promise.all()` 并行执行
|
|
1197
|
+
|
|
1198
|
+
#### P1 — 重要差距(已全部完成 v0.1.36,Vim 模式跳过)
|
|
1199
|
+
- [x] **`/memory` 命令**(v0.1.35):查看/手动追加/清空 memory.md,`/memory show|add|clear|path`
|
|
1200
|
+
- [x] **`/doctor` 健康检查**(v0.1.35):诊断 API Key 状态、配置文件、MCP 连接、context 占用率
|
|
1201
|
+
- [x] **`/bug` 反馈命令**(v0.1.36):生成含系统信息的 Bug 报告模板,`--copy` 复制到剪贴板
|
|
1202
|
+
- [ ] **Vim 编辑模式**:命令行输入支持 vim 键绑定(已跳过,优先级低)
|
|
1203
|
+
- [x] **桌面通知**(v0.1.36):`src/repl/notify.ts` 跨平台通知(osascript/PowerShell/notify-send),耗时超阈值自动触发,`config.ui.notificationThreshold`(默认 10000ms)
|
|
1204
|
+
- [x] **`--allowed-tools` / `--blocked-tools` 启动参数**(v0.1.35):启动时白名单/黑名单限制 AI 可用工具
|
|
1205
|
+
- [x] **流式 JSON 输出**(v0.1.36):`--output-format streaming-json`,NDJSON 每 chunk 一行 `{"type":"delta","text":"..."}` + 最终 `{"type":"done",...}`
|
|
1206
|
+
|
|
1207
|
+
#### P2 — 体验增强(v0.1.37 完成 4 项)
|
|
1208
|
+
- [x] **项目级 `.mcp.json`**(v0.1.37):项目根目录 `.mcp.json` 自动发现,与全局合并(项目覆盖同名),`/mcp` 显示来源标签
|
|
1209
|
+
- [x] **`--resume <id>` 启动参数**(v0.1.37):命令行直接恢复指定会话(前缀匹配),找不到时显示最近 5 个 session
|
|
1210
|
+
- [x] **Word wrap 配置**(v0.1.37):`config.ui.wordWrap`,ANSI 转义码感知折行
|
|
1211
|
+
- [x] **主题/颜色自定义**(v0.1.37):dark/light/custom 三主题 + 10 语义色槽 + Proxy 全局导出
|
|
967
1212
|
- [ ] **IDE 集成**:VS Code / JetBrains 扩展(架构已准备就绪)
|
|
968
1213
|
- [ ] **OAuth/浏览器登录**:无需手动填 API Key
|
|
969
|
-
- [ ]
|
|
970
|
-
- [ ] **Extended Thinking**:Claude 3.7 深度推理模式集成
|
|
971
|
-
- [ ] **Word wrap 配置**:终端输出折行宽度可配置
|
|
972
|
-
- [ ] **主题/颜色自定义**:dark/light/custom 主题
|
|
1214
|
+
- [ ] **Extended Thinking**:Claude 深度推理模式集成
|
|
@@ -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.
|
|
11
|
+
var VERSION = "0.1.38";
|
|
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
|
};
|