jinzd-ai-cli 0.4.217 → 0.4.219
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 +5 -2
- package/dist/{batch-YCOVKTXD.js → batch-CHAPYRVM.js} +2 -2
- package/dist/chunk-3I4RZYYO.js +638 -0
- package/dist/{chunk-KOPUCJXM.js → chunk-4ZN6L6K5.js} +3 -3
- package/dist/{chunk-VTH7BLXK.js → chunk-64NUW3WL.js} +1 -1
- package/dist/{chunk-QAYOI57M.js → chunk-EGMORH5W.js} +1 -1
- package/dist/{chunk-MGBMNCHG.js → chunk-GEN4O5QH.js} +94 -270
- package/dist/chunk-GGKQHPB3.js +604 -0
- package/dist/{chunk-WKOQ5CYC.js → chunk-KIEZBTVD.js} +1 -1
- package/dist/{chunk-OUAZOE5U.js → chunk-QUFYBR6Q.js} +47 -206
- package/dist/{chunk-XJGEQIYS.js → chunk-U7KVU25H.js} +1 -1
- package/dist/{chunk-WZ3VKLF3.js → chunk-VADHBW7T.js} +1 -1
- package/dist/{ci-52RZIYWB.js → ci-QPP66T53.js} +4 -4
- package/dist/{ci-format-73UXKE65.js → ci-format-5S3EEYRK.js} +2 -2
- package/dist/{constants-DIXAD35W.js → constants-FJOLBABC.js} +1 -1
- package/dist/doctor-cli-KB2LUDF3.js +17 -0
- package/dist/electron-server.js +921 -274
- package/dist/{hub-GIGBITZN.js → hub-DIM7SKKY.js} +1 -1
- package/dist/index.js +192 -200
- package/dist/{pr-KPQ5RPKB.js → pr-YQGH72N6.js} +4 -4
- package/dist/{run-tests-ZDSA3QES.js → run-tests-GEZSSNJM.js} +2 -2
- package/dist/{run-tests-K7QR5QN4.js → run-tests-O76JIBCW.js} +1 -1
- package/dist/{server-QT3SC2KI.js → server-5E2AIXVX.js} +108 -80
- package/dist/{server-22YF3U34.js → server-Z6O3G2LY.js} +9 -9
- package/dist/{task-orchestrator-BHQQCVTY.js → task-orchestrator-5HBW4O64.js} +9 -9
- package/dist/{usage-WZZFSFLM.js → usage-BMK6M5U3.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-524WZOKS.js +0 -166
- package/dist/chunk-SNJAOXFT.js +0 -129
- package/dist/doctor-cli-7GOQPULZ.js +0 -226
package/dist/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
autoTrimSessionIfNeeded,
|
|
7
7
|
buildInitPrompt,
|
|
8
8
|
clearDevState,
|
|
9
|
-
loadContextFiles,
|
|
10
9
|
loadDevState,
|
|
11
10
|
parseSimpleYaml,
|
|
12
11
|
persistToolRound,
|
|
@@ -15,7 +14,7 @@ import {
|
|
|
15
14
|
scanProject,
|
|
16
15
|
sessionHasMeaningfulContent,
|
|
17
16
|
setupProxy
|
|
18
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-QUFYBR6Q.js";
|
|
19
18
|
import {
|
|
20
19
|
buildReviewPrompt,
|
|
21
20
|
buildSecurityReviewPrompt
|
|
@@ -33,14 +32,12 @@ import {
|
|
|
33
32
|
exportMemoryEntries,
|
|
34
33
|
formatMemoryForPrompt,
|
|
35
34
|
formatPermissionProfileWarning,
|
|
36
|
-
getPendingHookTrust,
|
|
37
35
|
getRecentlyDeniedAutoActions,
|
|
38
36
|
googleSearchContext,
|
|
39
37
|
initTheme,
|
|
40
38
|
isInterrupted,
|
|
41
39
|
isMemoryExpired,
|
|
42
40
|
lastResponseStore,
|
|
43
|
-
listHooks,
|
|
44
41
|
listMemoryEntries,
|
|
45
42
|
memoryMarkdownPath,
|
|
46
43
|
memoryStorePath,
|
|
@@ -48,19 +45,17 @@ import {
|
|
|
48
45
|
requestInterrupt,
|
|
49
46
|
resetInterrupt,
|
|
50
47
|
rlInternal,
|
|
51
|
-
runLifecycleHooks,
|
|
52
48
|
setContextWindow,
|
|
53
49
|
setMaxOutputCap,
|
|
54
50
|
spawnAgentContext,
|
|
55
51
|
theme,
|
|
56
|
-
trustHook,
|
|
57
52
|
undoStack,
|
|
58
|
-
untrustHook,
|
|
59
53
|
updateMemoryApproval
|
|
60
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-GEN4O5QH.js";
|
|
55
|
+
import "./chunk-K3CF65QH.js";
|
|
61
56
|
import "./chunk-T2NL5ZIA.js";
|
|
62
57
|
import "./chunk-BXP6YZ2P.js";
|
|
63
|
-
import "./chunk-
|
|
58
|
+
import "./chunk-64NUW3WL.js";
|
|
64
59
|
import {
|
|
65
60
|
SessionManager,
|
|
66
61
|
getContentText
|
|
@@ -74,19 +69,45 @@ import {
|
|
|
74
69
|
getPricing
|
|
75
70
|
} from "./chunk-E44DTERW.js";
|
|
76
71
|
import {
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
fileCheckpoints
|
|
73
|
+
} from "./chunk-4BKXL7SM.js";
|
|
74
|
+
import {
|
|
75
|
+
buildChatIndex,
|
|
76
|
+
clearChatIndex,
|
|
77
|
+
getChatIndexStatus,
|
|
78
|
+
searchChatMemory
|
|
79
|
+
} from "./chunk-TB4W4Y4T.js";
|
|
80
|
+
import "./chunk-KHYD3WXE.js";
|
|
81
|
+
import {
|
|
82
|
+
DEFAULT_PATTERNS,
|
|
83
|
+
scanString
|
|
84
|
+
} from "./chunk-SLSWPBK3.js";
|
|
85
|
+
import {
|
|
86
|
+
buildDoctorReport,
|
|
87
|
+
formatDoctorReport,
|
|
88
|
+
loadContextFiles,
|
|
79
89
|
writeCrashLog
|
|
80
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-3I4RZYYO.js";
|
|
81
91
|
import {
|
|
82
92
|
ProviderRegistry
|
|
83
93
|
} from "./chunk-QMXC327F.js";
|
|
84
94
|
import {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
95
|
+
describePlugin,
|
|
96
|
+
getActivePluginAssets,
|
|
97
|
+
getInstalledPlugin,
|
|
98
|
+
getPendingHookTrust,
|
|
99
|
+
installFlushOnExit,
|
|
100
|
+
installPlugin,
|
|
101
|
+
listHooks,
|
|
102
|
+
listInstalledPlugins,
|
|
103
|
+
mergePluginHooks,
|
|
104
|
+
pluginRoot,
|
|
105
|
+
runLifecycleHooks,
|
|
106
|
+
setPluginEnabled,
|
|
107
|
+
trustHook,
|
|
108
|
+
trustPlugin,
|
|
109
|
+
untrustHook
|
|
110
|
+
} from "./chunk-GGKQHPB3.js";
|
|
90
111
|
import {
|
|
91
112
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
92
113
|
TEE_FINAL_USER_NUDGE,
|
|
@@ -108,7 +129,7 @@ import {
|
|
|
108
129
|
} from "./chunk-XPBEJB27.js";
|
|
109
130
|
import {
|
|
110
131
|
ConfigManager
|
|
111
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-KIEZBTVD.js";
|
|
112
133
|
import {
|
|
113
134
|
AuthError,
|
|
114
135
|
ProviderError,
|
|
@@ -126,34 +147,18 @@ import {
|
|
|
126
147
|
DESCRIPTION,
|
|
127
148
|
DEV_STATE_FILE_NAME,
|
|
128
149
|
MCP_PROJECT_CONFIG_NAME,
|
|
129
|
-
MEMORY_FILE_NAME,
|
|
130
150
|
PLAN_MODE_READONLY_TOOLS,
|
|
131
151
|
PLAN_MODE_SYSTEM_ADDON,
|
|
132
152
|
REPO_URL,
|
|
133
153
|
SKILLS_DIR_NAME,
|
|
134
154
|
VERSION,
|
|
135
155
|
buildUserIdentityPrompt
|
|
136
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-U7KVU25H.js";
|
|
137
157
|
import {
|
|
138
158
|
formatGitContextForPrompt,
|
|
139
159
|
getGitContext,
|
|
140
160
|
getGitRoot
|
|
141
161
|
} from "./chunk-HOSJZMQS.js";
|
|
142
|
-
import {
|
|
143
|
-
fileCheckpoints
|
|
144
|
-
} from "./chunk-4BKXL7SM.js";
|
|
145
|
-
import {
|
|
146
|
-
buildChatIndex,
|
|
147
|
-
clearChatIndex,
|
|
148
|
-
getChatIndexStatus,
|
|
149
|
-
searchChatMemory
|
|
150
|
-
} from "./chunk-TB4W4Y4T.js";
|
|
151
|
-
import "./chunk-KHYD3WXE.js";
|
|
152
|
-
import {
|
|
153
|
-
DEFAULT_PATTERNS,
|
|
154
|
-
scanString
|
|
155
|
-
} from "./chunk-SLSWPBK3.js";
|
|
156
|
-
import "./chunk-K3CF65QH.js";
|
|
157
162
|
import "./chunk-CKH4KQ4E.js";
|
|
158
163
|
import {
|
|
159
164
|
atomicWriteFileSync
|
|
@@ -164,7 +169,7 @@ import { program } from "commander";
|
|
|
164
169
|
|
|
165
170
|
// src/repl/repl.ts
|
|
166
171
|
import * as readline from "readline";
|
|
167
|
-
import { existsSync as existsSync4, readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as
|
|
172
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as statSync2, mkdirSync as mkdirSync4 } from "fs";
|
|
168
173
|
import { join as join4, resolve as resolve2, extname as extname2, dirname as dirname3, basename as basename2 } from "path";
|
|
169
174
|
import chalk4 from "chalk";
|
|
170
175
|
|
|
@@ -289,7 +294,7 @@ var ABOUT_FEATURES = [
|
|
|
289
294
|
"Sub-agents: spawn_agent delegates complex subtasks to an isolated tool-call loop",
|
|
290
295
|
"Agent Skills: ~/.aicli/skills/ reusable packs (system prompt + tool whitelist)",
|
|
291
296
|
"MCP protocol: connect external MCP server tools; aicli mcp-serve reverses aicli into a server",
|
|
292
|
-
"Plugin
|
|
297
|
+
"Plugin packages: skills/hooks/commands/MCP/agents via trusted .aicli-plugin/plugin.json",
|
|
293
298
|
"Permission rules + hooks: auto-approve/deny/confirm + pre/post tool execution hooks",
|
|
294
299
|
"User identity (/profile): persistent profile injected into every provider",
|
|
295
300
|
"Symbol + semantic code index: find_symbol/get_outline/find_references/search_code (8 languages)",
|
|
@@ -657,7 +662,7 @@ Error${typeName}: ${lines.join("\n")}
|
|
|
657
662
|
};
|
|
658
663
|
|
|
659
664
|
// src/repl/commands/index.ts
|
|
660
|
-
import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync2, readFileSync
|
|
665
|
+
import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync2, readFileSync } from "fs";
|
|
661
666
|
import { execSync as execSync2 } from "child_process";
|
|
662
667
|
import { platform } from "os";
|
|
663
668
|
import { resolve, dirname as dirname2, join as join2, basename } from "path";
|
|
@@ -916,6 +921,7 @@ function createDefaultCommands() {
|
|
|
916
921
|
rows: [
|
|
917
922
|
["/tools", "List all AI tools available"],
|
|
918
923
|
["/plugins", "Show plugin directory and loaded plugins"],
|
|
924
|
+
["/plugin [list|install|enable|disable|inspect|trust]", "Manage package plugins"],
|
|
919
925
|
["/mcp [reconnect [id]]", "MCP servers / reconnect disconnected"],
|
|
920
926
|
["/skill [name|off|list]", "Manage agent skills (reusable prompt packs)"],
|
|
921
927
|
["/context", "Show or reload hierarchical context layers"],
|
|
@@ -1376,7 +1382,7 @@ No commands match "${filter}".
|
|
|
1376
1382
|
console.log(" PermProf : " + (ctx.config.get("defaultPermissionProfile") ?? "legacy"));
|
|
1377
1383
|
console.log(" Network : " + (ctx.config.get("networkPolicy")?.enabled ?? false ? "on" : "off"));
|
|
1378
1384
|
console.log(" AutoMode : " + (ctx.getToolExecutor().sessionAutoMode ? "on" : "off"));
|
|
1379
|
-
console.log(" Hooks : " + getPendingHookTrust(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()).length + " pending trust");
|
|
1385
|
+
console.log(" Hooks : " + getPendingHookTrust(mergePluginHooks(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()), ctx.config.getConfigDir()).length + " pending trust");
|
|
1380
1386
|
console.log(` Messages : ${session?.messages.length ?? 0}`);
|
|
1381
1387
|
console.log(` Session : ${session?.id.slice(0, 8) ?? "none"}`);
|
|
1382
1388
|
if (layers.length > 0) {
|
|
@@ -1661,6 +1667,91 @@ No tools match "${filter}".
|
|
|
1661
1667
|
console.log();
|
|
1662
1668
|
}
|
|
1663
1669
|
},
|
|
1670
|
+
{
|
|
1671
|
+
name: "plugin",
|
|
1672
|
+
description: "Manage package plugins (.aicli-plugin/plugin.json)",
|
|
1673
|
+
usage: "/plugin [list|install <path>|enable <name>|disable <name>|inspect <name>|trust <name>]",
|
|
1674
|
+
async execute(args, ctx) {
|
|
1675
|
+
const sub = args[0] ?? "list";
|
|
1676
|
+
const configDir = ctx.config.getConfigDir();
|
|
1677
|
+
try {
|
|
1678
|
+
if (sub === "list") {
|
|
1679
|
+
const plugins = listInstalledPlugins(configDir);
|
|
1680
|
+
console.log(theme.heading("\n\u{1F50C} Package Plugins\n"));
|
|
1681
|
+
console.log(theme.dim(` Dir: ${pluginRoot(configDir)}`));
|
|
1682
|
+
if (plugins.length === 0) {
|
|
1683
|
+
console.log(theme.dim(" No package plugins installed."));
|
|
1684
|
+
console.log(theme.dim(" Use: /plugin install <path-to-plugin-dir>"));
|
|
1685
|
+
} else {
|
|
1686
|
+
for (const p of plugins) {
|
|
1687
|
+
const status = `${p.enabled ? theme.success("enabled") : theme.dim("disabled")} / ${p.trusted ? theme.success("trusted") : theme.warning("untrusted")}`;
|
|
1688
|
+
console.log(` ${theme.accent(p.name.padEnd(22))} ${p.manifest.version.padEnd(10)} ${status}`);
|
|
1689
|
+
if (p.manifest.description) console.log(theme.dim(` ${p.manifest.description}`));
|
|
1690
|
+
if (!p.valid && p.error) console.log(theme.warning(` invalid: ${p.error}`));
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
console.log();
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
if (sub === "install") {
|
|
1697
|
+
const input2 = args[1];
|
|
1698
|
+
if (!input2) {
|
|
1699
|
+
ctx.renderer.printInfo("Usage: /plugin install <path-to-plugin-dir>");
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
const plugin = installPlugin(configDir, input2);
|
|
1703
|
+
ctx.renderer.printSuccess(`Installed plugin ${plugin.name}@${plugin.manifest.version}. Run /plugin trust ${plugin.name}, then /plugin enable ${plugin.name}.`);
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
if (sub === "trust") {
|
|
1707
|
+
const name = args[1];
|
|
1708
|
+
if (!name) {
|
|
1709
|
+
ctx.renderer.printInfo("Usage: /plugin trust <name>");
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
const state = trustPlugin(configDir, name);
|
|
1713
|
+
ctx.renderer.printSuccess(`Trusted plugin ${state.name}.`);
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
if (sub === "enable" || sub === "disable") {
|
|
1717
|
+
const name = args[1];
|
|
1718
|
+
if (!name) {
|
|
1719
|
+
ctx.renderer.printInfo(`Usage: /plugin ${sub} <name>`);
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
const state = setPluginEnabled(configDir, name, sub === "enable");
|
|
1723
|
+
ctx.renderer.printSuccess(`${sub === "enable" ? "Enabled" : "Disabled"} plugin ${state.name}. Restart aicli or reload affected managers for changes to take effect.`);
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
if (sub === "inspect") {
|
|
1727
|
+
const name = args[1];
|
|
1728
|
+
if (!name) {
|
|
1729
|
+
ctx.renderer.printInfo("Usage: /plugin inspect <name>");
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
const plugin = getInstalledPlugin(configDir, name);
|
|
1733
|
+
console.log();
|
|
1734
|
+
for (const line of describePlugin(plugin)) console.log(line);
|
|
1735
|
+
console.log();
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
if (sub === "active") {
|
|
1739
|
+
const assets = getActivePluginAssets(configDir);
|
|
1740
|
+
console.log(JSON.stringify({
|
|
1741
|
+
plugins: assets.plugins.map((p) => p.name),
|
|
1742
|
+
skillDirs: assets.skillDirs,
|
|
1743
|
+
commandDirs: assets.commandDirs,
|
|
1744
|
+
agentDirs: assets.agentDirs,
|
|
1745
|
+
mcpServers: Object.keys(assets.mcpServers)
|
|
1746
|
+
}, null, 2));
|
|
1747
|
+
return;
|
|
1748
|
+
}
|
|
1749
|
+
ctx.renderer.printInfo("Usage: /plugin [list|install|enable|disable|inspect|trust]");
|
|
1750
|
+
} catch (err) {
|
|
1751
|
+
ctx.renderer.renderError(err instanceof Error ? err.message : String(err));
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
},
|
|
1664
1755
|
{
|
|
1665
1756
|
name: "mcp",
|
|
1666
1757
|
description: "Show MCP server connections and tools",
|
|
@@ -1670,7 +1761,7 @@ No tools match "${filter}".
|
|
|
1670
1761
|
const { join: join5 } = await import("path");
|
|
1671
1762
|
const { existsSync: existsSync5 } = await import("fs");
|
|
1672
1763
|
const { getGitRoot: getGitRoot2 } = await import("./git-context-EXOEHQSF.js");
|
|
1673
|
-
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-
|
|
1764
|
+
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-FJOLBABC.js");
|
|
1674
1765
|
const { approveProject, hashMcpFile } = await import("./project-trust-NKYHL3VZ.js");
|
|
1675
1766
|
const cwd = process.cwd();
|
|
1676
1767
|
const projectRoot = getGitRoot2(cwd) ?? cwd;
|
|
@@ -1979,7 +2070,7 @@ No tools match "${filter}".
|
|
|
1979
2070
|
return;
|
|
1980
2071
|
}
|
|
1981
2072
|
if (sub === "reload") {
|
|
1982
|
-
const count = manager.loadSkills();
|
|
2073
|
+
const count = manager.loadSkills(getActivePluginAssets(ctx.config.getConfigDir()).skillDirs);
|
|
1983
2074
|
ctx.renderer.printSuccess(`Reloaded: ${count} skill(s) found.`);
|
|
1984
2075
|
return;
|
|
1985
2076
|
}
|
|
@@ -2706,7 +2797,7 @@ ${hint}` : "")
|
|
|
2706
2797
|
}
|
|
2707
2798
|
const sub = args[0]?.toLowerCase();
|
|
2708
2799
|
if (sub === "reload") {
|
|
2709
|
-
const count = mgr.loadCommands();
|
|
2800
|
+
const count = mgr.loadCommands(getActivePluginAssets(ctx.config.getConfigDir()).commandDirs);
|
|
2710
2801
|
console.log(theme.success(` \u2713 Reloaded ${count} custom command(s).`));
|
|
2711
2802
|
return;
|
|
2712
2803
|
}
|
|
@@ -2729,7 +2820,7 @@ ${hint}` : "")
|
|
|
2729
2820
|
usage: "/test [command|filter]",
|
|
2730
2821
|
async execute(args, ctx) {
|
|
2731
2822
|
try {
|
|
2732
|
-
const { executeTests } = await import("./run-tests-
|
|
2823
|
+
const { executeTests } = await import("./run-tests-GEZSSNJM.js");
|
|
2733
2824
|
const argStr = args.join(" ").trim();
|
|
2734
2825
|
let testArgs = {};
|
|
2735
2826
|
if (argStr) {
|
|
@@ -3090,126 +3181,16 @@ ${hint}` : "")
|
|
|
3090
3181
|
// ── /doctor ────────────────────────────────────────────────────────────────
|
|
3091
3182
|
{
|
|
3092
3183
|
name: "doctor",
|
|
3093
|
-
description: "Health check:
|
|
3184
|
+
description: "Health check: context, permissions, hooks, plugins, MCP, config",
|
|
3094
3185
|
usage: "/doctor",
|
|
3095
3186
|
execute(_args, ctx) {
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
}
|
|
3104
|
-
console.log();
|
|
3105
|
-
const configDir = ctx.config.getConfigDir();
|
|
3106
|
-
console.log(theme.heading("Config Files:"));
|
|
3107
|
-
console.log(` Dir: ${theme.accent(configDir)}`);
|
|
3108
|
-
const checkFile = (label, filePath) => {
|
|
3109
|
-
const exists = existsSync2(filePath);
|
|
3110
|
-
const icon = exists ? theme.success("\u2713") : theme.dim("\u2013");
|
|
3111
|
-
let extra = "";
|
|
3112
|
-
if (exists) {
|
|
3113
|
-
try {
|
|
3114
|
-
extra = theme.dim(` (${statSync2(filePath).size} bytes)`);
|
|
3115
|
-
} catch {
|
|
3116
|
-
}
|
|
3117
|
-
}
|
|
3118
|
-
console.log(` ${icon} ${label.padEnd(14)} ${exists ? filePath : theme.dim("(not found)")}${extra}`);
|
|
3119
|
-
};
|
|
3120
|
-
checkFile("config.json", join2(configDir, "config.json"));
|
|
3121
|
-
checkFile("memory.md", join2(configDir, MEMORY_FILE_NAME));
|
|
3122
|
-
checkFile("dev-state.md", join2(configDir, "dev-state.md"));
|
|
3123
|
-
console.log();
|
|
3124
|
-
const mcpManager = ctx.getMcpManager();
|
|
3125
|
-
if (mcpManager) {
|
|
3126
|
-
console.log(theme.heading("MCP Servers:"));
|
|
3127
|
-
const statuses = mcpManager.getStatus();
|
|
3128
|
-
if (statuses.length === 0) {
|
|
3129
|
-
console.log(theme.dim(" (no servers configured)"));
|
|
3130
|
-
} else {
|
|
3131
|
-
for (const s of statuses) {
|
|
3132
|
-
const icon = s.connected ? theme.success(" \u2713") : theme.error(" \u2717");
|
|
3133
|
-
const state = s.connected ? theme.success(`connected`) + theme.dim(` \xB7 ${s.serverName} \xB7 ${s.toolCount} tools`) : theme.error("disconnected") + (s.error ? theme.dim(` \xB7 ${s.error}`) : "");
|
|
3134
|
-
console.log(`${icon} ${s.serverId.padEnd(16)} ${state}`);
|
|
3135
|
-
}
|
|
3136
|
-
}
|
|
3137
|
-
console.log();
|
|
3138
|
-
}
|
|
3139
|
-
const provider = ctx.getCurrentProvider();
|
|
3140
|
-
const model = ctx.getCurrentModel();
|
|
3141
|
-
const ctxTokens = ctx.estimateConversationTokens();
|
|
3142
|
-
const ctxWindow = ctx.getContextWindowSize();
|
|
3143
|
-
const pct = ctxWindow > 0 ? Math.round(ctxTokens / ctxWindow * 100) : 0;
|
|
3144
|
-
const pctColor = pct > 80 ? theme.error : pct > 60 ? theme.warning : theme.success;
|
|
3145
|
-
const dirs = ctx.listContextDirs();
|
|
3146
|
-
console.log(theme.heading("Current Session:"));
|
|
3147
|
-
console.log(` Provider: ${theme.accent(provider)}`);
|
|
3148
|
-
console.log(` Model: ${theme.accent(model)}`);
|
|
3149
|
-
console.log(` Context: ${pctColor(`${pct}%`)} (est. ${ctxTokens.toLocaleString()} / ${ctxWindow.toLocaleString()} tokens)`);
|
|
3150
|
-
if (dirs.length > 0) {
|
|
3151
|
-
console.log(` Extra dirs: ${dirs.map((d) => d.dir).join(", ")}`);
|
|
3152
|
-
}
|
|
3153
|
-
console.log();
|
|
3154
|
-
const crashes = listRecentCrashes(5, configDir);
|
|
3155
|
-
console.log(theme.heading("Recent Crashes (last 5):"));
|
|
3156
|
-
if (crashes.length === 0) {
|
|
3157
|
-
console.log(theme.dim(" (none \u2014 clean!)"));
|
|
3158
|
-
} else {
|
|
3159
|
-
for (const c of crashes) {
|
|
3160
|
-
console.log(` ${theme.error("\u2717")} ${c.timestamp} ${theme.warning(c.kind)}`);
|
|
3161
|
-
console.log(` ${theme.dim(c.message)}`);
|
|
3162
|
-
console.log(` ${theme.dim(c.file)}`);
|
|
3163
|
-
}
|
|
3164
|
-
}
|
|
3165
|
-
console.log();
|
|
3166
|
-
const allStats = getStatsSnapshot();
|
|
3167
|
-
const totalCalls = allStats.reduce((a, b) => a + b.calls, 0);
|
|
3168
|
-
const totalFails = allStats.reduce((a, b) => a + b.failures, 0);
|
|
3169
|
-
const topUsed = getTopUsedTools(5);
|
|
3170
|
-
const topFailing = getTopFailingTools(5);
|
|
3171
|
-
console.log(theme.heading("Tool Usage:"));
|
|
3172
|
-
const pctFail = totalCalls ? (totalFails * 100 / totalCalls).toFixed(1) : "0.0";
|
|
3173
|
-
console.log(` total: ${totalCalls} calls \xB7 ${totalFails} failures (${pctFail}%)`);
|
|
3174
|
-
if (topUsed.length > 0) {
|
|
3175
|
-
console.log(theme.dim(" top used:"));
|
|
3176
|
-
for (const t of topUsed) {
|
|
3177
|
-
const avg = t.calls ? (t.totalDurationMs / t.calls).toFixed(0) : "0";
|
|
3178
|
-
console.log(` ${t.name.padEnd(20)} ${String(t.calls).padStart(6)} calls \xB7 avg ${avg}ms`);
|
|
3179
|
-
}
|
|
3180
|
-
}
|
|
3181
|
-
if (topFailing.length > 0) {
|
|
3182
|
-
console.log(theme.dim(" top failing:"));
|
|
3183
|
-
for (const t of topFailing) {
|
|
3184
|
-
const rate = (t.failures * 100 / Math.max(1, t.calls)).toFixed(1);
|
|
3185
|
-
const msg = t.lastFailureMessage ? ` \xB7 ${theme.dim(t.lastFailureMessage.slice(0, 80))}` : "";
|
|
3186
|
-
console.log(` ${theme.error(t.name.padEnd(20))} ${t.failures}/${t.calls} (${rate}%)${msg}`);
|
|
3187
|
-
}
|
|
3188
|
-
}
|
|
3189
|
-
console.log();
|
|
3190
|
-
const usage = getConfigDirUsage(configDir);
|
|
3191
|
-
const fmt = (n) => {
|
|
3192
|
-
if (n < 1024) return `${n} B`;
|
|
3193
|
-
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
|
|
3194
|
-
if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
3195
|
-
return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
|
|
3196
|
-
};
|
|
3197
|
-
const dirAnnotations = {
|
|
3198
|
-
models: "semantic search model \u2192 /index semantic-clear to free",
|
|
3199
|
-
index: "symbol index \u2192 /index clear to rebuild",
|
|
3200
|
-
history: "conversation history \u2192 auto-pruned after 30 days",
|
|
3201
|
-
logs: "crash logs",
|
|
3202
|
-
"memory-index": "chat memory index \u2192 /memory index-clear to free"
|
|
3203
|
-
};
|
|
3204
|
-
console.log(theme.heading("Disk Usage (~/.aicli):"));
|
|
3205
|
-
console.log(` total: ${theme.accent(fmt(usage.totalBytes))}`);
|
|
3206
|
-
for (const e of usage.entries.slice(0, 10)) {
|
|
3207
|
-
const note = dirAnnotations[e.name];
|
|
3208
|
-
const noteStr = note ? ` ${theme.dim("\xB7")} ${theme.dim(note)}` : "";
|
|
3209
|
-
console.log(` ${e.name.padEnd(18)} ${theme.dim(fmt(e.bytes))}${noteStr}`);
|
|
3210
|
-
}
|
|
3211
|
-
console.log();
|
|
3212
|
-
console.log(theme.success("\u2713 Health check complete\n"));
|
|
3187
|
+
const report = buildDoctorReport({
|
|
3188
|
+
config: ctx.config,
|
|
3189
|
+
providers: ctx.providers,
|
|
3190
|
+
cwd: process.cwd(),
|
|
3191
|
+
mcpStatuses: ctx.getMcpManager()?.getStatus() ?? []
|
|
3192
|
+
});
|
|
3193
|
+
console.log(formatDoctorReport(report, true));
|
|
3213
3194
|
}
|
|
3214
3195
|
},
|
|
3215
3196
|
{
|
|
@@ -3377,7 +3358,7 @@ Summary: ${fileMap.size} file(s) \u2014 ${newFiles} new, ${modifiedFiles} modifi
|
|
|
3377
3358
|
usage: "/hooks [list|inspect <id>|trust <id>|untrust <id>|disable]",
|
|
3378
3359
|
execute(args, ctx) {
|
|
3379
3360
|
const sub = (args[0] || "list").toLowerCase();
|
|
3380
|
-
const hooks = listHooks(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir());
|
|
3361
|
+
const hooks = listHooks(mergePluginHooks(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()), ctx.config.getConfigDir());
|
|
3381
3362
|
const findHook = (id) => hooks.find((h) => h.id === id || h.hash.startsWith(id ?? ""));
|
|
3382
3363
|
if (sub === "list") {
|
|
3383
3364
|
console.log(theme.heading(" Hooks"));
|
|
@@ -3456,7 +3437,7 @@ Summary: ${fileMap.size} file(s) \u2014 ${newFiles} new, ${modifiedFiles} modifi
|
|
|
3456
3437
|
console.log(" profile : " + (ctx.config.get("defaultPermissionProfile") ?? "legacy"));
|
|
3457
3438
|
console.log(" network : " + (ctx.config.get("networkPolicy")?.enabled ?? false ? "on" : "off"));
|
|
3458
3439
|
console.log(" autoMode : " + (ctx.getToolExecutor().sessionAutoMode ? "on" : "off"));
|
|
3459
|
-
console.log(" hooks : " + getPendingHookTrust(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()).length + " pending trust");
|
|
3440
|
+
console.log(" hooks : " + getPendingHookTrust(mergePluginHooks(ctx.config.get("hooks") ?? void 0, ctx.config.getConfigDir()), ctx.config.getConfigDir()).length + " pending trust");
|
|
3460
3441
|
console.log(` patterns : ${DEFAULT_PATTERNS.length} built-in + ${security.customPatterns?.length ?? 0} custom`);
|
|
3461
3442
|
console.log(` last save : ${ctx.sessions.lastRedactionHits} hit(s) redacted`);
|
|
3462
3443
|
console.log();
|
|
@@ -4277,22 +4258,22 @@ var CustomCommandManager = class {
|
|
|
4277
4258
|
this.commandsDir = commandsDir;
|
|
4278
4259
|
}
|
|
4279
4260
|
commands = /* @__PURE__ */ new Map();
|
|
4280
|
-
loadCommands() {
|
|
4261
|
+
loadCommands(extraDirs = []) {
|
|
4281
4262
|
this.commands.clear();
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4263
|
+
this.loadCommandDir(this.commandsDir, true);
|
|
4264
|
+
for (const dir of extraDirs) this.loadCommandDir(dir, false);
|
|
4265
|
+
return this.commands.size;
|
|
4266
|
+
}
|
|
4267
|
+
loadCommandDir(dir, createIfMissing) {
|
|
4268
|
+
if (!existsSync3(dir)) {
|
|
4269
|
+
if (createIfMissing) mkdirSync3(dir, { recursive: true });
|
|
4270
|
+
return;
|
|
4285
4271
|
}
|
|
4286
|
-
|
|
4287
|
-
for (const file of readdirSync(this.commandsDir)) {
|
|
4272
|
+
for (const file of readdirSync(dir)) {
|
|
4288
4273
|
if (extname(file) !== ".md") continue;
|
|
4289
|
-
const cmd = parseCommandFile(join3(
|
|
4290
|
-
if (cmd)
|
|
4291
|
-
this.commands.set(cmd.meta.name, cmd);
|
|
4292
|
-
count++;
|
|
4293
|
-
}
|
|
4274
|
+
const cmd = parseCommandFile(join3(dir, file));
|
|
4275
|
+
if (cmd && !this.commands.has(cmd.meta.name)) this.commands.set(cmd.meta.name, cmd);
|
|
4294
4276
|
}
|
|
4295
|
-
return count;
|
|
4296
4277
|
}
|
|
4297
4278
|
listCommands() {
|
|
4298
4279
|
return [...this.commands.values()];
|
|
@@ -4596,7 +4577,7 @@ function parseAtReferences(input2, cwd) {
|
|
|
4596
4577
|
continue;
|
|
4597
4578
|
}
|
|
4598
4579
|
if (mime) {
|
|
4599
|
-
const fileSize =
|
|
4580
|
+
const fileSize = statSync2(absPath).size;
|
|
4600
4581
|
if (fileSize > MAX_IMAGE_BYTES) {
|
|
4601
4582
|
refs.push({ path: rawPath, type: "toolarge" });
|
|
4602
4583
|
continue;
|
|
@@ -4670,7 +4651,7 @@ var Repl = class {
|
|
|
4670
4651
|
const permissionProfileName = this.config.get("defaultPermissionProfile") ?? "legacy";
|
|
4671
4652
|
const permissionProfiles = this.config.get("permissionProfiles") ?? {};
|
|
4672
4653
|
this.toolExecutor.setConfig({
|
|
4673
|
-
hookConfig: this.config.get("hooks") ?? void 0,
|
|
4654
|
+
hookConfig: mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir()),
|
|
4674
4655
|
hookConfigDir: this.config.getConfigDir(),
|
|
4675
4656
|
permissionRules: this.config.get("permissionRules") ?? [],
|
|
4676
4657
|
defaultPermission: this.config.get("defaultPermission") ?? "confirm",
|
|
@@ -4680,11 +4661,12 @@ var Repl = class {
|
|
|
4680
4661
|
workspaceRoot: process.cwd(),
|
|
4681
4662
|
networkPolicy: this.config.get("networkPolicy")
|
|
4682
4663
|
});
|
|
4683
|
-
const
|
|
4664
|
+
const effectiveHooks = mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir());
|
|
4665
|
+
const pendingHooks = getPendingHookTrust(effectiveHooks, this.config.getConfigDir());
|
|
4684
4666
|
if (pendingHooks.length > 0) {
|
|
4685
4667
|
process.stderr.write(theme.warning(" \u26A0 " + pendingHooks.length + " project hook(s) require trust. Run /hooks list and /hooks trust <id>.\n"));
|
|
4686
4668
|
}
|
|
4687
|
-
runLifecycleHooks(
|
|
4669
|
+
runLifecycleHooks(effectiveHooks, "SessionStart", { source: "repl" }, { configDir: this.config.getConfigDir() });
|
|
4688
4670
|
if (this.config.get("alwaysYolo") === true) {
|
|
4689
4671
|
this.toolExecutor.sessionAutoApprove = true;
|
|
4690
4672
|
}
|
|
@@ -4853,7 +4835,7 @@ var Repl = class {
|
|
|
4853
4835
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
4854
4836
|
let isDir;
|
|
4855
4837
|
try {
|
|
4856
|
-
isDir =
|
|
4838
|
+
isDir = statSync2(fullPath).isDirectory();
|
|
4857
4839
|
} catch {
|
|
4858
4840
|
continue;
|
|
4859
4841
|
}
|
|
@@ -4885,7 +4867,7 @@ ${treeLines.join("\n")}`
|
|
|
4885
4867
|
const fullPath = join4(dir, name);
|
|
4886
4868
|
let st;
|
|
4887
4869
|
try {
|
|
4888
|
-
st =
|
|
4870
|
+
st = statSync2(fullPath);
|
|
4889
4871
|
} catch {
|
|
4890
4872
|
continue;
|
|
4891
4873
|
}
|
|
@@ -4932,7 +4914,7 @@ ${content}
|
|
|
4932
4914
|
}
|
|
4933
4915
|
let isDir;
|
|
4934
4916
|
try {
|
|
4935
|
-
isDir =
|
|
4917
|
+
isDir = statSync2(absPath).isDirectory();
|
|
4936
4918
|
} catch {
|
|
4937
4919
|
return { success: false, charCount: 0, added: false, error: `Cannot access: ${dirPath}` };
|
|
4938
4920
|
}
|
|
@@ -5145,7 +5127,7 @@ ${skillContent}`);
|
|
|
5145
5127
|
return false;
|
|
5146
5128
|
}
|
|
5147
5129
|
const preDecisions = runLifecycleHooks(
|
|
5148
|
-
this.config.get("hooks") ?? void 0,
|
|
5130
|
+
mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir()),
|
|
5149
5131
|
"PreCompact",
|
|
5150
5132
|
{ sessionId: session.id, messageCount: session.messages.length, instruction },
|
|
5151
5133
|
{ configDir: this.config.getConfigDir(), onSummary: (msg) => process.stdout.write(theme.dim(" [hook] " + msg) + "\n") }
|
|
@@ -5221,7 +5203,7 @@ ${response.content.trim()}
|
|
|
5221
5203
|
const removedCount = session.compact(summaryMsg, ackMsg, COMPACT_KEEP_LAST);
|
|
5222
5204
|
const afterCount = session.messages.length;
|
|
5223
5205
|
runLifecycleHooks(
|
|
5224
|
-
this.config.get("hooks") ?? void 0,
|
|
5206
|
+
mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir()),
|
|
5225
5207
|
"PostCompact",
|
|
5226
5208
|
{ sessionId: session.id, beforeCount, afterCount, removedCount, keepLast: COMPACT_KEEP_LAST, instruction },
|
|
5227
5209
|
{ configDir: this.config.getConfigDir(), onSummary: (msg) => process.stdout.write(theme.dim(" [hook] " + msg) + "\n") }
|
|
@@ -5423,14 +5405,15 @@ Session '${this.resumeSessionId}' not found.
|
|
|
5423
5405
|
}
|
|
5424
5406
|
const skillsDir = join4(this.config.getConfigDir(), SKILLS_DIR_NAME);
|
|
5425
5407
|
this.skillManager = new SkillManager(skillsDir, this.config.get("ui").skillSizeWarn);
|
|
5426
|
-
const
|
|
5408
|
+
const pluginAssets = getActivePluginAssets(this.config.getConfigDir());
|
|
5409
|
+
const skillCount = this.skillManager.loadSkills(pluginAssets.skillDirs);
|
|
5427
5410
|
if (skillCount > 0) {
|
|
5428
5411
|
process.stdout.write(theme.dim(` \u{1F3AF} Skills: ${skillCount} available (use /skill to manage)
|
|
5429
5412
|
`));
|
|
5430
5413
|
}
|
|
5431
5414
|
const commandsDir = join4(this.config.getConfigDir(), CUSTOM_COMMANDS_DIR_NAME);
|
|
5432
5415
|
this.customCommandManager = new CustomCommandManager(commandsDir);
|
|
5433
|
-
const customCmdCount = this.customCommandManager.loadCommands();
|
|
5416
|
+
const customCmdCount = this.customCommandManager.loadCommands(pluginAssets.commandDirs);
|
|
5434
5417
|
if (customCmdCount > 0) {
|
|
5435
5418
|
process.stdout.write(theme.dim(` \u{1F4CB} Custom commands: ${customCmdCount} loaded (use /commands to list)
|
|
5436
5419
|
`));
|
|
@@ -5486,6 +5469,7 @@ Session '${this.resumeSessionId}' not found.
|
|
|
5486
5469
|
})();
|
|
5487
5470
|
const mcpEnabled = this.config.get("mcpEnabled") !== false;
|
|
5488
5471
|
const globalMcpServers = mcpEnabled ? this.config.get("mcpServers") ?? {} : {};
|
|
5472
|
+
const pluginMcpServers = mcpEnabled ? getActivePluginAssets(this.config.getConfigDir()).mcpServers : {};
|
|
5489
5473
|
const projectMcpResult = mcpEnabled ? this.loadProjectMcpConfig() : null;
|
|
5490
5474
|
if (!mcpEnabled) {
|
|
5491
5475
|
process.stdout.write(theme.dim(" \u{1F50C} MCP: disabled (config.mcpEnabled=false)\n"));
|
|
@@ -5507,10 +5491,13 @@ Session '${this.resumeSessionId}' not found.
|
|
|
5507
5491
|
);
|
|
5508
5492
|
}
|
|
5509
5493
|
}
|
|
5510
|
-
const mergedMcpServers = { ...globalMcpServers, ...projectMcpServers };
|
|
5494
|
+
const mergedMcpServers = { ...globalMcpServers, ...pluginMcpServers, ...projectMcpServers };
|
|
5511
5495
|
for (const id of Object.keys(globalMcpServers)) {
|
|
5512
5496
|
this.mcpServerSources.set(id, "global");
|
|
5513
5497
|
}
|
|
5498
|
+
for (const id of Object.keys(pluginMcpServers)) {
|
|
5499
|
+
this.mcpServerSources.set(id, "plugin");
|
|
5500
|
+
}
|
|
5514
5501
|
for (const id of Object.keys(projectMcpServers)) {
|
|
5515
5502
|
this.mcpServerSources.set(id, "project");
|
|
5516
5503
|
}
|
|
@@ -5518,6 +5505,7 @@ Session '${this.resumeSessionId}' not found.
|
|
|
5518
5505
|
if (Object.keys(mergedMcpServers).length > 0) {
|
|
5519
5506
|
this.mcpManager = new McpManager();
|
|
5520
5507
|
const mcpProjectCount = Object.keys(projectMcpServers).length;
|
|
5508
|
+
const mcpPluginCount = Object.keys(pluginMcpServers).length;
|
|
5521
5509
|
let bannerEmitted = false;
|
|
5522
5510
|
const emitBanner = (afterDeadline) => {
|
|
5523
5511
|
if (bannerEmitted) return;
|
|
@@ -5663,7 +5651,7 @@ Session '${this.resumeSessionId}' not found.
|
|
|
5663
5651
|
}
|
|
5664
5652
|
runUserPromptHooks(sessionId, userInput) {
|
|
5665
5653
|
const promptDecisions = runLifecycleHooks(
|
|
5666
|
-
this.config.get("hooks") ?? void 0,
|
|
5654
|
+
mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir()),
|
|
5667
5655
|
"UserPromptSubmit",
|
|
5668
5656
|
{ sessionId, prompt: userInput },
|
|
5669
5657
|
{ configDir: this.config.getConfigDir(), onSummary: (msg) => process.stdout.write(theme.dim(" [hook] " + msg) + "\n") }
|
|
@@ -6096,7 +6084,7 @@ Session '${this.resumeSessionId}' not found.
|
|
|
6096
6084
|
if (!entry.toLowerCase().startsWith(prefix.toLowerCase())) continue;
|
|
6097
6085
|
try {
|
|
6098
6086
|
const fullPath = join4(absDir, entry);
|
|
6099
|
-
const stat =
|
|
6087
|
+
const stat = statSync2(fullPath);
|
|
6100
6088
|
const rel = dir === "." ? entry : `${dir}/${entry}`;
|
|
6101
6089
|
results.push(stat.isDirectory() ? `${rel}/` : rel);
|
|
6102
6090
|
} catch {
|
|
@@ -7152,7 +7140,7 @@ Tip: You can continue the conversation by asking the AI to proceed.`
|
|
|
7152
7140
|
void this.shutdownAsync();
|
|
7153
7141
|
}
|
|
7154
7142
|
async shutdownAsync() {
|
|
7155
|
-
runLifecycleHooks(this.config.get("hooks") ?? void 0, "Stop", { sessionId: this.sessions.current?.id }, { configDir: this.config.getConfigDir() });
|
|
7143
|
+
runLifecycleHooks(mergePluginHooks(this.config.get("hooks") ?? void 0, this.config.getConfigDir()), "Stop", { sessionId: this.sessions.current?.id }, { configDir: this.config.getConfigDir() });
|
|
7156
7144
|
this.running = false;
|
|
7157
7145
|
const sessionId = this.sessions.current?.id;
|
|
7158
7146
|
if (sessionId) {
|
|
@@ -7267,7 +7255,7 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
7267
7255
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
7268
7256
|
process.exit(1);
|
|
7269
7257
|
}
|
|
7270
|
-
const { startWebServer } = await import("./server-
|
|
7258
|
+
const { startWebServer } = await import("./server-5E2AIXVX.js");
|
|
7271
7259
|
await startWebServer({ port, host: options.host });
|
|
7272
7260
|
});
|
|
7273
7261
|
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) => {
|
|
@@ -7434,16 +7422,20 @@ program.command("sessions").description("List recent conversation sessions").opt
|
|
|
7434
7422
|
console.log(footer + "\n");
|
|
7435
7423
|
});
|
|
7436
7424
|
program.command("usage").description("Show token + cost usage grouped by provider/model (cross-session)").option("--days <n>", "Only the last N days (inclusive of today)").option("--month <ym>", "Only a specific month, format YYYY-MM (e.g. 2026-06)").option("--json", "Output as JSON (for scripting)").action(async (options) => {
|
|
7437
|
-
const { runUsageCli } = await import("./usage-
|
|
7425
|
+
const { runUsageCli } = await import("./usage-BMK6M5U3.js");
|
|
7438
7426
|
await runUsageCli(options);
|
|
7439
7427
|
});
|
|
7440
7428
|
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) => {
|
|
7441
|
-
const { runDoctorCli } = await import("./doctor-cli-
|
|
7442
|
-
|
|
7429
|
+
const { runDoctorCli } = await import("./doctor-cli-KB2LUDF3.js");
|
|
7430
|
+
const argv = process.argv.slice(2);
|
|
7431
|
+
await runDoctorCli({
|
|
7432
|
+
json: !!options.json || argv.includes("--json"),
|
|
7433
|
+
resetStats: !!options.resetStats || argv.includes("--reset-stats")
|
|
7434
|
+
});
|
|
7443
7435
|
});
|
|
7444
7436
|
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) => {
|
|
7445
7437
|
try {
|
|
7446
|
-
const batch = await import("./batch-
|
|
7438
|
+
const batch = await import("./batch-CHAPYRVM.js");
|
|
7447
7439
|
switch (action) {
|
|
7448
7440
|
case "submit":
|
|
7449
7441
|
if (!arg) {
|
|
@@ -7486,7 +7478,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
|
|
|
7486
7478
|
}
|
|
7487
7479
|
});
|
|
7488
7480
|
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) => {
|
|
7489
|
-
const { startMcpServer } = await import("./server-
|
|
7481
|
+
const { startMcpServer } = await import("./server-Z6O3G2LY.js");
|
|
7490
7482
|
await startMcpServer({
|
|
7491
7483
|
allowDestructive: !!options.allowDestructive,
|
|
7492
7484
|
allowOutsideCwd: !!options.allowOutsideCwd,
|
|
@@ -7499,7 +7491,7 @@ program.command("pr <action> [target]").description("PR review helpers: review |
|
|
|
7499
7491
|
console.error(`Unknown pr action: ${action}. Use review | security-review | summarize.`);
|
|
7500
7492
|
process.exit(1);
|
|
7501
7493
|
}
|
|
7502
|
-
const { runPrCli } = await import("./pr-
|
|
7494
|
+
const { runPrCli } = await import("./pr-YQGH72N6.js");
|
|
7503
7495
|
const result = await runPrCli({
|
|
7504
7496
|
action,
|
|
7505
7497
|
target,
|
|
@@ -7519,8 +7511,8 @@ program.command("pr <action> [target]").description("PR review helpers: review |
|
|
|
7519
7511
|
process.exit(result.exitCode);
|
|
7520
7512
|
});
|
|
7521
7513
|
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 or URL; diff fetched via gh pr diff <value>", (v) => /^#?\d+$/.test(v) ? parseInt(v.replace(/^#/, ""), 10) : v).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)").option("--json", "Output a structured JSON report").option("--markdown", "Output Markdown report (default)").option("--sarif", "Output SARIF 2.1.0 for code scanning artifacts").option("--fail-on-security-high", "Fail when the security review contains HIGH/CRITICAL findings (default)").option("--no-fail-on-security-high", "Do not fail on security HIGH/CRITICAL findings").option("--fail-on-test-failure", "Fail when the report mentions test failures (default)").option("--no-fail-on-test-failure", "Do not fail on test failure findings").option("--fail-on-lint-failure", "Fail when the report mentions lint/typecheck failures (default)").option("--no-fail-on-lint-failure", "Do not fail on lint/typecheck failure findings").action(async (options) => {
|
|
7522
|
-
const { runCi } = await import("./ci-
|
|
7523
|
-
const { formatCiResult } = await import("./ci-format-
|
|
7514
|
+
const { runCi } = await import("./ci-QPP66T53.js");
|
|
7515
|
+
const { formatCiResult } = await import("./ci-format-5S3EEYRK.js");
|
|
7524
7516
|
const formats = [options.json, options.markdown, options.sarif].filter(Boolean).length;
|
|
7525
7517
|
if (formats > 1) {
|
|
7526
7518
|
console.error("Choose only one output format: --json, --markdown, or --sarif.");
|
|
@@ -7677,7 +7669,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
7677
7669
|
}),
|
|
7678
7670
|
config.get("customProviders")
|
|
7679
7671
|
);
|
|
7680
|
-
const { startHub } = await import("./hub-
|
|
7672
|
+
const { startHub } = await import("./hub-DIM7SKKY.js");
|
|
7681
7673
|
await startHub(
|
|
7682
7674
|
{
|
|
7683
7675
|
topic: topic ?? "",
|