jinzd-ai-cli 0.4.144 → 0.4.146

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.
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-WPYKTLP2.js";
4
+ } from "./chunk-AQQSYFTU.js";
5
5
  import "./chunk-2ZD3YTVM.js";
6
- import "./chunk-XW4EP5IE.js";
6
+ import "./chunk-EUE7FFIO.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
 
9
9
  // src/cli/batch.ts
@@ -8,7 +8,7 @@ import {
8
8
  CONFIG_FILE_NAME,
9
9
  HISTORY_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-XW4EP5IE.js";
11
+ } from "./chunk-EUE7FFIO.js";
12
12
 
13
13
  // src/config/config-manager.ts
14
14
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CONFIG_DIR_NAME,
4
4
  VERSION
5
- } from "./chunk-XW4EP5IE.js";
5
+ } from "./chunk-EUE7FFIO.js";
6
6
 
7
7
  // src/diagnostics/crash-log.ts
8
8
  import {
@@ -5,12 +5,14 @@ import {
5
5
  } from "./chunk-UQQJWHRV.js";
6
6
  import {
7
7
  runTestsTool
8
- } from "./chunk-2JPLV25X.js";
8
+ } from "./chunk-GB2KTJC2.js";
9
9
  import {
10
- getDangerLevel,
11
- isFileWriteTool,
12
10
  runTool
13
- } from "./chunk-QSGDXXE6.js";
11
+ } from "./chunk-JB7LEZQO.js";
12
+ import {
13
+ getDangerLevel,
14
+ isFileWriteTool
15
+ } from "./chunk-OWPFDHKC.js";
14
16
  import {
15
17
  EnvLoader,
16
18
  NetworkError,
@@ -23,7 +25,7 @@ import {
23
25
  SUBAGENT_ALLOWED_TOOLS,
24
26
  SUBAGENT_DEFAULT_MAX_ROUNDS,
25
27
  SUBAGENT_MAX_ROUNDS_LIMIT
26
- } from "./chunk-XW4EP5IE.js";
28
+ } from "./chunk-EUE7FFIO.js";
27
29
  import {
28
30
  fileCheckpoints
29
31
  } from "./chunk-4BKXL7SM.js";
@@ -418,6 +420,11 @@ function buildErrorHint(command, stderr) {
418
420
  `Hint: On Windows, "Remove-Item ... -ErrorAction SilentlyContinue" still makes the powershell process exit 1 when no files match (even though the error is silenced). Use Test-Path as a guard: @('tmp_a.sql','tmp_b.sql','tmp_c.csv') | Where-Object { Test-Path $_ } | Remove-Item -Force \u2014 Test-Path returns a bool without raising, so missing paths are filtered out and exit code is 0.`
419
421
  );
420
422
  }
423
+ if (IS_WINDOWS && /-(?:EA|ErrorAction)\s+(?:SilentlyContinue|Ignore)\b/i.test(command) && /\b(Get-ChildItem|Get-Item|Get-Content|gci|gi|gc|dir|ls)\b/i.test(command) && !/Remove-Item/i.test(command) && !/Test-Path/i.test(command) && /cannot find path|no such file|does not exist|exit 1|不存在|找不到/i.test(stderr || command)) {
424
+ hints.push(
425
+ `Hint: On Windows, "-ErrorAction SilentlyContinue" silences the error MESSAGE but does NOT change the exit code \u2014 the process still exits 1 when the path doesn't exist (because powershell.exe -NonInteractive flips the exit code on any non-terminating error, silenced or not). If you're just probing for existence, use Test-Path instead \u2014 it returns $true/$false without raising: \`if (Test-Path ./mydir) { Get-ChildItem ./mydir }\` or unconditionally use \`New-Item -ItemType Directory -Force -Path ./mydir\` which is idempotent. Don't retry the same -ErrorAction SilentlyContinue probe expecting a different result.`
426
+ );
427
+ }
421
428
  const colMissing = stderr.match(/column "([^"]+)" does not exist/i);
422
429
  if (colMissing) {
423
430
  hints.push(
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.144";
4
+ var VERSION = "0.4.146";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-XW4EP5IE.js";
4
+ } from "./chunk-EUE7FFIO.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync, spawnSync } from "child_process";
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/review-prompts.ts
4
+ function buildReviewPrompt(diff, gitContextStr, detailed) {
5
+ const level = detailed ? "Please perform a detailed in-depth review covering: security, performance, maintainability, error handling, naming conventions, and code duplication." : "Please perform a concise code review focusing on bugs, security issues, and key improvement suggestions.";
6
+ return `# Code Review Request
7
+
8
+ ${level}
9
+
10
+ ## Git Status
11
+ ${gitContextStr}
12
+
13
+ ## Code Changes (diff)
14
+ \`\`\`diff
15
+ ${diff}
16
+ \`\`\`
17
+
18
+ ## Output Format
19
+ Please structure your review as follows:
20
+ 1. **Overall Assessment**: One-sentence summary of the change quality
21
+ 2. **Issues** (if any): Each issue with [Severity] file:line \u2014 description + suggested fix
22
+ 3. **Improvement Suggestions** (if any): Non-critical but recommended optimizations
23
+ 4. **Highlights** (if any): Good practices worth acknowledging
24
+
25
+ Severity levels: \u{1F534} Critical / \u{1F7E1} Warning / \u{1F535} Info`;
26
+ }
27
+ function buildSecurityReviewPrompt(diff, gitContextStr) {
28
+ return `# Security Vulnerability Review
29
+
30
+ Analyze the following code changes **exclusively for security vulnerabilities**.
31
+
32
+ ## Categories to check:
33
+ 1. **Injection** \u2014 SQL, command, path traversal, XSS, template injection
34
+ 2. **Authentication & Authorization** \u2014 hardcoded credentials, missing auth checks, privilege escalation
35
+ 3. **Secrets & Sensitive Data** \u2014 API keys, tokens, passwords in code, logging sensitive data
36
+ 4. **Input Validation** \u2014 missing validation, unsafe deserialization, buffer issues
37
+ 5. **Cryptography** \u2014 weak algorithms, improper random, hardcoded IVs/salts
38
+ 6. **Dependencies** \u2014 known vulnerable packages, unsafe dynamic imports
39
+ 7. **File System** \u2014 path traversal, unsafe file permissions, symlink attacks
40
+ 8. **Network** \u2014 SSRF, insecure protocols, missing TLS validation
41
+
42
+ ## Git Status
43
+ ${gitContextStr}
44
+
45
+ ## Code Changes (diff)
46
+ \`\`\`diff
47
+ ${diff}
48
+ \`\`\`
49
+
50
+ ## Output Format
51
+ For each finding:
52
+ - **Severity**: \u{1F534} CRITICAL / \u{1F7E0} HIGH / \u{1F7E1} MEDIUM / \u{1F535} LOW / \u2139\uFE0F INFO
53
+ - **Category**: (from list above)
54
+ - **File & location**: file:line
55
+ - **Description**: what the vulnerability is and how it could be exploited
56
+ - **Recommended fix**: specific code change to resolve
57
+
58
+ If no security issues found, state "\u2705 No security vulnerabilities detected" with a brief explanation of what was checked.`;
59
+ }
60
+ function truncateDiff(diff, maxChars) {
61
+ if (diff.length <= maxChars) return { diff, truncated: false };
62
+ const head = diff.slice(0, Math.floor(maxChars * 0.7));
63
+ const tail = diff.slice(diff.length - Math.floor(maxChars * 0.2));
64
+ return {
65
+ diff: head + "\n\n... [diff truncated, " + diff.length + " chars total] ...\n\n" + tail,
66
+ truncated: true
67
+ };
68
+ }
69
+
70
+ export {
71
+ buildReviewPrompt,
72
+ buildSecurityReviewPrompt,
73
+ truncateDiff
74
+ };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CONFIG_DIR_NAME
4
- } from "./chunk-XW4EP5IE.js";
4
+ } from "./chunk-EUE7FFIO.js";
5
5
 
