ccjk 10.1.0 → 10.3.0

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.
Files changed (115) hide show
  1. package/README.md +28 -0
  2. package/dist/chunks/agent-teams.mjs +1 -1
  3. package/dist/chunks/agent.mjs +1 -1
  4. package/dist/chunks/api-providers.mjs +1 -1
  5. package/dist/chunks/api.mjs +3 -3
  6. package/dist/chunks/auto-bootstrap.mjs +1 -1
  7. package/dist/chunks/auto-updater.mjs +1 -1
  8. package/dist/{shared/ccjk.Br91zBIG.mjs → chunks/banner.mjs} +52 -3
  9. package/dist/chunks/boost.mjs +2 -2
  10. package/dist/chunks/ccjk-agents.mjs +1 -1
  11. package/dist/chunks/ccjk-all.mjs +1 -1
  12. package/dist/chunks/ccjk-config.mjs +1 -1
  13. package/dist/chunks/ccjk-hooks.mjs +1 -1
  14. package/dist/chunks/ccjk-mcp.mjs +2 -2
  15. package/dist/chunks/ccjk-setup.mjs +1 -1
  16. package/dist/chunks/ccjk-skills.mjs +1 -1
  17. package/dist/chunks/ccr.mjs +11 -10
  18. package/dist/chunks/ccu.mjs +1 -1
  19. package/dist/chunks/check-updates.mjs +4 -3
  20. package/dist/chunks/claude-code-config-manager.mjs +8 -7
  21. package/dist/chunks/claude-code-incremental-manager.mjs +3 -2
  22. package/dist/chunks/claude-config.mjs +3 -3
  23. package/dist/chunks/claude-wrapper.mjs +2 -2
  24. package/dist/chunks/codex-config-switch.mjs +3 -2
  25. package/dist/chunks/codex-provider-manager.mjs +3 -2
  26. package/dist/chunks/codex-uninstaller.mjs +2 -2
  27. package/dist/chunks/codex.mjs +5 -5
  28. package/dist/chunks/commands.mjs +88 -391
  29. package/dist/chunks/commands2.mjs +391 -88
  30. package/dist/chunks/completion.mjs +1 -1
  31. package/dist/chunks/config-consolidator.mjs +2 -2
  32. package/dist/chunks/config-switch.mjs +4 -3
  33. package/dist/chunks/config.mjs +6 -98
  34. package/dist/chunks/config2.mjs +411 -400
  35. package/dist/chunks/config3.mjs +401 -410
  36. package/dist/chunks/constants.mjs +1 -1
  37. package/dist/chunks/context.mjs +283 -1
  38. package/dist/chunks/dashboard.mjs +365 -0
  39. package/dist/chunks/doctor.mjs +4 -4
  40. package/dist/chunks/features.mjs +12 -11
  41. package/dist/chunks/fs-operations.mjs +1 -1
  42. package/dist/chunks/health-alerts.mjs +304 -0
  43. package/dist/chunks/health-check.mjs +532 -0
  44. package/dist/chunks/index.mjs +10 -177
  45. package/dist/chunks/index2.mjs +168 -1162
  46. package/dist/chunks/index3.mjs +1076 -910
  47. package/dist/chunks/index4.mjs +947 -137
  48. package/dist/chunks/index5.mjs +167 -635
  49. package/dist/chunks/index6.mjs +663 -0
  50. package/dist/chunks/init.mjs +19 -19
  51. package/dist/chunks/installer.mjs +649 -147
  52. package/dist/chunks/installer2.mjs +147 -649
  53. package/dist/chunks/interview.mjs +2 -2
  54. package/dist/chunks/marketplace.mjs +1 -1
  55. package/dist/chunks/mcp.mjs +5 -4
  56. package/dist/chunks/menu.mjs +22 -9
  57. package/dist/chunks/metrics-display.mjs +152 -0
  58. package/dist/chunks/migrator.mjs +1 -1
  59. package/dist/chunks/monitor.mjs +2 -2
  60. package/dist/chunks/notification.mjs +1 -1
  61. package/dist/chunks/onboarding.mjs +2 -2
  62. package/dist/chunks/package.mjs +1 -1
  63. package/dist/chunks/permission-manager.mjs +2 -2
  64. package/dist/chunks/permissions.mjs +1 -1
  65. package/dist/chunks/persistence-manager.mjs +781 -0
  66. package/dist/chunks/persistence.mjs +667 -0
  67. package/dist/chunks/platform.mjs +1 -1
  68. package/dist/chunks/plugin.mjs +1 -1
  69. package/dist/chunks/prompts.mjs +1 -1
  70. package/dist/chunks/providers.mjs +1 -1
  71. package/dist/chunks/quick-actions.mjs +321 -0
  72. package/dist/chunks/quick-provider.mjs +2 -0
  73. package/dist/chunks/quick-setup.mjs +9 -8
  74. package/dist/chunks/silent-updater.mjs +1 -1
  75. package/dist/chunks/simple-config.mjs +3 -8
  76. package/dist/chunks/skill.mjs +1 -1
  77. package/dist/chunks/skills-sync.mjs +1 -1
  78. package/dist/chunks/skills.mjs +1 -1
  79. package/dist/chunks/slash-commands.mjs +208 -0
  80. package/dist/chunks/smart-defaults.mjs +1 -1
  81. package/dist/chunks/startup.mjs +1 -1
  82. package/dist/chunks/stats.mjs +1 -1
  83. package/dist/chunks/status.mjs +31 -2
  84. package/dist/chunks/team.mjs +1 -1
  85. package/dist/chunks/thinking.mjs +2 -2
  86. package/dist/chunks/uninstall.mjs +5 -5
  87. package/dist/chunks/update.mjs +8 -7
  88. package/dist/chunks/upgrade-manager.mjs +2 -2
  89. package/dist/chunks/version-checker.mjs +3 -3
  90. package/dist/chunks/vim.mjs +1 -1
  91. package/dist/chunks/zero-config.mjs +359 -0
  92. package/dist/cli.mjs +212 -21
  93. package/dist/i18n/locales/en/cli.json +14 -1
  94. package/dist/i18n/locales/en/common.json +27 -0
  95. package/dist/i18n/locales/en/configuration.json +33 -0
  96. package/dist/i18n/locales/en/context.json +54 -1
  97. package/dist/i18n/locales/en/dashboard.json +78 -0
  98. package/dist/i18n/locales/en/persistence.json +127 -0
  99. package/dist/i18n/locales/en/quick-actions.json +78 -0
  100. package/dist/i18n/locales/zh-CN/cli.json +14 -1
  101. package/dist/i18n/locales/zh-CN/common.json +27 -0
  102. package/dist/i18n/locales/zh-CN/configuration.json +33 -0
  103. package/dist/i18n/locales/zh-CN/context.json +54 -1
  104. package/dist/i18n/locales/zh-CN/dashboard.json +78 -0
  105. package/dist/i18n/locales/zh-CN/persistence.json +127 -0
  106. package/dist/i18n/locales/zh-CN/quick-actions.json +78 -0
  107. package/dist/index.mjs +3 -2
  108. package/dist/shared/{ccjk.DE91nClQ.mjs → ccjk.BKoi8-Hy.mjs} +1 -1
  109. package/dist/shared/ccjk.BiCrMV5O.mjs +94 -0
  110. package/dist/shared/{ccjk.Dpw86UX0.mjs → ccjk.CxtuJxaS.mjs} +1 -1
  111. package/dist/shared/{ccjk.ClzTOz9n.mjs → ccjk.DB2UYcq0.mjs} +5 -5
  112. package/dist/shared/{ccjk.CmsW23FN.mjs → ccjk.DVBW2wxp.mjs} +4 -3
  113. package/dist/shared/{ccjk.Bndhan7G.mjs → ccjk.DfwJOEok.mjs} +1 -1
  114. package/dist/shared/{ccjk.DvIrK0wz.mjs → ccjk.DrMygfCF.mjs} +1 -1
  115. package/package.json +19 -19
