@superdangerous/app-framework 4.9.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 (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +652 -0
  3. package/dist/api/logsRouter.d.ts +20 -0
  4. package/dist/api/logsRouter.d.ts.map +1 -0
  5. package/dist/api/logsRouter.js +515 -0
  6. package/dist/api/logsRouter.js.map +1 -0
  7. package/dist/cli/dev-server.d.ts +7 -0
  8. package/dist/cli/dev-server.d.ts.map +1 -0
  9. package/dist/cli/dev-server.js +640 -0
  10. package/dist/cli/dev-server.js.map +1 -0
  11. package/dist/cli/index.d.ts +7 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +26 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/core/StandardServer.d.ts +129 -0
  16. package/dist/core/StandardServer.d.ts.map +1 -0
  17. package/dist/core/StandardServer.js +453 -0
  18. package/dist/core/StandardServer.js.map +1 -0
  19. package/dist/core/apiResponse.d.ts +69 -0
  20. package/dist/core/apiResponse.d.ts.map +1 -0
  21. package/dist/core/apiResponse.js +127 -0
  22. package/dist/core/apiResponse.js.map +1 -0
  23. package/dist/core/healthCheck.d.ts +160 -0
  24. package/dist/core/healthCheck.d.ts.map +1 -0
  25. package/dist/core/healthCheck.js +398 -0
  26. package/dist/core/healthCheck.js.map +1 -0
  27. package/dist/core/index.d.ts +40 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +40 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/logger.d.ts +117 -0
  32. package/dist/core/logger.d.ts.map +1 -0
  33. package/dist/core/logger.js +826 -0
  34. package/dist/core/logger.js.map +1 -0
  35. package/dist/core/portUtils.d.ts +71 -0
  36. package/dist/core/portUtils.d.ts.map +1 -0
  37. package/dist/core/portUtils.js +240 -0
  38. package/dist/core/portUtils.js.map +1 -0
  39. package/dist/core/storageService.d.ts +119 -0
  40. package/dist/core/storageService.d.ts.map +1 -0
  41. package/dist/core/storageService.js +405 -0
  42. package/dist/core/storageService.js.map +1 -0
  43. package/dist/desktop/bundler.d.ts +40 -0
  44. package/dist/desktop/bundler.d.ts.map +1 -0
  45. package/dist/desktop/bundler.js +176 -0
  46. package/dist/desktop/bundler.js.map +1 -0
  47. package/dist/desktop/index.d.ts +25 -0
  48. package/dist/desktop/index.d.ts.map +1 -0
  49. package/dist/desktop/index.js +15 -0
  50. package/dist/desktop/index.js.map +1 -0
  51. package/dist/desktop/native-modules.d.ts +66 -0
  52. package/dist/desktop/native-modules.d.ts.map +1 -0
  53. package/dist/desktop/native-modules.js +200 -0
  54. package/dist/desktop/native-modules.js.map +1 -0
  55. package/dist/index.d.ts +29 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +39 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/logging/LogCategories.d.ts +87 -0
  60. package/dist/logging/LogCategories.d.ts.map +1 -0
  61. package/dist/logging/LogCategories.js +205 -0
  62. package/dist/logging/LogCategories.js.map +1 -0
  63. package/dist/middleware/aiErrorHandler.d.ts +31 -0
  64. package/dist/middleware/aiErrorHandler.d.ts.map +1 -0
  65. package/dist/middleware/aiErrorHandler.js +181 -0
  66. package/dist/middleware/aiErrorHandler.js.map +1 -0
  67. package/dist/middleware/auth.d.ts +101 -0
  68. package/dist/middleware/auth.d.ts.map +1 -0
  69. package/dist/middleware/auth.js +230 -0
  70. package/dist/middleware/auth.js.map +1 -0
  71. package/dist/middleware/cors.d.ts +56 -0
  72. package/dist/middleware/cors.d.ts.map +1 -0
  73. package/dist/middleware/cors.js +123 -0
  74. package/dist/middleware/cors.js.map +1 -0
  75. package/dist/middleware/errorHandler.d.ts +13 -0
  76. package/dist/middleware/errorHandler.d.ts.map +1 -0
  77. package/dist/middleware/errorHandler.js +85 -0
  78. package/dist/middleware/errorHandler.js.map +1 -0
  79. package/dist/middleware/fileUpload.d.ts +62 -0
  80. package/dist/middleware/fileUpload.d.ts.map +1 -0
  81. package/dist/middleware/fileUpload.js +175 -0
  82. package/dist/middleware/fileUpload.js.map +1 -0
  83. package/dist/middleware/health.d.ts +48 -0
  84. package/dist/middleware/health.d.ts.map +1 -0
  85. package/dist/middleware/health.js +143 -0
  86. package/dist/middleware/health.js.map +1 -0
  87. package/dist/middleware/index.d.ts +20 -0
  88. package/dist/middleware/index.d.ts.map +1 -0
  89. package/dist/middleware/index.js +18 -0
  90. package/dist/middleware/index.js.map +1 -0
  91. package/dist/middleware/openapi.d.ts +64 -0
  92. package/dist/middleware/openapi.d.ts.map +1 -0
  93. package/dist/middleware/openapi.js +258 -0
  94. package/dist/middleware/openapi.js.map +1 -0
  95. package/dist/middleware/requestLogging.d.ts +22 -0
  96. package/dist/middleware/requestLogging.d.ts.map +1 -0
  97. package/dist/middleware/requestLogging.js +61 -0
  98. package/dist/middleware/requestLogging.js.map +1 -0
  99. package/dist/middleware/session.d.ts +84 -0
  100. package/dist/middleware/session.d.ts.map +1 -0
  101. package/dist/middleware/session.js +189 -0
  102. package/dist/middleware/session.js.map +1 -0
  103. package/dist/middleware/validation.d.ts +1337 -0
  104. package/dist/middleware/validation.d.ts.map +1 -0
  105. package/dist/middleware/validation.js +483 -0
  106. package/dist/middleware/validation.js.map +1 -0
  107. package/dist/services/aiService.d.ts +180 -0
  108. package/dist/services/aiService.d.ts.map +1 -0
  109. package/dist/services/aiService.js +547 -0
  110. package/dist/services/aiService.js.map +1 -0
  111. package/dist/services/conversationStorage.d.ts +38 -0
  112. package/dist/services/conversationStorage.d.ts.map +1 -0
  113. package/dist/services/conversationStorage.js +158 -0
  114. package/dist/services/conversationStorage.js.map +1 -0
  115. package/dist/services/crossPlatformBuffer.d.ts +84 -0
  116. package/dist/services/crossPlatformBuffer.d.ts.map +1 -0
  117. package/dist/services/crossPlatformBuffer.js +246 -0
  118. package/dist/services/crossPlatformBuffer.js.map +1 -0
  119. package/dist/services/index.d.ts +17 -0
  120. package/dist/services/index.d.ts.map +1 -0
  121. package/dist/services/index.js +18 -0
  122. package/dist/services/index.js.map +1 -0
  123. package/dist/services/networkService.d.ts +81 -0
  124. package/dist/services/networkService.d.ts.map +1 -0
  125. package/dist/services/networkService.js +268 -0
  126. package/dist/services/networkService.js.map +1 -0
  127. package/dist/services/queueService.d.ts +112 -0
  128. package/dist/services/queueService.d.ts.map +1 -0
  129. package/dist/services/queueService.js +338 -0
  130. package/dist/services/queueService.js.map +1 -0
  131. package/dist/services/settingsService.d.ts +135 -0
  132. package/dist/services/settingsService.d.ts.map +1 -0
  133. package/dist/services/settingsService.js +425 -0
  134. package/dist/services/settingsService.js.map +1 -0
  135. package/dist/services/systemMonitor.d.ts +208 -0
  136. package/dist/services/systemMonitor.d.ts.map +1 -0
  137. package/dist/services/systemMonitor.js +693 -0
  138. package/dist/services/systemMonitor.js.map +1 -0
  139. package/dist/services/updateService.d.ts +78 -0
  140. package/dist/services/updateService.d.ts.map +1 -0
  141. package/dist/services/updateService.js +252 -0
  142. package/dist/services/updateService.js.map +1 -0
  143. package/dist/services/websocketEvents.d.ts +372 -0
  144. package/dist/services/websocketEvents.d.ts.map +1 -0
  145. package/dist/services/websocketEvents.js +338 -0
  146. package/dist/services/websocketEvents.js.map +1 -0
  147. package/dist/services/websocketServer.d.ts +80 -0
  148. package/dist/services/websocketServer.d.ts.map +1 -0
  149. package/dist/services/websocketServer.js +299 -0
  150. package/dist/services/websocketServer.js.map +1 -0
  151. package/dist/settings/SettingsSchema.d.ts +151 -0
  152. package/dist/settings/SettingsSchema.d.ts.map +1 -0
  153. package/dist/settings/SettingsSchema.js +424 -0
  154. package/dist/settings/SettingsSchema.js.map +1 -0
  155. package/dist/testing/TestServer.d.ts +69 -0
  156. package/dist/testing/TestServer.d.ts.map +1 -0
  157. package/dist/testing/TestServer.js +250 -0
  158. package/dist/testing/TestServer.js.map +1 -0
  159. package/dist/types/index.d.ts +137 -0
  160. package/dist/types/index.d.ts.map +1 -0
  161. package/dist/types/index.js +5 -0
  162. package/dist/types/index.js.map +1 -0
  163. package/dist/utils/appPaths.d.ts +74 -0
  164. package/dist/utils/appPaths.d.ts.map +1 -0
  165. package/dist/utils/appPaths.js +162 -0
  166. package/dist/utils/appPaths.js.map +1 -0
  167. package/dist/utils/fs-utils.d.ts +50 -0
  168. package/dist/utils/fs-utils.d.ts.map +1 -0
  169. package/dist/utils/fs-utils.js +114 -0
  170. package/dist/utils/fs-utils.js.map +1 -0
  171. package/dist/utils/index.d.ts +12 -0
  172. package/dist/utils/index.d.ts.map +1 -0
  173. package/dist/utils/index.js +10 -0
  174. package/dist/utils/index.js.map +1 -0
  175. package/dist/utils/standardConfig.d.ts +61 -0
  176. package/dist/utils/standardConfig.d.ts.map +1 -0
  177. package/dist/utils/standardConfig.js +109 -0
  178. package/dist/utils/standardConfig.js.map +1 -0
  179. package/dist/utils/startupBanner.d.ts +34 -0
  180. package/dist/utils/startupBanner.d.ts.map +1 -0
  181. package/dist/utils/startupBanner.js +169 -0
  182. package/dist/utils/startupBanner.js.map +1 -0
  183. package/dist/utils/startupLogger.d.ts +45 -0
  184. package/dist/utils/startupLogger.d.ts.map +1 -0
  185. package/dist/utils/startupLogger.js +200 -0
  186. package/dist/utils/startupLogger.js.map +1 -0
  187. package/package.json +151 -0
  188. package/src/api/logsRouter.ts +600 -0
  189. package/src/cli/dev-server.ts +803 -0
  190. package/src/cli/index.ts +31 -0
  191. package/src/core/StandardServer.ts +587 -0
  192. package/src/core/apiResponse.ts +202 -0
  193. package/src/core/healthCheck.ts +565 -0
  194. package/src/core/index.ts +80 -0
  195. package/src/core/logger.ts +1092 -0
  196. package/src/core/portUtils.ts +319 -0
  197. package/src/core/storageService.ts +595 -0
  198. package/src/desktop/bundler.ts +271 -0
  199. package/src/desktop/index.ts +18 -0
  200. package/src/desktop/native-modules.ts +289 -0
  201. package/src/index.ts +142 -0
  202. package/src/logging/LogCategories.ts +302 -0
  203. package/src/middleware/aiErrorHandler.ts +278 -0
  204. package/src/middleware/auth.ts +329 -0
  205. package/src/middleware/cors.ts +187 -0
  206. package/src/middleware/errorHandler.ts +103 -0
  207. package/src/middleware/fileUpload.ts +252 -0
  208. package/src/middleware/health.ts +206 -0
  209. package/src/middleware/index.ts +71 -0
  210. package/src/middleware/openapi.ts +305 -0
  211. package/src/middleware/requestLogging.ts +92 -0
  212. package/src/middleware/session.ts +238 -0
  213. package/src/middleware/validation.ts +603 -0
  214. package/src/services/aiService.ts +789 -0
  215. package/src/services/conversationStorage.ts +232 -0
  216. package/src/services/crossPlatformBuffer.ts +341 -0
  217. package/src/services/index.ts +47 -0
  218. package/src/services/networkService.ts +351 -0
  219. package/src/services/queueService.ts +446 -0
  220. package/src/services/settingsService.ts +549 -0
  221. package/src/services/systemMonitor.ts +936 -0
  222. package/src/services/updateService.ts +334 -0
  223. package/src/services/websocketEvents.ts +409 -0
  224. package/src/services/websocketServer.ts +394 -0
  225. package/src/settings/SettingsSchema.ts +664 -0
  226. package/src/testing/TestServer.ts +312 -0
  227. package/src/types/index.ts +154 -0
  228. package/src/utils/appPaths.ts +196 -0
  229. package/src/utils/fs-utils.ts +130 -0
  230. package/src/utils/index.ts +15 -0
  231. package/src/utils/standardConfig.ts +178 -0
  232. package/src/utils/startupBanner.ts +287 -0
  233. package/src/utils/startupLogger.ts +268 -0
  234. package/ui/dist/index.d.mts +1221 -0
  235. package/ui/dist/index.d.ts +1221 -0
  236. package/ui/dist/index.js +73 -0
  237. package/ui/dist/index.js.map +1 -0
  238. package/ui/dist/index.mjs +73 -0
  239. package/ui/dist/index.mjs.map +1 -0
@@ -0,0 +1,693 @@
1
+ /**
2
+ * Enhanced System Monitor Service
3
+ * Provides comprehensive system health and performance metrics
4
+ */
5
+ import os from "os";
6
+ import fs from "fs";
7
+ import { promisify } from "util";
8
+ import { exec } from "child_process";
9
+ import { createLogger } from "../core/index.js";
10
+ const execAsync = promisify(exec);
11
+ const logger = createLogger("SystemMonitor");
12
+ class SystemMonitor {
13
+ cpuUsageHistory = [];
14
+ lastCPUInfo = null;
15
+ diskIOCache = new Map();
16
+ /**
17
+ * Get comprehensive system health metrics
18
+ */
19
+ async getSystemHealth() {
20
+ const [cpu, memory, disk, system, network] = await Promise.all([
21
+ this.getCPUInfo(),
22
+ this.getMemoryInfo(),
23
+ this.getDiskInfo(),
24
+ this.getSystemInfo(),
25
+ this.getNetworkInfo(),
26
+ ]);
27
+ return {
28
+ cpu,
29
+ memory,
30
+ disk,
31
+ system,
32
+ network,
33
+ timestamp: new Date(),
34
+ };
35
+ }
36
+ /**
37
+ * Get CPU information including temperature
38
+ */
39
+ async getCPUInfo() {
40
+ const cpus = os.cpus();
41
+ const model = cpus[0]?.model || "Unknown";
42
+ const cores = cpus.length;
43
+ const speed = cpus[0]?.speed || 0;
44
+ const loadAverage = os.loadavg();
45
+ // Calculate CPU usage
46
+ const usage = await this.calculateCPUUsage();
47
+ // Try to get CPU temperature
48
+ const temperature = await this.getCPUTemperature();
49
+ return {
50
+ usage,
51
+ temperature,
52
+ cores,
53
+ model,
54
+ speed,
55
+ loadAverage,
56
+ };
57
+ }
58
+ /**
59
+ * Calculate CPU usage percentage
60
+ */
61
+ async calculateCPUUsage() {
62
+ const cpus = os.cpus();
63
+ let totalIdle = 0;
64
+ let totalTick = 0;
65
+ cpus.forEach((cpu) => {
66
+ for (const type in cpu.times) {
67
+ totalTick += cpu.times[type];
68
+ }
69
+ totalIdle += cpu.times.idle;
70
+ });
71
+ if (this.lastCPUInfo) {
72
+ const idleDiff = totalIdle - this.lastCPUInfo.idle;
73
+ const totalDiff = totalTick - this.lastCPUInfo.total;
74
+ const usage = Math.round(100 - (100 * idleDiff) / totalDiff);
75
+ this.cpuUsageHistory.push(usage);
76
+ if (this.cpuUsageHistory.length > 60) {
77
+ this.cpuUsageHistory.shift();
78
+ }
79
+ this.lastCPUInfo = { idle: totalIdle, total: totalTick };
80
+ return usage;
81
+ }
82
+ this.lastCPUInfo = { idle: totalIdle, total: totalTick };
83
+ return 0;
84
+ }
85
+ /**
86
+ * Get CPU temperature (platform-specific)
87
+ */
88
+ async getCPUTemperature() {
89
+ const platform = process.platform;
90
+ try {
91
+ if (platform === "darwin") {
92
+ // macOS - try using osx-temperature-sensor
93
+ const { stdout } = await execAsync('sysctl -n machdep.xcpm.cpu_thermal_level 2>/dev/null || echo ""');
94
+ if (stdout.trim()) {
95
+ return parseFloat(stdout.trim());
96
+ }
97
+ }
98
+ else if (platform === "linux") {
99
+ // Linux - read from thermal zone
100
+ const thermalZone = "/sys/class/thermal/thermal_zone0/temp";
101
+ if (fs.existsSync(thermalZone)) {
102
+ const temp = fs.readFileSync(thermalZone, "utf8");
103
+ return parseInt(temp) / 1000; // Convert from millidegrees
104
+ }
105
+ }
106
+ else if (platform === "win32") {
107
+ // Windows - use wmic
108
+ const { stdout } = await execAsync("wmic /namespace:\\\\root\\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature /value");
109
+ const match = stdout.match(/CurrentTemperature=(\d+)/);
110
+ if (match) {
111
+ // Convert from tenths of Kelvin to Celsius
112
+ return (parseInt(match[1]) - 2732) / 10;
113
+ }
114
+ }
115
+ }
116
+ catch (_error) {
117
+ logger.debug("Could not get CPU temperature:", _error);
118
+ }
119
+ return undefined;
120
+ }
121
+ /**
122
+ * Get memory information including swap and detailed breakdown
123
+ */
124
+ async getMemoryInfo() {
125
+ const totalMem = os.totalmem();
126
+ const freeMem = os.freemem();
127
+ const usedMem = totalMem - freeMem;
128
+ const percentage = Math.round((usedMem / totalMem) * 100);
129
+ const memInfo = {
130
+ total: totalMem,
131
+ used: usedMem,
132
+ free: freeMem,
133
+ percentage,
134
+ };
135
+ // Add process memory usage
136
+ const memUsage = process.memoryUsage();
137
+ memInfo.process = {
138
+ rss: memUsage.rss,
139
+ heapTotal: memUsage.heapTotal,
140
+ heapUsed: memUsage.heapUsed,
141
+ external: memUsage.external,
142
+ arrayBuffers: memUsage.arrayBuffers || 0,
143
+ };
144
+ // Try to get detailed memory information
145
+ const detailed = await this.getDetailedMemoryInfo();
146
+ if (detailed) {
147
+ Object.assign(memInfo, detailed);
148
+ }
149
+ // Try to get swap information
150
+ const swap = await this.getSwapInfo();
151
+ if (swap) {
152
+ memInfo.swap = {
153
+ ...swap,
154
+ percentage: swap.total > 0 ? Math.round((swap.used / swap.total) * 100) : 0,
155
+ };
156
+ }
157
+ return memInfo;
158
+ }
159
+ /**
160
+ * Get detailed memory breakdown (Linux only)
161
+ */
162
+ async getDetailedMemoryInfo() {
163
+ const platform = process.platform;
164
+ if (platform !== "linux") {
165
+ return undefined;
166
+ }
167
+ try {
168
+ const { stdout } = await execAsync("cat /proc/meminfo");
169
+ const lines = stdout.split("\n");
170
+ const meminfo = {};
171
+ for (const line of lines) {
172
+ const match = line.match(/^(\w+):\s+(\d+)\s+kB/);
173
+ if (match) {
174
+ meminfo[match[1]] = parseInt(match[2]) * 1024; // Convert to bytes
175
+ }
176
+ }
177
+ const result = {};
178
+ // Available memory
179
+ if (meminfo.MemAvailable) {
180
+ result.available = meminfo.MemAvailable;
181
+ }
182
+ // Active/Inactive
183
+ if (meminfo.Active)
184
+ result.active = meminfo.Active;
185
+ if (meminfo.Inactive)
186
+ result.inactive = meminfo.Inactive;
187
+ // Buffers/Cached
188
+ if (meminfo.Buffers)
189
+ result.buffers = meminfo.Buffers;
190
+ if (meminfo.Cached)
191
+ result.cached = meminfo.Cached;
192
+ // Detailed breakdown
193
+ if (meminfo.Slab || meminfo.KernelStack || meminfo.PageTables) {
194
+ result.breakdown = {
195
+ apps: meminfo.MemTotal -
196
+ meminfo.MemFree -
197
+ meminfo.Buffers -
198
+ meminfo.Cached || 0,
199
+ pageCache: meminfo.Cached || 0,
200
+ buffers: meminfo.Buffers || 0,
201
+ slab: meminfo.Slab || 0,
202
+ kernelStack: meminfo.KernelStack || 0,
203
+ pageTables: meminfo.PageTables || 0,
204
+ vmallocUsed: meminfo.VmallocUsed || 0,
205
+ };
206
+ }
207
+ return result;
208
+ }
209
+ catch (_error) {
210
+ logger.debug("Could not get detailed memory info:", _error);
211
+ return undefined;
212
+ }
213
+ }
214
+ /**
215
+ * Get swap memory information
216
+ */
217
+ async getSwapInfo() {
218
+ const platform = process.platform;
219
+ try {
220
+ if (platform === "linux") {
221
+ const { stdout } = await execAsync("free -b | grep Swap");
222
+ const parts = stdout.trim().split(/\s+/);
223
+ if (parts.length >= 3) {
224
+ return {
225
+ total: parseInt(parts[1]),
226
+ used: parseInt(parts[2]),
227
+ free: parseInt(parts[3]),
228
+ };
229
+ }
230
+ }
231
+ else if (platform === "darwin") {
232
+ const { stdout } = await execAsync("sysctl vm.swapusage");
233
+ const match = stdout.match(/total = ([\d.]+)M.*used = ([\d.]+)M.*free = ([\d.]+)M/);
234
+ if (match) {
235
+ return {
236
+ total: parseFloat(match[1]) * 1024 * 1024,
237
+ used: parseFloat(match[2]) * 1024 * 1024,
238
+ free: parseFloat(match[3]) * 1024 * 1024,
239
+ };
240
+ }
241
+ }
242
+ }
243
+ catch (_error) {
244
+ logger.debug("Could not get swap information:", _error);
245
+ }
246
+ return undefined;
247
+ }
248
+ /**
249
+ * Get disk information including I/O stats
250
+ */
251
+ async getDiskInfo() {
252
+ const platform = process.platform;
253
+ let diskInfo = {
254
+ total: 0,
255
+ used: 0,
256
+ free: 0,
257
+ percentage: 0,
258
+ };
259
+ try {
260
+ if (platform === "darwin" || platform === "linux") {
261
+ const { stdout } = await execAsync("df -k / | tail -1");
262
+ const parts = stdout.trim().split(/\s+/);
263
+ if (parts.length >= 4) {
264
+ const total = parseInt(parts[1]) * 1024;
265
+ const used = parseInt(parts[2]) * 1024;
266
+ const free = parseInt(parts[3]) * 1024;
267
+ const percentage = Math.round((used / total) * 100);
268
+ diskInfo = { total, used, free, percentage };
269
+ }
270
+ }
271
+ else if (platform === "win32") {
272
+ const { stdout } = await execAsync("wmic logicaldisk get size,freespace /value");
273
+ const lines = stdout.trim().split("\n");
274
+ let total = 0, free = 0;
275
+ lines.forEach((line) => {
276
+ if (line.startsWith("FreeSpace=")) {
277
+ const value = line.split("=")[1];
278
+ if (value)
279
+ free += parseInt(value);
280
+ }
281
+ else if (line.startsWith("Size=")) {
282
+ const value = line.split("=")[1];
283
+ if (value)
284
+ total += parseInt(value);
285
+ }
286
+ });
287
+ const used = total - free;
288
+ const percentage = total > 0 ? Math.round((used / total) * 100) : 0;
289
+ diskInfo = { total, used, free, percentage };
290
+ }
291
+ // Get I/O stats
292
+ const io = await this.getDiskIOStats();
293
+ if (io) {
294
+ diskInfo.io = io;
295
+ }
296
+ }
297
+ catch (_error) {
298
+ logger.debug("Could not get disk information:", _error);
299
+ }
300
+ return diskInfo;
301
+ }
302
+ /**
303
+ * Get disk I/O statistics
304
+ */
305
+ async getDiskIOStats() {
306
+ const platform = process.platform;
307
+ try {
308
+ if (platform === "linux") {
309
+ const { stdout } = await execAsync('cat /proc/diskstats | grep -E "sda |nvme0n1 " | head -1');
310
+ const parts = stdout.trim().split(/\s+/);
311
+ if (parts.length >= 10) {
312
+ const current = {
313
+ readOps: parseInt(parts[3]),
314
+ readBytes: parseInt(parts[5]) * 512,
315
+ writeOps: parseInt(parts[7]),
316
+ writeBytes: parseInt(parts[9]) * 512,
317
+ };
318
+ // Calculate rate if we have previous data
319
+ const cacheKey = "diskio";
320
+ const previous = this.diskIOCache.get(cacheKey);
321
+ if (previous) {
322
+ const timeDiff = Date.now() - previous.timestamp;
323
+ const rateFactor = 1000 / timeDiff; // Convert to per second
324
+ const io = {
325
+ readBytes: Math.round((current.readBytes - previous.readBytes) * rateFactor),
326
+ writeBytes: Math.round((current.writeBytes - previous.writeBytes) * rateFactor),
327
+ readOps: Math.round((current.readOps - previous.readOps) * rateFactor),
328
+ writeOps: Math.round((current.writeOps - previous.writeOps) * rateFactor),
329
+ };
330
+ this.diskIOCache.set(cacheKey, {
331
+ ...current,
332
+ timestamp: Date.now(),
333
+ });
334
+ return io;
335
+ }
336
+ this.diskIOCache.set(cacheKey, { ...current, timestamp: Date.now() });
337
+ }
338
+ }
339
+ else if (platform === "darwin") {
340
+ const { stdout } = await execAsync("iostat -d -w 1 -c 2 | tail -1");
341
+ const parts = stdout.trim().split(/\s+/);
342
+ if (parts.length >= 3) {
343
+ return {
344
+ readBytes: parseFloat(parts[0]) * 1024,
345
+ writeBytes: parseFloat(parts[1]) * 1024,
346
+ readOps: 0,
347
+ writeOps: 0,
348
+ };
349
+ }
350
+ }
351
+ }
352
+ catch (_error) {
353
+ logger.debug("Could not get disk I/O statistics:", _error);
354
+ }
355
+ return undefined;
356
+ }
357
+ /**
358
+ * Get system information
359
+ */
360
+ async getSystemInfo() {
361
+ const platform = process.platform;
362
+ const arch = process.arch;
363
+ const version = os.release();
364
+ const hostname = os.hostname();
365
+ const uptime = os.uptime();
366
+ const bootTime = new Date(Date.now() - uptime * 1000);
367
+ let kernel = version;
368
+ // Try to get more detailed kernel info
369
+ try {
370
+ if (platform === "linux" || platform === "darwin") {
371
+ const { stdout } = await execAsync("uname -r");
372
+ kernel = stdout.trim();
373
+ }
374
+ }
375
+ catch {
376
+ // Use default
377
+ }
378
+ return {
379
+ platform,
380
+ arch,
381
+ version,
382
+ kernel,
383
+ hostname,
384
+ uptime,
385
+ bootTime,
386
+ };
387
+ }
388
+ /**
389
+ * Get network information
390
+ */
391
+ async getNetworkInfo() {
392
+ const interfaces = await this.getNetworkInterfaces();
393
+ const connections = await this.getNetworkConnections();
394
+ return {
395
+ interfaces,
396
+ connections,
397
+ };
398
+ }
399
+ /**
400
+ * Get detailed network interface information
401
+ */
402
+ async getNetworkInterfaces() {
403
+ const interfaces = os.networkInterfaces();
404
+ const result = [];
405
+ for (const [name, addresses] of Object.entries(interfaces)) {
406
+ if (!addresses)
407
+ continue;
408
+ const ipv4Addresses = addresses
409
+ .filter((addr) => addr.family === "IPv4")
410
+ .map((addr) => addr.address);
411
+ if (ipv4Addresses.length > 0) {
412
+ const interfaceInfo = {
413
+ name,
414
+ addresses: ipv4Addresses,
415
+ mac: addresses[0]?.mac || "00:00:00:00:00:00",
416
+ };
417
+ // Try to get interface statistics
418
+ const stats = await this.getInterfaceStats(name);
419
+ if (stats) {
420
+ interfaceInfo.stats = stats;
421
+ }
422
+ result.push(interfaceInfo);
423
+ }
424
+ }
425
+ return result;
426
+ }
427
+ /**
428
+ * Get network interface statistics
429
+ */
430
+ async getInterfaceStats(interfaceName) {
431
+ const platform = process.platform;
432
+ try {
433
+ if (platform === "linux") {
434
+ const statsFile = `/sys/class/net/${interfaceName}/statistics`;
435
+ if (fs.existsSync(statsFile)) {
436
+ const readFile = (file) => {
437
+ try {
438
+ return parseInt(fs.readFileSync(`${statsFile}/${file}`, "utf8").trim());
439
+ }
440
+ catch {
441
+ return 0;
442
+ }
443
+ };
444
+ return {
445
+ rxBytes: readFile("rx_bytes"),
446
+ txBytes: readFile("tx_bytes"),
447
+ rxPackets: readFile("rx_packets"),
448
+ txPackets: readFile("tx_packets"),
449
+ rxErrors: readFile("rx_errors"),
450
+ txErrors: readFile("tx_errors"),
451
+ };
452
+ }
453
+ }
454
+ else if (platform === "darwin") {
455
+ const { stdout } = await execAsync(`netstat -ibn | grep -A 1 "^${interfaceName}"`);
456
+ const lines = stdout.trim().split("\n");
457
+ if (lines.length >= 2) {
458
+ const parts = lines[1].trim().split(/\s+/);
459
+ if (parts.length >= 10) {
460
+ return {
461
+ rxPackets: parseInt(parts[4]),
462
+ rxErrors: parseInt(parts[5]),
463
+ rxBytes: parseInt(parts[6]),
464
+ txPackets: parseInt(parts[7]),
465
+ txErrors: parseInt(parts[8]),
466
+ txBytes: parseInt(parts[9]),
467
+ };
468
+ }
469
+ }
470
+ }
471
+ }
472
+ catch (_error) {
473
+ logger.debug(`Could not get stats for interface ${interfaceName}:`, _error);
474
+ }
475
+ return undefined;
476
+ }
477
+ /**
478
+ * Get detailed network statistics with bandwidth usage
479
+ */
480
+ async getNetworkStatistics() {
481
+ const interfaces = await this.getNetworkInterfaces();
482
+ let totalBytesReceived = 0;
483
+ let totalBytesSent = 0;
484
+ let totalPacketsReceived = 0;
485
+ let totalPacketsSent = 0;
486
+ // Sum up statistics from all interfaces
487
+ for (const iface of interfaces) {
488
+ if (iface.stats) {
489
+ totalBytesReceived += iface.stats.rxBytes || 0;
490
+ totalBytesSent += iface.stats.txBytes || 0;
491
+ totalPacketsReceived += iface.stats.rxPackets || 0;
492
+ totalPacketsSent += iface.stats.txPackets || 0;
493
+ }
494
+ }
495
+ const connections = await this.getNetworkConnections();
496
+ // Calculate bandwidth if we have previous measurements
497
+ const bandwidth = await this.calculateBandwidth(totalBytesReceived, totalBytesSent);
498
+ return {
499
+ interfaces,
500
+ totalBytesReceived,
501
+ totalBytesSent,
502
+ totalPacketsReceived,
503
+ totalPacketsSent,
504
+ connections,
505
+ bandwidth,
506
+ };
507
+ }
508
+ /**
509
+ * Calculate bandwidth based on byte counters
510
+ */
511
+ lastNetworkMeasurement;
512
+ async calculateBandwidth(currentBytesReceived, currentBytesSent) {
513
+ const now = Date.now();
514
+ if (this.lastNetworkMeasurement) {
515
+ const timeDiff = (now - this.lastNetworkMeasurement.timestamp) / 1000; // seconds
516
+ if (timeDiff > 0) {
517
+ const download = (currentBytesReceived - this.lastNetworkMeasurement.bytesReceived) /
518
+ timeDiff;
519
+ const upload = (currentBytesSent - this.lastNetworkMeasurement.bytesSent) / timeDiff;
520
+ this.lastNetworkMeasurement = {
521
+ timestamp: now,
522
+ bytesReceived: currentBytesReceived,
523
+ bytesSent: currentBytesSent,
524
+ };
525
+ return {
526
+ download: Math.max(0, download),
527
+ upload: Math.max(0, upload),
528
+ };
529
+ }
530
+ }
531
+ else {
532
+ // First measurement
533
+ this.lastNetworkMeasurement = {
534
+ timestamp: now,
535
+ bytesReceived: currentBytesReceived,
536
+ bytesSent: currentBytesSent,
537
+ };
538
+ }
539
+ return undefined;
540
+ }
541
+ /**
542
+ * Get active network connections by state
543
+ */
544
+ async getNetworkConnectionsByState() {
545
+ const platform = process.platform;
546
+ try {
547
+ let established = 0;
548
+ let listening = 0;
549
+ let timeWait = 0;
550
+ let closeWait = 0;
551
+ if (platform === "linux") {
552
+ const { stdout } = await execAsync("ss -tan");
553
+ const lines = stdout.split("\n").slice(1); // Skip header
554
+ for (const line of lines) {
555
+ if (line.includes("ESTAB"))
556
+ established++;
557
+ else if (line.includes("LISTEN"))
558
+ listening++;
559
+ else if (line.includes("TIME-WAIT"))
560
+ timeWait++;
561
+ else if (line.includes("CLOSE-WAIT"))
562
+ closeWait++;
563
+ }
564
+ }
565
+ else if (platform === "darwin" || platform === "win32") {
566
+ const { stdout } = await execAsync("netstat -an");
567
+ const lines = stdout.split("\n");
568
+ for (const line of lines) {
569
+ if (line.includes("ESTABLISHED"))
570
+ established++;
571
+ else if (line.includes("LISTEN"))
572
+ listening++;
573
+ else if (line.includes("TIME_WAIT"))
574
+ timeWait++;
575
+ else if (line.includes("CLOSE_WAIT"))
576
+ closeWait++;
577
+ }
578
+ }
579
+ return {
580
+ established,
581
+ listening,
582
+ timeWait,
583
+ closeWait,
584
+ total: established + listening + timeWait + closeWait,
585
+ };
586
+ }
587
+ catch (_error) {
588
+ logger.debug("Could not get network connections by state:", _error);
589
+ return {
590
+ established: 0,
591
+ listening: 0,
592
+ timeWait: 0,
593
+ closeWait: 0,
594
+ total: 0,
595
+ };
596
+ }
597
+ }
598
+ /**
599
+ * Get number of network connections
600
+ */
601
+ async getNetworkConnections() {
602
+ try {
603
+ const platform = process.platform;
604
+ let command = "";
605
+ if (platform === "linux") {
606
+ command = "ss -tun | tail -n +2 | wc -l";
607
+ }
608
+ else if (platform === "darwin") {
609
+ command = "netstat -an | grep ESTABLISHED | wc -l";
610
+ }
611
+ else if (platform === "win32") {
612
+ command = 'netstat -an | find /c "ESTABLISHED"';
613
+ }
614
+ if (command) {
615
+ const { stdout } = await execAsync(command);
616
+ return parseInt(stdout.trim()) || 0;
617
+ }
618
+ }
619
+ catch (_error) {
620
+ logger.debug("Could not get network connections:", _error);
621
+ }
622
+ return 0;
623
+ }
624
+ /**
625
+ * Get top processes by CPU or memory usage
626
+ */
627
+ async getTopProcesses(sortBy = "cpu", limit = 10) {
628
+ const platform = process.platform;
629
+ const processes = [];
630
+ try {
631
+ if (platform === "linux" || platform === "darwin") {
632
+ const sortFlag = sortBy === "cpu" ? "-pcpu" : "-pmem";
633
+ const { stdout } = await execAsync(`ps aux --sort=${sortFlag} | head -${limit + 1} | tail -${limit}`);
634
+ const lines = stdout.trim().split("\n");
635
+ for (const line of lines) {
636
+ const parts = line.trim().split(/\s+/);
637
+ if (parts.length >= 11) {
638
+ processes.push({
639
+ pid: parseInt(parts[1]),
640
+ cpu: parseFloat(parts[2]),
641
+ memory: parseFloat(parts[3]),
642
+ name: parts[10],
643
+ uptime: 0, // Would need additional parsing
644
+ });
645
+ }
646
+ }
647
+ }
648
+ else if (platform === "win32") {
649
+ await execAsync("wmic process get ProcessId,Name,PageFileUsage,UserModeTime /format:csv");
650
+ // Parse Windows output
651
+ // Implementation would be more complex
652
+ }
653
+ }
654
+ catch (_error) {
655
+ logger.debug("Could not get process list:", _error);
656
+ }
657
+ return processes;
658
+ }
659
+ /**
660
+ * Get CPU usage history
661
+ */
662
+ getCPUHistory() {
663
+ return [...this.cpuUsageHistory];
664
+ }
665
+ /**
666
+ * Monitor system health continuously
667
+ */
668
+ async startMonitoring(interval = 5000, callback) {
669
+ // Initial reading
670
+ await this.getSystemHealth();
671
+ return setInterval(async () => {
672
+ try {
673
+ const health = await this.getSystemHealth();
674
+ if (callback) {
675
+ callback(health);
676
+ }
677
+ }
678
+ catch (_error) {
679
+ logger.error("Error monitoring system health:", _error);
680
+ }
681
+ }, interval);
682
+ }
683
+ }
684
+ // Singleton instance
685
+ let systemMonitor = null;
686
+ export function getSystemMonitor() {
687
+ if (!systemMonitor) {
688
+ systemMonitor = new SystemMonitor();
689
+ }
690
+ return systemMonitor;
691
+ }
692
+ export default SystemMonitor;
693
+ //# sourceMappingURL=systemMonitor.js.map