6
6
  // src/diagnostics/tool-stats.ts
7
7
  import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from "fs";
@@ -118,69 +118,11 @@ function installFlushOnExit() {
118
118
  process.on("exit", () => flush());
119
119
  }
120
120
 
121
- // src/tools/types.ts
122
- function isFileWriteTool(name) {
123
- return name === "write_file" || name === "edit_file" || name === "notebook_edit";
124
- }
125
- function getDangerLevel(toolName, args) {
126
- if (toolName.startsWith("mcp__")) return "safe";
127
- if (toolName === "bash") {
128
- const cmd = String(args["command"] ?? "");
129
- if (/\brm\s+[^\n]*(?:-\w*[rRfF]\w*|--recursive|--force)\b/.test(cmd)) return "destructive";
130
- if (/\brm\s+\S/.test(cmd)) return "destructive";
131
- if (/\brmdir\b|\bformat\b|\bmkfs\b|\bdd\s+if=|\bshred\b|\bfdisk\b|\bparted\b/.test(cmd)) return "destructive";
132
- if (/\bshutdown\b|\breboot\b|\bhalt\b|\bpoweroff\b/.test(cmd)) return "destructive";
133
- if (/\bkill\s+-9\b|\bkillall\b/.test(cmd)) return "destructive";
134
- if (/\bRemove-Item\b|\bri\s+\S/i.test(cmd)) return "destructive";
135
- if (/\brd\s+\/s\b|\brmdir\s+\/s\b/i.test(cmd)) return "destructive";
136
- if (/\bdel\s+\S/.test(cmd)) return "destructive";
137
- if (/\bShutdown(-Computer)?\b|\bRestart-Computer\b/i.test(cmd)) return "destructive";
138
- if (/(?:^|[\s|;&])>>?\s*\S/.test(cmd)) return "write";
139
- if (/\btee\b|\bcp\b|\bmv\b|\bln\s+-s/.test(cmd)) return "write";
140
- if (/\bchmod\b|\bchown\b/.test(cmd)) return "write";
141
- if (/\bSet-Content\b|\bOut-File\b|\bAdd-Content\b|\bCopy-Item\b|\bMove-Item\b|\bSet-ItemProperty\b|\bNew-ItemProperty\b/i.test(cmd)) return "write";
142
- return "safe";
143
- }
144
- if (toolName === "write_file") return "write";
145
- if (toolName === "edit_file") return "write";
146
- if (toolName === "save_last_response") return "write";
147
- if (toolName === "run_interactive") {
148
- const exe = String(args["executable"] ?? "").toLowerCase();
149
- if (/\b(rm|rmdir|del|format|mkfs|Remove-Item)\b/i.test(exe)) return "destructive";
150
- if (/\b(bash|sh|zsh|cmd|powershell|pwsh|python|node|ruby|perl)\b/i.test(exe)) return "write";
151
- return "write";
152
- }
153
- if (toolName === "task_create" || toolName === "task_stop") return "write";
154
- if (toolName === "task_list") return "safe";
155
- if (toolName === "git_commit") return "write";
156
- if (toolName === "git_status" || toolName === "git_diff" || toolName === "git_log") return "safe";
157
- if (toolName === "notebook_edit") return "write";
158
- if (toolName === "read_file" || toolName === "list_dir" || toolName === "grep_files" || toolName === "glob_files" || toolName === "web_fetch" || toolName === "save_memory" || toolName === "ask_user" || toolName === "write_todos" || toolName === "google_search" || toolName === "spawn_agent" || toolName === "run_tests") return "safe";
159
- return "write";
160
- }
161
- function schemaToJsonSchema(schema) {
162
- const result = {
163
- type: schema.type,
164
- description: schema.description
165
- };
166
- if (schema.enum) result["enum"] = schema.enum;
167
- if (schema.items) result["items"] = schemaToJsonSchema(schema.items);
168
- if (schema.properties) {
169
- result["properties"] = Object.fromEntries(
170
- Object.entries(schema.properties).map(([k, v]) => [k, schemaToJsonSchema(v)])
171
- );
172
- }
173
- return result;
174
- }
175
-
176
121
  export {
177
122
  runTool,
178
123
  getStatsSnapshot,
179
124
  getTopFailingTools,
180
125
  getTopUsedTools,
181
126
  resetStats,
182
- installFlushOnExit,
183
- isFileWriteTool,
184
- getDangerLevel,
185
- schemaToJsonSchema
127
+ installFlushOnExit
186
128
  };
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/tools/types.ts
4
+ function isFileWriteTool(name) {
5
+ return name === "write_file" || name === "edit_file" || name === "notebook_edit";
6
+ }
7
+ function getDangerLevel(toolName, args) {
8
+ if (toolName.startsWith("mcp__")) return "safe";
9
+ if (toolName === "bash") {
10
+ const cmd = String(args["command"] ?? "");
11
+ if (/\brm\s+[^\n]*(?:-\w*[rRfF]\w*|--recursive|--force)\b/.test(cmd)) return "destructive";
12
+ if (/\brm\s+\S/.test(cmd)) return "destructive";
13
+ if (/\brmdir\b|\bformat\b|\bmkfs\b|\bdd\s+if=|\bshred\b|\bfdisk\b|\bparted\b/.test(cmd)) return "destructive";
14
+ if (/\bshutdown\b|\breboot\b|\bhalt\b|\bpoweroff\b/.test(cmd)) return "destructive";
15
+ if (/\bkill\s+-9\b|\bkillall\b/.test(cmd)) return "destructive";
16
+ if (/\bRemove-Item\b|\bri\s+\S/i.test(cmd)) return "destructive";
17
+ if (/\brd\s+\/s\b|\brmdir\s+\/s\b/i.test(cmd)) return "destructive";
18
+ if (/\bdel\s+\S/.test(cmd)) return "destructive";
19
+ if (/\bShutdown(-Computer)?\b|\bRestart-Computer\b/i.test(cmd)) return "destructive";
20
+ if (/(?:^|[\s|;&])>>?\s*\S/.test(cmd)) return "write";
21
+ if (/\btee\b|\bcp\b|\bmv\b|\bln\s+-s/.test(cmd)) return "write";
22
+ if (/\bchmod\b|\bchown\b/.test(cmd)) return "write";
23
+ if (/\bSet-Content\b|\bOut-File\b|\bAdd-Content\b|\bCopy-Item\b|\bMove-Item\b|\bSet-ItemProperty\b|\bNew-ItemProperty\b/i.test(cmd)) return "write";
24
+ return "safe";
25
+ }
26
+ if (toolName === "write_file") return "write";
27
+ if (toolName === "edit_file") return "write";
28
+ if (toolName === "save_last_response") return "write";
29
+ if (toolName === "run_interactive") {
30
+ const exe = String(args["executable"] ?? "").toLowerCase();
31
+ if (/\b(rm|rmdir|del|format|mkfs|Remove-Item)\b/i.test(exe)) return "destructive";
32
+ if (/\b(bash|sh|zsh|cmd|powershell|pwsh|python|node|ruby|perl)\b/i.test(exe)) return "write";
33
+ return "write";
34
+ }
35
+ if (toolName === "task_create" || toolName === "task_stop") return "write";
36
+ if (toolName === "task_list") return "safe";
37
+ if (toolName === "git_commit") return "write";
38
+ if (toolName === "git_status" || toolName === "git_diff" || toolName === "git_log") return "safe";
39
+ if (toolName === "notebook_edit") return "write";
40
+ if (toolName === "read_file" || toolName === "list_dir" || toolName === "grep_files" || toolName === "glob_files" || toolName === "web_fetch" || toolName === "save_memory" || toolName === "ask_user" || toolName === "write_todos" || toolName === "google_search" || toolName === "spawn_agent" || toolName === "run_tests") return "safe";
41
+ return "write";
42
+ }
43
+ function schemaToJsonSchema(schema) {
44
+ const result = {
45
+ type: schema.type,
46
+ description: schema.description
47
+ };
48
+ if (schema.enum) result["enum"] = schema.enum;
49
+ if (schema.items) result["items"] = schemaToJsonSchema(schema.items);
50
+ if (schema.properties) {
51
+ result["properties"] = Object.fromEntries(
52
+ Object.entries(schema.properties).map(([k, v]) => [k, schemaToJsonSchema(v)])
53
+ );
54
+ }
55
+ return result;
56
+ }
57
+
58
+ export {
59
+ isFileWriteTool,
60
+ getDangerLevel,
61
+ schemaToJsonSchema
62
+ };
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.144";
9
+ var VERSION = "0.4.146";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-PWCPOHZ4.js";
4
+ } from "./chunk-BOQ4YWRM.js";
5
5
  import {
6
6
  APP_NAME,
7
7
  CONFIG_DIR_NAME,
@@ -11,7 +11,7 @@ import {
11
11
  MCP_PROTOCOL_VERSION,
12
12
  MCP_TOOL_PREFIX,
13
13
  VERSION
14
- } from "./chunk-XW4EP5IE.js";
14
+ } from "./chunk-EUE7FFIO.js";
15
15
  import {
16
16
  redactJson
17
17
  } from "./chunk-7ZJN4KLV.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  schemaToJsonSchema