@@ -5,14 +5,14 @@ import inquirer from 'inquirer';
5
5
  import { resolve, join, dirname } from 'pathe';
6
6
  import { getApiProviderPresets } from './api-providers.mjs';
7
7
  import { SETTINGS_FILE, CLAUDE_DIR } from './constants.mjs';
8
- import { i18n } from './index.mjs';
8
+ import { i18n } from './index2.mjs';
9
9
  import { g as getPermissionManager } from '../shared/ccjk.h7_W-wTs.mjs';
10
- import { c as commandExists } from './platform.mjs';
10
+ import { h as commandExists } from './platform.mjs';
11
11
  import { P as ProviderHealthMonitor } from '../shared/ccjk.J8YiPsOw.mjs';
12
12
  import { platform, userInfo, homedir } from 'node:os';
13
13
  import ora from 'ora';
14
14
  import { exec } from 'tinyexec';
15
- import { S as STATUS } from '../shared/ccjk.Br91zBIG.mjs';
15
+ import { STATUS } from './banner.mjs';
16
16
  import { writeFileAtomic } from './fs-operations.mjs';
17
17
  import 'node:url';
18
18
  import 'i18next';
@@ -799,7 +799,7 @@ async function checkPermissionRules() {
799
799
  }
800
800
  async function fixSettingsFile() {
801
801
  const isZh = i18n.language === "zh-CN";
802
- const { copyConfigFiles } = await import('./config.mjs').then(function (n) { return n.c; });
802
+ const { copyConfigFiles } = await import('./config.mjs').then(function (n) { return n.j; });
803
803
  console.log("");
804
804
  console.log(ansis.bold.cyan("\u{1F527} Fixing settings.json"));
805
805
  console.log(ansis.dim("\u2500".repeat(50)));
@@ -4,15 +4,15 @@ import process__default from 'node:process';
4
4
  import ansis from 'ansis';
5
5
  import inquirer from 'inquirer';
6
6
  import { join } from 'pathe';
7
- import { s as selectMcpServices, g as getMcpServices } from './codex.mjs';
7
+ import { d as selectMcpServices, g as getMcpServices } from './codex.mjs';
8
8
  import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
9
- import { ensureI18nInitialized, i18n, changeLanguage } from './index.mjs';
9
+ import { ensureI18nInitialized, i18n, changeLanguage } from './index2.mjs';
10
10
  import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
11
- import { setupCcrConfiguration } from './config3.mjs';
11
+ import { setupCcrConfiguration } from './config2.mjs';
12
12
  import { a as isCcrInstalled, b as installCcr } from './init.mjs';
13
- import { r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, c as buildMcpServerConfig, m as mergeMcpServers } from './claude-config.mjs';
14
- import { d as applyAiLanguageDirective, h as getExistingModelConfig, u as updateCustomModel, i as updateDefaultModel, g as getExistingApiConfig, p as promptApiConfigurationAction, f as configureApi, s as switchToOfficialLogin } from './config.mjs';
15
- import { b as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.CmsW23FN.mjs';
13
+ import { r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, a as buildMcpServerConfig, m as mergeMcpServers } from './claude-config.mjs';
14
+ import { a as applyAiLanguageDirective, g as getExistingModelConfig, u as updateCustomModel, d as updateDefaultModel, e as getExistingApiConfig, p as promptApiConfigurationAction, f as configureApi, s as switchToOfficialLogin } from './config.mjs';
15
+ import { c as configureOutputStyle, a as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.DVBW2wxp.mjs';
16
16
  import { i as isWindows } from './platform.mjs';
17
17
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
18
18
  import { openSettingsJson, importRecommendedPermissions, importRecommendedEnv } from './simple-config.mjs';
@@ -33,16 +33,17 @@ import 'node:child_process';
33
33
  import 'i18next';
34
34
  import 'i18next-fs-backend';
35
35
  import 'node:util';
36
- import '../shared/ccjk.Br91zBIG.mjs';
36
+ import './banner.mjs';
37
37
  import './auto-updater.mjs';
38
38
  import './version-checker.mjs';
39
39
  import 'node:path';
40
- import '../shared/ccjk.Dpw86UX0.mjs';
40
+ import '../shared/ccjk.CxtuJxaS.mjs';
41
41
  import './smart-defaults.mjs';
42
42
  import '../shared/ccjk.DKojSRzw.mjs';
43
- import '../shared/ccjk.DvIrK0wz.mjs';
44
- import './installer2.mjs';
45
- import '../shared/ccjk.DE91nClQ.mjs';
43
+ import '../shared/ccjk.DrMygfCF.mjs';
44
+ import './installer.mjs';
45
+ import '../shared/ccjk.BKoi8-Hy.mjs';
46
+ import '../shared/ccjk.BiCrMV5O.mjs';
46
47
  import 'inquirer-toggle';
47
48
 
48
49
  async function handleCancellation() {
@@ -1,5 +1,5 @@
1
1
  import { randomBytes } from 'node:crypto';
2
- import { existsSync, readFileSync, writeFileSync, renameSync, unlinkSync, mkdirSync, copyFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, unlinkSync, copyFileSync, readdirSync, statSync } from 'node:fs';
3
3
  import { mkdir, writeFile as writeFile$1, rename, unlink } from 'node:fs/promises';
4
4
  import { dirname, join } from 'pathe';
5
5
 
@@ -0,0 +1,304 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join, dirname } from 'pathe';
3
+ import { DatabaseHealthMonitor } from './health-check.mjs';
4
+ import 'better-sqlite3';
5
+
6
+ const DEFAULT_CONFIG = {
7
+ silent: false,
8
+ walThresholdMB: 10,
9
+ diskUtilizationThreshold: 70,
10
+ backupAgeThresholdDays: 7,
11
+ enableHistory: true
12
+ };
13
+ class HealthAlertsManager {
14
+ monitor;
15
+ config;
16
+ historyPath;
17
+ dbPath;
18
+ constructor(dbPath, config) {
19
+ this.dbPath = dbPath;
20
+ this.monitor = new DatabaseHealthMonitor(dbPath);
21
+ this.config = { ...DEFAULT_CONFIG, ...config };
22
+ this.historyPath = join(dirname(dbPath), "alert-history.json");
23
+ }
24
+ /**
25
+ * Run health checks and generate alerts
26
+ */
27
+ async checkHealth() {
28
+ const alerts = [];
29
+ try {
30
+ const health = await this.monitor.runHealthCheck();
31
+ if (!health.checks.integrity.passed) {
32
+ alerts.push({
33
+ severity: "critical" /* CRITICAL */,
34
+ category: "corruption",
35
+ message: "Database corruption detected",
36
+ action: "Run: ccjk context recover",
37
+ timestamp: Date.now()
38
+ });
39
+ for (const error of health.checks.integrity.errors) {
40
+ alerts.push({
41
+ severity: "critical" /* CRITICAL */,
42
+ category: "corruption",
43
+ message: error,
44
+ timestamp: Date.now()
45
+ });
46
+ }
47
+ }
48
+ const walSizeMB = health.checks.wal.walSize / (1024 * 1024);
49
+ if (walSizeMB > this.config.walThresholdMB) {
50
+ alerts.push({
51
+ severity: "warning" /* WARNING */,
52
+ category: "wal",
53
+ message: `WAL file is ${walSizeMB.toFixed(1)}MB (threshold: ${this.config.walThresholdMB}MB)`,
54
+ action: "Run: ccjk context checkpoint",
55
+ timestamp: Date.now()
56
+ });
57
+ } else if (walSizeMB > this.config.walThresholdMB / 2) {
58
+ alerts.push({
59
+ severity: "info" /* INFO */,
60
+ category: "wal",
61
+ message: `WAL file is ${walSizeMB.toFixed(1)}MB`,
62
+ action: "Consider checkpointing soon",
63
+ timestamp: Date.now()
64
+ });
65
+ }
66
+ if (health.checks.size.utilizationPercent < this.config.diskUtilizationThreshold) {
67
+ alerts.push({
68
+ severity: "warning" /* WARNING */,
69
+ category: "disk",
70
+ message: `Disk utilization is ${health.checks.size.utilizationPercent.toFixed(1)}% (threshold: ${this.config.diskUtilizationThreshold}%)`,
71
+ action: "Run: ccjk context vacuum",
72
+ timestamp: Date.now()
73
+ });
74
+ }
75
+ const backupAlert = await this.checkBackupStatus();
76
+ if (backupAlert) {
77
+ alerts.push(backupAlert);
78
+ }
79
+ if (health.checks.performance.queryTime > 100) {
80
+ alerts.push({
81
+ severity: "warning" /* WARNING */,
82
+ category: "performance",
83
+ message: `Query performance is slow (${health.checks.performance.queryTime}ms)`,
84
+ action: "Check database indexes",
85
+ timestamp: Date.now()
86
+ });
87
+ }
88
+ if (this.config.enableHistory && alerts.length > 0) {
89
+ await this.logToHistory(alerts, health.status);
90
+ }
91
+ return alerts;
92
+ } catch (error) {
93
+ return [{
94
+ severity: "critical" /* CRITICAL */,
95
+ category: "corruption",
96
+ message: `Health check failed: ${error instanceof Error ? error.message : String(error)}`,
97
+ timestamp: Date.now()
98
+ }];
99
+ }
100
+ }
101
+ /**
102
+ * Check backup status
103
+ */
104
+ async checkBackupStatus() {
105
+ try {
106
+ const backups = this.monitor.listBackups();
107
+ if (backups.length === 0) {
108
+ return {
109
+ severity: "warning" /* WARNING */,
110
+ category: "backup",
111
+ message: "No backups found",
112
+ action: "Run: ccjk context backup",
113
+ timestamp: Date.now()
114
+ };
115
+ }
116
+ const latestBackup = backups[0];
117
+ const ageMs = Date.now() - latestBackup.metadata.timestamp;
118
+ const ageDays = ageMs / (1e3 * 60 * 60 * 24);
119
+ if (ageDays > this.config.backupAgeThresholdDays) {
120
+ return {
121
+ severity: "warning" /* WARNING */,
122
+ category: "backup",
123
+ message: `Latest backup is ${Math.floor(ageDays)} days old (threshold: ${this.config.backupAgeThresholdDays} days)`,
124
+ action: "Run: ccjk context backup",
125
+ timestamp: Date.now()
126
+ };
127
+ }
128
+ if (ageDays > this.config.backupAgeThresholdDays / 2) {
129
+ return {
130
+ severity: "info" /* INFO */,
131
+ category: "backup",
132
+ message: `Latest backup is ${Math.floor(ageDays)} days old`,
133
+ action: "Consider creating a new backup",
134
+ timestamp: Date.now()
135
+ };
136
+ }
137
+ return null;
138
+ } catch {
139
+ return null;
140
+ }
141
+ }
142
+ /**
143
+ * Display alerts with emoji indicators
144
+ */
145
+ displayAlerts(alerts) {
146
+ if (alerts.length === 0) {
147
+ return;
148
+ }
149
+ console.log("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
150
+ console.log("\u{1F4CA} Database Health Alerts");
151
+ console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
152
+ const critical = alerts.filter((a) => a.severity === "critical" /* CRITICAL */);
153
+ const warnings = alerts.filter((a) => a.severity === "warning" /* WARNING */);
154
+ const info = alerts.filter((a) => a.severity === "info" /* INFO */);
155
+ if (critical.length > 0) {
156
+ for (const alert of critical) {
157
+ console.log(`\u{1F534} CRITICAL: ${alert.message}`);
158
+ if (alert.action) {
159
+ console.log(` \u2192 ${alert.action}`);
160
+ }
161
+ }
162
+ console.log();
163
+ }
164
+ if (warnings.length > 0) {
165
+ for (const alert of warnings) {
166
+ console.log(`\u{1F7E1} WARNING: ${alert.message}`);
167
+ if (alert.action) {
168
+ console.log(` \u2192 ${alert.action}`);
169
+ }
170
+ }
171
+ console.log();
172
+ }
173
+ if (info.length > 0) {
174
+ for (const alert of info) {
175
+ console.log(`\u{1F4A1} INFO: ${alert.message}`);
176
+ if (alert.action) {
177
+ console.log(` \u2192 ${alert.action}`);
178
+ }
179
+ }
180
+ console.log();
181
+ }
182
+ console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
183
+ }
184
+ /**
185
+ * Log alerts to history
186
+ */
187
+ async logToHistory(alerts, healthStatus) {
188
+ try {
189
+ const fs = await import('node:fs/promises');
190
+ let history = [];
191
+ if (existsSync(this.historyPath)) {
192
+ const content = await fs.readFile(this.historyPath, "utf-8");
193
+ history = JSON.parse(content);
194
+ }
195
+ history.unshift({
196
+ timestamp: Date.now(),
197
+ alerts,
198
+ healthStatus,
199
+ resolved: false
200
+ });
201
+ history = history.slice(0, 100);
202
+ await fs.writeFile(this.historyPath, JSON.stringify(history, null, 2));
203
+ } catch {
204
+ }
205
+ }
206
+ /**
207
+ * Get alert history
208
+ */
209
+ async getHistory(limit = 10) {
210
+ try {
211
+ if (!existsSync(this.historyPath)) {
212
+ return [];
213
+ }
214
+ const fs = await import('node:fs/promises');
215
+ const content = await fs.readFile(this.historyPath, "utf-8");
216
+ const history = JSON.parse(content);
217
+ return history.slice(0, limit);
218
+ } catch {
219
+ return [];
220
+ }
221
+ }
222
+ /**
223
+ * Mark alerts as resolved
224
+ */
225
+ async markResolved(timestamp) {
226
+ try {
227
+ if (!existsSync(this.historyPath)) {
228
+ return;
229
+ }
230
+ const fs = await import('node:fs/promises');
231
+ const content = await fs.readFile(this.historyPath, "utf-8");
232
+ const history = JSON.parse(content);
233
+ const entry = history.find((e) => e.timestamp === timestamp);
234
+ if (entry) {
235
+ entry.resolved = true;
236
+ await fs.writeFile(this.historyPath, JSON.stringify(history, null, 2));
237
+ }
238
+ } catch {
239
+ }
240
+ }
241
+ /**
242
+ * Clear alert history
243
+ */
244
+ async clearHistory() {
245
+ try {
246
+ if (existsSync(this.historyPath)) {
247
+ const fs = await import('node:fs/promises');
248
+ await fs.unlink(this.historyPath);
249
+ }
250
+ } catch {
251
+ }
252
+ }
253
+ /**
254
+ * Get summary statistics
255
+ */
256
+ async getSummary() {
257
+ const history = await this.getHistory(100);
258
+ if (history.length === 0) {
259
+ return {
260
+ totalAlerts: 0,
261
+ criticalCount: 0,
262
+ warningCount: 0,
263
+ infoCount: 0,
264
+ unresolvedCount: 0
265
+ };
266
+ }
267
+ const unresolved = history.filter((e) => !e.resolved);
268
+ const allAlerts = unresolved.flatMap((e) => e.alerts);
269
+ return {
270
+ totalAlerts: allAlerts.length,
271
+ criticalCount: allAlerts.filter((a) => a.severity === "critical" /* CRITICAL */).length,
272
+ warningCount: allAlerts.filter((a) => a.severity === "warning" /* WARNING */).length,
273
+ infoCount: allAlerts.filter((a) => a.severity === "info" /* INFO */).length,
274
+ unresolvedCount: unresolved.length,
275
+ lastCheckTime: history[0]?.timestamp
276
+ };
277
+ }
278
+ /**
279
+ * Close monitor
280
+ */
281
+ close() {
282
+ this.monitor.close();
283
+ }
284
+ }
285
+ async function runStartupHealthCheck(dbPath, config) {
286
+ if (!existsSync(dbPath)) {
287
+ return [];
288
+ }
289
+ if (config?.silent) {
290
+ return [];
291
+ }
292
+ const manager = new HealthAlertsManager(dbPath, config);
293
+ try {
294
+ const alerts = await manager.checkHealth();
295
+ if (alerts.length > 0) {
296
+ manager.displayAlerts(alerts);
297
+ }
298
+ return alerts;
299
+ } finally {
300
+ manager.close();
301
+ }
302
+ }
303
+
304
+ export { HealthAlertsManager, runStartupHealthCheck };