jinzd-ai-cli 0.4.273 → 0.4.276

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 (103) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +610 -610
  3. package/README.zh-CN.md +559 -559
  4. package/dist/agent-client-6GX6QQDU.js +0 -0
  5. package/dist/auth-PE3Z5OHS.js +0 -0
  6. package/dist/{batch-LOW3GM26.js → batch-F7SKIBI3.js} +2 -2
  7. package/dist/chat-index-2D5GK2DB.js +0 -0
  8. package/dist/chunk-23SJVOQD.js +0 -0
  9. package/dist/chunk-3FEZSLGI.js +0 -0
  10. package/dist/chunk-4BKXL7SM.js +0 -0
  11. package/dist/{chunk-AUEX6RNY.js → chunk-4KTK2OYU.js} +54 -21
  12. package/dist/{chunk-M3NXF4GD.js → chunk-4NH4Q7QK.js} +1 -1
  13. package/dist/chunk-5C76XDDF.js +0 -0
  14. package/dist/chunk-6YZEZFX5.js +0 -0
  15. package/dist/{chunk-FHXLAJJG.js → chunk-AOISQVXS.js} +1 -1
  16. package/dist/{chunk-FNLWPYP5.js → chunk-ATD2Y3PB.js} +1 -1
  17. package/dist/chunk-BXP6YZ2P.js +0 -0
  18. package/dist/chunk-CGDYO52A.js +0 -0
  19. package/dist/chunk-CKH4KQ4E.js +0 -0
  20. package/dist/{chunk-JT6UN5C6.js → chunk-DPTEC6AQ.js} +3 -0
  21. package/dist/{chunk-EDAUDILT.js → chunk-FLDYAXJR.js} +1 -1
  22. package/dist/chunk-GHWZVPUV.js +0 -0
  23. package/dist/chunk-GLSR2NR3.js +0 -0
  24. package/dist/chunk-HLWUDRBO.js +0 -0
  25. package/dist/chunk-HOSJZMQS.js +0 -0
  26. package/dist/chunk-IW3Q7AE5.js +0 -0
  27. package/dist/chunk-KHYD3WXE.js +0 -0
  28. package/dist/{chunk-Z3UXZ5EI.js → chunk-KWSGSSWN.js} +1 -1
  29. package/dist/{chunk-4FIDMC2K.js → chunk-MCKUGWOY.js} +69 -4
  30. package/dist/chunk-MX75TNE5.js +0 -0
  31. package/dist/{chunk-FN7DE4HA.js → chunk-MXPUOF5K.js} +4 -4
  32. package/dist/chunk-NR5U6LVG.js +0 -0
  33. package/dist/{chunk-ZWCQQZT5.js → chunk-NXAHXWPF.js} +1 -1
  34. package/dist/{chunk-R4YGDJPL.js → chunk-NXNXWM6H.js} +5 -5
  35. package/dist/chunk-NYNSYLFY.js +0 -0
  36. package/dist/{chunk-WSCZRQDR.js → chunk-OMBKLWLJ.js} +1 -1
  37. package/dist/chunk-RYQBBEMM.js +0 -0
  38. package/dist/{chunk-3OBY7WSS.js → chunk-TEXT4DAT.js} +7 -1
  39. package/dist/chunk-TU3L3PW7.js +0 -0
  40. package/dist/{chunk-LEK5WGKV.js → chunk-UNL7NR55.js} +1 -1
  41. package/dist/chunk-UUSRWSSX.js +0 -0
  42. package/dist/{chunk-T65VFCID.js → chunk-VF7DMSKF.js} +1 -1
  43. package/dist/chunk-VOIOUJXI.js +0 -0
  44. package/dist/{chunk-MTQBSOZW.js → chunk-WYDP2WEQ.js} +4 -4
  45. package/dist/chunk-XNFIYS7G.js +0 -0
  46. package/dist/{ci-C5YMQXCS.js → ci-VURFRMWQ.js} +6 -6
  47. package/dist/{ci-format-R6EMNOGZ.js → ci-format-AFJJIURF.js} +2 -2
  48. package/dist/config-command-E5DHADEV.js +0 -0
  49. package/dist/{constants-QJCNMBPJ.js → constants-WO7ERENL.js} +1 -1
  50. package/dist/{doctor-cli-5CM2I6OF.js → doctor-cli-BGGILTHE.js} +6 -6
  51. package/dist/electron-server.js +167 -57
  52. package/dist/file-checkpoint-NKBHGC7L.js +0 -0
  53. package/dist/git-context-EXOEHQSF.js +0 -0
  54. package/dist/{hub-7JBSZOSD.js → hub-Z73RLNJI.js} +1 -1
  55. package/dist/hub-server-RF6LURXY.js +0 -0
  56. package/dist/index.js +57 -43
  57. package/dist/indexer-VZETNE4H.js +0 -0
  58. package/dist/persist-PQM4BRI4.js +0 -0
  59. package/dist/{persistent-memory-4E53HW3U.js → persistent-memory-5QMARQJF.js} +2 -2
  60. package/dist/{persistent-memory-KYRY56PG.js → persistent-memory-CI544RLT.js} +2 -2
  61. package/dist/{pr-NPUGZSXB.js → pr-24REDMGV.js} +6 -6
  62. package/dist/project-trust-NKYHL3VZ.js +0 -0
  63. package/dist/{run-tests-5FHQ5IBX.js → run-tests-72VNZXNT.js} +2 -2
  64. package/dist/{run-tests-SU5CDQKF.js → run-tests-JJ3KOY5E.js} +2 -2
  65. package/dist/semantic-HLAE2O4F.js +0 -0
  66. package/dist/{server-ER36M7TR.js → server-JMXC2N3F.js} +40 -29
  67. package/dist/{server-77YS5NNN.js → server-QJHCJDA7.js} +6 -6
  68. package/dist/setup-wizard-S55ICNHH.js +0 -0
  69. package/dist/store-MWNHVGJT.js +0 -0
  70. package/dist/{task-orchestrator-56PQ7LGV.js → task-orchestrator-DJN36HP5.js} +6 -6
  71. package/dist/{usage-3YATXRFZ.js → usage-HXJVDETY.js} +3 -3
  72. package/dist/vector-store-BBDXB5IQ.js +0 -0
  73. package/dist/wasm/web-tree-sitter.wasm +0 -0
  74. package/dist/web/client/actions.js +104 -104
  75. package/dist/web/client/actions.js.br +0 -0
  76. package/dist/web/client/actions.js.gz +0 -0
  77. package/dist/web/client/api.js.gz +0 -0
  78. package/dist/web/client/app.js.gz +0 -0
  79. package/dist/web/client/dom.js.gz +0 -0
  80. package/dist/web/client/icon.svg +22 -22
  81. package/dist/web/client/icon.svg.br +0 -0
  82. package/dist/web/client/icon.svg.gz +0 -0
  83. package/dist/web/client/index.html +388 -388
  84. package/dist/web/client/index.html.br +0 -0
  85. package/dist/web/client/index.html.gz +0 -0
  86. package/dist/web/client/manifest.json +15 -15
  87. package/dist/web/client/sidebar-tabs.js.gz +0 -0
  88. package/dist/web/client/state.js.gz +0 -0
  89. package/dist/web/client/style.css +991 -991
  90. package/dist/web/client/style.css.br +0 -0
  91. package/dist/web/client/style.css.gz +0 -0
  92. package/dist/web/client/sw.js +85 -85
  93. package/dist/web/client/sw.js.br +0 -0
  94. package/dist/web/client/sw.js.gz +0 -0
  95. package/dist/web/client/templates.js.gz +0 -0
  96. package/dist/web/client/util.js.gz +0 -0
  97. package/dist/web/client/vendor/daisyui-full.min.css.gz +0 -0
  98. package/dist/web/client/vendor/github-dark.min.css.gz +0 -0
  99. package/dist/web/client/vendor/github.min.css.gz +0 -0
  100. package/dist/web/client/vendor/highlight.min.js.gz +0 -0
  101. package/dist/web/client/vendor/marked.min.js.gz +0 -0
  102. package/dist/web/client/vendor/tailwind.js.gz +0 -0
  103. package/package.json +178 -178