4
- } from "./chunk-QSGDXXE6.js";
4
+ } from "./chunk-OWPFDHKC.js";
5
5
  import {
6
6
  AuthError,
7
7
  ProviderError,
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ buildReviewPrompt,
4
+ buildSecurityReviewPrompt,
5
+ truncateDiff
6
+ } from "./chunk-HLWUDRBO.js";
7
+ import {
8
+ ProviderRegistry
9
+ } from "./chunk-XZBA3NHG.js";
10
+ import {
11
+ ConfigManager
12
+ } from "./chunk-AQQSYFTU.js";
13
+ import "./chunk-OWPFDHKC.js";
14
+ import "./chunk-2ZD3YTVM.js";
15
+ import {
16
+ VERSION
17
+ } from "./chunk-EUE7FFIO.js";
18
+ import "./chunk-PDX44BCA.js";
19
+
20
+ // src/cli/ci.ts
21
+ import { execFileSync, execSync } from "child_process";
22
+ var CI_COMMENT_MARKER = "<!-- aicli-ci-review -->";
23
+ function fetchDiff(opts) {
24
+ if (opts.diffOverride != null) return opts.diffOverride;
25
+ if (opts.pr != null) {
26
+ try {
27
+ return execFileSync("gh", ["pr", "diff", String(opts.pr)], {
28
+ encoding: "utf-8",
29
+ maxBuffer: 50 * 1024 * 1024
30
+ });
31
+ } catch (err) {
32
+ const msg = err.stderr?.toString() ?? err.message;
33
+ throw new Error(`gh pr diff ${opts.pr} failed: ${msg.trim()}`);
34
+ }
35
+ }
36
+ if (opts.base) {
37
+ try {
38
+ return execSync(`git diff ${shellQuote(opts.base)}...HEAD`, {
39
+ encoding: "utf-8",
40
+ maxBuffer: 50 * 1024 * 1024,
41
+ timeout: 3e4
42
+ });
43
+ } catch (err) {
44
+ throw new Error(`git diff ${opts.base}...HEAD failed: ${err.message}`);
45
+ }
46
+ }
47
+ throw new Error("aicli ci: must supply --pr <num> or --base <ref> to determine the diff source");
48
+ }
49
+ function shellQuote(ref) {
50
+ if (!/^[A-Za-z0-9._/\-]+$/.test(ref)) {
51
+ throw new Error(`unsafe ref: ${ref}`);
52
+ }
53
+ return ref;
54
+ }
55
+ function buildGitContextStr(opts) {
56
+ const parts = [];
57
+ if (opts.pr != null) parts.push(`PR: #${opts.pr}`);
58
+ if (opts.base) parts.push(`Base: ${opts.base}`);
59
+ try {
60
+ const branch = execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8", timeout: 5e3 }).trim();
61
+ if (branch) parts.push(`Branch: ${branch}`);
62
+ } catch {
63
+ }
64
+ parts.push(`Reviewer: aicli v${VERSION}`);
65
+ return parts.join(" | ");
66
+ }
67
+ function countSeverity(md) {
68
+ const count = (re) => (md.match(re) ?? []).length;
69
+ return {
70
+ critical: count(/🔴\s*(?:CRITICAL|Critical|critical)/g),
71
+ high: count(/🟠\s*(?:HIGH|High|high)/g),
72
+ warning: count(/🟡\s*(?:WARNING|Warning|warning|MEDIUM|Medium|medium)/g),
73
+ info: count(/🔵\s*(?:INFO|Info|info|LOW|Low|low)/g)
74
+ };
75
+ }
76
+ async function runOnePrompt(registry, providerId, modelId, prompt) {
77
+ const provider = registry.get(providerId);
78
+ const resp = await provider.chat({
79
+ messages: [{ role: "user", content: prompt }],
80
+ model: modelId,
81
+ stream: false,
82
+ temperature: 0.3,
83
+ maxTokens: 8192
84
+ });
85
+ return resp.content?.trim() ?? "";
86
+ }
87
+ function postOrUpdatePrComment(prNumber, body, update) {
88
+ const fullBody = `${body}
89
+
90
+ ${CI_COMMENT_MARKER}`;
91
+ if (update) {
92
+ let comments = [];
93
+ try {
94
+ const out = execFileSync("gh", ["pr", "view", String(prNumber), "--json", "comments"], {
95
+ encoding: "utf-8",
96
+ maxBuffer: 20 * 1024 * 1024
97
+ });
98
+ const parsed = JSON.parse(out);
99
+ comments = parsed.comments ?? [];
100
+ } catch {
101
+ }
102
+ const existing = comments.find((c) => c.body.includes(CI_COMMENT_MARKER));
103
+ if (existing) {
104
+ execFileSync(
105
+ "gh",
106
+ ["api", "--method", "PATCH", `repos/{owner}/{repo}/issues/comments/${gqlIdToRest(existing.id)}`, "-f", `body=${fullBody}`],
107
+ { stdio: "pipe" }
108
+ );
109
+ return { updated: true, id: existing.id };
110
+ }
111
+ }
112
+ execFileSync("gh", ["pr", "comment", String(prNumber), "--body-file", "-"], {
113
+ input: fullBody,
114
+ stdio: ["pipe", "pipe", "pipe"]
115
+ });
116
+ return { updated: false };
117
+ }
118
+ function gqlIdToRest(graphqlId) {
119
+ if (/^\d+$/.test(graphqlId)) return graphqlId;
120
+ const query = `query($id:ID!){ node(id:$id){ ... on IssueComment { databaseId } } }`;
121
+ const out = execFileSync("gh", ["api", "graphql", "-f", `query=${query}`, "-F", `id=${graphqlId}`], {
122
+ encoding: "utf-8"
123
+ });
124
+ const parsed = JSON.parse(out);
125
+ const id = parsed.data?.node?.databaseId;
126
+ if (!id) throw new Error(`could not resolve comment id ${graphqlId}`);
127
+ return String(id);
128
+ }
129
+ async function runCi(opts) {
130
+ const maxDiff = opts.maxDiffChars ?? 3e4;
131
+ let diff;
132
+ try {
133
+ diff = fetchDiff(opts).trim();
134
+ } catch (err) {
135
+ return {
136
+ exitCode: 2,
137
+ markdown: `\u274C ${err.message}`,
138
+ posted: false,
139
+ severity: { critical: 0, high: 0, warning: 0, info: 0 }
140
+ };
141
+ }
142
+ if (!diff) {
143
+ return {
144
+ exitCode: 0,
145
+ markdown: "\u2705 No changes to review.",
146
+ posted: false,
147
+ severity: { critical: 0, high: 0, warning: 0, info: 0 }
148
+ };
149
+ }
150
+ const { diff: trimmedDiff, truncated } = truncateDiff(diff, maxDiff);
151
+ const gitCtx = buildGitContextStr(opts);
152
+ const config = new ConfigManager();
153
+ await config.load();
154
+ const registry = new ProviderRegistry(config);
155
+ await registry.initialize();
156
+ const providerId = opts.provider ?? config.getDefaultProvider();
157
+ if (!registry.has(providerId)) {
158
+ return {
159
+ exitCode: 2,
160
+ markdown: `\u274C Provider '${providerId}' is not configured. Set the right AICLI_API_KEY_* env var or pass --provider.`,
161
+ posted: false,
162
+ severity: { critical: 0, high: 0, warning: 0, info: 0 }
163
+ };
164
+ }
165
+ const providerInfo = registry.get(providerId).info;
166
+ const modelId = opts.model ?? config.get("defaultModels")[providerId] ?? providerInfo.defaultModel;
167
+ const sections = [];
168
+ sections.push(`## \u{1F916} aicli code review`);
169
+ sections.push(`*Provider: \`${providerId}\` \xB7 Model: \`${modelId}\` \xB7 aicli v${VERSION}*`);
170
+ sections.push("");
171
+ try {
172
+ if (!opts.skipCode) {
173
+ const prompt = buildReviewPrompt(trimmedDiff, gitCtx, !!opts.detailed);
174
+ const review = await runOnePrompt(registry, providerId, modelId, prompt);
175
+ sections.push("### Code Review");
176
+ sections.push(review);
177
+ sections.push("");
178
+ }
179
+ if (!opts.skipSecurity) {
180
+ const prompt = buildSecurityReviewPrompt(trimmedDiff, gitCtx);
181
+ const review = await runOnePrompt(registry, providerId, modelId, prompt);
182
+ sections.push("### Security Review");
183
+ sections.push(review);
184
+ sections.push("");
185
+ }
186
+ } catch (err) {
187
+ return {
188
+ exitCode: 2,
189
+ markdown: `\u274C Review call failed: ${err.message}`,
190
+ posted: false,
191
+ severity: { critical: 0, high: 0, warning: 0, info: 0 }
192
+ };
193
+ }
194
+ if (truncated) {
195
+ sections.push(`> \u26A0 Diff was truncated to ${maxDiff} chars (original: ${diff.length}). Consider splitting large PRs.`);
196
+ }
197
+ const markdown = sections.join("\n");
198
+ const severity = countSeverity(markdown);
199
+ let posted = false;
200
+ let updatedCommentId;
201
+ if (opts.post && opts.pr != null && !opts.dryRun) {
202
+ try {
203
+ const result = postOrUpdatePrComment(opts.pr, markdown, opts.update !== false);
204
+ posted = true;
205
+ updatedCommentId = result.id;
206
+ } catch (err) {
207
+ return {
208
+ exitCode: 2,
209
+ markdown: `${markdown}
210
+
211
+ ---
212
+
213
+ \u274C Failed to post comment: ${err.message}`,
214
+ posted: false,
215
+ severity
216
+ };
217
+ }
218
+ }
219
+ const hasBlocker = severity.critical > 0 || severity.high > 0;
220
+ return {
221
+ exitCode: hasBlocker ? 1 : 0,
222
+ markdown,
223
+ posted,
224
+ updatedCommentId,
225
+ severity
226
+ };
227
+ }
228
+ export {
229
+ CI_COMMENT_MARKER,
230
+ countSeverity,
231
+ runCi
232
+ };
@@ -36,7 +36,7 @@ import {
36
36
  TEST_TIMEOUT,
37
37
  VERSION,
38
38
  buildUserIdentityPrompt
39
- } from "./chunk-XW4EP5IE.js";
39
+ } from "./chunk-EUE7FFIO.js";
40
40
  import "./chunk-PDX44BCA.js";
