jinzd-ai-cli 0.4.144 → 0.4.145
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/dist/{batch-64YESATH.js → batch-ZMDHCPMO.js} +2 -2
- package/dist/{chunk-PWCPOHZ4.js → chunk-A3RPBWBF.js} +7 -5
- package/dist/{chunk-XW4EP5IE.js → chunk-EYUL75S4.js} +1 -1
- package/dist/{chunk-QSGDXXE6.js → chunk-GZNBAFTO.js} +2 -60
- package/dist/chunk-HLWUDRBO.js +74 -0
- package/dist/{chunk-IGZVCNGE.js → chunk-JFLT57TG.js} +2 -2
- package/dist/{chunk-WPYKTLP2.js → chunk-MII3VYZ7.js} +1 -1
- package/dist/{chunk-YGGW2D2V.js → chunk-OH5HVL5O.js} +1 -1
- package/dist/chunk-OWPFDHKC.js +62 -0
- package/dist/{chunk-2JPLV25X.js → chunk-QWP4RFMS.js} +1 -1
- package/dist/{chunk-EHLHWFZP.js → chunk-XZBA3NHG.js} +1 -1
- package/dist/{chunk-HUILGJNB.js → chunk-ZFEFS5HS.js} +1 -1
- package/dist/ci-FCVBC4WJ.js +232 -0
- package/dist/{constants-7Q5DB2X6.js → constants-MNI3S4EV.js} +1 -1
- package/dist/{doctor-cli-RHGMQVCU.js → doctor-cli-56AJTKP2.js} +6 -5
- package/dist/electron-server.js +2 -2
- package/dist/{hub-SXNKYCN7.js → hub-DEZX2PAA.js} +1 -1
- package/dist/index.js +44 -71
- package/dist/{run-tests-SUYREW3B.js → run-tests-MDJLWONR.js} +1 -1
- package/dist/{run-tests-X4YQXIGP.js → run-tests-MYF3A4YR.js} +2 -2
- package/dist/{server-MGKTVVAR.js → server-IITOENMZ.js} +7 -5
- package/dist/{server-X24SIKZE.js → server-RB4ACTOJ.js} +11 -9
- package/dist/{task-orchestrator-R6VOCA4V.js → task-orchestrator-5N4WD2VT.js} +7 -5
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MII3VYZ7.js";
|
|
5
5
|
import "./chunk-2ZD3YTVM.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-EYUL75S4.js";
|
|
7
7
|
import "./chunk-PDX44BCA.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/batch.ts
|
|
@@ -5,12 +5,14 @@ import {
|
|
|
5
5
|
} from "./chunk-UQQJWHRV.js";
|
|
6
6
|
import {
|
|
7
7
|
runTestsTool
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QWP4RFMS.js";
|
|
9
9
|
import {
|
|
10
|
-
getDangerLevel,
|
|
11
|
-
isFileWriteTool,
|
|
12
10
|
runTool
|
|
13
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GZNBAFTO.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-
|
|
28
|
+
} from "./chunk-EYUL75S4.js";
|
|
27
29
|
import {
|
|
28
30
|
fileCheckpoints
|
|
29
31
|
} from "./chunk-4BKXL7SM.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CONFIG_DIR_NAME
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EYUL75S4.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,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
|
truncateForPersist
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-A3RPBWBF.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-
|
|
14
|
+
} from "./chunk-EYUL75S4.js";
|
|
15
15
|
import {
|
|
16
16
|
redactJson
|
|
17
17
|
} from "./chunk-7ZJN4KLV.js";
|
|
@@ -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
|
+
};
|
|
@@ -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-MII3VYZ7.js";
|
|
13
|
+
import "./chunk-OWPFDHKC.js";
|
|
14
|
+
import "./chunk-2ZD3YTVM.js";
|
|
15
|
+
import {
|
|
16
|
+
VERSION
|
|
17
|
+
} from "./chunk-EYUL75S4.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
|
+
};
|
|
@@ -2,25 +2,26 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getConfigDirUsage,
|
|
4
4
|
listRecentCrashes
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZFEFS5HS.js";
|
|
6
6
|
import {
|
|
7
7
|
ProviderRegistry
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XZBA3NHG.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigManager
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MII3VYZ7.js";
|
|
12
12
|
import {
|
|
13
13
|
getStatsSnapshot,
|
|
14
14
|
getTopFailingTools,
|
|
15
15
|
getTopUsedTools,
|
|
16
16
|
resetStats
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GZNBAFTO.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-
|
|
24
|
+
} from "./chunk-EYUL75S4.js";
|
|
24
25
|
import "./chunk-PDX44BCA.js";
|
|
25
26
|
|
|
26
27
|
// src/diagnostics/doctor-cli.ts
|
package/dist/electron-server.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
VERSION,
|
|
37
37
|
buildUserIdentityPrompt,
|
|
38
38
|
runTestsTool
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-OH5HVL5O.js";
|
|
40
40
|
import {
|
|
41
41
|
hasSemanticIndex,
|
|
42
42
|
semanticSearch
|
|
@@ -12568,7 +12568,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
12568
12568
|
case "test": {
|
|
12569
12569
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
12570
12570
|
try {
|
|
12571
|
-
const { executeTests } = await import("./run-tests-
|
|
12571
|
+
const { executeTests } = await import("./run-tests-MDJLWONR.js");
|
|
12572
12572
|
const argStr = args.join(" ").trim();
|
|
12573
12573
|
let testArgs = {};
|
|
12574
12574
|
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-
|
|
389
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-5N4WD2VT.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-
|
|
23
|
+
} from "./chunk-JFLT57TG.js";
|
|
20
24
|
import {
|
|
21
25
|
getConfigDirUsage,
|
|
22
26
|
listRecentCrashes,
|
|
23
27
|
writeCrashLog
|
|
24
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-ZFEFS5HS.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-
|
|
46
|
+
} from "./chunk-XZBA3NHG.js";
|
|
43
47
|
import {
|
|
44
48
|
ConfigManager
|
|
45
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-MII3VYZ7.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-
|
|
68
|
+
} from "./chunk-A3RPBWBF.js";
|
|
65
69
|
import "./chunk-UQQJWHRV.js";
|
|
66
70
|
import "./chunk-2DXY7UGF.js";
|
|
67
|
-
import "./chunk-
|
|
71
|
+
import "./chunk-QWP4RFMS.js";
|
|
68
72
|
import {
|
|
69
73
|
getStatsSnapshot,
|
|
70
74
|
getTopFailingTools,
|
|
71
75
|
getTopUsedTools,
|
|
72
76
|
installFlushOnExit
|
|
73
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-GZNBAFTO.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-
|
|
105
|
+
} from "./chunk-EYUL75S4.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-
|
|
1772
|
+
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-MNI3S4EV.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-
|
|
2833
|
+
const { executeTests } = await import("./run-tests-MYF3A4YR.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-
|
|
7533
|
+
const { startWebServer } = await import("./server-RB4ACTOJ.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-
|
|
7700
|
+
const { runDoctorCli } = await import("./doctor-cli-56AJTKP2.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-
|
|
7705
|
+
const batch = await import("./batch-ZMDHCPMO.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-
|
|
7748
|
+
const { startMcpServer } = await import("./server-IITOENMZ.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-FCVBC4WJ.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-
|
|
7898
|
+
const { startHub } = await import("./hub-DEZX2PAA.js");
|
|
7926
7899
|
await startHub(
|
|
7927
7900
|
{
|
|
7928
7901
|
topic: topic ?? "",
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ToolRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-A3RPBWBF.js";
|
|
5
5
|
import "./chunk-UQQJWHRV.js";
|
|
6
6
|
import "./chunk-2DXY7UGF.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-QWP4RFMS.js";
|
|
8
|
+
import {
|
|
9
|
+
runTool
|
|
10
|
+
} from "./chunk-GZNBAFTO.js";
|
|
8
11
|
import {
|
|
9
12
|
getDangerLevel,
|
|
10
|
-
runTool,
|
|
11
13
|
schemaToJsonSchema
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OWPFDHKC.js";
|
|
13
15
|
import "./chunk-2ZD3YTVM.js";
|
|
14
16
|
import {
|
|
15
17
|
VERSION
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-EYUL75S4.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-
|
|
17
|
+
} from "./chunk-JFLT57TG.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-
|
|
31
|
+
} from "./chunk-XZBA3NHG.js";
|
|
32
32
|
import {
|
|
33
33
|
ConfigManager
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-MII3VYZ7.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-
|
|
52
|
+
} from "./chunk-A3RPBWBF.js";
|
|
53
53
|
import "./chunk-UQQJWHRV.js";
|
|
54
54
|
import "./chunk-2DXY7UGF.js";
|
|
55
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-QWP4RFMS.js";
|
|
56
56
|
import {
|
|
57
|
-
getDangerLevel,
|
|
58
57
|
runTool
|
|
59
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-GZNBAFTO.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-
|
|
81
|
+
} from "./chunk-EYUL75S4.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-
|
|
2465
|
+
const { executeTests } = await import("./run-tests-MYF3A4YR.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-
|
|
6
|
+
} from "./chunk-A3RPBWBF.js";
|
|
7
7
|
import "./chunk-UQQJWHRV.js";
|
|
8
8
|
import "./chunk-2DXY7UGF.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-QWP4RFMS.js";
|
|
10
10
|
import {
|
|
11
|
-
getDangerLevel,
|
|
12
11
|
runTool
|
|
13
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GZNBAFTO.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-
|
|
19
|
+
} from "./chunk-EYUL75S4.js";
|
|
18
20
|
import "./chunk-4BKXL7SM.js";
|
|
19
21
|
import "./chunk-7ZJN4KLV.js";
|
|
20
22
|
import "./chunk-KHYD3WXE.js";
|