jinzd-ai-cli 0.4.263 → 0.4.265

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.
Files changed (41) hide show
  1. package/README.md +59 -37
  2. package/README.zh-CN.md +63 -41
  3. package/dist/{batch-AN47AYCZ.js → batch-C7SHXRQ2.js} +2 -2
  4. package/dist/{chunk-VT6NRDD2.js → chunk-23SJVOQD.js} +6 -2
  5. package/dist/{chunk-QMB7QYZC.js → chunk-2MR7EP24.js} +1 -1
  6. package/dist/chunk-5C76XDDF.js +78 -0
  7. package/dist/chunk-6YZEZFX5.js +40 -0
  8. package/dist/{chunk-TL5MD5XU.js → chunk-AUEX6RNY.js} +17 -1
  9. package/dist/{chunk-MTZ6XHJD.js → chunk-CVI3LSGR.js} +2 -2
  10. package/dist/{chunk-B27MLWFJ.js → chunk-E3JRGJCJ.js} +4 -4
  11. package/dist/{chunk-MJICIIBW.js → chunk-IFTUBTDA.js} +1 -1
  12. package/dist/{chunk-VUZAKIZ5.js → chunk-LZBD2VGJ.js} +1 -1
  13. package/dist/{chunk-3RHY2HF7.js → chunk-M2RKBTVZ.js} +1 -1
  14. package/dist/{chunk-7YCA2BD3.js → chunk-NJLPA6S4.js} +1 -1
  15. package/dist/{chunk-GMZTY7DA.js → chunk-NOS3QV7G.js} +13 -8
  16. package/dist/{chunk-GKI7B4BD.js → chunk-TJBG4F2R.js} +24 -95
  17. package/dist/{chunk-QG4NG7KJ.js → chunk-V4D7YD24.js} +9 -2
  18. package/dist/{chunk-3ARPAVNV.js → chunk-VOIOUJXI.js} +11 -3
  19. package/dist/{chunk-WM4VTGAF.js → chunk-X6NWK2YK.js} +1 -1
  20. package/dist/{chunk-VKBGOFEO.js → chunk-Y7KJPNQI.js} +1 -1
  21. package/dist/{chunk-XST4N2JM.js → chunk-YDTYBUAB.js} +1 -1
  22. package/dist/{chunk-5K2LFD7D.js → chunk-YXYOLPDB.js} +1 -1
  23. package/dist/{ci-JTO7LN5S.js → ci-TDXLI3OM.js} +6 -5
  24. package/dist/{ci-format-2VGHOLBA.js → ci-format-AFX2LP4Y.js} +2 -2
  25. package/dist/{constants-HLSJL5HQ.js → constants-66TQEDGO.js} +1 -1
  26. package/dist/{doctor-cli-JML4FGH4.js → doctor-cli-GMCOGCDR.js} +5 -5
  27. package/dist/electron-server.js +57 -12
  28. package/dist/{hub-6EYFGJRT.js → hub-2YXETHPY.js} +8 -4
  29. package/dist/{hub-server-QGUSMN22.js → hub-server-RF6LURXY.js} +3 -1
  30. package/dist/index.js +123 -546
  31. package/dist/{persistent-memory-MPBPSZDN.js → persistent-memory-2DKCETB7.js} +2 -2
  32. package/dist/{persistent-memory-ANIMO5CF.js → persistent-memory-WTZO5CQ7.js} +2 -2
  33. package/dist/{pr-XE7NGT6U.js → pr-Y2LDG3R7.js} +15 -10
  34. package/dist/{run-tests-TF7UPUWW.js → run-tests-FIUGDIDL.js} +2 -2
  35. package/dist/{run-tests-ME5KED57.js → run-tests-PWTNSUVP.js} +2 -2
  36. package/dist/{server-VKA4FR2Z.js → server-OZ4RFDFH.js} +25 -15
  37. package/dist/{server-BIYJEJK3.js → server-ZCG5QD6P.js} +6 -5
  38. package/dist/setup-wizard-S55ICNHH.js +483 -0
  39. package/dist/{task-orchestrator-2RAKLFWN.js → task-orchestrator-Q2L6JEUX.js} +10 -7
  40. package/dist/{usage-5F5Q3GGR.js → usage-SDL5Z4CS.js} +3 -3
  41. package/package.json +1 -1
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  **English** | [中文](README.zh-CN.md)
2
2
 
3
- # ai-cli
4
-
5
- <!-- AICLI:DOCS_DEFAULT_WEB_PORT=3000 -->
6
- <!-- AICLI:DOCS_BUILTIN_TOOL_COUNT=30 -->
7
- <!-- AICLI:DOCS_REPL_COMMAND_COUNT=48 -->
8
- <!-- AICLI:DOCS_BUILTIN_PROVIDER_COUNT=10 -->
9
- <!-- AICLI:DOCS_MEMORY_SOURCE=memory.jsonl -->
10
-
11
- > A cross-platform AI coding assistant — CLI, Web UI, and Desktop App — with multi-provider support and agentic tool calling
3
+ # ai-cli
4
+
5
+ <!-- AICLI:DOCS_DEFAULT_WEB_PORT=3000 -->
6
+ <!-- AICLI:DOCS_BUILTIN_TOOL_COUNT=30 -->
7
+ <!-- AICLI:DOCS_REPL_COMMAND_COUNT=48 -->
8
+ <!-- AICLI:DOCS_BUILTIN_PROVIDER_COUNT=10 -->
9
+ <!-- AICLI:DOCS_MEMORY_SOURCE=memory.jsonl -->
10
+
11
+ > A cross-platform AI coding assistant — CLI, Web UI, and Desktop App — with multi-provider support and agentic tool calling
12
12
 