41
41
  export {
42
42
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -2,25 +2,26 @@
2
2
  import {
3
3
  getConfigDirUsage,
4
4
  listRecentCrashes
5
- } from "./chunk-HUILGJNB.js";
5
+ } from "./chunk-AWRXHBW2.js";
6
6
  import {
7
7
  ProviderRegistry
8
- } from "./chunk-EHLHWFZP.js";
8
+ } from "./chunk-XZBA3NHG.js";
9
9
  import {
10
10
  ConfigManager
11
- } from "./chunk-WPYKTLP2.js";
11
+ } from "./chunk-AQQSYFTU.js";
12
12
  import {
13
13
  getStatsSnapshot,
14
14
  getTopFailingTools,
15
15
  getTopUsedTools,
16
16
  resetStats
17
- } from "./chunk-QSGDXXE6.js";
17
+ } from "./chunk-JB7LEZQO.js";
18
+ import "./chunk-OWPFDHKC.js";
18
19
  import "./chunk-2ZD3YTVM.js";
19
20
  import {
20
21
  DEV_STATE_FILE_NAME,
21
22
  MEMORY_FILE_NAME,
22
23
  VERSION
23
- } from "./chunk-XW4EP5IE.js";
24
+ } from "./chunk-EUE7FFIO.js";
24
25
  import "./chunk-PDX44BCA.js";
