jinzd-ai-cli 0.2.11 → 0.2.13
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 +44 -0
- package/README.zh-CN.md +44 -0
- package/dist/{chunk-NT7GYZEL.js → chunk-2VKCVDHP.js} +1 -1
- package/dist/{chunk-HLR3T3PP.js → chunk-64ORNJVC.js} +1 -1
- package/dist/index.js +44 -7
- package/dist/{run-tests-TGHLGADJ.js → run-tests-7L33QJHM.js} +1 -1
- package/dist/{server-HERHWMR4.js → server-SZVS3S42.js} +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -237,6 +237,50 @@ Configuration is stored at `~/.aicli/config.json`. Run `aicli config` for the in
|
|
|
237
237
|
}
|
|
238
238
|
```
|
|
239
239
|
|
|
240
|
+
### Permission Rules
|
|
241
|
+
|
|
242
|
+
Control when tools require confirmation. Rules are checked in order — first match wins:
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"permissionRules": [
|
|
247
|
+
{ "tool": "read_file", "action": "auto-approve" },
|
|
248
|
+
{ "tool": "list_dir", "action": "auto-approve" },
|
|
249
|
+
{ "tool": "grep_files", "action": "auto-approve" },
|
|
250
|
+
{ "tool": "glob_files", "action": "auto-approve" },
|
|
251
|
+
{ "tool": "write_todos", "action": "auto-approve" },
|
|
252
|
+
{ "tool": "bash", "action": "auto-approve", "when": { "dangerLevel": "safe" } },
|
|
253
|
+
{ "tool": "write_file", "action": "auto-approve", "when": { "pathPattern": "src/" } },
|
|
254
|
+
{ "tool": "bash", "action": "deny", "when": { "pathPattern": "rm -rf" } },
|
|
255
|
+
{ "tool": "*", "action": "confirm" }
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
| Field | Description |
|
|
261
|
+
|-------|-------------|
|
|
262
|
+
| `tool` | Tool name, or `*` for all tools |
|
|
263
|
+
| `action` | `auto-approve` (skip confirmation), `deny` (block), `confirm` (ask user) |
|
|
264
|
+
| `when.dangerLevel` | Only match when danger level is `safe`, `write`, or `destructive` |
|
|
265
|
+
| `when.pathPattern` | Substring match against tool's `path` or `command` argument |
|
|
266
|
+
|
|
267
|
+
**Recommended minimal config** — auto-approve all read-only tools to reduce y/N prompts:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"permissionRules": [
|
|
272
|
+
{ "tool": "read_file", "action": "auto-approve" },
|
|
273
|
+
{ "tool": "list_dir", "action": "auto-approve" },
|
|
274
|
+
{ "tool": "grep_files", "action": "auto-approve" },
|
|
275
|
+
{ "tool": "glob_files", "action": "auto-approve" },
|
|
276
|
+
{ "tool": "web_fetch", "action": "auto-approve" },
|
|
277
|
+
{ "tool": "write_todos", "action": "auto-approve" },
|
|
278
|
+
{ "tool": "ask_user", "action": "auto-approve" },
|
|
279
|
+
{ "tool": "run_tests", "action": "auto-approve" }
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
240
284
|
### Environment Variables
|
|
241
285
|
|
|
242
286
|
Environment variables take precedence over config file values:
|
package/README.zh-CN.md
CHANGED
|
@@ -252,6 +252,50 @@ aicli
|
|
|
252
252
|
HTTPS_PROXY=http://127.0.0.1:10809 aicli
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
+
### 权限规则(Permission Rules)
|
|
256
|
+
|
|
257
|
+
控制工具何时需要用户确认。规则按顺序匹配,第一条命中的生效:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"permissionRules": [
|
|
262
|
+
{ "tool": "read_file", "action": "auto-approve" },
|
|
263
|
+
{ "tool": "list_dir", "action": "auto-approve" },
|
|
264
|
+
{ "tool": "grep_files", "action": "auto-approve" },
|
|
265
|
+
{ "tool": "glob_files", "action": "auto-approve" },
|
|
266
|
+
{ "tool": "write_todos", "action": "auto-approve" },
|
|
267
|
+
{ "tool": "bash", "action": "auto-approve", "when": { "dangerLevel": "safe" } },
|
|
268
|
+
{ "tool": "write_file", "action": "auto-approve", "when": { "pathPattern": "src/" } },
|
|
269
|
+
{ "tool": "bash", "action": "deny", "when": { "pathPattern": "rm -rf" } },
|
|
270
|
+
{ "tool": "*", "action": "confirm" }
|
|
271
|
+
]
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
| 字段 | 说明 |
|
|
276
|
+
|------|------|
|
|
277
|
+
| `tool` | 工具名,`*` 匹配所有工具 |
|
|
278
|
+
| `action` | `auto-approve`(跳过确认自动执行)、`deny`(拒绝)、`confirm`(需用户确认) |
|
|
279
|
+
| `when.dangerLevel` | 仅当危险级别为 `safe`、`write` 或 `destructive` 时匹配 |
|
|
280
|
+
| `when.pathPattern` | 子串匹配工具的 `path` 或 `command` 参数 |
|
|
281
|
+
|
|
282
|
+
**推荐配置** — 自动放行所有只读工具,减少 y/N 确认次数:
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"permissionRules": [
|
|
287
|
+
{ "tool": "read_file", "action": "auto-approve" },
|
|
288
|
+
{ "tool": "list_dir", "action": "auto-approve" },
|
|
289
|
+
{ "tool": "grep_files", "action": "auto-approve" },
|
|
290
|
+
{ "tool": "glob_files", "action": "auto-approve" },
|
|
291
|
+
{ "tool": "web_fetch", "action": "auto-approve" },
|
|
292
|
+
{ "tool": "write_todos", "action": "auto-approve" },
|
|
293
|
+
{ "tool": "ask_user", "action": "auto-approve" },
|
|
294
|
+
{ "tool": "run_tests", "action": "auto-approve" }
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
255
299
|
### 环境变量
|
|
256
300
|
|
|
257
301
|
| 变量 | 说明 |
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
theme,
|
|
36
36
|
truncateOutput,
|
|
37
37
|
undoStack
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-64ORNJVC.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-
|
|
58
|
+
} from "./chunk-2VKCVDHP.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-
|
|
1907
|
+
const { executeTests } = await import("./run-tests-7L33QJHM.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
|
|
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 ===
|
|
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-
|
|
5477
|
+
const { startWebServer } = await import("./server-SZVS3S42.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) => {
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
setupProxy,
|
|
24
24
|
spawnAgentContext,
|
|
25
25
|
truncateOutput
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-64ORNJVC.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-
|
|
38
|
+
} from "./chunk-2VKCVDHP.js";
|
|
39
39
|
import {
|
|
40
40
|
AuthManager
|
|
41
41
|
} from "./chunk-CPLT6CD3.js";
|