13
13
  [![npm version](https://img.shields.io/npm/v/jinzd-ai-cli)](https://www.npmjs.com/package/jinzd-ai-cli)
14
14
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
@@ -131,14 +131,14 @@ aicli user delete x # Delete user
131
131
  |----------|--------|-------------|
132
132
  | **Claude** | Opus 4, Sonnet 4, Haiku 4 | [console.anthropic.com](https://console.anthropic.com) |
133
133
  | **Gemini** | 2.5 Pro, 2.5 Flash | [aistudio.google.com](https://aistudio.google.com) |
134
- | **DeepSeek** | deepseek-v4-flash (default), deepseek-v4-pro | [platform.deepseek.com](https://platform.deepseek.com) |
134
+ | **DeepSeek** | deepseek-v4-flash (default), deepseek-v4-pro | [platform.deepseek.com](https://platform.deepseek.com) |
135
135
  | **OpenAI** | GPT-5.4, GPT-5, GPT-4.1, o3, o4-mini | [platform.openai.com](https://platform.openai.com) |
136
136
  | **OpenRouter** | 300+ models (Claude, GPT, Gemini, Llama, Qwen, Mistral...) | [openrouter.ai](https://openrouter.ai) |
137
137
  | **Zhipu** | GLM-4, GLM-5 | [open.bigmodel.cn](https://open.bigmodel.cn) |
138
138
  | **Kimi** | Kimi K2.6, K2.5, K2 Thinking | [platform.moonshot.cn](https://platform.moonshot.cn) |
139
- | **Qwen** | qwen-plus, qwen-max, qwen-turbo, qwen-coder-plus | [bailian.console.aliyun.com](https://bailian.console.aliyun.com) |
140
- | **MiniMax** | MiniMax-M3 (default), M2.7, M2.5, M2.1, M2 | [platform.minimaxi.com](https://platform.minimaxi.com) |
141
- | **Ollama** | Any locally installed model (Llama, Qwen, Gemma, Mistral...) | No API key — [ollama.com](https://ollama.com) |
139
+ | **Qwen** | qwen-plus, qwen-max, qwen-turbo, qwen-coder-plus | [bailian.console.aliyun.com](https://bailian.console.aliyun.com) |
140
+ | **MiniMax** | MiniMax-M3 (default), M2.7, M2.5, M2.1, M2 | [platform.minimaxi.com](https://platform.minimaxi.com) |
141
+ | **Ollama** | Any locally installed model (Llama, Qwen, Gemma, Mistral...) | No API key — [ollama.com](https://ollama.com) |
142
142
 
143
143
  Any OpenAI-compatible API can also be used via `customBaseUrls` in config.
144
144
 
@@ -172,11 +172,11 @@ AI autonomously invokes these 30 tools during conversations:
172
172
  | `edit_file` | write | Precise string replacement with fuzzy matching hints + `replaceAll` mode |
173
173
  | `list_dir` | safe | List directory contents |
174
174
  | `grep_files` | safe | Regex search across files |
175
- | `glob_files` | safe | Match files by glob pattern |
176
- | `web_fetch` | safe | Fetch web pages as Markdown (SSRF-protected) |
177
- | `web_search` | safe | Keyless Bing/Google web search with weak-result fallback |
178
- | `google_search` | safe | Google Custom Search API |
179
- | `run_interactive` | write | Run interactive programs with stdin input; arbitrary executables require confirmation |
175
+ | `glob_files` | safe | Match files by glob pattern |
176
+ | `web_fetch` | safe | Fetch web pages as Markdown (SSRF-protected) |
177
+ | `web_search` | safe | Keyless Bing/Google web search with weak-result fallback |
178
+ | `google_search` | safe | Google Custom Search API |
179
+ | `run_interactive` | write | Run interactive programs with stdin input; arbitrary executables require confirmation |
180
180
  | `run_tests` | safe | Auto-detect and run project tests (JUnit XML parsing) |
181
181
  | `spawn_agent` | safe | Delegate subtasks to named isolated agents (`agent`: explorer/worker/reviewer/security/tester) |
182
182
  | `ask_user` | safe | Pause and ask the user a question |
@@ -193,11 +193,11 @@ AI autonomously invokes these 30 tools during conversations:
193
193
  | `notebook_edit` | write | Edit Jupyter notebook cells (add/edit/delete/move) |
194
194
  | `find_symbol` | safe | Locate symbol definitions via persistent tree-sitter index (TS/JS/TSX/Python/Go/Rust/Java/C++) |
195
195
  | `get_outline` | safe | Enumerate all top-level declarations in one source file |
196
- | `find_references` | safe | Search indexed files for references to a symbol name |
197
- | `search_code` | safe | Semantic (meaning-based) code search via local sentence embeddings — bilingual, "grep by meaning" |
198
- | `recall_memory` | safe | Semantically recall relevant excerpts from earlier chat sessions |
196
+ | `find_references` | safe | Search indexed files for references to a symbol name |
197
+ | `search_code` | safe | Semantic (meaning-based) code search via local sentence embeddings — bilingual, "grep by meaning" |
198
+ | `recall_memory` | safe | Semantically recall relevant excerpts from earlier chat sessions |
199
199
 
200
- **Safety levels**: `safe` = auto-execute, `write` = confirmation required (file-editing tools also show a diff preview), `destructive` = prominent warning + confirmation.
200
+ **Safety levels**: `safe` = auto-execute, `write` = confirmation required (file-editing tools also show a diff preview), `destructive` = prominent warning + confirmation.
201
201
 
202
202
  ## Key REPL Commands
203
203
 
@@ -465,9 +465,9 @@ Environment variables take precedence over config file values:
465
465
  | `AICLI_API_KEY_OPENROUTER` | OpenRouter API Key |
466
466
  | `AICLI_API_KEY_ZHIPU` | Zhipu API Key |
467
467
  | `AICLI_API_KEY_KIMI` | Kimi API Key |
468
- | `AICLI_API_KEY_QWEN` | Qwen / Alibaba Cloud API Key |
469
- | `AICLI_API_KEY_MINIMAX` | MiniMax API Key |
470
- | `AICLI_PROVIDER` | Default provider ID |
468
+ | `AICLI_API_KEY_QWEN` | Qwen / Alibaba Cloud API Key |
469
+ | `AICLI_API_KEY_MINIMAX` | MiniMax API Key |
470
+ | `AICLI_PROVIDER` | Default provider ID |
471
471
  | `AICLI_NO_STREAM` | Set to `1` to disable streaming |
472
472
  | `HTTPS_PROXY` / `HTTP_PROXY` | Proxy URL |
473
473
 
@@ -521,15 +521,15 @@ The Web UI (`aicli web`) provides a full-featured browser interface:
521
521
  ## Testing
522
522
 
523
523
  ```bash
524
- npm test # Offline regression suite
524
+ npm test # Offline regression suite
525
525
  npm run test:providers # Real-provider smoke tests (network/API-key dependent)
526
526
  npm run test:e2e-web # Playwright browser smoke; may need browser-process permission in sandboxes
527
527
  npm run test:watch # Watch mode
528
528
  ```
529
529
 
530
- Offline tests cover authentication, sessions, tool types and danger levels, permissions, output truncation, diff rendering, edit-file similarity, error hierarchy, config management, env loading, provider registry, web-fetch, grep-files, Hub, dev-state, token estimation, tool registry budgets, parallel tool execution, cost tracking, and session tool history.
530
+ Offline tests cover authentication, sessions, tool types and danger levels, permissions, output truncation, diff rendering, edit-file similarity, error hierarchy, config management, env loading, provider registry, web-fetch, grep-files, Hub, dev-state, token estimation, tool registry budgets, parallel tool execution, cost tracking, and session tool history.
531
531
 
532
- ## Releasing (Version Bump → Git Tag → Trusted npm Publish)
532
+ ## Releasing (Version Bump → Git Tag → Trusted npm Publish)
533
533
 
534
534
  > **For contributors and AI agents: the entire release is driven by [`scripts/release.mjs`](scripts/release.mjs). Never manually bump the version or run `npm publish` yourself** — a hand-publish of `0.4.207` shipped a version that reported the wrong number and forced a corrective re-release (`0.4.208`). The script's guards exist precisely to stop that.
535
535
 
@@ -537,7 +537,7 @@ Offline tests cover authentication, sessions, tool types and danger levels, perm
537
537
 
538
538
  - You are on the `main` branch and the changes to ship are already in the working tree.
539
539
  - `npx tsc --noEmit` is clean and `npm test` is green (the script enforces both and rolls the bump back on failure).
540
- - npm Trusted Publishing is configured for `jinzd-ai-cli` and `.github/workflows/release.yml`.
540
+ - npm Trusted Publishing is configured for `jinzd-ai-cli` and `.github/workflows/release.yml`.
541
541
  - You have push access to the GitHub remote.
542
542
 
543
543
  **Step 1 — Write the milestone entry FIRST (Guard A).** Add a one-line entry to the `## 最近里程碑` section of [`CLAUDE.md`](CLAUDE.md) that contains the exact full-width-parenthesis marker `(vX.Y.Z)` for the target version. The script refuses to start without it. (Full narrative goes in `CHANGELOG.md`; this section is just the index line.)
@@ -564,10 +564,32 @@ node scripts/release.mjs patch -m "..." --dry-run
564
564
  5. `npm test` must pass (rolls the bump back on failure).
565
565
  6. Prints the exact file list entering the release commit and blocks if any looks sensitive (`.env`, `*.pem`, `*.key`, `secret`, …). Override consciously with `--allow-sensitive`.
566
566
  7. `git add -A` + commit `"<title> (vX.Y.Z)"` (message passed via argv, not shell-interpolated).
567
- 8. Creates an annotated `vX.Y.Z` release tag.
568
- 9. Pushes `main` and the tag. The pinned GitHub Actions workflow verifies the project and publishes to npm through OIDC, without a long-lived npm token.
569
-
570
- **Optional flags:** `--dry-run` · `--skip-tests` · `--no-tag` · `--no-push` · `--allow-sensitive`. The old `--no-publish` flag remains an alias for `--no-tag`.
567
+ 8. Creates an annotated `vX.Y.Z` release tag.
568
+ 9. Pushes `main` and the tag. The pinned GitHub Actions workflow verifies the project and publishes to npm through OIDC, without a long-lived npm token.
569
+
570
+ **Optional flags:** `--dry-run` · `--skip-tests` · `--no-tag` · `--no-push` · `--allow-sensitive`. The old `--no-publish` flag remains an alias for `--no-tag`.
571
+
572
+ ### Which files a release touches
573
+
574
+ Two groups: what **you** write by hand (the script never touches these, and Guard A refuses to start without them) and what the **script** rewrites (never edit these by hand).
575
+
576
+ | File | Written by | What changes |
577
+ |---|---|---|
578
+ | `CHANGELOG.md` | **By hand, before releasing** | A new `## [X.Y.Z] - YYYY-MM-DD` section with the full narrative: root cause / fix / tests. This is the only place detail lives |
579
+ | `CLAUDE.md` → `## 最近里程碑` | **By hand, before releasing** | **One** index line at the top, which must carry the full-width marker `(vX.Y.Z)` — this exact line is what Guard A checks |
580
+ | `package.json` | Script | `"version"` |
581
+ | `src/core/constants.ts` | Script | The `VERSION` constant (what `aicli --version` and the help banner actually read — drift here ships a package that reports the wrong version) |
582
+ | `CLAUDE.md` → `**当前版本**` | Script | The version number (a *second*, separate spot from the hand-written milestone line) |
583
+ | `docs/USAGE.md`, `docs/USAGE.zh-CN.md`, `docs/ADVANCED*.md`, `docs/TUTORIAL*.md`, `docs/RECIPES*.md`, `SECURITY.md`, `docs/SECURITY*.md` | Script | Only the **document-header** baseline lines (`> **Version**: vX.Y.Z`, security baseline, `当前 vX.Y.Z`). Deliberately first-match-only — "feature introduced in v0.4.246+" markers in the body must keep their original versions |
584
+ | `dist/` | Script | Built once before the test gate so `dist` matches the new version (the `version-drift` guard compares the build output); `prepublishOnly` builds again from scratch at publish time |
585
+
586
+ **Guard B only watches the first three** (`package.json` / `constants.ts` / `CLAUDE.md` current version) — it re-reads them from disk after the bump and asserts each one landed. Both historical incidents (`0.4.207`, `0.4.239`) were drift across exactly these three, and both happened by bypassing the script.
587
+
588
+ **If the change itself touches any of the following, sync it too** (guards will catch these, but knowing up front saves a round):
589
+
590
+ - Adding/removing a provider, built-in tool, or REPL command → the `docs-drift` guard requires the count markers and tables across all four docs to match
591
+ - Adding a provider → it must be added to the matrix in `tests/unit/providers/quirk-contracts.test.ts`
592
+ - Node minimum version, the `bin` name, or recovery-path wording → covered by the `version-drift` guard
571
593
 
572
594
  ## Documentation
573
595
 
@@ -577,10 +599,10 @@ node scripts/release.mjs patch -m "..." --dry-run
577
599
  - [`docs/MIGRATION.md`](docs/MIGRATION.md) — Migration guide from Claude Code, Codex, Claude Desktop, and Cursor
578
600
  - [`docs/RECIPES.md`](docs/RECIPES.md) — Practical recipes by scenario
579
601
  - [`docs/SECURITY.md`](docs/SECURITY.md) — **Security model, deployment checklist, audit history.** Read before exposing `aicli web` to a network.
580
- - [`CHANGELOG.md`](CHANGELOG.md) — Per-version change log
581
- - [`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SUPPORT.md`](SUPPORT.md) · [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — Community guides
582
- - [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) — Licenses for vendored browser assets
583
- - [`docs/OPEN_SOURCE_CHECKLIST.md`](docs/OPEN_SOURCE_CHECKLIST.md) — Repository-owner launch checklist
602
+ - [`CHANGELOG.md`](CHANGELOG.md) — Per-version change log
603
+ - [`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SUPPORT.md`](SUPPORT.md) · [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) — Community guides
604
+ - [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) — Licenses for vendored browser assets
605
+ - [`docs/OPEN_SOURCE_CHECKLIST.md`](docs/OPEN_SOURCE_CHECKLIST.md) — Repository-owner launch checklist
584
606
  - [Chinese README](README.zh-CN.md) — 中文说明文档
585
607
 
586
608
  ## License
package/README.zh-CN.md CHANGED
@@ -1,14 +1,14 @@
1
1
  [English](README.md) | **中文**
2
2
 
3
- # ai-cli
4
-
5
- <!-- AICLI:DOCS_DEFAULT_WEB_PORT=3000 -->
6
- <!-- AICLI:DOCS_BUILTIN_TOOL_COUNT=30 -->
7
- <!-- AICLI:DOCS_REPL_COMMAND_COUNT=48 -->
8
- <!-- AICLI:DOCS_BUILTIN_PROVIDER_COUNT=10 -->
9
- <!-- AICLI:DOCS_MEMORY_SOURCE=memory.jsonl -->
10
-
11
- > 跨平台 AI 编程助手 — CLI 终端、Web 界面、桌面应用三合一,支持 10 大 Provider(含本地 Ollama)与 Agentic 工具调用
3
+ # ai-cli
4
+
5
+ <!-- AICLI:DOCS_DEFAULT_WEB_PORT=3000 -->
6
+ <!-- AICLI:DOCS_BUILTIN_TOOL_COUNT=30 -->
7
+ <!-- AICLI:DOCS_REPL_COMMAND_COUNT=48 -->
8
+ <!-- AICLI:DOCS_BUILTIN_PROVIDER_COUNT=10 -->
9
+ <!-- AICLI:DOCS_MEMORY_SOURCE=memory.jsonl -->
10
+
11
+ > 跨平台 AI 编程助手 — CLI 终端、Web 界面、桌面应用三合一,支持 10 大 Provider(含本地 Ollama)与 Agentic 工具调用
12
12
 
13
13
  [![npm version](https://img.shields.io/npm/v/jinzd-ai-cli)](https://www.npmjs.com/package/jinzd-ai-cli)
14
14
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
@@ -119,14 +119,14 @@ aicli user delete x # 删除用户
119
119
  |----------|------|-------------|
120
120
  | **Claude** | Opus 4, Sonnet 4, Haiku 4 | [console.anthropic.com](https://console.anthropic.com) |
121
121
  | **Gemini** | 2.5 Pro, 2.5 Flash | [aistudio.google.com](https://aistudio.google.com) |
122
- | **DeepSeek** | deepseek-v4-flash(默认), deepseek-v4-pro | [platform.deepseek.com](https://platform.deepseek.com) |
122
+ | **DeepSeek** | deepseek-v4-flash(默认), deepseek-v4-pro | [platform.deepseek.com](https://platform.deepseek.com) |
123
123
  | **OpenAI** | GPT-5.4, GPT-5, GPT-4.1, o3, o4-mini | [platform.openai.com](https://platform.openai.com) |
124
124
  | **OpenRouter** | 300+ 模型(Claude/GPT/Gemini/Llama/Qwen/Mistral...) | [openrouter.ai](https://openrouter.ai) |
125
- | **Zhipu(智谱)** | GLM-4, GLM-5 | [open.bigmodel.cn](https://open.bigmodel.cn) |
125
+ | **Zhipu(智谱)** | GLM-4, GLM-5 | [open.bigmodel.cn](https://open.bigmodel.cn) |
126
126
  | **Kimi** | Kimi K2.6, K2.5, K2 Thinking | [platform.moonshot.cn](https://platform.moonshot.cn) |
127
- | **Qwen** | qwen-plus, qwen-max, qwen-turbo, qwen-coder-plus | [bailian.console.aliyun.com](https://bailian.console.aliyun.com) |
128
- | **MiniMax** | MiniMax-M3(默认)、M2.7、M2.5、M2.1、M2 | [platform.minimaxi.com](https://platform.minimaxi.com) |
129
- | **Ollama** | 任意本地模型(Llama、Qwen、Gemma、Mistral...) | 无需 API Key — [ollama.com](https://ollama.com) |
127
+ | **Qwen** | qwen-plus, qwen-max, qwen-turbo, qwen-coder-plus | [bailian.console.aliyun.com](https://bailian.console.aliyun.com) |
128
+ | **MiniMax** | MiniMax-M3(默认)、M2.7、M2.5、M2.1、M2 | [platform.minimaxi.com](https://platform.minimaxi.com) |
129
+ | **Ollama** | 任意本地模型(Llama、Qwen、Gemma、Mistral...) | 无需 API Key — [ollama.com](https://ollama.com) |
130
130
 
131
131
  也可通过 `customBaseUrls` 配置接入任意 OpenAI 兼容 API。
132
132
 
@@ -160,11 +160,11 @@ AI 在对话中可自主调用 30 个工具:
160
160
  | `edit_file` | 写入 | 精确字符串替换,模糊匹配提示 + `replaceAll` 全局替换模式 |
161
161
  | `list_dir` | 安全 | 列出目录内容 |
162
162
  | `grep_files` | 安全 | 正则搜索文件内容 |
163
- | `glob_files` | 安全 | 按 glob 模式匹配文件 |
164
- | `web_fetch` | 安全 | 抓取网页转 Markdown(防 SSRF) |
165
- | `web_search` | 安全 | 无需 Key 的 Bing/Google 网页搜索,弱结果自动降级 |
166
- | `google_search` | 安全 | Google 自定义搜索 |
167
- | `run_interactive` | 写入 | 运行交互式程序并输入;任意可执行程序均需确认 |
163
+ | `glob_files` | 安全 | 按 glob 模式匹配文件 |
164
+ | `web_fetch` | 安全 | 抓取网页转 Markdown(防 SSRF) |
165
+ | `web_search` | 安全 | 无需 Key 的 Bing/Google 网页搜索,弱结果自动降级 |
166
+ | `google_search` | 安全 | Google 自定义搜索 |
167
+ | `run_interactive` | 写入 | 运行交互式程序并输入;任意可执行程序均需确认 |
168
168
  | `run_tests` | 安全 | 自动检测并运行测试(JUnit XML 解析) |
169
169
  | `spawn_agent` | 安全 | 委派子任务给命名隔离 agent(`agent`: explorer/worker/reviewer/security/tester) |
170
170
  | `ask_user` | 安全 | 暂停并向用户提问 |
@@ -181,11 +181,11 @@ AI 在对话中可自主调用 30 个工具:
181
181
  | `notebook_edit` | 写入 | 编辑 Jupyter notebook 单元格(增/改/删/移动) |
182
182
  | `find_symbol` | 安全 | 按名称精确查找函数/类/方法定义(C1,tree-sitter 索引) |
183
183
  | `get_outline` | 安全 | 获取文件的符号大纲(类 → 方法树)(C1) |
184
- | `find_references` | 安全 | 查找符号的所有引用(C1) |
185
- | `search_code` | 安全 | 语义代码搜索(C2,自然语言查询,中英文均可) |
186
- | `recall_memory` | 安全 | 从历史聊天会话中语义召回相关片段 |
184
+ | `find_references` | 安全 | 查找符号的所有引用(C1) |
185
+ | `search_code` | 安全 | 语义代码搜索(C2,自然语言查询,中英文均可) |
186
+ | `recall_memory` | 安全 | 从历史聊天会话中语义召回相关片段 |
187
187
 
188
- **安全级别**:`安全` = 自动执行,`写入` = 需要确认(文件编辑工具还会显示 diff 预览),`破坏性` = 醒目警告 + 确认。
188
+ **安全级别**:`安全` = 自动执行,`写入` = 需要确认(文件编辑工具还会显示 diff 预览),`破坏性` = 醒目警告 + 确认。
189
189
 
190
190
  ### 文档深入阅读
191
191
 
@@ -423,9 +423,9 @@ Auto Mode 不会被项目配置静默开启。用 `/permissions recently-denied`
423
423
  | `AICLI_API_KEY_OPENROUTER` | OpenRouter API Key |
424
424
  | `AICLI_API_KEY_ZHIPU` | 智谱 API Key |
425
425
  | `AICLI_API_KEY_KIMI` | Kimi API Key |
426
- | `AICLI_API_KEY_QWEN` | Qwen / Alibaba Cloud API Key |
427
- | `AICLI_API_KEY_MINIMAX` | MiniMax API Key |
428
- | `AICLI_PROVIDER` | 默认 Provider |
426
+ | `AICLI_API_KEY_QWEN` | Qwen / Alibaba Cloud API Key |
427
+ | `AICLI_API_KEY_MINIMAX` | MiniMax API Key |
428
+ | `AICLI_PROVIDER` | 默认 Provider |
429
429
  | `AICLI_NO_STREAM` | 设为 `1` 禁用流式输出 |
430
430
  | `HTTPS_PROXY` / `HTTP_PROXY` | 代理地址 |
431
431
 
@@ -479,13 +479,13 @@ Web UI(`aicli web`)提供功能完备的浏览器界面:
479
479
  ## 测试
480
480
 
481
481
  ```bash
482
- npm test # 运行离线回归测试
482
+ npm test # 运行离线回归测试
483
483
  npm run test:watch # 监听模式
484
484
  ```
485
485
 
486
- 离线测试覆盖:认证、会话、工具类型与危险级别、权限、输出截断、diff 渲染、edit-file 相似度、错误层级、配置管理、环境变量、Provider 注册、web-fetch、grep-files、Hub、开发状态、Token 估算、工具注册表预算、并行工具执行、费用追踪和会话工具历史。
486
+ 离线测试覆盖:认证、会话、工具类型与危险级别、权限、输出截断、diff 渲染、edit-file 相似度、错误层级、配置管理、环境变量、Provider 注册、web-fetch、grep-files、Hub、开发状态、Token 估算、工具注册表预算、并行工具执行、费用追踪和会话工具历史。
487
487
 
488
- ## 发布(版本提升 → Git Tag → npm 可信发布)
488
+ ## 发布(版本提升 → Git Tag → npm 可信发布)
489
489
 
490
490
  > **给贡献者与 AI 模型:整个发布流程一律走 [`scripts/release.mjs`](scripts/release.mjs),切勿手动 bump 版本号或自己跑 `npm publish`。** 曾经手工 publish 的 `0.4.207` 装上后 `--version` 报错版本号,被迫补发 `0.4.208` 对齐——脚本的四道守卫就是为拦住这类事故而存在。
491
491
 
@@ -493,7 +493,7 @@ npm run test:watch # 监听模式
493
493
 
494
494
  - 当前在 `main` 分支,待发布的改动已在工作区。
495
495
  - `npx tsc --noEmit` 零错误、`npm test` 全绿(脚本会强制校验,失败自动回滚版本号)。
496
- - 已为 `jinzd-ai-cli` 和 `.github/workflows/release.yml` 配置 npm Trusted Publishing。
496
+ - 已为 `jinzd-ai-cli` 和 `.github/workflows/release.yml` 配置 npm Trusted Publishing。
497
497
  - 有 GitHub 远端推送权限。
498
498
 
499
499
  **第 1 步 —— 先写里程碑条目(Guard A)。** 在 [`CLAUDE.md`](CLAUDE.md) 的 `## 最近里程碑` 一节加一行,条目中必须含目标版本的**全角括号**标记 `(vX.Y.Z)`,否则脚本拒绝启动。(完整叙事写进 `CHANGELOG.md`,本节只留一行式索引。)
@@ -520,17 +520,39 @@ node scripts/release.mjs patch -m "..." --dry-run
520
520
  5. `npm test` 必须全绿(失败则回滚版本号)。
521
521
  6. 打印进入发布 commit 的完整文件清单,若含疑似敏感文件(`.env`、`*.pem`、`*.key`、`secret`…)直接拦下,确认无误加 `--allow-sensitive`。
522
522
  7. `git add -A` + commit `"<标题> (vX.Y.Z)"`(消息走 argv 传参,不经 shell 拼接)。
523
- 8. 创建带注释的 `vX.Y.Z` release tag。
524
- 9. 推送 `main` 和 tag;固定到完整 SHA 的 GitHub Actions 工作流会完成验证,并通过 OIDC 发布到 npm,无需长期 npm token。
525
-
526
- **可选 flag:** `--dry-run` · `--skip-tests` · `--no-tag` · `--no-push` · `--allow-sensitive`。旧的 `--no-publish` 仍作为 `--no-tag` 的兼容别名。
527
-
528
- ## 文档
529
-
530
- - [English README](README.md) — English documentation
531
- - [贡献指南](CONTRIBUTING.md) · [支持指南](SUPPORT.md) · [行为准则](CODE_OF_CONDUCT.md)
532
- - [第三方许可证声明](THIRD_PARTY_NOTICES.md)
533
- - [开源前检查清单](docs/OPEN_SOURCE_CHECKLIST.md)
523
+ 8. 创建带注释的 `vX.Y.Z` release tag。
524
+ 9. 推送 `main` 和 tag;固定到完整 SHA 的 GitHub Actions 工作流会完成验证,并通过 OIDC 发布到 npm,无需长期 npm token。
525
+
526
+ **可选 flag:** `--dry-run` · `--skip-tests` · `--no-tag` · `--no-push` · `--allow-sensitive`。旧的 `--no-publish` 仍作为 `--no-tag` 的兼容别名。
527
+
528
+ ### 一次发版到底改哪些文件
529
+
530
+ 分两类:**你手写的**(脚本不管,缺了 Guard A 直接拒绝启动)和**脚本自动改的**(不要手动动)。
531
+
532
+ | 文件 | 谁改 | 改什么 |
533
+ |---|---|---|
534
+ | `CHANGELOG.md` | **手写(发版前)** | 新增 `## [X.Y.Z] - YYYY-MM-DD` 段落,写完整叙事:根因 / 修法 / 测试。这是唯一的详细记录处 |
535
+ | `CLAUDE.md` → `## 最近里程碑` | **手写(发版前)** | 顶部加**一行**索引,必须含全角括号标记 `(vX.Y.Z)`——**Guard A 查的就是这一行** |
536
+ | `package.json` | 脚本 | `"version"` |
537
+ | `src/core/constants.ts` | 脚本 | `VERSION` 常量(`aicli --version` 与 help banner 读的是它,脱同步会发出"装了新版报旧版号"的包) |
538
+ | `CLAUDE.md` → `**当前版本**` | 脚本 | 版本号(与上面手写的里程碑行是两处,别混) |
539
+ | `docs/USAGE.md`、`docs/USAGE.zh-CN.md`、`docs/ADVANCED*.md`、`docs/TUTORIAL*.md`、`docs/RECIPES*.md`、`SECURITY.md`、`docs/SECURITY*.md` | 脚本 | 仅**文档头部**的版本基线行(`> **版本**:vX.Y.Z`、文档安全基线、`当前 vX.Y.Z`)。刻意只替换首个匹配——正文里 `v0.4.246+` 这类"功能引入版本"标记必须保持原值 |
540
+ | `dist/` | 脚本 | 测试前先 build 一次让 dist 与新版本对齐(`version-drift` 守卫拿构建产物比对),publish 时 `prepublishOnly` 再全新构建一次 |
541
+
542
+ **Guard B 只盯前三处**(`package.json` / `constants.ts` / `CLAUDE.md` 当前版本)——bump 后从磁盘重读逐一断言。历史上 `0.4.207` 和 `0.4.239` 两次事故都是这三处脱同步,且都因为绕开了脚本。
543
+
544
+ **改动本身若涉及以下内容,别忘了同步**(有守卫会红,但先想到更省一轮):
545
+
546
+ - 新增/删除 provider、内置工具、REPL 命令 → `docs-drift` 守卫要求四份文档的计数标记与表格同步
547
+ - 新增 provider → 必须加进 `tests/unit/providers/quirk-contracts.test.ts` 的矩阵
548
+ - Node 版本下限、`bin` 名称、恢复路径文案 → `version-drift` 守卫覆盖
549
+
550
+ ## 文档
551
+
552
+ - [English README](README.md) — English documentation
553
+ - [贡献指南](CONTRIBUTING.md) · [支持指南](SUPPORT.md) · [行为准则](CODE_OF_CONDUCT.md)
554
+ - [第三方许可证声明](THIRD_PARTY_NOTICES.md)
555
+ - [开源前检查清单](docs/OPEN_SOURCE_CHECKLIST.md)
534
556
 
535
557
  ## License
536
558
 
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-WM4VTGAF.js";
4
+ } from "./chunk-X6NWK2YK.js";
5
5
  import "./chunk-TU3L3PW7.js";
6
- import "./chunk-VKBGOFEO.js";
6
+ import "./chunk-Y7KJPNQI.js";
7
7
  import {
8
8
  atomicWriteFileSync
9
9
  } from "./chunk-IW3Q7AE5.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  HubAgent,
4
4
  isConverged
5
- } from "./chunk-3ARPAVNV.js";
5
+ } from "./chunk-VOIOUJXI.js";
6
6
 
7
7
  // src/hub/discuss.ts
8
8
  var DiscussionOrchestrator = class {
@@ -21,7 +21,11 @@ var DiscussionOrchestrator = class {
21
21
  onRoundReview;
22
22
  constructor(config, providers) {
23
23
  this.agents = config.roles.map(
24
- (role) => new HubAgent(role, providers, config.defaultProvider, config.defaultModel, config.context)
24
+ (role) => {
25
+ const agent = new HubAgent(role, providers, config.defaultProvider, config.defaultModel, config.context);
26
+ agent.thinking = config.thinking;
27
+ return agent;
28
+ }
25
29
  );
26
30
  this.humanSteer = config.humanSteer ?? false;
27
31
  this.voteConverge = config.voteConverge ?? false;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CONFIG_DIR_NAME,
4
4
  PLUGINS_DIR_NAME
5
- } from "./chunk-VKBGOFEO.js";
5
+ } from "./chunk-Y7KJPNQI.js";
6
6
  import {
7
7
  atomicWriteFileSync
8
8
  } from "./chunk-IW3Q7AE5.js";
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/repl/theme.ts
4
+ import chalk from "chalk";
5
+ var DARK_THEME = {
6
+ prompt: chalk.green,
7
+ info: chalk.cyan,
8
+ warning: chalk.yellow,
9
+ error: chalk.red,
10
+ success: chalk.green,
11
+ dim: chalk.dim,
12
+ accent: chalk.cyan,
13
+ toolCall: chalk.yellow,
14
+ toolResult: chalk.green,
15
+ heading: chalk.bold.cyan
16
+ };
17
+ var LIGHT_THEME = {
18
+ prompt: chalk.blue,
19
+ info: chalk.blueBright,
20
+ warning: chalk.yellow,
21
+ error: chalk.red,
22
+ success: chalk.green,
23
+ dim: chalk.gray,
24
+ accent: chalk.blueBright,
25
+ toolCall: chalk.magenta,
26
+ toolResult: chalk.green,
27
+ heading: chalk.bold.blue
28
+ };
29
+ function resolveColor(name) {
30
+ if (name.startsWith("#")) return chalk.hex(name);
31
+ const parts = name.split(".");
32
+ let result = chalk;
33
+ for (const part of parts) {
34
+ const obj = result;
35
+ if (obj && typeof obj[part] !== "undefined") {
36
+ result = obj[part];
37
+ }
38
+ }
39
+ if (typeof result !== "function") {
40
+ process.stderr.write(`[theme] Warning: unrecognized color "${name}", using default.
41
+ `);
42
+ return chalk;
43
+ }
44
+ return result;
45
+ }
46
+ function buildCustomTheme(base, overrides) {
47
+ if (!overrides) return base;
48
+ const result = { ...base };
49
+ for (const [key, colorName] of Object.entries(overrides)) {
50
+ if (key in result && colorName) {
51
+ result[key] = resolveColor(colorName);
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+ var _currentTheme = DARK_THEME;
57
+ function initTheme(themeId = "dark", customColors) {
58
+ switch (themeId) {
59
+ case "light":
60
+ _currentTheme = LIGHT_THEME;
61
+ break;
62
+ case "custom":
63
+ _currentTheme = buildCustomTheme(DARK_THEME, customColors);
64
+ break;
65
+ default:
66
+ _currentTheme = DARK_THEME;
67
+ }
68
+ }
69
+ var theme = new Proxy(DARK_THEME, {
70
+ get(_target, prop) {
71
+ return _currentTheme[prop];
72
+ }
73
+ });
74
+
75
+ export {
76
+ initTheme,
77
+ theme
78
+ };
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/core/chat-params.ts
4
+ function chatParamsFrom(params) {
5
+ return {
6
+ temperature: params.temperature,
7
+ maxTokens: params.maxTokens,
8
+ timeout: params.timeout,
9
+ thinking: params.thinking,
10
+ thinkingEffort: params.thinkingEffort,
11
+ thinkingBudget: params.thinkingBudget
12
+ };
13
+ }
14
+ function thinkingParamsFor(allModelParams, model) {
15
+ const params = allModelParams?.[model];
16
+ if (!params) return {};
17
+ const out = {};
18
+ if (params.thinking !== void 0) out.thinking = params.thinking;
19
+ if (params.thinkingEffort !== void 0) out.thinkingEffort = params.thinkingEffort;
20
+ if (params.thinkingBudget !== void 0) out.thinkingBudget = params.thinkingBudget;
21
+ return out;
22
+ }
23
+ function applyThinkingFlag(fromConfig, flag) {
24
+ if (flag === void 0) return fromConfig;
25
+ const mode = flag.toLowerCase();
26
+ if (mode === "off") return { ...fromConfig, thinking: false };
27
+ if (mode === "on") return { ...fromConfig, thinking: true };
28
+ if (mode === "low" || mode === "high" || mode === "max") {
29
+ return { ...fromConfig, thinking: true, thinkingEffort: mode };
30
+ }
31
+ throw new Error(`Invalid --think value "${flag}" (expected: off | on | low | high | max)`);
32
+ }
33
+ var NO_THINKING = { thinking: false };
34
+
35
+ export {
36
+ chatParamsFrom,
37
+ thinkingParamsFor,
38
+ applyThinkingFlag,
39
+ NO_THINKING
40
+ };
@@ -30,6 +30,16 @@ var BaseProvider = class {
30
30
  get supportsContentOnlyTee() {
31
31
  return this.reliableContentOnlyTee;
32
32
  }
33
+ /**
34
+ * 该 provider 是否支持 `reasoning_effort` 档位(low/high/max)。目前只有 DeepSeek V4。
35
+ *
36
+ * 2026-08-14 审计 P2-03:提示符标签此前无条件渲染成 `[THINK:high]`,于是 Claude
37
+ * (用 thinkingBudget 计 token 预算)和 GLM(根本没有 effort 概念)也显示一个
38
+ * 既不生效、也无从设置的档位——屏幕上的假信息比没有信息更坏。
39
+ */
40
+ get supportsReasoningEffort() {
41
+ return false;
42
+ }
33
43
  /**
34
44
  * 将 Message[] 转换为 OpenAI API 格式的消息数组。
35
45
  * content 为 string 时直接传递;为 MessageContentPart[] 时保留数组格式(vision 请求)。
@@ -1113,10 +1123,12 @@ var OpenAICompatibleProvider = class extends BaseProvider {
1113
1123
  if (!firstChoice) {
1114
1124
  return { content: "", model: response.model, usage: void 0 };
1115
1125
  }
1126
+ const reasoningContent = firstChoice.message.reasoning_content;
1116
1127
  return {
1117
1128
  content: firstChoice.message.content ?? "",
1118
1129
  model: response.model,
1119
- usage: toUsage(response.usage)
1130
+ usage: toUsage(response.usage),
1131
+ ...reasoningContent ? { reasoningContent } : {}
1120
1132
  };
1121
1133
  } catch (err) {
1122
1134
  throw this.wrapError(err);
@@ -1513,6 +1525,10 @@ var DeepSeekProvider = class extends OpenAICompatibleProvider {
1513
1525
  ...thinkingEnabled ? { reasoning_effort: request.thinkingEffort ?? "high" } : {}
1514
1526
  };
1515
1527
  }
1528
+ /** V4 支持 low/high/max 三档 reasoning_effort(官方 2026-08 更新公告)。 */
1529
+ get supportsReasoningEffort() {
1530
+ return true;
1531
+ }
1516
1532
  /** 禁用流式工具调用,确保 chatWithTools 覆写(代码块检测)生效 */
1517
1533
  enableStreamingToolCalls = false;
1518
1534
  /**
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-GKI7B4BD.js";
4
+ } from "./chunk-TJBG4F2R.js";
5
5
  import {
6
6
  APP_NAME,
7
7
  CONFIG_DIR_NAME,
@@ -11,7 +11,7 @@ import {
11
11
  MCP_PROTOCOL_VERSION,
12
12
  MCP_TOOL_PREFIX,
13
13
  VERSION
14
- } from "./chunk-VKBGOFEO.js";
14
+ } from "./chunk-Y7KJPNQI.js";
15
15
  import {
16
16
  atomicWriteFileSync
17
17
  } from "./chunk-IW3Q7AE5.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ProviderRegistry
4
- } from "./chunk-TL5MD5XU.js";
4
+ } from "./chunk-AUEX6RNY.js";
5
5
  import {
6
6
  ConfigManager
7
- } from "./chunk-WM4VTGAF.js";
7
+ } from "./chunk-X6NWK2YK.js";
8
8
  import {
9
9
  getActivePluginAssets,
10
10
  getPendingHookTrust,
@@ -14,7 +14,7 @@ import {
14
14
  listHooks,
15
15
  listInstalledPlugins,
16
16
  resetStats
17
- } from "./chunk-QMB7QYZC.js";
17
+ } from "./chunk-2MR7EP24.js";
18
18
  import {
19
19
  getGitRoot
20
20
  } from "./chunk-HOSJZMQS.js";
@@ -26,7 +26,7 @@ import {
26
26
  MCP_PROJECT_CONFIG_NAME,
27
27
  MEMORY_FILE_NAME,
28
28
  VERSION
29
- } from "./chunk-VKBGOFEO.js";
29
+ } from "./chunk-Y7KJPNQI.js";
30
30
 
31
31
  // src/diagnostics/doctor-report.ts
32
32
  import { existsSync as existsSync3, statSync as statSync2 } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-VKBGOFEO.js";
4
+ } from "./chunk-Y7KJPNQI.js";
5
5
 
6
6
  // src/cli/ci-format.ts
7
7
  var DEFAULT_CI_THRESHOLDS = {
@@ -6,7 +6,7 @@ import {
6
6
  MEMORY_FILE_NAME,
7
7
  MEMORY_MAX_CHARS,
8
8
  MEMORY_STORE_FILE_NAME
9
- } from "./chunk-VKBGOFEO.js";
9
+ } from "./chunk-Y7KJPNQI.js";
10
10
  import {
11
11
  DEFAULT_PATTERNS,
12
12
  redactString
@@ -1,5 +1,5 @@
1
1
  // src/core/constants.ts
2
- var VERSION = "0.4.263";
2
+ var VERSION = "0.4.265";
3
3
  var APP_NAME = "ai-cli";
4
4
  var CONFIG_DIR_NAME = ".aicli";
5
5
  var CONFIG_FILE_NAME = "config.json";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TEST_TIMEOUT
3
- } from "./chunk-3RHY2HF7.js";
3
+ } from "./chunk-M2RKBTVZ.js";
4
4
 
5
5
  // src/tools/builtin/run-tests.ts
6
6
  import { execSync, spawnSync } from "child_process";