25
26
 
26
27
  // src/diagnostics/doctor-cli.ts
@@ -36,7 +36,7 @@ import {
36
36
  VERSION,
37
37
  buildUserIdentityPrompt,
38
38
  runTestsTool
39
- } from "./chunk-YGGW2D2V.js";
39
+ } from "./chunk-QJWZ5G64.js";
40
40
  import {
41
41
  hasSemanticIndex,
42
42
  semanticSearch
@@ -4121,6 +4121,11 @@ function buildErrorHint(command, stderr) {
4121
4121
  `Hint: On Windows, "Remove-Item ... -ErrorAction SilentlyContinue" still makes the powershell process exit 1 when no files match (even though the error is silenced). Use Test-Path as a guard: @('tmp_a.sql','tmp_b.sql','tmp_c.csv') | Where-Object { Test-Path $_ } | Remove-Item -Force \u2014 Test-Path returns a bool without raising, so missing paths are filtered out and exit code is 0.`
4122
4122
  );
4123
4123
  }
4124
+ if (IS_WINDOWS && /-(?:EA|ErrorAction)\s+(?:SilentlyContinue|Ignore)\b/i.test(command) && /\b(Get-ChildItem|Get-Item|Get-Content|gci|gi|gc|dir|ls)\b/i.test(command) && !/Remove-Item/i.test(command) && !/Test-Path/i.test(command) && /cannot find path|no such file|does not exist|exit 1|不存在|找不到/i.test(stderr || command)) {
4125
+ hints.push(
4126
+ `Hint: On Windows, "-ErrorAction SilentlyContinue" silences the error MESSAGE but does NOT change the exit code \u2014 the process still exits 1 when the path doesn't exist (because powershell.exe -NonInteractive flips the exit code on any non-terminating error, silenced or not). If you're just probing for existence, use Test-Path instead \u2014 it returns $true/$false without raising: \`if (Test-Path ./mydir) { Get-ChildItem ./mydir }\` or unconditionally use \`New-Item -ItemType Directory -Force -Path ./mydir\` which is idempotent. Don't retry the same -ErrorAction SilentlyContinue probe expecting a different result.`
4127
+ );
4128
+ }
4124
4129
  const colMissing = stderr.match(/column "([^"]+)" does not exist/i);
