jinzd-ai-cli 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,7 @@
9
9
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org)
10
10
  [![Tests](https://img.shields.io/badge/tests-138%20passing-brightgreen)]()
11
11
  [![GitHub Release](https://img.shields.io/github/v/release/jinzhengdong/ai-cli)](https://github.com/jinzhengdong/ai-cli/releases)
12
+ [![CI](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml)
12
13
 
13
14
  **ai-cli** is a powerful AI assistant that connects to 7 providers 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.
14
15
 
@@ -26,13 +27,15 @@
26
27
  - **Streaming Tool Use** — Real-time streaming of AI reasoning and tool calls as they happen
27
28
  - **Sub-Agents** — Delegate complex subtasks to isolated child agents with independent tool loops
28
29
  - **Extended Thinking** — Claude deep reasoning mode with `/think` toggle
29
- - **Plan Mode** — Read-only planning phase (`/plan`) where AI analyzes before executing
30
+ - **Plan Mode** — Read-only planning phase (`/plan`) where AI analyzes before executing, with loop detection
31
+ - **Auto-Pause** — Automatically pauses every 10 rounds for user review and redirection
30
32
  - **MCP Protocol** — Connect external MCP servers for dynamic tool discovery
31
33
  - **Multi-User Auth** — Web UI supports multiple users with password authentication
32
34
  - **PWA Support** — Install Web UI as a desktop/mobile app, accessible over LAN
33
35
  - **Hierarchical Context** — 3-layer context files (global / project / subdirectory) auto-injected
34
36
  - **Headless Mode** — `ai-cli -p "prompt"` for CI/CD pipelines and scripting
35
37
  - **35+ REPL Commands** — Session management, checkpointing, code review, scaffolding, and more
38
+ - **GitHub Actions CI/CD** — Automated testing on Node 20/22 + npm publish on release tags
36
39
  - **Cross-Platform** — Windows, macOS, Linux
37
40
 
38
41
  ## Installation
@@ -125,7 +128,7 @@ AI autonomously invokes these 16 tools during conversations:
125
128
  | `bash` | varies | Execute shell commands (PowerShell on Windows, $SHELL on Unix) |
126
129
  | `read_file` | safe | Read file contents (10 MB limit, image support) |
127
130
  | `write_file` | write | Create/overwrite files (diff preview + confirmation) |
128
- | `edit_file` | write | Precise string replacement with fuzzy matching hints |
131
+ | `edit_file` | write | Precise string replacement with fuzzy matching hints + `replaceAll` mode |
129
132
  | `list_dir` | safe | List directory contents |
130
133
  | `grep_files` | safe | Regex search across files |
131
134
  | `glob_files` | safe | Match files by glob pattern |
@@ -167,6 +170,8 @@ AI autonomously invokes these 16 tools during conversations:
167
170
  | `/config` | Open configuration wizard |
168
171
  | `/help` | Show all available commands |
169
172
 
173
+ **Multi-line input**: Use `\` at end of line for continuation, or paste multi-line content directly (auto-detected and merged).
174
+
170
175
  See the [full command reference](USAGE.md) for all 35+ commands.
171
176
 
172
177
  ## CLI Parameters
package/README.zh-CN.md CHANGED
@@ -9,6 +9,7 @@
9
9
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org)
10
10
  [![Tests](https://img.shields.io/badge/tests-138%20passing-brightgreen)]()
11
11
  [![GitHub Release](https://img.shields.io/github/v/release/jinzhengdong/ai-cli)](https://github.com/jinzhengdong/ai-cli/releases)
12
+ [![CI](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml)
12
13
 
13
14
  ## 特性亮点
14
15
 
@@ -18,13 +19,15 @@
18
19
  - **流式工具调用** — 实时流式展示 AI 推理过程和工具调用
19
20
  - **子代理系统** — 将复杂子任务委派给独立子代理执行
20
21
  - **深度推理** — Claude Extended Thinking,`/think` 一键切换
21
- - **规划模式** — `/plan` 进入只读规划,AI 先分析后执行
22
+ - **规划模式** — `/plan` 进入只读规划,AI 先分析后执行,内置死循环检测
23
+ - **自动暂停** — 每 10 轮自动暂停,用户可审查进度或重定向 AI
22
24
  - **MCP 协议** — 接入外部 MCP 服务器,动态发现工具
23
25
  - **多用户认证** — Web UI 支持多用户密码登录
24
26
  - **PWA 支持** — Web UI 可安装为桌面/移动应用,支持局域网访问
25
27
  - **三层级上下文** — 全局 / 项目 / 子目录上下文文件自动注入
26
28
  - **无头模式** — `aicli -p "提示词"` 用于 CI/CD 管道和脚本
27
29
  - **35+ REPL 命令** — 会话管理、检查点、代码审查、脚手架等
30
+ - **GitHub Actions CI/CD** — Node 20/22 自动测试 + Release tag 自动发布 npm
28
31
  - **跨平台** — Windows、macOS、Linux
29
32
 
30
33
  ## 安装
@@ -117,7 +120,7 @@ AI 在对话中可自主调用 16 个工具:
117
120
  | `bash` | 动态判断 | 执行 shell 命令(Windows: PowerShell,Unix: $SHELL) |
118
121
  | `read_file` | 安全 | 读取文件内容(10 MB 限制,支持图片) |
119
122
  | `write_file` | 写入 | 创建/覆盖文件(diff 预览 + 确认) |
120
- | `edit_file` | 写入 | 精确字符串替换,模糊匹配提示 |
123
+ | `edit_file` | 写入 | 精确字符串替换,模糊匹配提示 + `replaceAll` 全局替换模式 |
121
124
  | `list_dir` | 安全 | 列出目录内容 |
122
125
  | `grep_files` | 安全 | 正则搜索文件内容 |
123
126
  | `glob_files` | 安全 | 按 glob 模式匹配文件 |
@@ -159,6 +162,8 @@ AI 在对话中可自主调用 16 个工具:
159
162
  | `/config` | 打开配置向导 |
160
163
  | `/help` | 显示所有命令 |
161
164
 
165
+ **多行输入**:行末加 `\` 续行,或直接粘贴多行内容(自动检测合并)。
166
+
162
167
  完整命令参考见 [使用说明](USAGE.md)。
163
168
 
164
169
  ## CLI 参数
@@ -8,7 +8,7 @@ import { platform } from "os";
8
8
  import chalk from "chalk";
9
9
 
10
10
  // src/core/constants.ts
11
- var VERSION = "0.2.10";
11
+ var VERSION = "0.2.12";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -16,7 +16,7 @@ import {
16
16
  SUBAGENT_MAX_ROUNDS_LIMIT,
17
17
  VERSION,
18
18
  runTestsTool
19
- } from "./chunk-OOLIOMNF.js";
19
+ } from "./chunk-GGAA3JRD.js";
20
20
 
21
21
  // src/config/config-manager.ts
22
22
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  theme,
36
36
  truncateOutput,
37
37
  undoStack
38
- } from "./chunk-MBIHQ34V.js";
38
+ } from "./chunk-IGZDXYIX.js";
39
39
  import {
40
40
  AGENTIC_BEHAVIOR_GUIDELINE,
41
41
  AUTHOR,
@@ -55,7 +55,7 @@ import {
55
55
  REPO_URL,
56
56
  SKILLS_DIR_NAME,
57
57
  VERSION
58
- } from "./chunk-OOLIOMNF.js";
58
+ } from "./chunk-GGAA3JRD.js";
59
59
 
60
60
  // src/index.ts
61
61
  import { program } from "commander";
@@ -1904,7 +1904,7 @@ ${hint}` : "")
1904
1904
  description: "Run project tests and show structured report",
1905
1905
  usage: "/test [command|filter]",
1906
1906
  async execute(args, _ctx) {
1907
- const { executeTests } = await import("./run-tests-RAXI3LMY.js");
1907
+ const { executeTests } = await import("./run-tests-R2BHDFGB.js");
1908
1908
  const argStr = args.join(" ").trim();
1909
1909
  let testArgs = {};
1910
1910
  if (argStr) {
@@ -3785,7 +3785,15 @@ ${projectContext}`);
3785
3785
  const envInfo = `OS: ${osName}
3786
3786
  ${shellInfo}
3787
3787
  Working directory: ${process.cwd()}`;
3788
- const parts = [dateTimeInfo + "\n" + envInfo, AGENTIC_BEHAVIOR_GUIDELINE];
3788
+ const budgetInfo = `
3789
+
3790
+ # Tool Round Budget
3791
+ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds per conversation turn. Plan your work accordingly:
3792
+ - Use efficient approaches: batch edits (replaceAll), read multiple files in one round, avoid re-reading files you already read.
3793
+ - On Windows, use PowerShell cmdlets (Invoke-RestMethod, Get-ChildItem) instead of Unix commands (curl, grep, find).
3794
+ - If starting a long-running server process via bash, use background execution \u2014 do not block the tool round.
3795
+ - Prioritize the most critical tasks first in case you run out of rounds.`;
3796
+ const parts = [dateTimeInfo + "\n" + envInfo, AGENTIC_BEHAVIOR_GUIDELINE + budgetInfo];
3789
3797
  const memory = this.loadMemoryContent();
3790
3798
  if (memory) {
3791
3799
  parts.push(`# Persistent Memory
@@ -4821,6 +4829,7 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
4821
4829
  let consecutiveFreeRounds = 0;
4822
4830
  let lastToolCallSignature = "";
4823
4831
  let repeatedToolCallCount = 0;
4832
+ const roundToolHistory = [];
4824
4833
  this.setupInterjectionListener();
4825
4834
  process.stdout.write(theme.dim(" (Type a message + Enter to redirect AI at any time)\n"));
4826
4835
  try {
@@ -4841,12 +4850,24 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
4841
4850
  extraMessages.push({ role: "user", content: cmd });
4842
4851
  }
4843
4852
  const roundsLeft = MAX_TOOL_ROUNDS - round;
4844
- if (roundsLeft === 5) {
4853
+ if (roundsLeft === 10) {
4854
+ extraMessages.push({
4855
+ role: "user",
4856
+ content: `\u{1F4CA} Budget note: ${roundsLeft} tool rounds remaining out of ${MAX_TOOL_ROUNDS}. Plan your remaining work efficiently \u2014 use batch operations (e.g., replaceAll) when possible.`
4857
+ });
4858
+ } else if (roundsLeft === 5) {
4845
4859
  extraMessages.push({
4846
4860
  role: "user",
4847
- content: `\u26A0\uFE0F Budget warning: Only ${roundsLeft} tool rounds remaining. Prioritize completing the most critical task. If you cannot finish everything, summarize what's done and what remains.`
4861
+ content: `\u26A0\uFE0F Budget warning: Only ${roundsLeft} tool rounds remaining. Prioritize completing the most critical task. Use efficient approaches (batch edits, fewer reads). If you cannot finish everything, summarize what's done and what remains.`
4848
4862
  });
4849
4863
  process.stdout.write(theme.warning(` \u26A0\uFE0F Low budget: ${roundsLeft} rounds remaining
4864
+ `));
4865
+ } else if (roundsLeft === 3) {
4866
+ extraMessages.push({
4867
+ role: "user",
4868
+ content: `\u{1F6A8} Critical budget: Only ${roundsLeft} rounds left! Wrap up NOW \u2014 complete the current operation and give a final summary. Do NOT start new tasks.`
4869
+ });
4870
+ process.stdout.write(theme.error(` \u{1F6A8} Critical: ${roundsLeft} rounds remaining
4850
4871
  `));
4851
4872
  }
4852
4873
  if (this._userInterjection) {
@@ -5031,6 +5052,10 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
5031
5052
  process.stdin.removeListener("data", this._interjectionHandler);
5032
5053
  }
5033
5054
  const toolResults = await this.toolExecutor.executeAll(result.toolCalls);
5055
+ roundToolHistory.push({
5056
+ round: round + 1,
5057
+ tools: result.toolCalls.map((tc) => tc.name)
5058
+ });
5034
5059
  if (this._interjectionHandler) {
5035
5060
  process.stdin.on("data", this._interjectionHandler);
5036
5061
  process.stdin.resume();
@@ -5083,6 +5108,18 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
5083
5108
  process.stdout.write("\n");
5084
5109
  process.stdout.write(theme.warning(`\u23F8 Auto-pause: ${effectiveRound}/${MAX_TOOL_ROUNDS} rounds used, ${remaining} remaining
5085
5110
  `));
5111
+ const recentHistory = roundToolHistory.slice(-AUTO_PAUSE_INTERVAL);
5112
+ if (recentHistory.length > 0) {
5113
+ const toolCounts = /* @__PURE__ */ new Map();
5114
+ for (const rh of recentHistory) {
5115
+ for (const t of rh.tools) {
5116
+ toolCounts.set(t, (toolCounts.get(t) || 0) + 1);
5117
+ }
5118
+ }
5119
+ const summary = [...toolCounts.entries()].sort((a, b) => b[1] - a[1]).map(([name, count]) => count > 1 ? `${name}\xD7${count}` : name).join(", ");
5120
+ process.stdout.write(theme.dim(` Tools used: ${summary}
5121
+ `));
5122
+ }
5086
5123
  process.stdout.write(theme.dim(" Press ") + theme.info("y") + theme.dim(" to continue, or ") + theme.info("type a message") + theme.dim(" to redirect AI:\n"));
5087
5124
  process.stdout.write(theme.dim(" (Press ") + theme.info("n") + theme.dim(" or ") + theme.info("Esc") + theme.dim(" to stop)\n"));
5088
5125
  this.teardownInterjectionListener();
@@ -5437,7 +5474,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5437
5474
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5438
5475
  process.exit(1);
5439
5476
  }
5440
- const { startWebServer } = await import("./server-HYAIDK7B.js");
5477
+ const { startWebServer } = await import("./server-Z3UV3EZB.js");
5441
5478
  await startWebServer({ port, host: options.host });
5442
5479
  });
5443
5480
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-OOLIOMNF.js";
5
+ } from "./chunk-GGAA3JRD.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -23,7 +23,7 @@ import {
23
23
  setupProxy,
24
24
  spawnAgentContext,
25
25
  truncateOutput
26
- } from "./chunk-MBIHQ34V.js";
26
+ } from "./chunk-IGZDXYIX.js";
27
27
  import {
28
28
  AGENTIC_BEHAVIOR_GUIDELINE,
29
29
  CONTEXT_FILE_CANDIDATES,
@@ -35,7 +35,7 @@ import {
35
35
  PLAN_MODE_SYSTEM_ADDON,
36
36
  SKILLS_DIR_NAME,
37
37
  VERSION
38
- } from "./chunk-OOLIOMNF.js";
38
+ } from "./chunk-GGAA3JRD.js";
39
39
  import {
40
40
  AuthManager
41
41
  } from "./chunk-CPLT6CD3.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",