package/README.md CHANGED
@@ -1,610 +1,610 @@
1
- **English** | [中文](README.zh-CN.md)
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
12
-
13
- [![npm version](https://img.shields.io/npm/v/jinzd-ai-cli)](https://www.npmjs.com/package/jinzd-ai-cli)
14
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
15
- [![Node.js](https://img.shields.io/badge/node-%3E%3D20.18.1-brightgreen)](https://nodejs.org)
16
- [![GitHub Release](https://img.shields.io/github/v/release/jinzhengdong/ai-cli)](https://github.com/jinzhengdong/ai-cli/releases)
17
- [![CI](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml)
18
-
19
- **ai-cli** is a powerful AI assistant that connects to 10 providers (including local Ollama models) and executes tasks autonomously through agentic tool calling. Use it as a terminal REPL, a browser-based Web UI, or a standalone Electron desktop app.
20
-
21
- <p align="center">
22
- <img src="https://img.shields.io/badge/CLI-Terminal-blue" alt="CLI" />
23
- <img src="https://img.shields.io/badge/Web_UI-Browser-green" alt="Web UI" />
24
- <img src="https://img.shields.io/badge/Desktop-Electron-purple" alt="Desktop" />
25
- </p>
26
-
27
- ## Highlights
28
-
29
- - **10 Built-in Providers** — Claude, Gemini, DeepSeek, OpenAI, Zhipu GLM, Kimi, Qwen, **MiniMax (海螺)**, OpenRouter (300+ models), **Ollama** (local models, no API key needed)
30
- - **3 Interfaces** — Terminal CLI, browser Web UI (`aicli web`), Electron desktop app
31
- - **Agentic Tool Calling** — AI autonomously runs shell commands, reads/writes files, searches code, fetches web, runs tests (default 200 rounds, configurable up to 10000 via `config.maxToolRounds` or `--max-tool-rounds`)
32
- - **Prompt Caching** *(v0.4.70+)* — System prompt split into stable/volatile halves so Claude caches the stable part with `cache_control: ephemeral`; cached tokens bill at ~10% of the input price
33
- - **Unified-Diff Patch Edits** *(v0.4.72+)* — `edit_file` accepts standard `@@ -a,b +c,d @@` hunks for the most compact way to apply many scattered small changes to a large file (±200-line drift tolerance + whitespace fallback)
34
- - **Anthropic Batches API** *(v0.4.73+)* — `aicli batch submit/list/status/results/cancel` for 50%-off, 24-hour async processing — ideal for offline analysis and bulk evals
35
- - **Web UI Session Replay** *(v0.4.71+)* — 🎬 button on every saved session opens a timeline replay: every message, tool call, reasoning, and cache-aware token usage at a glance
36
- - **Conversation Branching** *(v0.4.74+)* — `/branch list/new/switch/delete/rename` inside the REPL, plus a 🌿 "fork here" button on every replay step — explore alternate directions without losing the original thread
37
- - **Symbol Index** *(v0.4.76+, multi-language since v0.4.143)* — persistent tree-sitter index for TypeScript / JavaScript / TSX / Python / Go / Rust / Java / C/C++ powers three new AI tools: `find_symbol`, `get_outline`, `find_references`. Orders of magnitude faster than grep for definition lookups; background refresh on REPL startup, `/index status|rebuild|clear` to manage
38
- - **Semantic Code Search** *(v0.4.77+)* — `search_code` tool finds code by meaning, not name. Local sentence embeddings (multilingual MiniLM, 117 MB one-time download) score symbols by cosine similarity against natural-language queries in English or Chinese ("where are users authenticated", "哪里做了速率限制"). No API key, runs on CPU. Manage with `/index semantic-rebuild|semantic-clear`
39
- - **MCP Server Mode** *(v0.4.84+)* — `aicli mcp-serve` reverses ai-cli into an MCP server (JSON-RPC 2.0 over stdio), exposing its 30 built-in tools (incl. `find_symbol` / `search_code` / `run_tests`) to Claude Desktop / Cursor / any MCP client. Opt-in destructive-tool allow, `--tools` whitelist, `--cwd` override
40
- - **Session Sensitive-Data Redaction** *(v0.4.88+)* — unified redactor scrubs `password=` / `api_key` / bearer tokens / OpenAI-style keys from every message **before it hits disk**. Query text is redacted too, so secrets never reach embeddings or logs. `/security status` + `/security scan` to audit
41
- - **Human-like Long-Term Memory** *(v0.4.89+, B4)* — semantic index over every past chat session + `recall_memory` AI tool + `/memory rebuild|refresh|status|recall` commands. AI is prompted to auto-recall when it sees "last time" / "之前" / ambiguous references. Reuses the same MiniLM embedder as semantic code search
42
- - **Governed Persistent Memory** *(v0.4.217+)* — `save_memory` and `/memory add` write auditable `memory.jsonl` entries with id/scope/source/sensitivity/approval/expiry; AI-written entries (`save_memory`) always stay pending until `/memory approve <id>` (v0.4.242+), low-risk manual entries auto-approve, project-scoped memories only inject inside the same project, and `/memory clear` confirms + keeps a timestamped backup
43
- - **Package Plugin Ecosystem** *(v0.4.218+)* — install shareable .aicli-plugin/plugin.json packages with skills, hooks, commands, MCP servers, agents, and permission hints; only trusted+enabled plugins load, hooks still require hook trust, and MCP/tools remain under permission profiles/network policy
44
- - **Web UI Memory Panel** *(v0.4.90+, B4)* — new 🧠 Memory sidebar tab with semantic search across past chats; each hit has **➕ Inject** (quotes the snippet into the chat input as a markdown blockquote so you can review/edit before sending — no silent context injection) and **↗ Load** (jumps to source session). Bulk "Inject top 3" for recall bundles
45
- - **Streaming Tool Use** — Real-time streaming of AI reasoning and tool calls as they happen
46
- - **Sub-Agents** — Delegate complex subtasks to isolated child agents with independent tool loops
47
- - **Extended Thinking** — Claude deep reasoning mode with `/think` toggle
48
- - **Plan Mode** — Read-only planning phase (`/plan`) where AI analyzes before executing, with loop detection
49
- - **Auto-Pause** — Automatically pauses every 10 rounds for user review and redirection
50
- - **MCP Protocol** — Connect external MCP servers for dynamic tool discovery
51
- - **Multi-User Auth** — Web UI supports multiple users with password authentication
52
- - **PWA Support** — Install Web UI as a desktop/mobile app, accessible over LAN
53
- - **Hierarchical Context** — 3-layer context files (global / project / subdirectory) auto-injected; supports native AICLI.md, Claude-compatible CLAUDE.md, and Codex-compatible AGENTS.md with override files
54
- - **Headless Mode** — `ai-cli -p "prompt"` for CI/CD pipelines and scripting
55
- - **48 REPL Commands** — Session management, checkpointing, code review, security review/scan, rewind, scaffolding, cross-session history search, chat-memory recall, smart model routing (`/route`), and more
56
- - **GitHub Actions CI/CD** — Automated testing on Node 20/22 + npm publish on release tags
57
- - **PR Review CLI** *(v0.4.216+)* — `aicli pr review|security-review|summarize` reviews `main...HEAD`, custom `--base/--head`, or GitHub PR URLs; optional `--agents security,bugs,tests,maintainability`; never posts comments unless `--post` is explicit
58
- - **CI Review Artifacts** *(v0.4.216+)* — `aicli ci` emits Markdown, JSON, or SARIF and gates on security-high, test-failure, and lint-failure findings in read-only review mode
59
- - **Cross-Platform** — Windows, macOS, Linux
60
-
61
- ## Installation
62
-
63
- ### npm (recommended)
64
-
65
- ```bash
66
- npm install -g jinzd-ai-cli
67
- ```
68
-
69
- Requires Node.js >= 20.18.1. After installation, use `aicli` to start.
70
-
71
- ### Electron Desktop App (Windows)
72
-
73
- Download the installer from [GitHub Releases](https://github.com/jinzhengdong/ai-cli/releases) — no Node.js required:
74
-
75
- | Platform | Download |
76
- |----------|----------|
77
- | Windows x64 | [`ai-cli-setup.exe`](https://github.com/jinzhengdong/ai-cli/releases/latest) |
78
-
79
- ### Standalone CLI Executables
80
-
81
- Pre-built CLI binaries (no Node.js required, ~56 MB):
82
-
83
- | Platform | File |
84
- |----------|------|
85
- | Windows x64 | `ai-cli-win.exe` |
86
- | macOS arm64 | `ai-cli-mac` |
87
- | macOS x64 | `ai-cli-mac-x64` |
88
- | Linux x64 | `ai-cli-linux` |
89
-
90
- ## Quick Start
91
-
92
- ### Terminal CLI
93
-
94
- ```bash
95
- aicli
96
- ```
97
-
98
- On first run, an interactive setup wizard guides you through setting up your profile and entering your API key. Your identity is persisted and injected into every AI conversation.
99
-
100
- ```
101
- [deepseek] > Hello! Tell me about this project
102
- [deepseek] > @src/main.ts Review this file for bugs
103
- [deepseek] > @screenshot.png What's in this image?
104
- [deepseek] > /help
105
- ```
106
-
107
- Use `@filepath` to reference files or images directly in your prompt.
108
-
109
- ### Web UI
110
-
111
- ```bash
112
- aicli web # Start on localhost:3000
113
- aicli web --port 8080 # Custom port
114
- aicli web --host 0.0.0.0 # LAN access (shows QR-friendly URL)
115
- ```
116
-
117
- Features: multi-tab sessions, file tree panel, drag & drop images, prompt templates, 8 DaisyUI themes, PWA installable, keyboard shortcuts, diff syntax highlighting.
118
-
119
- ### User Management
120
-
121
- ```bash
122
- aicli user create admin # Create user (enables auth)
123
- aicli user list # List all users
124
- aicli user reset-password x # Reset password
125
- aicli user delete x # Delete user
126
- ```
127
-
128
- ## Supported Providers
129
-
130
- | Provider | Models | Get API Key |
131
- |----------|--------|-------------|
132
- | **Claude** | Opus 4, Sonnet 4, Haiku 4 | [console.anthropic.com](https://console.anthropic.com) |
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) |
135
- | **OpenAI** | GPT-5.4, GPT-5, GPT-4.1, o3, o4-mini | [platform.openai.com](https://platform.openai.com) |
136
- | **OpenRouter** | 300+ models (Claude, GPT, Gemini, Llama, Qwen, Mistral...) | [openrouter.ai](https://openrouter.ai) |
137
- | **Zhipu** | GLM-4, GLM-5 | [open.bigmodel.cn](https://open.bigmodel.cn) |
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) |
142
-
143
- Any OpenAI-compatible API can also be used via `customBaseUrls` in config.
144
-
145
- ### Ollama (Local Models)
146
-
147
- Run AI models entirely on your own hardware — no API key, no usage fees, no data leaving your machine.
148
-
149
- ```bash
150
- # Install Ollama from https://ollama.com, then pull a model:
151
- ollama pull qwen3:4b # recommended: good tool-calling support
152
- ollama pull gemma3:4b
153
- ollama pull llama3.1:8b
154
-
155
- # Start aicli and switch to Ollama:
156
- aicli
157
- [deepseek] > /provider ollama # auto-discovers installed models
158
- [ollama] > /model # select from your local models
159
- ```
160
-
161
- > **Note**: Use models 4B+ for best results with tool calling. Small models (<4B) may struggle with the tool definitions injected by MCP servers.
162
-
163
- ## Built-in Tools (Agentic)
164
-
165
- AI autonomously invokes these 30 tools during conversations:
166
-
167
- | Tool | Safety | Description |
168
- |------|--------|-------------|
169
- | `bash` | varies | Execute shell commands (PowerShell on Windows, $SHELL on Unix) |
170
- | `read_file` | safe | Read file contents (10 MB limit, image support) |
171
- | `write_file` | write | Create/overwrite files (diff preview + confirmation) |
172
- | `edit_file` | write | Precise string replacement with fuzzy matching hints + `replaceAll` mode |
173
- | `list_dir` | safe | List directory contents |
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 |
180
- | `run_tests` | safe | Auto-detect and run project tests (JUnit XML parsing) |
181
- | `spawn_agent` | safe | Delegate subtasks to named isolated agents (`agent`: explorer/worker/reviewer/security/tester) |
182
- | `ask_user` | safe | Pause and ask the user a question |
183
- | `save_memory` | safe | Persist governed memory across sessions; AI-written entries stay pending until `/memory approve <id>` |
184
- | `write_todos` | safe | Task breakdown with live progress rendering |
185
- | `save_last_response` | write | Save AI response to file |
186
- | `task_create` | write | Start a command running in the background |
187
- | `task_list` | safe | List background tasks and their status/output |
188
- | `task_stop` | write | Stop a running background task |
189
- | `git_status` | safe | Show working tree status (branch, staged, modified, untracked) |
190
- | `git_diff` | safe | Show file diffs (staged/unstaged, stat summary) |
191
- | `git_log` | safe | Show commit history (oneline/full, filter by file/author) |
192
- | `git_commit` | write | Create a git commit (stage files, message) |
193
- | `notebook_edit` | write | Edit Jupyter notebook cells (add/edit/delete/move) |
194
- | `find_symbol` | safe | Locate symbol definitions via persistent tree-sitter index (TS/JS/TSX/Python/Go/Rust/Java/C++) |
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 |
199
-
200
- **Safety levels**: `safe` = auto-execute, `write` = confirmation required (file-editing tools also show a diff preview), `destructive` = prominent warning + confirmation.
201
-
202
- ## Key REPL Commands
203
-
204
- | Command | Description |
205
- |---------|-------------|
206
- | `/provider` | Switch AI provider |
207
- | `/model` | Switch model; `/model refresh [provider]` refreshes live model cache |
208
- | `/plan` | Enter read-only planning mode |
209
- | `/think` | Toggle Claude extended thinking |
210
- | `/test` | Auto-detect and run project tests |
211
- | `/review` | AI code review of current git diff |
212
- | `/security-review` | Security vulnerability scan on git diff |
213
- | `/rewind` | Rewind conversation + restore files to checkpoint state |
214
- | `/scaffold <desc>` | AI generates project skeleton |
215
- | `/init` | AI generates project context file (AICLI.md) |
216
- | `/compact` | Compress conversation history |
217
- | `/session` | Session management (new / list / load) |
218
- | `/checkpoint` | Save/restore conversation checkpoints |
219
- | `/fork` | Fork the current session into a new session file |
220
- | `/branch` | Create/switch/delete branches *within* the current session (B2) |
221
- | `/index` | Manage symbol + semantic index (status/rebuild/clear/semantic-rebuild/semantic-clear) — powers `find_symbol` / `get_outline` / `find_references` / `search_code` (C1+C2) |
222
- | `/search <keyword>` | Full-text search across all sessions |
223
- | `/skill` | Manage agent skill packs |
224
- | `/mcp` | View MCP server status and tools |
225
- | `/cost` | Show token usage statistics |
226
- | `/undo` | Undo last file operation |
227
- | `/doctor` | Health check (API keys, MCP, context) |
228
- | `/export` | Export session as Markdown or JSON |
229
- | `/profile` | View/edit your identity (AI knows who you are across all providers) |
230
- | `/config` | Open configuration wizard |
231
- | /help | Show all available commands |
232
- | /plugin | Install, trust, enable, disable, and inspect package plugins |
233
-
234
- **Multi-line input**: Use `\` at end of line for continuation, or paste multi-line content directly (auto-detected and merged).
235
-
236
- Type `/help` in the REPL to see all 48 commands.
237
-
238
- ## CLI Parameters
239
-
240
- ```bash
241
- aicli [options]
242
-
243
- Options:
244
- --provider <name> Set AI provider
245
- -m, --model <name> Set model
246
- -p, --prompt <text> Headless mode: single prompt, then exit
247
- --system <prompt> Override system prompt (headless)
248
- --json Output JSON response (headless)
249
- --output-format <fmt> text | streaming-json (NDJSON)
250
- --resume <id> Resume a previous session
251
- --allowed-tools <list> Comma-separated tool whitelist
252
- --blocked-tools <list> Comma-separated tool blacklist
253
- --no-stream Disable streaming output
254
-
255
- Subcommands:
256
- aicli web [options] Start Web UI server
257
- aicli config Run configuration wizard
258
- aicli providers List all providers and status
259
- aicli sessions List recent sessions
260
- aicli user <action> Manage Web UI users
261
- aicli batch <action> Anthropic Batches API (submit | list | status | results | cancel)
262
- ```
263
-
264
- ### Batch Mode (Anthropic Message Batches)
265
-
266
- For offline analysis, bulk evals, or any workload where latency is flexible, use the Batches API for **50% off** tokens with a 24-hour processing window.
267
-
268
- ```bash
269
- # 1. Prepare a JSONL file (one request per line):
270
- # {"customId":"req-1","messages":[{"role":"user","content":"..."}],"maxTokens":1024}
271
- aicli batch submit prompts.jsonl # validate + submit + track locally
272
- aicli batch submit --dry-run prompts.jsonl # parse only, no network
273
-
274
- aicli batch list # live status of recent batches
275
- aicli batch status <id> # detailed status + request counts
276
- aicli batch results <id> out.jsonl # download results (stdout if no path)
277
- aicli batch cancel <id> # cancel an in-progress batch
278
- ```
279
-
280
- Local tracking file: `~/.aicli/batches.json` (last 200 submissions). Requires `AICLI_API_KEY_CLAUDE` or a Claude API key configured via `aicli config`.
281
-
282
- ### Headless Mode
283
-
284
- ```bash
285
- # Single prompt
286
- aicli -p "Explain recursion in one sentence"
287
-
288
- # Pipe stdin
289
- cat src/main.ts | aicli -p "Review this code"
290
-
291
- # JSON output for scripting
292
- aicli -p "hello" --json
293
-
294
- # Streaming JSON (NDJSON)
295
- aicli -p "write a poem" --output-format streaming-json
296
- ```
297
-
298
- ## Configuration
299
-
300
- Configuration is stored at `~/.aicli/config.json`. Run `aicli config` for the interactive wizard, or edit directly:
301
-
302
- ```json
303
- {
304
- "defaultProvider": "deepseek",
305
- "apiKeys": {
306
- "deepseek": "sk-...",
307
- "claude": "sk-ant-...",
308
- "openrouter": "sk-or-..."
309
- },
310
- "proxy": "http://127.0.0.1:10809",
311
- "mcpServers": { },
312
- "ui": {
313
- "theme": "dark",
314
- "wordWrap": 0,
315
- "notificationThreshold": 10000
316
- }
317
- }
318
- ```
319
-
320
- ### Permission Rules
321
-
322
- Control when tools require confirmation. Rules are checked in order — first match wins:
323
-
324
- ```json
325
- {
326
- "permissionRules": [
327
- { "tool": "read_file", "action": "auto-approve" },
328
- { "tool": "list_dir", "action": "auto-approve" },
329
- { "tool": "grep_files", "action": "auto-approve" },
330
- { "tool": "glob_files", "action": "auto-approve" },
331
- { "tool": "write_todos", "action": "auto-approve" },
332
- { "tool": "bash", "action": "auto-approve", "when": { "dangerLevel": "safe" } },
333
- { "tool": "write_file", "action": "auto-approve", "when": { "pathPattern": "src/" } },
334
- { "tool": "bash", "action": "deny", "when": { "pathPattern": "rm -rf" } },
335
- { "tool": "*", "action": "confirm" }
336
- ]
337
- }
338
- ```
339
-
340
- | Field | Description |
341
- |-------|-------------|
342
- | `tool` | Tool name, or `*` for all tools |
343
- | `action` | `auto-approve` (skip confirmation), `deny` (block), `confirm` (ask user) |
344
- | `when.dangerLevel` | Only match when danger level is `safe`, `write`, or `destructive` |
345
- | `when.pathPattern` | Substring match against tool's `path` or `command` argument |
346
-
347
- ### Permission Profiles
348
-
349
- Permission profiles provide coarse-grained safety boundaries before fine-grained `permissionRules` run. The default profile is `legacy`, so existing configs keep their old behavior.
350
-
351
- Built-in profiles:
352
-
353
- | Profile | Behavior |
354
- |---------|----------|
355
- | `legacy` | Backward-compatible mode. Uses `permissionRules` and `defaultPermission` as before. |
356
- | `read-only` | Allows known read-only/safe tools and safe MCP tools; blocks write and destructive tools. |
357
- | `workspace-write` | Allows explicit file writes only inside the workspace roots or temp dirs; destructive tools still require confirmation. |
358
- | `danger-full-access` | Auto-approves non-destructive tools by default; destructive tools still require confirmation. Use only in isolated environments. |
359
-
360
- ```json
361
- {
362
- "defaultPermissionProfile": "workspace-write",
363
- "allowedPermissionProfiles": ["legacy", "read-only", "workspace-write", "danger-full-access"],
364
- "permissionProfiles": {
365
- "workspace-write": {
366
- "workspaceRoots": ["D:/github/ai-cli"],
367
- "allowTemp": true,
368
- "rules": [
369
- { "tool": "read_file", "action": "auto-approve" },
370
- { "tool": "list_dir", "action": "auto-approve" }
371
- ]
372
- }
373
- },
374
- "permissionRules": [
375
- { "tool": "bash", "action": "deny", "when": { "pathPattern": "rm -rf" } }
376
- ]
377
- }
378
- ```
379
-
380
- `/status` and `/security status` show the active profile. The Web status payload also includes `permissionProfile` for UI surfaces.
381
- ### Auto Mode
382
-
383
- `/auto on|off|status` enables a session-scoped, rule-based action classifier. It is designed to reduce confirmation fatigue without widening `/yolo`: `/yolo` still only skips write confirmations, while destructive tools still require confirmation.
384
-
385
- Auto Mode may auto-approve low-risk actions such as explicit writes inside the workspace/temp roots, read-only HTTP tools, plain non-force `git push`, and dependency installs already declared in `package.json` or a lockfile. It denies high-risk shapes such as `curl | bash`, force push, and likely secret exfiltration. Production deploys, database migrations, IaC destroy, credential/permission changes, and third-party agent loops fall back to confirmation.
386
-
387
- Auto Mode is not enabled by project config. Use `/permissions recently-denied` to inspect actions it blocked, or `/permissions clear-denied` to clear that session list.
388
- ### Agent Team
389
-
390
- `spawn_agent` can now use named roles from built-ins or JSON configs in `~/.aicli/agents/` and `.aicli/agents/`. Built-ins are `explorer`, `worker`, `reviewer`, `security`, and `tester`. Agent configs may set description, provider/model, system instructions, allowed/blocked tools, permission profile, max tool rounds, and context policy; they can only narrow the inherited sub-agent safety boundary. Use `/agent list|switch|stop|summary` to inspect roles and recent sub-agent runs.
391
-
392
- ### Network Policy
393
- `networkPolicy` is disabled by default for backward compatibility. When enabled, it governs network-facing tools before execution: `web_fetch`, `web_search`, `google_search`, MCP tools, and shell commands that look like network access (`curl`, `wget`, `git clone/fetch/pull/push`, package installs, SSH/SCP, etc.).
394
-
395
- ```json
396
- {
397
- "networkPolicy": {
398
- "enabled": true,
399
- "defaultAction": "confirm",
400
- "allowDomains": ["github.com", "docs.anthropic.com", "platform.openai.com"],
401
- "denyDomains": ["example-danger.test"],
402
- "allowPrivateNetwork": false,
403
- "tools": {
404
- "web_fetch": "confirm",
405
- "web_search": "allow",
406
- "google_search": "confirm",
407
- "shell": "confirm",
408
- "mcp": "confirm"
409
- }
410
- }
411
- }
412
- ```
413
-
414
- Actions are `allow`, `confirm`, or `deny`. Domain entries match the exact host or subdomains; port lists match the resolved URL port. Private/internal hosts such as `localhost`, `127.0.0.1`, `10.0.0.0/8`, `192.168.0.0/16`, and private IPv6 ranges are blocked unless `allowPrivateNetwork` is true.
415
- ### Trusted Hooks Lifecycle
416
-
417
- Legacy `preToolExecution` / `postToolExecution` hooks still work. New lifecycle hooks live under `hooks.events.<EventName>` and receive a JSON payload through `AICLI_HOOK_EVENT_JSON`; if the command prints JSON, ai-cli reads decisions such as `allow`, `deny`, `ask`, `warning`, or `warnings`.
418
-
419
- ```json
420
- {
421
- "hooks": {
422
- "events": {
423
- "PreToolUse": {
424
- "command": "node ./scripts/aicli-pre-tool-hook.mjs",
425
- "source": "project",
426
- "description": "Block unsafe local commands"
427
- },
428
- "UserPromptSubmit": "node ./scripts/aicli-prompt-hook.mjs",
429
- "Stop": { "command": "npm test -- --runInBand", "timeoutMs": 10000 }
430
- }
431
- }
432
- }
433
- ```
434
-
435
- Supported lifecycle names are `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PermissionRequest`, `PostToolUse`, `PreCompact`, `PostCompact`, `Stop`, `SubagentStart`, and `SubagentStop`. Project-sourced hooks must be trusted before execution; ai-cli stores trust records locally under the user config directory, keyed by hook hash, so changing hook content requires re-trust.
436
-
437
- Use `/hooks list`, `/hooks inspect <id>`, `/hooks trust <id>`, `/hooks untrust <id>`, and `/hooks disable` to manage them. `/status`, `/security status`, and Web status show pending project hooks that require trust.
438
- **Recommended minimal config** — auto-approve all read-only tools to reduce y/N prompts:
439
-
440
- ```json
441
- {
442
- "permissionRules": [
443
- { "tool": "read_file", "action": "auto-approve" },
444
- { "tool": "list_dir", "action": "auto-approve" },
445
- { "tool": "grep_files", "action": "auto-approve" },
446
- { "tool": "glob_files", "action": "auto-approve" },
447
- { "tool": "web_fetch", "action": "auto-approve" },
448
- { "tool": "write_todos", "action": "auto-approve" },
449
- { "tool": "ask_user", "action": "auto-approve" },
450
- { "tool": "run_tests", "action": "auto-approve" }
451
- ]
452
- }
453
- ```
454
-
455
- ### Environment Variables
456
-
457
- Environment variables take precedence over config file values:
458
-
459
- | Variable | Description |
460
- |----------|-------------|
461
- | `AICLI_API_KEY_CLAUDE` | Claude API Key |
462
- | `AICLI_API_KEY_GEMINI` | Gemini API Key |
463
- | `AICLI_API_KEY_DEEPSEEK` | DeepSeek API Key |
464
- | `AICLI_API_KEY_OPENAI` | OpenAI API Key |
465
- | `AICLI_API_KEY_OPENROUTER` | OpenRouter API Key |
466
- | `AICLI_API_KEY_ZHIPU` | Zhipu API Key |
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 |
471
- | `AICLI_NO_STREAM` | Set to `1` to disable streaming |
472
- | `HTTPS_PROXY` / `HTTP_PROXY` | Proxy URL |
473
-
474
- ### Hierarchical Context Files
475
-
476
- ai-cli automatically discovers and injects context files into the system prompt:
477
-
478
- | Layer | Path | Purpose |
479
- |-------|------|---------|
480
- | Global | `~/.aicli/<context-file>` | Personal preferences across all projects |
481
- | Project | `<git-root>/<context-file>` | Project rules (commit to git for team sharing) |
482
- | Subdirectory | `<cwd>/<context-file>` | Directory-specific instructions |
483
-
484
- At each layer, ai-cli loads the first non-empty file in this priority order: `AICLI.override.md`, `AGENTS.override.md`, `AICLI.md`, `CLAUDE.md`, `AGENTS.md`. `AICLI.md` is the native filename; `CLAUDE.md` and `AGENTS.md` are compatibility filenames for Claude Code and Codex-style projects.
485
-
486
- ### MCP Integration
487
-
488
- Connect external [MCP](https://modelcontextprotocol.io/) servers for dynamic tool discovery. Configuration is compatible with Claude Desktop format:
489
-
490
- ```json
491
- {
492
- "mcpServers": {
493
- "filesystem": {
494
- "command": "npx",
495
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
496
- "timeout": 30000
497
- }
498
- }
499
- }
500
- ```
501
-
502
- Project-level `.mcp.json` files are also supported and automatically merged with global config.
503
-
504
- ## Web UI Features
505
-
506
- The Web UI (`aicli web`) provides a full-featured browser interface:
507
-
508
- - **Multi-Tab Sessions** — parallel conversations in separate browser tabs
509
- - **File Tree Panel** — browse project files, click to insert `@path` references
510
- - **Image Upload** — drag & drop or Ctrl+V paste images into chat
511
- - **Prompt Templates** — CRUD with tags, search, import/export
512
- - **8 Themes** — DaisyUI themes with code highlight auto-sync
513
- - **Diff Syntax Highlighting** — colored diff in tool confirm dialogs
514
- - **Keyboard Shortcuts** — `Esc` stop, `Ctrl+L` clear, `↑↓` history
515
- - **Export** — `/export md` or `/export json` browser download
516
- - **PWA** — installable as desktop/mobile app
517
- - **LAN Access** — `--host 0.0.0.0` for phone/tablet access
518
- - **Multi-User Auth** — password authentication with per-user data isolation
519
- - **Auto-Reconnect** — heartbeat + exponential backoff reconnection
520
-
521
- ## Testing
522
-
523
- ```bash
524
- npm test # Offline regression suite
525
- npm run test:providers # Real-provider smoke tests (network/API-key dependent)
526
- npm run test:e2e-web # Playwright browser smoke; may need browser-process permission in sandboxes
527
- npm run test:watch # Watch mode
528
- ```
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.
531
-
532
- ## Releasing (Version Bump → Git Tag → Trusted npm Publish)
533
-
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
-
536
- **Prerequisites**
537
-
538
- - You are on the `main` branch and the changes to ship are already in the working tree.
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`.
541
- - You have push access to the GitHub remote.
542
-
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.)
544
-
545
- **Step 2 — Run the release script.**
546
-
547
- ```bash
548
- # patch: 0.4.209 → 0.4.210 (also accepts: minor / major / an explicit x.y.z)
549
- node scripts/release.mjs patch -m "fix(scope): one-line commit title"
550
-
551
- # preview only — validates guards, writes nothing:
552
- node scripts/release.mjs patch -m "..." --dry-run
553
- ```
554
-
555
- - Do **not** put a `(vX.Y.Z)` suffix in `-m`; the script appends it automatically.
556
- - On Windows PowerShell, call `node` directly — `npm run release -- -m ...` swallows the `-m` argument.
557
-
558
- **What the script does, in order:**
559
-
560
- 1. **Guard A** — asserts `CLAUDE.md` contains the `(vX.Y.Z)` milestone entry.
561
- 2. Bumps the version in **three** places: `package.json`, `src/core/constants.ts` (`VERSION`), and `CLAUDE.md` (`**当前版本**`).
562
- 3. **Guard B** — re-reads all three files from disk and asserts every bump landed.
563
- 4. **Guard C** — `tsc --noEmit` must be zero-error (rolls the bump back on failure).
564
- 5. `npm test` must pass (rolls the bump back on failure).
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
- 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`.
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
593
-
594
- ## Documentation
595
-
596
- - [`docs/USAGE.md`](docs/USAGE.md) — Complete reference manual (commands, tools, config)
597
- - [`docs/TUTORIAL.md`](docs/TUTORIAL.md) — Hands-on tutorial, zero to fluent in an hour
598
- - [`docs/ADVANCED.md`](docs/ADVANCED.md) — Architecture and internals (for developers)
599
- - [`docs/MIGRATION.md`](docs/MIGRATION.md) — Migration guide from Claude Code, Codex, Claude Desktop, and Cursor
600
- - [`docs/RECIPES.md`](docs/RECIPES.md) — Practical recipes by scenario
601
- - [`docs/SECURITY.md`](docs/SECURITY.md) — **Security model, deployment checklist, audit history.** Read before exposing `aicli web` to a network.
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
606
- - [Chinese README](README.zh-CN.md) — 中文说明文档
607
-
608
- ## License
609
-
610
- [MIT](LICENSE)
1
+ **English** | [中文](README.zh-CN.md)
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
12
+
13
+ [![npm version](https://img.shields.io/npm/v/jinzd-ai-cli)](https://www.npmjs.com/package/jinzd-ai-cli)
14
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
15
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D20.18.1-brightgreen)](https://nodejs.org)
16
+ [![GitHub Release](https://img.shields.io/github/v/release/jinzhengdong/ai-cli)](https://github.com/jinzhengdong/ai-cli/releases)
17
+ [![CI](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml)
18
+
19
+ **ai-cli** is a powerful AI assistant that connects to 10 providers (including local Ollama models) and executes tasks autonomously through agentic tool calling. Use it as a terminal REPL, a browser-based Web UI, or a standalone Electron desktop app.
20
+
21
+ <p align="center">
22
+ <img src="https://img.shields.io/badge/CLI-Terminal-blue" alt="CLI" />
23
+ <img src="https://img.shields.io/badge/Web_UI-Browser-green" alt="Web UI" />
24
+ <img src="https://img.shields.io/badge/Desktop-Electron-purple" alt="Desktop" />
25
+ </p>
26
+
27
+ ## Highlights
28
+
29
+ - **10 Built-in Providers** — Claude, Gemini, DeepSeek, OpenAI, Zhipu GLM, Kimi, Qwen, **MiniMax (海螺)**, OpenRouter (300+ models), **Ollama** (local models, no API key needed)
30
+ - **3 Interfaces** — Terminal CLI, browser Web UI (`aicli web`), Electron desktop app
31
+ - **Agentic Tool Calling** — AI autonomously runs shell commands, reads/writes files, searches code, fetches web, runs tests (default 200 rounds, configurable up to 10000 via `config.maxToolRounds` or `--max-tool-rounds`)
32
+ - **Prompt Caching** *(v0.4.70+)* — System prompt split into stable/volatile halves so Claude caches the stable part with `cache_control: ephemeral`; cached tokens bill at ~10% of the input price
33
+ - **Unified-Diff Patch Edits** *(v0.4.72+)* — `edit_file` accepts standard `@@ -a,b +c,d @@` hunks for the most compact way to apply many scattered small changes to a large file (±200-line drift tolerance + whitespace fallback)
34
+ - **Anthropic Batches API** *(v0.4.73+)* — `aicli batch submit/list/status/results/cancel` for 50%-off, 24-hour async processing — ideal for offline analysis and bulk evals
35
+ - **Web UI Session Replay** *(v0.4.71+)* — 🎬 button on every saved session opens a timeline replay: every message, tool call, reasoning, and cache-aware token usage at a glance
36
+ - **Conversation Branching** *(v0.4.74+)* — `/branch list/new/switch/delete/rename` inside the REPL, plus a 🌿 "fork here" button on every replay step — explore alternate directions without losing the original thread
37
+ - **Symbol Index** *(v0.4.76+, multi-language since v0.4.143)* — persistent tree-sitter index for TypeScript / JavaScript / TSX / Python / Go / Rust / Java / C/C++ powers three new AI tools: `find_symbol`, `get_outline`, `find_references`. Orders of magnitude faster than grep for definition lookups; background refresh on REPL startup, `/index status|rebuild|clear` to manage
38
+ - **Semantic Code Search** *(v0.4.77+)* — `search_code` tool finds code by meaning, not name. Local sentence embeddings (multilingual MiniLM, 117 MB one-time download) score symbols by cosine similarity against natural-language queries in English or Chinese ("where are users authenticated", "哪里做了速率限制"). No API key, runs on CPU. Manage with `/index semantic-rebuild|semantic-clear`
39
+ - **MCP Server Mode** *(v0.4.84+)* — `aicli mcp-serve` reverses ai-cli into an MCP server (JSON-RPC 2.0 over stdio), exposing its 30 built-in tools (incl. `find_symbol` / `search_code` / `run_tests`) to Claude Desktop / Cursor / any MCP client. Opt-in destructive-tool allow, `--tools` whitelist, `--cwd` override
40
+ - **Session Sensitive-Data Redaction** *(v0.4.88+)* — unified redactor scrubs `password=` / `api_key` / bearer tokens / OpenAI-style keys from every message **before it hits disk**. Query text is redacted too, so secrets never reach embeddings or logs. `/security status` + `/security scan` to audit
41
+ - **Human-like Long-Term Memory** *(v0.4.89+, B4)* — semantic index over every past chat session + `recall_memory` AI tool + `/memory rebuild|refresh|status|recall` commands. AI is prompted to auto-recall when it sees "last time" / "之前" / ambiguous references. Reuses the same MiniLM embedder as semantic code search
42
+ - **Governed Persistent Memory** *(v0.4.217+)* — `save_memory` and `/memory add` write auditable `memory.jsonl` entries with id/scope/source/sensitivity/approval/expiry; AI-written entries (`save_memory`) always stay pending until `/memory approve <id>` (v0.4.242+), low-risk manual entries auto-approve, project-scoped memories only inject inside the same project, and `/memory clear` confirms + keeps a timestamped backup
43
+ - **Package Plugin Ecosystem** *(v0.4.218+)* — install shareable .aicli-plugin/plugin.json packages with skills, hooks, commands, MCP servers, agents, and permission hints; only trusted+enabled plugins load, hooks still require hook trust, and MCP/tools remain under permission profiles/network policy
44
+ - **Web UI Memory Panel** *(v0.4.90+, B4)* — new 🧠 Memory sidebar tab with semantic search across past chats; each hit has **➕ Inject** (quotes the snippet into the chat input as a markdown blockquote so you can review/edit before sending — no silent context injection) and **↗ Load** (jumps to source session). Bulk "Inject top 3" for recall bundles
45
+ - **Streaming Tool Use** — Real-time streaming of AI reasoning and tool calls as they happen
46
+ - **Sub-Agents** — Delegate complex subtasks to isolated child agents with independent tool loops
47
+ - **Extended Thinking** — Claude deep reasoning mode with `/think` toggle
48
+ - **Plan Mode** — Read-only planning phase (`/plan`) where AI analyzes before executing, with loop detection
49
+ - **Auto-Pause** — Automatically pauses every 10 rounds for user review and redirection
50
+ - **MCP Protocol** — Connect external MCP servers for dynamic tool discovery
51
+ - **Multi-User Auth** — Web UI supports multiple users with password authentication
52
+ - **PWA Support** — Install Web UI as a desktop/mobile app, accessible over LAN
53
+ - **Hierarchical Context** — 3-layer context files (global / project / subdirectory) auto-injected; supports native AICLI.md, Claude-compatible CLAUDE.md, and Codex-compatible AGENTS.md with override files
54
+ - **Headless Mode** — `ai-cli -p "prompt"` for CI/CD pipelines and scripting
55
+ - **48 REPL Commands** — Session management, checkpointing, code review, security review/scan, rewind, scaffolding, cross-session history search, chat-memory recall, smart model routing (`/route`), and more
56
+ - **GitHub Actions CI/CD** — Automated testing on Node 20/22 + npm publish on release tags
57
+ - **PR Review CLI** *(v0.4.216+)* — `aicli pr review|security-review|summarize` reviews `main...HEAD`, custom `--base/--head`, or GitHub PR URLs; optional `--agents security,bugs,tests,maintainability`; never posts comments unless `--post` is explicit
58
+ - **CI Review Artifacts** *(v0.4.216+)* — `aicli ci` emits Markdown, JSON, or SARIF and gates on security-high, test-failure, and lint-failure findings in read-only review mode
59
+ - **Cross-Platform** — Windows, macOS, Linux
60
+
61
+ ## Installation
62
+
63
+ ### npm (recommended)
64
+
65
+ ```bash
66
+ npm install -g jinzd-ai-cli
67
+ ```
68
+
69
+ Requires Node.js >= 20.18.1. After installation, use `aicli` to start.
70
+
71
+ ### Electron Desktop App (Windows)
72
+
73
+ Download the installer from [GitHub Releases](https://github.com/jinzhengdong/ai-cli/releases) — no Node.js required:
74
+
75
+ | Platform | Download |
76
+ |----------|----------|
77
+ | Windows x64 | [`ai-cli-setup.exe`](https://github.com/jinzhengdong/ai-cli/releases/latest) |
78
+
79
+ ### Standalone CLI Executables
80
+
81
+ Pre-built CLI binaries (no Node.js required, ~56 MB):
82
+
83
+ | Platform | File |
84
+ |----------|------|
85
+ | Windows x64 | `ai-cli-win.exe` |
86
+ | macOS arm64 | `ai-cli-mac` |
87
+ | macOS x64 | `ai-cli-mac-x64` |
88
+ | Linux x64 | `ai-cli-linux` |
89
+
90
+ ## Quick Start
91
+
92
+ ### Terminal CLI
93
+
94
+ ```bash
95
+ aicli
96
+ ```
97
+
98
+ On first run, an interactive setup wizard guides you through setting up your profile and entering your API key. Your identity is persisted and injected into every AI conversation.
99
+
100
+ ```
101
+ [deepseek] > Hello! Tell me about this project
102
+ [deepseek] > @src/main.ts Review this file for bugs
103
+ [deepseek] > @screenshot.png What's in this image?
104
+ [deepseek] > /help
105
+ ```
106
+
107
+ Use `@filepath` to reference files or images directly in your prompt.
108
+
109
+ ### Web UI
110
+
111
+ ```bash
112
+ aicli web # Start on localhost:3000
113
+ aicli web --port 8080 # Custom port
114
+ aicli web --host 0.0.0.0 # LAN access (shows QR-friendly URL)
115
+ ```
116
+
117
+ Features: multi-tab sessions, file tree panel, drag & drop images, prompt templates, 8 DaisyUI themes, PWA installable, keyboard shortcuts, diff syntax highlighting.
118
+
119
+ ### User Management
120
+
121
+ ```bash
122
+ aicli user create admin # Create user (enables auth)
123
+ aicli user list # List all users
124
+ aicli user reset-password x # Reset password
125
+ aicli user delete x # Delete user
126
+ ```
127
+
128
+ ## Supported Providers
129
+
130
+ | Provider | Models | Get API Key |
131
+ |----------|--------|-------------|
132
+ | **Claude** | Opus 4, Sonnet 4, Haiku 4 | [console.anthropic.com](https://console.anthropic.com) |
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) |
135
+ | **OpenAI** | GPT-5.4, GPT-5, GPT-4.1, o3, o4-mini | [platform.openai.com](https://platform.openai.com) |
136
+ | **OpenRouter** | 300+ models (Claude, GPT, Gemini, Llama, Qwen, Mistral...) | [openrouter.ai](https://openrouter.ai) |
137
+ | **Zhipu** | GLM-4, GLM-5 | [open.bigmodel.cn](https://open.bigmodel.cn) |
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) |
142
+
143
+ Any OpenAI-compatible API can also be used via `customBaseUrls` in config.
144
+
145
+ ### Ollama (Local Models)
146
+
147
+ Run AI models entirely on your own hardware — no API key, no usage fees, no data leaving your machine.
148
+
149
+ ```bash
150
+ # Install Ollama from https://ollama.com, then pull a model:
151
+ ollama pull qwen3:4b # recommended: good tool-calling support
152
+ ollama pull gemma3:4b
153
+ ollama pull llama3.1:8b
154
+
155
+ # Start aicli and switch to Ollama:
156
+ aicli
157
+ [deepseek] > /provider ollama # auto-discovers installed models
158
+ [ollama] > /model # select from your local models
159
+ ```
160
+
161
+ > **Note**: Use models 4B+ for best results with tool calling. Small models (<4B) may struggle with the tool definitions injected by MCP servers.
162
+
163
+ ## Built-in Tools (Agentic)
164
+
165
+ AI autonomously invokes these 30 tools during conversations:
166
+
167
+ | Tool | Safety | Description |
168
+ |------|--------|-------------|
169
+ | `bash` | varies | Execute shell commands (PowerShell on Windows, $SHELL on Unix) |
170
+ | `read_file` | safe | Read file contents (10 MB limit, image support) |
171
+ | `write_file` | write | Create/overwrite files (diff preview + confirmation) |
172
+ | `edit_file` | write | Precise string replacement with fuzzy matching hints + `replaceAll` mode |
173
+ | `list_dir` | safe | List directory contents |
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 |
180
+ | `run_tests` | safe | Auto-detect and run project tests (JUnit XML parsing) |
181
+ | `spawn_agent` | safe | Delegate subtasks to named isolated agents (`agent`: explorer/worker/reviewer/security/tester) |
182
+ | `ask_user` | safe | Pause and ask the user a question |
183
+ | `save_memory` | safe | Persist governed memory across sessions; AI-written entries stay pending until `/memory approve <id>` |
184
+ | `write_todos` | safe | Task breakdown with live progress rendering |
185
+ | `save_last_response` | write | Save AI response to file |
186
+ | `task_create` | write | Start a command running in the background |
187
+ | `task_list` | safe | List background tasks and their status/output |
188
+ | `task_stop` | write | Stop a running background task |
189
+ | `git_status` | safe | Show working tree status (branch, staged, modified, untracked) |
190
+ | `git_diff` | safe | Show file diffs (staged/unstaged, stat summary) |
191
+ | `git_log` | safe | Show commit history (oneline/full, filter by file/author) |
192
+ | `git_commit` | write | Create a git commit (stage files, message) |
193
+ | `notebook_edit` | write | Edit Jupyter notebook cells (add/edit/delete/move) |
194
+ | `find_symbol` | safe | Locate symbol definitions via persistent tree-sitter index (TS/JS/TSX/Python/Go/Rust/Java/C++) |
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 |
199
+
200
+ **Safety levels**: `safe` = auto-execute, `write` = confirmation required (file-editing tools also show a diff preview), `destructive` = prominent warning + confirmation.
201
+
202
+ ## Key REPL Commands
203
+
204
+ | Command | Description |
205
+ |---------|-------------|
206
+ | `/provider` | Switch AI provider |
207
+ | `/model` | Switch model; `/model refresh [provider]` refreshes live model cache |
208
+ | `/plan` | Enter read-only planning mode |
209
+ | `/think` | Toggle Claude extended thinking |
210
+ | `/test` | Auto-detect and run project tests |
211
+ | `/review` | AI code review of current git diff |
212
+ | `/security-review` | Security vulnerability scan on git diff |
213
+ | `/rewind` | Rewind conversation + restore files to checkpoint state |
214
+ | `/scaffold <desc>` | AI generates project skeleton |
215
+ | `/init` | AI generates project context file (AICLI.md) |
216
+ | `/compact` | Compress conversation history |
217
+ | `/session` | Session management (new / list / load) |
218
+ | `/checkpoint` | Save/restore conversation checkpoints |
219
+ | `/fork` | Fork the current session into a new session file |
220
+ | `/branch` | Create/switch/delete branches *within* the current session (B2) |
221
+ | `/index` | Manage symbol + semantic index (status/rebuild/clear/semantic-rebuild/semantic-clear) — powers `find_symbol` / `get_outline` / `find_references` / `search_code` (C1+C2) |
222
+ | `/search <keyword>` | Full-text search across all sessions |
223
+ | `/skill` | Manage agent skill packs |
224
+ | `/mcp` | View MCP server status and tools |
225
+ | `/cost` | Show token usage statistics |
226
+ | `/undo` | Undo last file operation |
227
+ | `/doctor` | Health check (API keys, MCP, context) |
228
+ | `/export` | Export session as Markdown or JSON |
229
+ | `/profile` | View/edit your identity (AI knows who you are across all providers) |
230
+ | `/config` | Open configuration wizard |
231
+ | /help | Show all available commands |
232
+ | /plugin | Install, trust, enable, disable, and inspect package plugins |
233
+
234
+ **Multi-line input**: Use `\` at end of line for continuation, or paste multi-line content directly (auto-detected and merged).
235
+
236
+ Type `/help` in the REPL to see all 48 commands.
237
+
238
+ ## CLI Parameters
239
+
240
+ ```bash
241
+ aicli [options]
242
+
243
+ Options:
244
+ --provider <name> Set AI provider
245
+ -m, --model <name> Set model
246
+ -p, --prompt <text> Headless mode: single prompt, then exit
247
+ --system <prompt> Override system prompt (headless)
248
+ --json Output JSON response (headless)
249
+ --output-format <fmt> text | streaming-json (NDJSON)
250
+ --resume <id> Resume a previous session
251
+ --allowed-tools <list> Comma-separated tool whitelist
252
+ --blocked-tools <list> Comma-separated tool blacklist
253
+ --no-stream Disable streaming output
254
+
255
+ Subcommands:
256
+ aicli web [options] Start Web UI server
257
+ aicli config Run configuration wizard
258
+ aicli providers List all providers and status
259
+ aicli sessions List recent sessions
260
+ aicli user <action> Manage Web UI users
261
+ aicli batch <action> Anthropic Batches API (submit | list | status | results | cancel)
262
+ ```
263
+
264
+ ### Batch Mode (Anthropic Message Batches)
265
+
266
+ For offline analysis, bulk evals, or any workload where latency is flexible, use the Batches API for **50% off** tokens with a 24-hour processing window.
267
+
268
+ ```bash
269
+ # 1. Prepare a JSONL file (one request per line):
270
+ # {"customId":"req-1","messages":[{"role":"user","content":"..."}],"maxTokens":1024}
271
+ aicli batch submit prompts.jsonl # validate + submit + track locally
272
+ aicli batch submit --dry-run prompts.jsonl # parse only, no network
273
+
274
+ aicli batch list # live status of recent batches
275
+ aicli batch status <id> # detailed status + request counts
276
+ aicli batch results <id> out.jsonl # download results (stdout if no path)
277
+ aicli batch cancel <id> # cancel an in-progress batch
278
+ ```
279
+
280
+ Local tracking file: `~/.aicli/batches.json` (last 200 submissions). Requires `AICLI_API_KEY_CLAUDE` or a Claude API key configured via `aicli config`.
281
+
282
+ ### Headless Mode
283
+
284
+ ```bash
285
+ # Single prompt
286
+ aicli -p "Explain recursion in one sentence"
287
+
288
+ # Pipe stdin
289
+ cat src/main.ts | aicli -p "Review this code"
290
+
291
+ # JSON output for scripting
292
+ aicli -p "hello" --json
293
+
294
+ # Streaming JSON (NDJSON)
295
+ aicli -p "write a poem" --output-format streaming-json
296
+ ```
297
+
298
+ ## Configuration
299
+
300
+ Configuration is stored at `~/.aicli/config.json`. Run `aicli config` for the interactive wizard, or edit directly:
301
+
302
+ ```json
303
+ {
304
+ "defaultProvider": "deepseek",
305
+ "apiKeys": {
306
+ "deepseek": "sk-...",
307
+ "claude": "sk-ant-...",
308
+ "openrouter": "sk-or-..."
309
+ },
310
+ "proxy": "http://127.0.0.1:10809",
311
+ "mcpServers": { },
312
+ "ui": {
313
+ "theme": "dark",
314
+ "wordWrap": 0,
315
+ "notificationThreshold": 10000
316
+ }
317
+ }
318
+ ```
319
+
320
+ ### Permission Rules
321
+
322
+ Control when tools require confirmation. Rules are checked in order — first match wins:
323
+
324
+ ```json
325
+ {
326
+ "permissionRules": [
327
+ { "tool": "read_file", "action": "auto-approve" },
328
+ { "tool": "list_dir", "action": "auto-approve" },
329
+ { "tool": "grep_files", "action": "auto-approve" },
330
+ { "tool": "glob_files", "action": "auto-approve" },
331
+ { "tool": "write_todos", "action": "auto-approve" },
332
+ { "tool": "bash", "action": "auto-approve", "when": { "dangerLevel": "safe" } },
333
+ { "tool": "write_file", "action": "auto-approve", "when": { "pathPattern": "src/" } },
334
+ { "tool": "bash", "action": "deny", "when": { "pathPattern": "rm -rf" } },
335
+ { "tool": "*", "action": "confirm" }
336
+ ]
337
+ }
338
+ ```
339
+
340
+ | Field | Description |
341
+ |-------|-------------|
342
+ | `tool` | Tool name, or `*` for all tools |
343
+ | `action` | `auto-approve` (skip confirmation), `deny` (block), `confirm` (ask user) |
344
+ | `when.dangerLevel` | Only match when danger level is `safe`, `write`, or `destructive` |
345
+ | `when.pathPattern` | Substring match against tool's `path` or `command` argument |
346
+
347
+ ### Permission Profiles
348
+
349
+ Permission profiles provide coarse-grained safety boundaries before fine-grained `permissionRules` run. The default profile is `legacy`, so existing configs keep their old behavior.
350
+
351
+ Built-in profiles:
352
+
353
+ | Profile | Behavior |
354
+ |---------|----------|
355
+ | `legacy` | Backward-compatible mode. Uses `permissionRules` and `defaultPermission` as before. |
356
+ | `read-only` | Allows known read-only/safe tools and safe MCP tools; blocks write and destructive tools. |
357
+ | `workspace-write` | Allows explicit file writes only inside the workspace roots or temp dirs; destructive tools still require confirmation. |
358
+ | `danger-full-access` | Auto-approves non-destructive tools by default; destructive tools still require confirmation. Use only in isolated environments. |
359
+
360
+ ```json
361
+ {
362
+ "defaultPermissionProfile": "workspace-write",
363
+ "allowedPermissionProfiles": ["legacy", "read-only", "workspace-write", "danger-full-access"],
364
+ "permissionProfiles": {
365
+ "workspace-write": {
366
+ "workspaceRoots": ["D:/github/ai-cli"],
367
+ "allowTemp": true,
368
+ "rules": [
369
+ { "tool": "read_file", "action": "auto-approve" },
370
+ { "tool": "list_dir", "action": "auto-approve" }
371
+ ]
372
+ }
373
+ },
374
+ "permissionRules": [
375
+ { "tool": "bash", "action": "deny", "when": { "pathPattern": "rm -rf" } }
376
+ ]
377
+ }
378
+ ```
379
+
380
+ `/status` and `/security status` show the active profile. The Web status payload also includes `permissionProfile` for UI surfaces.
381
+ ### Auto Mode
382
+
383
+ `/auto on|off|status` enables a session-scoped, rule-based action classifier. It is designed to reduce confirmation fatigue without widening `/yolo`: `/yolo` still only skips write confirmations, while destructive tools still require confirmation.
384
+
385
+ Auto Mode may auto-approve low-risk actions such as explicit writes inside the workspace/temp roots, read-only HTTP tools, plain non-force `git push`, and dependency installs already declared in `package.json` or a lockfile. It denies high-risk shapes such as `curl | bash`, force push, and likely secret exfiltration. Production deploys, database migrations, IaC destroy, credential/permission changes, and third-party agent loops fall back to confirmation.
386
+
387
+ Auto Mode is not enabled by project config. Use `/permissions recently-denied` to inspect actions it blocked, or `/permissions clear-denied` to clear that session list.
388
+ ### Agent Team
389
+
390
+ `spawn_agent` can now use named roles from built-ins or JSON configs in `~/.aicli/agents/` and `.aicli/agents/`. Built-ins are `explorer`, `worker`, `reviewer`, `security`, and `tester`. Agent configs may set description, provider/model, system instructions, allowed/blocked tools, permission profile, max tool rounds, and context policy; they can only narrow the inherited sub-agent safety boundary. Use `/agent list|switch|stop|summary` to inspect roles and recent sub-agent runs.
391
+
392
+ ### Network Policy
393
+ `networkPolicy` is disabled by default for backward compatibility. When enabled, it governs network-facing tools before execution: `web_fetch`, `web_search`, `google_search`, MCP tools, and shell commands that look like network access (`curl`, `wget`, `git clone/fetch/pull/push`, package installs, SSH/SCP, etc.).
394
+
395
+ ```json
396
+ {
397
+ "networkPolicy": {
398
+ "enabled": true,
399
+ "defaultAction": "confirm",
400
+ "allowDomains": ["github.com", "docs.anthropic.com", "platform.openai.com"],
401
+ "denyDomains": ["example-danger.test"],
402
+ "allowPrivateNetwork": false,
403
+ "tools": {
404
+ "web_fetch": "confirm",
405
+ "web_search": "allow",
406
+ "google_search": "confirm",
407
+ "shell": "confirm",
408
+ "mcp": "confirm"
409
+ }
410
+ }
411
+ }
412
+ ```
413
+
414
+ Actions are `allow`, `confirm`, or `deny`. Domain entries match the exact host or subdomains; port lists match the resolved URL port. Private/internal hosts such as `localhost`, `127.0.0.1`, `10.0.0.0/8`, `192.168.0.0/16`, and private IPv6 ranges are blocked unless `allowPrivateNetwork` is true.
415
+ ### Trusted Hooks Lifecycle
416
+
417
+ Legacy `preToolExecution` / `postToolExecution` hooks still work. New lifecycle hooks live under `hooks.events.<EventName>` and receive a JSON payload through `AICLI_HOOK_EVENT_JSON`; if the command prints JSON, ai-cli reads decisions such as `allow`, `deny`, `ask`, `warning`, or `warnings`.
418
+
419
+ ```json
420
+ {
421
+ "hooks": {
422
+ "events": {
423
+ "PreToolUse": {
424
+ "command": "node ./scripts/aicli-pre-tool-hook.mjs",
425
+ "source": "project",
426
+ "description": "Block unsafe local commands"
427
+ },
428
+ "UserPromptSubmit": "node ./scripts/aicli-prompt-hook.mjs",
429
+ "Stop": { "command": "npm test -- --runInBand", "timeoutMs": 10000 }
430
+ }
431
+ }
432
+ }
433
+ ```
434
+
435
+ Supported lifecycle names are `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PermissionRequest`, `PostToolUse`, `PreCompact`, `PostCompact`, `Stop`, `SubagentStart`, and `SubagentStop`. Project-sourced hooks must be trusted before execution; ai-cli stores trust records locally under the user config directory, keyed by hook hash, so changing hook content requires re-trust.
436
+
437
+ Use `/hooks list`, `/hooks inspect <id>`, `/hooks trust <id>`, `/hooks untrust <id>`, and `/hooks disable` to manage them. `/status`, `/security status`, and Web status show pending project hooks that require trust.
438
+ **Recommended minimal config** — auto-approve all read-only tools to reduce y/N prompts:
439
+
440
+ ```json
441
+ {
442
+ "permissionRules": [
443
+ { "tool": "read_file", "action": "auto-approve" },
444
+ { "tool": "list_dir", "action": "auto-approve" },
445
+ { "tool": "grep_files", "action": "auto-approve" },
446
+ { "tool": "glob_files", "action": "auto-approve" },
447
+ { "tool": "web_fetch", "action": "auto-approve" },
448
+ { "tool": "write_todos", "action": "auto-approve" },
449
+ { "tool": "ask_user", "action": "auto-approve" },
450
+ { "tool": "run_tests", "action": "auto-approve" }
451
+ ]
452
+ }
453
+ ```
454
+
455
+ ### Environment Variables
456
+
457
+ Environment variables take precedence over config file values:
458
+
459
+ | Variable | Description |
460
+ |----------|-------------|
461
+ | `AICLI_API_KEY_CLAUDE` | Claude API Key |
462
+ | `AICLI_API_KEY_GEMINI` | Gemini API Key |
463
+ | `AICLI_API_KEY_DEEPSEEK` | DeepSeek API Key |
464
+ | `AICLI_API_KEY_OPENAI` | OpenAI API Key |
465
+ | `AICLI_API_KEY_OPENROUTER` | OpenRouter API Key |
466
+ | `AICLI_API_KEY_ZHIPU` | Zhipu API Key |
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 |
471
+ | `AICLI_NO_STREAM` | Set to `1` to disable streaming |
472
+ | `HTTPS_PROXY` / `HTTP_PROXY` | Proxy URL |
473
+
474
+ ### Hierarchical Context Files
475
+
476
+ ai-cli automatically discovers and injects context files into the system prompt:
477
+
478
+ | Layer | Path | Purpose |
479
+ |-------|------|---------|
480
+ | Global | `~/.aicli/<context-file>` | Personal preferences across all projects |
481
+ | Project | `<git-root>/<context-file>` | Project rules (commit to git for team sharing) |
482
+ | Subdirectory | `<cwd>/<context-file>` | Directory-specific instructions |
483
+
484
+ At each layer, ai-cli loads the first non-empty file in this priority order: `AICLI.override.md`, `AGENTS.override.md`, `AICLI.md`, `CLAUDE.md`, `AGENTS.md`. `AICLI.md` is the native filename; `CLAUDE.md` and `AGENTS.md` are compatibility filenames for Claude Code and Codex-style projects.
485
+
486
+ ### MCP Integration
487
+
488
+ Connect external [MCP](https://modelcontextprotocol.io/) servers for dynamic tool discovery. Configuration is compatible with Claude Desktop format:
489
+
490
+ ```json
491
+ {
492
+ "mcpServers": {
493
+ "filesystem": {
494
+ "command": "npx",
495
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
496
+ "timeout": 30000
497
+ }
498
+ }
499
+ }
500
+ ```
501
+
502
+ Project-level `.mcp.json` files are also supported and automatically merged with global config.
503
+
504
+ ## Web UI Features
505
+
506
+ The Web UI (`aicli web`) provides a full-featured browser interface:
507
+
508
+ - **Multi-Tab Sessions** — parallel conversations in separate browser tabs
509
+ - **File Tree Panel** — browse project files, click to insert `@path` references
510
+ - **Image Upload** — drag & drop or Ctrl+V paste images into chat
511
+ - **Prompt Templates** — CRUD with tags, search, import/export
512
+ - **8 Themes** — DaisyUI themes with code highlight auto-sync
513
+ - **Diff Syntax Highlighting** — colored diff in tool confirm dialogs
514
+ - **Keyboard Shortcuts** — `Esc` stop, `Ctrl+L` clear, `↑↓` history
515
+ - **Export** — `/export md` or `/export json` browser download
516
+ - **PWA** — installable as desktop/mobile app
517
+ - **LAN Access** — `--host 0.0.0.0` for phone/tablet access
518
+ - **Multi-User Auth** — password authentication with per-user data isolation
519
+ - **Auto-Reconnect** — heartbeat + exponential backoff reconnection
520
+
521
+ ## Testing
522
+
523
+ ```bash
524
+ npm test # Offline regression suite
525
+ npm run test:providers # Real-provider smoke tests (network/API-key dependent)
526
+ npm run test:e2e-web # Playwright browser smoke; may need browser-process permission in sandboxes
527
+ npm run test:watch # Watch mode
528
+ ```
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.
531
+
532
+ ## Releasing (Version Bump → Git Tag → Trusted npm Publish)
533
+
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
+
536
+ **Prerequisites**
537
+
538
+ - You are on the `main` branch and the changes to ship are already in the working tree.
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`.
541
+ - You have push access to the GitHub remote.
542
+
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.)
544
+
545
+ **Step 2 — Run the release script.**
546
+
547
+ ```bash
548
+ # patch: 0.4.209 → 0.4.210 (also accepts: minor / major / an explicit x.y.z)
549
+ node scripts/release.mjs patch -m "fix(scope): one-line commit title"
550
+
551
+ # preview only — validates guards, writes nothing:
552
+ node scripts/release.mjs patch -m "..." --dry-run
553
+ ```
554
+
555
+ - Do **not** put a `(vX.Y.Z)` suffix in `-m`; the script appends it automatically.
556
+ - On Windows PowerShell, call `node` directly — `npm run release -- -m ...` swallows the `-m` argument.
557
+
558
+ **What the script does, in order:**
559
+
560
+ 1. **Guard A** — asserts `CLAUDE.md` contains the `(vX.Y.Z)` milestone entry.
561
+ 2. Bumps the version in **three** places: `package.json`, `src/core/constants.ts` (`VERSION`), and `CLAUDE.md` (`**当前版本**`).
562
+ 3. **Guard B** — re-reads all three files from disk and asserts every bump landed.
563
+ 4. **Guard C** — `tsc --noEmit` must be zero-error (rolls the bump back on failure).
564
+ 5. `npm test` must pass (rolls the bump back on failure).
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
+ 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`.
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
593
+
594
+ ## Documentation
595
+
596
+ - [`docs/USAGE.md`](docs/USAGE.md) — Complete reference manual (commands, tools, config)
597
+ - [`docs/TUTORIAL.md`](docs/TUTORIAL.md) — Hands-on tutorial, zero to fluent in an hour
598
+ - [`docs/ADVANCED.md`](docs/ADVANCED.md) — Architecture and internals (for developers)
599
+ - [`docs/MIGRATION.md`](docs/MIGRATION.md) — Migration guide from Claude Code, Codex, Claude Desktop, and Cursor
600
+ - [`docs/RECIPES.md`](docs/RECIPES.md) — Practical recipes by scenario
601
+ - [`docs/SECURITY.md`](docs/SECURITY.md) — **Security model, deployment checklist, audit history.** Read before exposing `aicli web` to a network.
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
606
+ - [Chinese README](README.zh-CN.md) — 中文说明文档
607
+
608
+ ## License
609
+
610
+ [MIT](LICENSE)