4125
4130
  if (colMissing) {
4126
4131
  hints.push(
@@ -12568,7 +12573,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
12568
12573
  case "test": {
12569
12574
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
12570
12575
  try {
12571
- const { executeTests } = await import("./run-tests-SUYREW3B.js");
12576
+ const { executeTests } = await import("./run-tests-OP6HUEBM.js");
12572
12577
  const argStr = args.join(" ").trim();
12573
12578
  let testArgs = {};
12574
12579
  if (argStr) {
@@ -386,7 +386,7 @@ ${content}`);
386
386
  }
387
387
  }
388
388
  async function runTaskMode(config, providers, configManager, topic) {
389
- const { TaskOrchestrator } = await import("./task-orchestrator-R6VOCA4V.js");
389
+ const { TaskOrchestrator } = await import("./task-orchestrator-JWQJJY3H.js");
390
390
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
391
391
  let interrupted = false;
392
392
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ buildReviewPrompt,
4
+ buildSecurityReviewPrompt
5
+ } from "./chunk-HLWUDRBO.js";
2
6
  import {
3
7
  McpManager,
4
8
  SNAPSHOT_PROMPT,
@@ -16,12 +20,12 @@ import {
16
20
  saveDevState,
17
21
  sessionHasMeaningfulContent,
18
22
  setupProxy
19
- } from "./chunk-IGZVCNGE.js";
23
+ } from "./chunk-RJYVWTHV.js";
20
24
  import {
21
25
  getConfigDirUsage,
22
26
  listRecentCrashes,
23
27
  writeCrashLog
24
- } from "./chunk-HUILGJNB.js";
28
+ } from "./chunk-AWRXHBW2.js";
25
29
  import {
26
30
  CONTENT_ONLY_STREAM_REMINDER,
27
31
  HALLUCINATION_CORRECTION_MESSAGE,
@@ -39,10 +43,10 @@ import {
39
43
  looksLikeDocumentBody,
40
44
  stripPseudoToolCalls,
41
45
  stripToolCallReminder
42
- } from "./chunk-EHLHWFZP.js";
46
+ } from "./chunk-XZBA3NHG.js";
43
47
  import {
44
48
  ConfigManager
45
- } from "./chunk-WPYKTLP2.js";
49
+ } from "./chunk-AQQSYFTU.js";
46
50
  import {
47
51
  ToolExecutor,
48
52
  ToolRegistry,
@@ -61,16 +65,17 @@ import {
61
65
  spawnAgentContext,
62
66
  theme,
63
67
  undoStack
64
- } from "./chunk-PWCPOHZ4.js";
68
+ } from "./chunk-BOQ4YWRM.js";
65
69
  import "./chunk-UQQJWHRV.js";
66
70
  import "./chunk-2DXY7UGF.js";
67
- import "./chunk-2JPLV25X.js";
71
+ import "./chunk-GB2KTJC2.js";
68
72
  import {
69
73
  getStatsSnapshot,
70
74
  getTopFailingTools,
71
75
  getTopUsedTools,
72
76
  installFlushOnExit
73
- } from "./chunk-QSGDXXE6.js";
77
+ } from "./chunk-JB7LEZQO.js";
78
+ import "./chunk-OWPFDHKC.js";
74
79
  import {
75
80
  AuthError,
76
81
  ProviderError,
@@ -97,7 +102,7 @@ import {
97
102
  SKILLS_DIR_NAME,
98
103
  VERSION,
99
104
  buildUserIdentityPrompt
100
- } from "./chunk-XW4EP5IE.js";
105
+ } from "./chunk-EUE7FFIO.js";
101
106
  import {
102
107
  formatGitContextForPrompt,
103
108
  getGitContext,
@@ -449,6 +454,7 @@ var Renderer = class {
449
454
  console.log(feat("save_last_response Web mode (v0.4.101\u20130.4.102+): hidden from CLI-only contexts and tee-streams chunks to disk in Web UI as the response arrives"));
450
455
  console.log(feat("write_file long-content guidance (v0.4.103+): tool description no longer encourages AI to chunk long files \u2014 single-shot writes prevented from being split into truncated parts"));
451
456
  console.log(feat("Provider retry + fallback chain (v0.4.144+): transient network / 5xx / 429 errors retry on the same provider with exponential backoff; persistent failures walk config.fallback.chain (per-entry provider+model). Opt-in via config.fallback.enabled. Stream-safe: never retries after first chunk yielded"));
457
+ console.log(feat("aicli ci \u2014 headless PR review for GitHub Actions (v0.4.145+): `aicli ci --pr <num> --post` reads diff via gh CLI, runs code + security review, posts/updates a single PR comment via sentinel marker. Drop-in workflow YAML at docs/github-actions-example.yml. Critical/high findings \u2192 exit 1 (CI gate)"));
452
458
  console.log();
453
459
  }
454
460
  printPrompt(provider, _model) {
@@ -993,62 +999,6 @@ function copyToClipboard(text) {
993
999
  }
994
1000
  }
995
1001
  }
996
- function buildReviewPrompt(diff, gitContextStr, detailed) {
997
- const level = detailed ? "Please perform a detailed in-depth review covering: security, performance, maintainability, error handling, naming conventions, and code duplication." : "Please perform a concise code review focusing on bugs, security issues, and key improvement suggestions.";
998
- return `# Code Review Request
999
-
1000
- ${level}
1001
-
1002
- ## Git Status
1003
- ${gitContextStr}
1004
-
1005
- ## Code Changes (diff)
1006
- \`\`\`diff
1007
- ${diff}
1008
- \`\`\`
1009
-
1010
- ## Output Format
1011
- Please structure your review as follows:
1012
- 1. **Overall Assessment**: One-sentence summary of the change quality
1013
- 2. **Issues** (if any): Each issue with [Severity] file:line \u2014 description + suggested fix
1014
- 3. **Improvement Suggestions** (if any): Non-critical but recommended optimizations
1015
- 4. **Highlights** (if any): Good practices worth acknowledging
1016
-
1017
- Severity levels: \u{1F534} Critical / \u{1F7E1} Warning / \u{1F535} Info`;
1018
- }
1019
- function buildSecurityReviewPrompt(diff, gitContextStr) {
1020
- return `# Security Vulnerability Review
1021
-
1022
- Analyze the following code changes **exclusively for security vulnerabilities**.
1023
-
1024
- ## Categories to check:
1025
- 1. **Injection** \u2014 SQL, command, path traversal, XSS, template injection
1026
- 2. **Authentication & Authorization** \u2014 hardcoded credentials, missing auth checks, privilege escalation
1027
- 3. **Secrets & Sensitive Data** \u2014 API keys, tokens, passwords in code, logging sensitive data
1028
- 4. **Input Validation** \u2014 missing validation, unsafe deserialization, buffer issues
1029
- 5. **Cryptography** \u2014 weak algorithms, improper random, hardcoded IVs/salts
1030
- 6. **Dependencies** \u2014 known vulnerable packages, unsafe dynamic imports
1031
- 7. **File System** \u2014 path traversal, unsafe file permissions, symlink attacks
1032
- 8. **Network** \u2014 SSRF, insecure protocols, missing TLS validation
1033
-
1034
- ## Git Status
1035
- ${gitContextStr}
1036
-
1037
- ## Code Changes (diff)
1038
- \`\`\`diff
1039
- ${diff}
1040
- \`\`\`
1041
-
1042
- ## Output Format
1043
- For each finding:
1044
- - **Severity**: \u{1F534} CRITICAL / \u{1F7E0} HIGH / \u{1F7E1} MEDIUM / \u{1F535} LOW / \u2139\uFE0F INFO
1045
- - **Category**: (from list above)
1046
- - **File & location**: file:line
1047
- - **Description**: what the vulnerability is and how it could be exploited
1048
- - **Recommended fix**: specific code change to resolve
1049
-
1050
- If no security issues found, state "\u2705 No security vulnerabilities detected" with a brief explanation of what was checked.`;
1051
- }
1052
1002
  var CommandRegistry = class {
1053
1003
  commands = /* @__PURE__ */ new Map();
1054
1004
  register(command) {
@@ -1819,7 +1769,7 @@ No tools match "${filter}".
1819
1769
  const { join: join6 } = await import("path");
1820
1770
  const { existsSync: existsSync6 } = await import("fs");
1821
1771
  const { getGitRoot: getGitRoot2 } = await import("./git-context-7KIP4X2V.js");
1822
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-7Q5DB2X6.js");
1772
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-3VNPPLEQ.js");
1823
1773
  const { approveProject, hashMcpFile } = await import("./project-trust-IFM7FXEV.js");
1824
1774
  const cwd = process.cwd();
1825
1775
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2880,7 +2830,7 @@ ${hint}` : "")
2880
2830
  usage: "/test [command|filter]",
2881
2831
  async execute(args, ctx) {
2882
2832
  try {
2883
- const { executeTests } = await import("./run-tests-X4YQXIGP.js");
2833
+ const { executeTests } = await import("./run-tests-D4ZQ7NLP.js");
2884
2834
  const argStr = args.join(" ").trim();
2885
2835
  let testArgs = {};
2886
2836
  if (argStr) {
@@ -7580,7 +7530,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7580
7530
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7581
7531
  process.exit(1);
7582
7532
  }
7583
- const { startWebServer } = await import("./server-X24SIKZE.js");
7533
+ const { startWebServer } = await import("./server-KJJEI67Z.js");
7584
7534
  await startWebServer({ port, host: options.host });
7585
7535
  });
7586
7536
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
@@ -7747,12 +7697,12 @@ program.command("sessions").description("List recent conversation sessions").opt
7747
7697
  console.log(footer + "\n");
7748
7698
  });
7749
7699
  program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
7750
- const { runDoctorCli } = await import("./doctor-cli-RHGMQVCU.js");
7700
+ const { runDoctorCli } = await import("./doctor-cli-HVLJGWSO.js");
7751
7701
  await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
7752
7702
  });
7753
7703
  program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
7754
7704
  try {
7755
- const batch = await import("./batch-64YESATH.js");
7705
+ const batch = await import("./batch-GMCR2YE6.js");
7756
7706
  switch (action) {
7757
7707
  case "submit":
7758
7708
  if (!arg) {
@@ -7795,7 +7745,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7795
7745
  }
7796
7746
  });
7797
7747
  program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
7798
- const { startMcpServer } = await import("./server-MGKTVVAR.js");
7748
+ const { startMcpServer } = await import("./server-IKU7UN7J.js");
7799
7749
  await startMcpServer({
7800
7750
  allowDestructive: !!options.allowDestructive,
7801
7751
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7803,6 +7753,29 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
7803
7753
  cwd: options.cwd
7804
7754
  });
7805
7755
  });
7756
+ program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number; diff fetched via `gh pr diff <num>`", (v) => parseInt(v, 10)).option("--base <ref>", "Base ref for `git diff <ref>...HEAD` (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").action(async (options) => {
7757
+ const { runCi } = await import("./ci-CPXECTTZ.js");
7758
+ const result = await runCi({
7759
+ pr: options.pr,
7760
+ base: options.base,
7761
+ post: !!options.post,
7762
+ update: options.update !== false,
7763
+ skipCode: !!options.skipCode,
7764
+ skipSecurity: !!options.skipSecurity,
7765
+ detailed: !!options.detailed,
7766
+ maxDiffChars: options.maxDiff,
7767
+ provider: options.provider,
7768
+ model: options.model,
7769
+ dryRun: !!options.dryRun
7770
+ });
7771
+ process.stdout.write(result.markdown + "\n");
7772
+ if (result.posted) {
7773
+ process.stderr.write(`
7774
+ \u2705 Posted review to PR #${options.pr}${result.updatedCommentId ? " (updated existing comment)" : ""}
7775
+ `);
7776
+ }
7777
+ process.exit(result.exitCode);
7778
+ });
7806
7779
  program.command("help").description("Show a comprehensive guide to all aicli features and commands").action(() => {
7807
7780
  const B = "\x1B[1m";
7808
7781
  const D = "\x1B[2m";
@@ -7922,7 +7895,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7922
7895
  }),
7923
7896
  config.get("customProviders")
7924
7897
  );
7925
- const { startHub } = await import("./hub-SXNKYCN7.js");
7898
+ const { startHub } = await import("./hub-PSQ3P5DO.js");
7926
7899
  await startHub(
7927
7900
  {
7928
7901
  topic: topic ?? "",
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-2JPLV25X.js";
6
- import "./chunk-XW4EP5IE.js";
5
+ } from "./chunk-GB2KTJC2.js";
6
+ import "./chunk-EUE7FFIO.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
  export {
9
9
  executeTests,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-YGGW2D2V.js";
4
+ } from "./chunk-QJWZ5G64.js";
5
5
  import "./chunk-3RG5ZIWI.js";
6
6
  export {
7
7
  executeTests,
@@ -1,19 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-PWCPOHZ4.js";
4
+ } from "./chunk-BOQ4YWRM.js";
5
5
  import "./chunk-UQQJWHRV.js";
6
6
  import "./chunk-2DXY7UGF.js";
7
- import "./chunk-2JPLV25X.js";
7
+ import "./chunk-GB2KTJC2.js";
8
+ import {
9
+ runTool
10
+ } from "./chunk-JB7LEZQO.js";
8
11
  import {
9
12
  getDangerLevel,
10
- runTool,
11
13
  schemaToJsonSchema
12
- } from "./chunk-QSGDXXE6.js";
14
+ } from "./chunk-OWPFDHKC.js";
13
15
  import "./chunk-2ZD3YTVM.js";
14
16
  import {
15
17
  VERSION
16
- } from "./chunk-XW4EP5IE.js";
18
+ } from "./chunk-EUE7FFIO.js";
17
19
  import "./chunk-4BKXL7SM.js";
18
20
  import "./chunk-7ZJN4KLV.js";
19
21
  import "./chunk-KHYD3WXE.js";
@@ -14,7 +14,7 @@ import {
14
14
  loadDevState,
15
15
  persistToolRound,
16
16
  setupProxy
17
- } from "./chunk-IGZVCNGE.js";
17
+ } from "./chunk-RJYVWTHV.js";
18
18
  import {
19
19
  CONTENT_ONLY_STREAM_REMINDER,
20
20
  HALLUCINATION_CORRECTION_MESSAGE,
@@ -28,10 +28,10 @@ import {
28
28
  looksLikeDocumentBody,
29
29
  stripPseudoToolCalls,
30
30
  stripToolCallReminder
31
- } from "./chunk-EHLHWFZP.js";
31
+ } from "./chunk-XZBA3NHG.js";
32
32
  import {
33
33
  ConfigManager
34
- } from "./chunk-WPYKTLP2.js";
34
+ } from "./chunk-AQQSYFTU.js";
35
35
  import {
36
36
  ToolExecutor,
37
37
  ToolRegistry,
@@ -49,14 +49,16 @@ import {
49
49
  spawnAgentContext,
50
50
  truncateOutput,
51
51
  undoStack
52
- } from "./chunk-PWCPOHZ4.js";
52
+ } from "./chunk-BOQ4YWRM.js";
53
53
  import "./chunk-UQQJWHRV.js";
54
54
  import "./chunk-2DXY7UGF.js";
55
- import "./chunk-2JPLV25X.js";
55
+ import "./chunk-GB2KTJC2.js";
56
56
  import {
57
- getDangerLevel,
58
57
  runTool
59
- } from "./chunk-QSGDXXE6.js";
58
+ } from "./chunk-JB7LEZQO.js";
59
+ import {
60
+ getDangerLevel
61
+ } from "./chunk-OWPFDHKC.js";
60
62
  import "./chunk-2ZD3YTVM.js";
61
63
  import {
62
64
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -76,7 +78,7 @@ import {
76
78
  SKILLS_DIR_NAME,
77
79
  VERSION,
78
80
  buildUserIdentityPrompt
79
- } from "./chunk-XW4EP5IE.js";
81
+ } from "./chunk-EUE7FFIO.js";
80
82
  import {
81
83
  formatGitContextForPrompt,
82
84
  getGitContext,
@@ -2460,7 +2462,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2460
2462
  case "test": {
2461
2463
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
2462
2464
  try {
2463
- const { executeTests } = await import("./run-tests-X4YQXIGP.js");
2465
+ const { executeTests } = await import("./run-tests-D4ZQ7NLP.js");
2464
2466
  const argStr = args.join(" ").trim();
2465
2467
  let testArgs = {};
2466
2468
  if (argStr) {
@@ -3,18 +3,20 @@ import {
3
3
  ToolRegistry,
4
4
  googleSearchContext,
5
5
  truncateOutput
6
- } from "./chunk-PWCPOHZ4.js";
6
+ } from "./chunk-BOQ4YWRM.js";
7
7
  import "./chunk-UQQJWHRV.js";
8
8
  import "./chunk-2DXY7UGF.js";
9
- import "./chunk-2JPLV25X.js";
9
+ import "./chunk-GB2KTJC2.js";
10
10
  import {
11
- getDangerLevel,
12
11
  runTool
13
- } from "./chunk-QSGDXXE6.js";
12
+ } from "./chunk-JB7LEZQO.js";
13
+ import {
14
+ getDangerLevel
15
+ } from "./chunk-OWPFDHKC.js";
14
16
  import "./chunk-2ZD3YTVM.js";
15
17
  import {
16
18
  SUBAGENT_ALLOWED_TOOLS
17
- } from "./chunk-XW4EP5IE.js";
19
+ } from "./chunk-EUE7FFIO.js";
18
20
  import "./chunk-4BKXL7SM.js";
19
21
  import "./chunk-7ZJN4KLV.js";
20
22
  import "./chunk-KHYD3WXE.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.144",
3
+ "version": "0.4.146",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",