jinzd-ai-cli 0.4.218 → 0.4.220
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 +102 -99
- package/README.zh-CN.md +40 -38
- package/dist/{batch-7V7OTMUP.js → batch-QBSKTLTO.js} +3 -3
- package/dist/{chunk-TZQHYZKT.js → chunk-5ULLIOVC.js} +1 -0
- package/dist/{chunk-P4VBLXKS.js → chunk-5WBNXYDJ.js} +2 -2
- package/dist/chunk-ALQN7VUJ.js +604 -0
- package/dist/{chunk-C2Z42DI5.js → chunk-CAUHLHDR.js} +1 -1
- package/dist/{chunk-GX3HSGJX.js → chunk-IZW5LMI6.js} +166 -638
- package/dist/chunk-P3LKFA54.js +639 -0
- package/dist/{chunk-5CA2TJ5F.js → chunk-P4DYAGUI.js} +1 -1
- package/dist/{chunk-L4UREAID.js → chunk-P4PTXCHY.js} +6 -5
- package/dist/{chunk-QMXC327F.js → chunk-PUBCJF7E.js} +213 -175
- package/dist/{chunk-NTCB7CMT.js → chunk-QZYNRCPX.js} +1 -1
- package/dist/{chunk-H2UIHGHH.js → chunk-VHX7KZDY.js} +29 -189
- package/dist/{chunk-VGFTM3XT.js → chunk-Y25MSSUP.js} +1 -1
- package/dist/{ci-L6GH2WVC.js → ci-5SNXGM3M.js} +6 -6
- package/dist/{ci-format-WW7454AY.js → ci-format-57QQTHQE.js} +2 -2
- package/dist/{constants-NCTFSHDU.js → constants-ML5KFEOH.js} +1 -1
- package/dist/doctor-cli-ZRH3XZ3R.js +17 -0
- package/dist/electron-server.js +836 -470
- package/dist/{hub-CDL6T7CP.js → hub-IPLMJ6TJ.js} +1 -1
- package/dist/index.js +125 -194
- package/dist/{pr-D6PEKEGK.js → pr-GJYDAPK4.js} +8 -7
- package/dist/{run-tests-NXVVKAK2.js → run-tests-GK5AIAV2.js} +1 -1
- package/dist/{run-tests-SWU2XEV7.js → run-tests-KLQAI5CX.js} +2 -2
- package/dist/{server-WUT7VYTD.js → server-5FZDALHH.js} +10 -10
- package/dist/{server-LHYSS6CK.js → server-RU36PRSH.js} +74 -83
- package/dist/{task-orchestrator-C5AA2BI5.js → task-orchestrator-JMHPVNUO.js} +10 -10
- package/dist/{usage-6ZUUJBI2.js → usage-IRMRCCKN.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-MWKE2TNS.js +0 -129
- package/dist/chunk-OUC75QCF.js +0 -166
- package/dist/doctor-cli-EWMFBP5Q.js +0 -226
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ToolRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IZW5LMI6.js";
|
|
5
|
+
import "./chunk-K3CF65QH.js";
|
|
5
6
|
import "./chunk-T2NL5ZIA.js";
|
|
6
7
|
import "./chunk-BXP6YZ2P.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-Y25MSSUP.js";
|
|
9
|
+
import "./chunk-4BKXL7SM.js";
|
|
10
|
+
import "./chunk-TB4W4Y4T.js";
|
|
11
|
+
import "./chunk-KHYD3WXE.js";
|
|
12
|
+
import "./chunk-SLSWPBK3.js";
|
|
8
13
|
import {
|
|
9
14
|
runTool
|
|
10
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ALQN7VUJ.js";
|
|
11
16
|
import {
|
|
12
17
|
getDangerLevel,
|
|
13
18
|
schemaToJsonSchema
|
|
14
19
|
} from "./chunk-XPBEJB27.js";
|
|
15
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-5ULLIOVC.js";
|
|
16
21
|
import {
|
|
17
22
|
VERSION
|
|
18
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-QZYNRCPX.js";
|
|
19
24
|
import "./chunk-HOSJZMQS.js";
|
|
20
|
-
import "./chunk-4BKXL7SM.js";
|
|
21
|
-
import "./chunk-TB4W4Y4T.js";
|
|
22
|
-
import "./chunk-KHYD3WXE.js";
|
|
23
|
-
import "./chunk-SLSWPBK3.js";
|
|
24
|
-
import "./chunk-K3CF65QH.js";
|
|
25
25
|
import "./chunk-CKH4KQ4E.js";
|
|
26
26
|
import "./chunk-IW3Q7AE5.js";
|
|
27
27
|
|
|
@@ -17,14 +17,13 @@ import {
|
|
|
17
17
|
SkillManager,
|
|
18
18
|
autoTrimSessionIfNeeded,
|
|
19
19
|
buildInitPrompt,
|
|
20
|
-
loadContextFiles,
|
|
21
20
|
loadDevState,
|
|
22
21
|
persistToolRound,
|
|
23
22
|
readGitDiff,
|
|
24
23
|
scanDirTree,
|
|
25
24
|
scanProject,
|
|
26
25
|
setupProxy
|
|
27
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-VHX7KZDY.js";
|
|
28
27
|
import {
|
|
29
28
|
buildReviewPrompt,
|
|
30
29
|
buildSecurityReviewPrompt
|
|
@@ -40,49 +39,38 @@ import {
|
|
|
40
39
|
clearRecentlyDeniedAutoActions,
|
|
41
40
|
defaultActionClassifier,
|
|
42
41
|
deleteMemoryEntry,
|
|
43
|
-
describePlugin,
|
|
44
42
|
estimateTokens,
|
|
45
43
|
expireMemoryEntry,
|
|
46
44
|
exportMemoryEntries,
|
|
47
45
|
formatMemoryForPrompt,
|
|
48
46
|
formatPermissionProfileWarning,
|
|
49
|
-
getActivePluginAssets,
|
|
50
|
-
getInstalledPlugin,
|
|
51
|
-
getPendingHookTrust,
|
|
52
47
|
getPreferredAgentName,
|
|
53
48
|
getRecentlyDeniedAutoActions,
|
|
54
49
|
googleSearchContext,
|
|
55
50
|
groupCallsByPhase,
|
|
56
|
-
installPlugin,
|
|
57
51
|
isMemoryExpired,
|
|
58
52
|
listAgentConfigs,
|
|
59
53
|
listAgentRuns,
|
|
60
|
-
listInstalledPlugins,
|
|
61
54
|
listMemoryEntries,
|
|
62
55
|
memoryStorePath,
|
|
63
|
-
mergePluginHooks,
|
|
64
|
-
pluginRoot,
|
|
65
56
|
recordRecentlyDeniedAutoAction,
|
|
66
57
|
renderDiff,
|
|
67
58
|
requestAgentStop,
|
|
68
59
|
resolveAgentConfig,
|
|
69
|
-
runHook,
|
|
70
|
-
runLifecycleHooks,
|
|
71
60
|
runSafePhases,
|
|
72
61
|
runWithSessionKey,
|
|
73
62
|
setContextWindow,
|
|
74
63
|
setMaxOutputCap,
|
|
75
|
-
setPluginEnabled,
|
|
76
64
|
setPreferredAgentName,
|
|
77
65
|
spawnAgentContext,
|
|
78
66
|
truncateOutput,
|
|
79
|
-
trustPlugin,
|
|
80
67
|
undoStack,
|
|
81
68
|
updateMemoryApproval
|
|
82
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-IZW5LMI6.js";
|
|
70
|
+
import "./chunk-K3CF65QH.js";
|
|
83
71
|
import "./chunk-T2NL5ZIA.js";
|
|
84
72
|
import "./chunk-BXP6YZ2P.js";
|
|
85
|
-
import "./chunk-
|
|
73
|
+
import "./chunk-Y25MSSUP.js";
|
|
86
74
|
import {
|
|
87
75
|
SessionManager,
|
|
88
76
|
getContentText
|
|
@@ -91,12 +79,35 @@ import {
|
|
|
91
79
|
computeCost,
|
|
92
80
|
formatCost
|
|
93
81
|
} from "./chunk-E44DTERW.js";
|
|
82
|
+
import "./chunk-4BKXL7SM.js";
|
|
83
|
+
import "./chunk-TB4W4Y4T.js";
|
|
84
|
+
import "./chunk-KHYD3WXE.js";
|
|
85
|
+
import {
|
|
86
|
+
scanString
|
|
87
|
+
} from "./chunk-SLSWPBK3.js";
|
|
88
|
+
import {
|
|
89
|
+
buildDoctorReport,
|
|
90
|
+
formatDoctorReport,
|
|
91
|
+
loadContextFiles
|
|
92
|
+
} from "./chunk-P3LKFA54.js";
|
|
94
93
|
import {
|
|
95
94
|
ProviderRegistry
|
|
96
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-PUBCJF7E.js";
|
|
97
96
|
import {
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
describePlugin,
|
|
98
|
+
getActivePluginAssets,
|
|
99
|
+
getInstalledPlugin,
|
|
100
|
+
getPendingHookTrust,
|
|
101
|
+
installPlugin,
|
|
102
|
+
listInstalledPlugins,
|
|
103
|
+
mergePluginHooks,
|
|
104
|
+
pluginRoot,
|
|
105
|
+
runHook,
|
|
106
|
+
runLifecycleHooks,
|
|
107
|
+
runTool,
|
|
108
|
+
setPluginEnabled,
|
|
109
|
+
trustPlugin
|
|
110
|
+
} from "./chunk-ALQN7VUJ.js";
|
|
100
111
|
import {
|
|
101
112
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
102
113
|
TEE_FINAL_USER_NUDGE,
|
|
@@ -115,8 +126,8 @@ import {
|
|
|
115
126
|
} from "./chunk-XPBEJB27.js";
|
|
116
127
|
import {
|
|
117
128
|
ConfigManager
|
|
118
|
-
} from "./chunk-
|
|
119
|
-
import "./chunk-
|
|
129
|
+
} from "./chunk-5WBNXYDJ.js";
|
|
130
|
+
import "./chunk-5ULLIOVC.js";
|
|
120
131
|
import {
|
|
121
132
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
122
133
|
AUTHOR,
|
|
@@ -133,19 +144,12 @@ import {
|
|
|
133
144
|
SKILLS_DIR_NAME,
|
|
134
145
|
VERSION,
|
|
135
146
|
buildUserIdentityPrompt
|
|
136
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-QZYNRCPX.js";
|
|
137
148
|
import {
|
|
138
149
|
formatGitContextForPrompt,
|
|
139
150
|
getGitContext,
|
|
140
151
|
getGitRoot
|
|
141
152
|
} from "./chunk-HOSJZMQS.js";
|
|
142
|
-
import "./chunk-4BKXL7SM.js";
|
|
143
|
-
import "./chunk-TB4W4Y4T.js";
|
|
144
|
-
import "./chunk-KHYD3WXE.js";
|
|
145
|
-
import {
|
|
146
|
-
scanString
|
|
147
|
-
} from "./chunk-SLSWPBK3.js";
|
|
148
|
-
import "./chunk-K3CF65QH.js";
|
|
149
153
|
import "./chunk-CKH4KQ4E.js";
|
|
150
154
|
import {
|
|
151
155
|
atomicWriteFileSync
|
|
@@ -1678,13 +1682,39 @@ ${summaryContent}`,
|
|
|
1678
1682
|
break;
|
|
1679
1683
|
}
|
|
1680
1684
|
case "model": {
|
|
1681
|
-
const
|
|
1682
|
-
if (!
|
|
1683
|
-
this.send({ type: "error", message: "Usage: /model <id
|
|
1685
|
+
const sub = args[0];
|
|
1686
|
+
if (!sub) {
|
|
1687
|
+
this.send({ type: "error", message: "Usage: /model <id>|refresh [provider]|cache [clear [provider]]" });
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
if (sub === "refresh") {
|
|
1691
|
+
const providerId = args[1] ?? this.currentProvider;
|
|
1692
|
+
try {
|
|
1693
|
+
const models2 = await this.providers.refreshModels(providerId);
|
|
1694
|
+
this.send({ type: "info", message: `Refreshed ${models2.length} model(s) for ${providerId}.` });
|
|
1695
|
+
this.sendStatus();
|
|
1696
|
+
} catch (err) {
|
|
1697
|
+
this.send({ type: "error", message: `Model refresh failed: ${err instanceof Error ? err.message : String(err)}` });
|
|
1698
|
+
}
|
|
1699
|
+
return;
|
|
1700
|
+
}
|
|
1701
|
+
if (sub === "cache") {
|
|
1702
|
+
if ((args[1] ?? "").toLowerCase() === "clear") {
|
|
1703
|
+
const providerId = args[2];
|
|
1704
|
+
this.providers.clearModelCache(providerId);
|
|
1705
|
+
this.send({ type: "info", message: providerId ? `Cleared model cache for ${providerId}.` : "Cleared model cache." });
|
|
1706
|
+
return;
|
|
1707
|
+
}
|
|
1708
|
+
const rows = this.providers.getModelCacheStatus();
|
|
1709
|
+
this.send({
|
|
1710
|
+
type: "info",
|
|
1711
|
+
message: rows.length === 0 ? "Model cache is empty. Use /model refresh to populate it." : rows.map((row) => `${row.providerId}: ${row.count} model(s), fetched ${row.fetchedAt}`).join("\n")
|
|
1712
|
+
});
|
|
1684
1713
|
return;
|
|
1685
1714
|
}
|
|
1686
|
-
const
|
|
1687
|
-
const
|
|
1715
|
+
const modelId = sub;
|
|
1716
|
+
const models = await this.providers.listModels(this.currentProvider);
|
|
1717
|
+
const found = models.find((m) => m.id === modelId);
|
|
1688
1718
|
if (!found) {
|
|
1689
1719
|
this.send({ type: "error", message: `Model "${modelId}" not found` });
|
|
1690
1720
|
return;
|
|
@@ -2761,7 +2791,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2761
2791
|
case "test": {
|
|
2762
2792
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2763
2793
|
try {
|
|
2764
|
-
const { executeTests } = await import("./run-tests-
|
|
2794
|
+
const { executeTests } = await import("./run-tests-KLQAI5CX.js");
|
|
2765
2795
|
const argStr = args.join(" ").trim();
|
|
2766
2796
|
let testArgs = {};
|
|
2767
2797
|
if (argStr) {
|
|
@@ -2800,53 +2830,13 @@ Use /context reload to load it.` });
|
|
|
2800
2830
|
}
|
|
2801
2831
|
// ── /doctor ─────────────────────────────────────────────────────
|
|
2802
2832
|
case "doctor": {
|
|
2803
|
-
const
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
}
|
|
2811
|
-
lines.push("");
|
|
2812
|
-
const configDir = this.config.getConfigDir();
|
|
2813
|
-
lines.push("**Config Files:**");
|
|
2814
|
-
lines.push(` Dir: ${configDir}`);
|
|
2815
|
-
const checkFile = (label, filePath) => {
|
|
2816
|
-
const exists = existsSync2(filePath);
|
|
2817
|
-
let extra = "";
|
|
2818
|
-
if (exists) {
|
|
2819
|
-
try {
|
|
2820
|
-
extra = ` (${statSync(filePath).size} bytes)`;
|
|
2821
|
-
} catch {
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
lines.push(` ${exists ? "\u2713" : "\u2013"} ${label.padEnd(14)} ${exists ? filePath + extra : "(not found)"}`);
|
|
2825
|
-
};
|
|
2826
|
-
checkFile("config.json", join(configDir, "config.json"));
|
|
2827
|
-
checkFile("memory.md", join(configDir, MEMORY_FILE_NAME));
|
|
2828
|
-
checkFile("dev-state.md", join(configDir, "dev-state.md"));
|
|
2829
|
-
lines.push("");
|
|
2830
|
-
if (this.mcpManager) {
|
|
2831
|
-
lines.push("**MCP Servers:**");
|
|
2832
|
-
const statuses = this.mcpManager.getStatus();
|
|
2833
|
-
if (statuses.length === 0) {
|
|
2834
|
-
lines.push(" (no servers configured)");
|
|
2835
|
-
} else {
|
|
2836
|
-
for (const s of statuses) {
|
|
2837
|
-
const state = s.connected ? `connected \xB7 ${s.serverName} \xB7 ${s.toolCount} tools` : `disconnected${s.error ? ` \xB7 ${s.error}` : ""}`;
|
|
2838
|
-
lines.push(` ${s.connected ? "\u2713" : "\u2717"} ${s.serverId.padEnd(16)} ${state}`);
|
|
2839
|
-
}
|
|
2840
|
-
}
|
|
2841
|
-
lines.push("");
|
|
2842
|
-
}
|
|
2843
|
-
lines.push("**Current Session:**");
|
|
2844
|
-
lines.push(` Provider: ${this.currentProvider}`);
|
|
2845
|
-
lines.push(` Model: ${this.currentModel}`);
|
|
2846
|
-
lines.push(` Version: ${VERSION}`);
|
|
2847
|
-
lines.push("");
|
|
2848
|
-
lines.push("\u2713 Health check complete");
|
|
2849
|
-
this.send({ type: "info", message: lines.join("\n") });
|
|
2833
|
+
const report = buildDoctorReport({
|
|
2834
|
+
config: this.config,
|
|
2835
|
+
providers: this.providers,
|
|
2836
|
+
cwd: process.cwd(),
|
|
2837
|
+
mcpStatuses: this.mcpManager?.getStatus() ?? []
|
|
2838
|
+
});
|
|
2839
|
+
this.send({ type: "info", message: formatDoctorReport(report, false) });
|
|
2850
2840
|
break;
|
|
2851
2841
|
}
|
|
2852
2842
|
// ── /about ──────────────────────────────────────────────────────
|
|
@@ -3637,7 +3627,8 @@ async function startWebServer(options = {}) {
|
|
|
3637
3627
|
timeout: config.get("timeouts")[id],
|
|
3638
3628
|
proxy: config.get("proxy")
|
|
3639
3629
|
}),
|
|
3640
|
-
config.get("customProviders")
|
|
3630
|
+
config.get("customProviders"),
|
|
3631
|
+
config.getConfigDir()
|
|
3641
3632
|
);
|
|
3642
3633
|
if (options._extraProviders) {
|
|
3643
3634
|
for (const p of options._extraProviders) {
|
|
@@ -3,27 +3,27 @@ import {
|
|
|
3
3
|
ToolRegistry,
|
|
4
4
|
googleSearchContext,
|
|
5
5
|
truncateOutput
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IZW5LMI6.js";
|
|
7
|
+
import "./chunk-K3CF65QH.js";
|
|
7
8
|
import "./chunk-T2NL5ZIA.js";
|
|
8
9
|
import "./chunk-BXP6YZ2P.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-Y25MSSUP.js";
|
|
11
|
+
import "./chunk-4BKXL7SM.js";
|
|
12
|
+
import "./chunk-TB4W4Y4T.js";
|
|
13
|
+
import "./chunk-KHYD3WXE.js";
|
|
14
|
+
import "./chunk-SLSWPBK3.js";
|
|
10
15
|
import {
|
|
11
16
|
runTool
|
|
12
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ALQN7VUJ.js";
|
|
13
18
|
import {
|
|
14
19
|
getDangerLevel,
|
|
15
20
|
runLeanAgentLoop
|
|
16
21
|
} from "./chunk-XPBEJB27.js";
|
|
17
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-5ULLIOVC.js";
|
|
18
23
|
import {
|
|
19
24
|
SUBAGENT_ALLOWED_TOOLS
|
|
20
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-QZYNRCPX.js";
|
|
21
26
|
import "./chunk-HOSJZMQS.js";
|
|
22
|
-
import "./chunk-4BKXL7SM.js";
|
|
23
|
-
import "./chunk-TB4W4Y4T.js";
|
|
24
|
-
import "./chunk-KHYD3WXE.js";
|
|
25
|
-
import "./chunk-SLSWPBK3.js";
|
|
26
|
-
import "./chunk-K3CF65QH.js";
|
|
27
27
|
import "./chunk-CKH4KQ4E.js";
|
|
28
28
|
import {
|
|
29
29
|
atomicWriteFileSync
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
} from "./chunk-E44DTERW.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigManager
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-5WBNXYDJ.js";
|
|
12
|
+
import "./chunk-5ULLIOVC.js";
|
|
13
|
+
import "./chunk-QZYNRCPX.js";
|
|
14
14
|
import "./chunk-IW3Q7AE5.js";
|
|
15
15
|
|
|
16
16
|
// src/cli/usage.ts
|
package/package.json
CHANGED
package/dist/chunk-MWKE2TNS.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
CONFIG_DIR_NAME
|
|
4
|
-
} from "./chunk-NTCB7CMT.js";
|
|
5
|
-
import {
|
|
6
|
-
atomicWriteFileSync
|
|
7
|
-
} from "./chunk-IW3Q7AE5.js";
|
|
8
|
-
|
|
9
|
-
// src/diagnostics/tool-stats.ts
|
|
10
|
-
import { existsSync, readFileSync, mkdirSync } from "fs";
|
|
11
|
-
import { join, dirname } from "path";
|
|
12
|
-
import { homedir } from "os";
|
|
13
|
-
var STATS_FILE_NAME = "tool-stats.json";
|
|
14
|
-
var STATS_VERSION = 1;
|
|
15
|
-
var FLUSH_EVERY_N = 50;
|
|
16
|
-
var state = null;
|
|
17
|
-
var dirty = false;
|
|
18
|
-
var pendingWrites = 0;
|
|
19
|
-
var configDirOverride;
|
|
20
|
-
function statsFilePath() {
|
|
21
|
-
const base = configDirOverride ?? join(homedir(), CONFIG_DIR_NAME);
|
|
22
|
-
return join(base, STATS_FILE_NAME);
|
|
23
|
-
}
|
|
24
|
-
function load() {
|
|
25
|
-
const path = statsFilePath();
|
|
26
|
-
if (!existsSync(path)) {
|
|
27
|
-
return { version: STATS_VERSION, startedAt: (/* @__PURE__ */ new Date()).toISOString(), entries: {} };
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
31
|
-
if (raw.version !== STATS_VERSION || !raw.entries) {
|
|
32
|
-
return { version: STATS_VERSION, startedAt: (/* @__PURE__ */ new Date()).toISOString(), entries: {} };
|
|
33
|
-
}
|
|
34
|
-
return raw;
|
|
35
|
-
} catch {
|
|
36
|
-
return { version: STATS_VERSION, startedAt: (/* @__PURE__ */ new Date()).toISOString(), entries: {} };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function ensureLoaded() {
|
|
40
|
-
if (state === null) state = load();
|
|
41
|
-
return state;
|
|
42
|
-
}
|
|
43
|
-
function recordToolCall(name, durationMs, ok, errorMessage) {
|
|
44
|
-
const s = ensureLoaded();
|
|
45
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
46
|
-
let entry = s.entries[name];
|
|
47
|
-
if (!entry) {
|
|
48
|
-
entry = {
|
|
49
|
-
name,
|
|
50
|
-
calls: 0,
|
|
51
|
-
failures: 0,
|
|
52
|
-
totalDurationMs: 0,
|
|
53
|
-
firstSeenAt: now,
|
|
54
|
-
lastUsedAt: now
|
|
55
|
-
};
|
|
56
|
-
s.entries[name] = entry;
|
|
57
|
-
}
|
|
58
|
-
entry.calls += 1;
|
|
59
|
-
entry.totalDurationMs += Math.max(0, Math.round(durationMs));
|
|
60
|
-
entry.lastUsedAt = now;
|
|
61
|
-
if (!ok) {
|
|
62
|
-
entry.failures += 1;
|
|
63
|
-
entry.lastFailureAt = now;
|
|
64
|
-
if (errorMessage) entry.lastFailureMessage = errorMessage.slice(0, 300);
|
|
65
|
-
}
|
|
66
|
-
dirty = true;
|
|
67
|
-
pendingWrites += 1;
|
|
68
|
-
if (pendingWrites >= FLUSH_EVERY_N) {
|
|
69
|
-
flush();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
async function runTool(tool, args, name) {
|
|
73
|
-
const start = Date.now();
|
|
74
|
-
try {
|
|
75
|
-
const result = await tool.execute(args);
|
|
76
|
-
recordToolCall(name, Date.now() - start, true);
|
|
77
|
-
return result;
|
|
78
|
-
} catch (err) {
|
|
79
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
80
|
-
recordToolCall(name, Date.now() - start, false, msg);
|
|
81
|
-
throw err;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function flush() {
|
|
85
|
-
if (!dirty || state === null) return;
|
|
86
|
-
const path = statsFilePath();
|
|
87
|
-
try {
|
|
88
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
89
|
-
atomicWriteFileSync(path, JSON.stringify(state, null, 2));
|
|
90
|
-
dirty = false;
|
|
91
|
-
pendingWrites = 0;
|
|
92
|
-
} catch {
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
function getStatsSnapshot() {
|
|
96
|
-
const s = ensureLoaded();
|
|
97
|
-
return Object.values(s.entries).map((e) => ({ ...e }));
|
|
98
|
-
}
|
|
99
|
-
function getTopFailingTools(limit = 5) {
|
|
100
|
-
return getStatsSnapshot().filter((e) => e.failures > 0).sort((a, b) => {
|
|
101
|
-
const rateA = a.failures / Math.max(1, a.calls);
|
|
102
|
-
const rateB = b.failures / Math.max(1, b.calls);
|
|
103
|
-
if (rateB !== rateA) return rateB - rateA;
|
|
104
|
-
return b.failures - a.failures;
|
|
105
|
-
}).slice(0, limit);
|
|
106
|
-
}
|
|
107
|
-
function getTopUsedTools(limit = 5) {
|
|
108
|
-
return getStatsSnapshot().sort((a, b) => b.calls - a.calls).slice(0, limit);
|
|
109
|
-
}
|
|
110
|
-
function resetStats() {
|
|
111
|
-
state = { version: STATS_VERSION, startedAt: (/* @__PURE__ */ new Date()).toISOString(), entries: {} };
|
|
112
|
-
dirty = true;
|
|
113
|
-
flush();
|
|
114
|
-
}
|
|
115
|
-
var exitHookInstalled = false;
|
|
116
|
-
function installFlushOnExit() {
|
|
117
|
-
if (exitHookInstalled) return;
|
|
118
|
-
exitHookInstalled = true;
|
|
119
|
-
process.on("exit", () => flush());
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export {
|
|
123
|
-
runTool,
|
|
124
|
-
getStatsSnapshot,
|
|
125
|
-
getTopFailingTools,
|
|
126
|
-
getTopUsedTools,
|
|
127
|
-
resetStats,
|
|
128
|
-
installFlushOnExit
|
|
129
|
-
};
|
package/dist/chunk-OUC75QCF.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
CONFIG_DIR_NAME,
|
|
4
|
-
VERSION
|
|
5
|
-
} from "./chunk-NTCB7CMT.js";
|
|
6
|
-
|
|
7
|
-
// src/diagnostics/crash-log.ts
|
|
8
|
-
import {
|
|
9
|
-
existsSync,
|
|
10
|
-
mkdirSync,
|
|
11
|
-
readdirSync,
|
|
12
|
-
readFileSync,
|
|
13
|
-
statSync,
|
|
14
|
-
unlinkSync,
|
|
15
|
-
writeFileSync
|
|
16
|
-
} from "fs";
|
|
17
|
-
import { join } from "path";
|
|
18
|
-
import { homedir, platform, release, arch } from "os";
|
|
19
|
-
var LOGS_DIR_NAME = "logs";
|
|
20
|
-
var CRASH_LOG_PREFIX = "crash-";
|
|
21
|
-
var MAX_CRASH_FILES = 20;
|
|
22
|
-
function getLogsDir(configDir) {
|
|
23
|
-
const base = configDir ?? join(homedir(), CONFIG_DIR_NAME);
|
|
24
|
-
return join(base, LOGS_DIR_NAME);
|
|
25
|
-
}
|
|
26
|
-
function ensureLogsDir(configDir) {
|
|
27
|
-
const dir = getLogsDir(configDir);
|
|
28
|
-
if (!existsSync(dir)) {
|
|
29
|
-
mkdirSync(dir, { recursive: true });
|
|
30
|
-
}
|
|
31
|
-
return dir;
|
|
32
|
-
}
|
|
33
|
-
function isoTimestampForFilename(d = /* @__PURE__ */ new Date()) {
|
|
34
|
-
return d.toISOString().replace(/[:.]/g, "-");
|
|
35
|
-
}
|
|
36
|
-
function writeCrashLog(err, context, configDir) {
|
|
37
|
-
try {
|
|
38
|
-
const dir = ensureLogsDir(configDir);
|
|
39
|
-
const ts = /* @__PURE__ */ new Date();
|
|
40
|
-
const file = join(dir, `${CRASH_LOG_PREFIX}${isoTimestampForFilename(ts)}.log`);
|
|
41
|
-
const errMessage = err instanceof Error ? err.message : String(err);
|
|
42
|
-
const errStack = err instanceof Error ? err.stack ?? "(no stack)" : "(non-Error thrown)";
|
|
43
|
-
const lines = [
|
|
44
|
-
`# ai-cli crash log`,
|
|
45
|
-
`timestamp: ${ts.toISOString()}`,
|
|
46
|
-
`kind: ${context.kind}`,
|
|
47
|
-
`version: ${VERSION}`,
|
|
48
|
-
`node: ${process.version}`,
|
|
49
|
-
`platform: ${platform()} ${release()} (${arch()})`,
|
|
50
|
-
`pid: ${process.pid}`,
|
|
51
|
-
context.provider ? `provider: ${context.provider}` : "",
|
|
52
|
-
context.model ? `model: ${context.model}` : "",
|
|
53
|
-
context.lastAction ? `lastAction: ${truncate(context.lastAction, 500)}` : "",
|
|
54
|
-
"",
|
|
55
|
-
`## message`,
|
|
56
|
-
errMessage,
|
|
57
|
-
"",
|
|
58
|
-
`## stack`,
|
|
59
|
-
errStack,
|
|
60
|
-
""
|
|
61
|
-
].filter(Boolean);
|
|
62
|
-
writeFileSync(file, lines.join("\n"), "utf-8");
|
|
63
|
-
pruneOldCrashes(configDir);
|
|
64
|
-
return file;
|
|
65
|
-
} catch {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function truncate(s, n) {
|
|
70
|
-
return s.length <= n ? s : s.slice(0, n) + "\u2026";
|
|
71
|
-
}
|
|
72
|
-
function pruneOldCrashes(configDir) {
|
|
73
|
-
try {
|
|
74
|
-
const dir = getLogsDir(configDir);
|
|
75
|
-
if (!existsSync(dir)) return;
|
|
76
|
-
const entries = readdirSync(dir).filter((f) => f.startsWith(CRASH_LOG_PREFIX) && f.endsWith(".log")).map((f) => {
|
|
77
|
-
const full = join(dir, f);
|
|
78
|
-
let mtime = 0;
|
|
79
|
-
try {
|
|
80
|
-
mtime = statSync(full).mtimeMs;
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
return { file: full, mtime };
|
|
84
|
-
}).sort((a, b) => b.mtime - a.mtime);
|
|
85
|
-
for (const e of entries.slice(MAX_CRASH_FILES)) {
|
|
86
|
-
try {
|
|
87
|
-
unlinkSync(e.file);
|
|
88
|
-
} catch {
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
} catch {
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function listRecentCrashes(limit = 10, configDir) {
|
|
95
|
-
const dir = getLogsDir(configDir);
|
|
96
|
-
if (!existsSync(dir)) return [];
|
|
97
|
-
const files = [];
|
|
98
|
-
let names;
|
|
99
|
-
try {
|
|
100
|
-
names = readdirSync(dir);
|
|
101
|
-
} catch {
|
|
102
|
-
return [];
|
|
103
|
-
}
|
|
104
|
-
for (const name of names) {
|
|
105
|
-
if (!name.startsWith(CRASH_LOG_PREFIX) || !name.endsWith(".log")) continue;
|
|
106
|
-
const full = join(dir, name);
|
|
107
|
-
try {
|
|
108
|
-
const st = statSync(full);
|
|
109
|
-
const head = readFileSync(full, "utf-8").split("\n").slice(0, 20);
|
|
110
|
-
const tsLine = head.find((l) => l.startsWith("timestamp:"));
|
|
111
|
-
const kindLine = head.find((l) => l.startsWith("kind:"));
|
|
112
|
-
const msgIdx = head.findIndex((l) => l.trim() === "## message");
|
|
113
|
-
const message = msgIdx >= 0 && head[msgIdx + 1] ? head[msgIdx + 1] : "";
|
|
114
|
-
files.push({
|
|
115
|
-
file: full,
|
|
116
|
-
timestamp: tsLine ? tsLine.replace("timestamp:", "").trim() : st.mtime.toISOString(),
|
|
117
|
-
kind: kindLine ? kindLine.replace("kind:", "").trim() : "unknown",
|
|
118
|
-
message: truncate(message, 200),
|
|
119
|
-
sizeBytes: st.size
|
|
120
|
-
});
|
|
121
|
-
} catch {
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
files.sort((a, b) => a.timestamp < b.timestamp ? 1 : -1);
|
|
125
|
-
return files.slice(0, limit);
|
|
126
|
-
}
|
|
127
|
-
function getConfigDirUsage(configDir) {
|
|
128
|
-
const base = configDir ?? join(homedir(), CONFIG_DIR_NAME);
|
|
129
|
-
if (!existsSync(base)) return { totalBytes: 0, entries: [] };
|
|
130
|
-
const entries = [];
|
|
131
|
-
let total = 0;
|
|
132
|
-
let names;
|
|
133
|
-
try {
|
|
134
|
-
names = readdirSync(base);
|
|
135
|
-
} catch {
|
|
136
|
-
return { totalBytes: 0, entries: [] };
|
|
137
|
-
}
|
|
138
|
-
for (const name of names) {
|
|
139
|
-
const full = join(base, name);
|
|
140
|
-
const bytes = dirSize(full);
|
|
141
|
-
entries.push({ name, bytes });
|
|
142
|
-
total += bytes;
|
|
143
|
-
}
|
|
144
|
-
entries.sort((a, b) => b.bytes - a.bytes);
|
|
145
|
-
return { totalBytes: total, entries };
|
|
146
|
-
}
|
|
147
|
-
function dirSize(path) {
|
|
148
|
-
try {
|
|
149
|
-
const st = statSync(path);
|
|
150
|
-
if (st.isFile()) return st.size;
|
|
151
|
-
if (!st.isDirectory()) return 0;
|
|
152
|
-
let sum = 0;
|
|
153
|
-
for (const name of readdirSync(path)) {
|
|
154
|
-
sum += dirSize(join(path, name));
|
|
155
|
-
}
|
|
156
|
-
return sum;
|
|
157
|
-
} catch {
|
|
158
|
-
return 0;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export {
|
|
163
|
-
writeCrashLog,
|
|
164
|
-
listRecentCrashes,
|
|
165
|
-
getConfigDirUsage
|
|
166
|
-
};
|