opencode-system-metrics-tui 0.1.4 → 0.1.5
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 +16 -10
- package/dist/install-hack-font.js +10 -4
- package/dist/tui.js +92 -59
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## Install globally in OpenCode
|
|
4
4
|
|
|
5
5
|
```powershell
|
|
6
|
-
opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
6
|
+
opencode plugin -g opencode-system-metrics-tui@0.1.4 --force
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
This is the primary installation path. The version must match `package.json`; `--force` asks OpenCode to refresh its package cache. Verify the actual installed artifact afterward:
|
|
@@ -40,6 +40,8 @@ The README is available in **Español**, **English**, and **Português**.
|
|
|
40
40
|
- En Windows, la temperatura de CPU requiere LibreHardwareMonitor ejecutándose como administrador con **Remote Web Server** activo en `http://127.0.0.1:8085`.
|
|
41
41
|
- En Windows, la velocidad de red usa PowerShell y `Get-NetAdapterStatistics`; no agrega una dependencia npm.
|
|
42
42
|
- Las lecturas opcionales de Windows se hacen bajo demanda, con timeout y caché; no hay timers globales de PowerShell.
|
|
43
|
+
- La detección de Nerd Font en Linux/macOS está limitada a rutas conocidas, 2 niveles de profundidad y 256 entradas por directorio; una ruta ausente o inaccesible usa Unicode. Windows no escanea fuentes salvo con `OPENCODE_MONITOR_NERD_FONT=1`.
|
|
44
|
+
- Si una fuente de métricas no responde a tiempo, su intento en caché se abandona de forma segura para permitir reintentos sin cancelar APIs que no aceptan `AbortSignal`.
|
|
43
45
|
|
|
44
46
|
### Requisitos
|
|
45
47
|
|
|
@@ -89,7 +91,7 @@ npm publish --access public
|
|
|
89
91
|
En otro equipo:
|
|
90
92
|
|
|
91
93
|
```bash
|
|
92
|
-
opencode plugin opencode-system-metrics-tui@0.1.
|
|
94
|
+
opencode plugin opencode-system-metrics-tui@0.1.4
|
|
93
95
|
```
|
|
94
96
|
|
|
95
97
|
El paquete exporta tanto la raíz (`opencode-system-metrics-tui`) como `./tui`; ambas rutas cargan el mismo bundle TUI.
|
|
@@ -99,8 +101,8 @@ El instalador de OpenCode configura el plugin TUI automáticamente. Reinicia Ope
|
|
|
99
101
|
Publicar en npm e instalar en OpenCode son pasos distintos:
|
|
100
102
|
|
|
101
103
|
- `npm publish --access public` publica el paquete en npm.
|
|
102
|
-
- `opencode plugin opencode-system-metrics-tui@0.1.
|
|
103
|
-
- `opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
104
|
+
- `opencode plugin opencode-system-metrics-tui@0.1.4` lo instala solo en el proyecto actual.
|
|
105
|
+
- `opencode plugin -g opencode-system-metrics-tui@0.1.4 --force` lo instala globalmente para todos los proyectos.
|
|
104
106
|
|
|
105
107
|
### Verificación
|
|
106
108
|
|
|
@@ -131,6 +133,8 @@ npm run build
|
|
|
131
133
|
- On Windows, CPU temperature requires LibreHardwareMonitor running as administrator with **Remote Web Server** enabled at `http://127.0.0.1:8085`.
|
|
132
134
|
- On Windows, network speed uses PowerShell and `Get-NetAdapterStatistics`; it adds no npm dependency.
|
|
133
135
|
- Optional Windows reads are on demand, timeout-bounded, and cached; no global PowerShell timers are used.
|
|
136
|
+
- Linux/macOS Nerd Font detection is limited to known paths, two directory levels, and 256 entries per directory; missing or inaccessible paths safely fall back to Unicode. Windows does not scan fonts unless `OPENCODE_MONITOR_NERD_FONT=1` is set.
|
|
137
|
+
- When a metric source does not respond in time, its cache attempt is safely abandoned so retries remain possible without cancelling APIs that do not accept `AbortSignal`.
|
|
134
138
|
|
|
135
139
|
### Requirements
|
|
136
140
|
|
|
@@ -180,7 +184,7 @@ npm publish --access public
|
|
|
180
184
|
On another machine:
|
|
181
185
|
|
|
182
186
|
```bash
|
|
183
|
-
opencode plugin opencode-system-metrics-tui@0.1.
|
|
187
|
+
opencode plugin opencode-system-metrics-tui@0.1.4
|
|
184
188
|
```
|
|
185
189
|
|
|
186
190
|
The package exports both the root (`opencode-system-metrics-tui`) and `./tui`; both paths load the same TUI bundle.
|
|
@@ -190,8 +194,8 @@ The OpenCode installer configures the TUI plugin automatically. Restart OpenCode
|
|
|
190
194
|
Publishing to npm and installing in OpenCode are separate steps:
|
|
191
195
|
|
|
192
196
|
- `npm publish --access public` publishes the package to npm.
|
|
193
|
-
- `opencode plugin opencode-system-metrics-tui@0.1.
|
|
194
|
-
- `opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
197
|
+
- `opencode plugin opencode-system-metrics-tui@0.1.4` installs it for the current project only.
|
|
198
|
+
- `opencode plugin -g opencode-system-metrics-tui@0.1.4 --force` installs it globally for all projects.
|
|
195
199
|
|
|
196
200
|
### Verification
|
|
197
201
|
|
|
@@ -222,6 +226,8 @@ npm run build
|
|
|
222
226
|
- No Windows, a temperatura da CPU requer o LibreHardwareMonitor executado como administrador com o **Remote Web Server** ativo em `http://127.0.0.1:8085`.
|
|
223
227
|
- No Windows, a velocidade da rede usa o PowerShell e `Get-NetAdapterStatistics`; nenhuma dependência npm é adicionada.
|
|
224
228
|
- As leituras opcionais do Windows são sob demanda, têm timeout e cache; não há timers globais do PowerShell.
|
|
229
|
+
- A detecção de Nerd Font no Linux/macOS é limitada a caminhos conhecidos, dois níveis de profundidade e 256 entradas por diretório; caminhos ausentes ou inacessíveis usam Unicode. O Windows não verifica fontes sem `OPENCODE_MONITOR_NERD_FONT=1`.
|
|
230
|
+
- Quando uma fonte de métricas não responde a tempo, a tentativa em cache é abandonada com segurança para permitir novas tentativas sem cancelar APIs que não aceitam `AbortSignal`.
|
|
225
231
|
|
|
226
232
|
### Requisitos
|
|
227
233
|
|
|
@@ -271,7 +277,7 @@ npm publish --access public
|
|
|
271
277
|
Em outro computador:
|
|
272
278
|
|
|
273
279
|
```bash
|
|
274
|
-
opencode plugin opencode-system-metrics-tui@0.1.
|
|
280
|
+
opencode plugin opencode-system-metrics-tui@0.1.4
|
|
275
281
|
```
|
|
276
282
|
|
|
277
283
|
O pacote exporta tanto a raiz (`opencode-system-metrics-tui`) quanto `./tui`; os dois caminhos carregam o mesmo bundle TUI.
|
|
@@ -281,8 +287,8 @@ O instalador do OpenCode configura o plugin TUI automaticamente. Reinicie o Open
|
|
|
281
287
|
Publicar no npm e instalar no OpenCode são etapas diferentes:
|
|
282
288
|
|
|
283
289
|
- `npm publish --access public` publica o pacote no npm.
|
|
284
|
-
- `opencode plugin opencode-system-metrics-tui@0.1.
|
|
285
|
-
- `opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
290
|
+
- `opencode plugin opencode-system-metrics-tui@0.1.4` instala o plugin apenas no projeto atual.
|
|
291
|
+
- `opencode plugin -g opencode-system-metrics-tui@0.1.4 --force` instala o plugin globalmente para todos os projetos.
|
|
286
292
|
|
|
287
293
|
### Verificação
|
|
288
294
|
|
|
@@ -10,6 +10,8 @@ import { existsSync, readdirSync } from "node:fs";
|
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { join as posixJoin, win32 } from "node:path";
|
|
12
12
|
var NERD_FONT_FILE_PATTERN = /NerdFont[A-Za-z0-9-]*[-_][A-Za-z0-9-]+\.(?:ttf|otf)$/i;
|
|
13
|
+
var MAX_FONT_SCAN_DEPTH = 2;
|
|
14
|
+
var MAX_FONT_SCAN_ENTRIES = 256;
|
|
13
15
|
function getFontDirectories(platform, home = homedir(), env = process.env) {
|
|
14
16
|
if (platform === "darwin")
|
|
15
17
|
return [posixJoin(home, "Library", "Fonts"), "/Library/Fonts", "/System/Library/Fonts"];
|
|
@@ -25,19 +27,23 @@ function isNerdFontFile(fileName) {
|
|
|
25
27
|
}
|
|
26
28
|
var isHackNerdFontFile = isNerdFontFile;
|
|
27
29
|
function hasNerdFont(platform = process.platform, home = homedir(), env = process.env) {
|
|
28
|
-
|
|
30
|
+
if (platform === "win32" && env.OPENCODE_MONITOR_NERD_FONT !== "1")
|
|
31
|
+
return false;
|
|
32
|
+
const containsFont = (directory, depth) => {
|
|
33
|
+
if (depth > MAX_FONT_SCAN_DEPTH)
|
|
34
|
+
return false;
|
|
29
35
|
if (!existsSync(directory))
|
|
30
36
|
return false;
|
|
31
37
|
try {
|
|
32
|
-
return readdirSync(directory, { withFileTypes: true }).some((entry) => {
|
|
38
|
+
return readdirSync(directory, { withFileTypes: true }).slice(0, MAX_FONT_SCAN_ENTRIES).some((entry) => {
|
|
33
39
|
const path = platform === "win32" ? win32.join(directory, entry.name) : posixJoin(directory, entry.name);
|
|
34
|
-
return entry.isFile() ? isNerdFontFile(entry.name) : entry.isDirectory() && containsFont(path);
|
|
40
|
+
return entry.isFile() ? isNerdFontFile(entry.name) : entry.isDirectory() && containsFont(path, depth + 1);
|
|
35
41
|
});
|
|
36
42
|
} catch {
|
|
37
43
|
return false;
|
|
38
44
|
}
|
|
39
45
|
};
|
|
40
|
-
return getFontDirectories(platform, home, env).some(containsFont);
|
|
46
|
+
return getFontDirectories(platform, home, env).some((directory) => containsFont(directory, 0));
|
|
41
47
|
}
|
|
42
48
|
var hasHackNerdFont = hasNerdFont;
|
|
43
49
|
var nerdFontIcons = {
|
package/dist/tui.js
CHANGED
|
@@ -52,22 +52,31 @@ async function readLibreHardwareMonitorTemperature() {
|
|
|
52
52
|
if (!response.ok)
|
|
53
53
|
return;
|
|
54
54
|
const root = await response.json();
|
|
55
|
+
if (root === null || typeof root !== "object")
|
|
56
|
+
return;
|
|
55
57
|
const sensors = [];
|
|
56
58
|
const visit = (node) => {
|
|
57
59
|
if (node.Type === "Temperature" && node.Text !== undefined)
|
|
58
60
|
sensors.push(node);
|
|
59
|
-
for (const child of node.Children
|
|
60
|
-
|
|
61
|
+
for (const child of Array.isArray(node.Children) ? node.Children : []) {
|
|
62
|
+
if (child !== null && typeof child === "object")
|
|
63
|
+
visit(child);
|
|
64
|
+
}
|
|
61
65
|
};
|
|
62
66
|
visit(root);
|
|
63
67
|
const cpuSensor = sensors.find((sensor) => sensor.Text === "CPU Package") ?? sensors.find((sensor) => sensor.Text === "Core Average") ?? sensors.find((sensor) => sensor.Text === "Core Max");
|
|
64
68
|
return parseMonitorTemperature(cpuSensor?.Value);
|
|
65
69
|
}
|
|
66
70
|
function parseWindowsNetworkOutput(stdout) {
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
let parsed;
|
|
72
|
+
try {
|
|
73
|
+
parsed = JSON.parse(stdout.trim());
|
|
74
|
+
} catch {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
const rows = (Array.isArray(parsed) ? parsed : [parsed]).filter((item) => item !== null && typeof item === "object");
|
|
69
78
|
return rows.map((item) => ({
|
|
70
|
-
iface: item.Name,
|
|
79
|
+
iface: typeof item.Name === "string" ? item.Name : undefined,
|
|
71
80
|
rx_bytes: finite(item.ReceivedBytes) ?? 0,
|
|
72
81
|
tx_bytes: finite(item.SentBytes) ?? 0
|
|
73
82
|
}));
|
|
@@ -126,14 +135,15 @@ function selectGpuMetrics(graphics) {
|
|
|
126
135
|
gpuMemoryTotalBytes: null,
|
|
127
136
|
gpuMemoryPercent: null
|
|
128
137
|
};
|
|
129
|
-
if (graphics === undefined)
|
|
138
|
+
if (graphics === undefined || graphics === null || !Array.isArray(graphics.controllers))
|
|
130
139
|
return empty;
|
|
131
140
|
const controller = graphics.controllers.map((item) => {
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
const
|
|
141
|
+
const source = item ?? {};
|
|
142
|
+
const utilization = finite(source.utilizationGpu);
|
|
143
|
+
const temperature = finite(source.temperatureGpu);
|
|
144
|
+
const memoryTotal = finite(source.memoryTotal);
|
|
145
|
+
const memoryFree = finite(source.memoryFree);
|
|
146
|
+
const memoryUsed = finite(source.memoryUsed) ?? (memoryTotal !== null && memoryFree !== null ? Math.max(0, memoryTotal - memoryFree) : null);
|
|
137
147
|
const hasMemory = memoryUsed !== null && memoryTotal !== null && memoryTotal > 0;
|
|
138
148
|
return { utilization, temperature, memoryUsed, memoryTotal, hasMemory };
|
|
139
149
|
}).filter(({ utilization, temperature, hasMemory }) => utilization !== null || temperature !== null || hasMemory).sort((left, right) => {
|
|
@@ -156,7 +166,7 @@ function selectGpuMetrics(graphics) {
|
|
|
156
166
|
}
|
|
157
167
|
return result;
|
|
158
168
|
}
|
|
159
|
-
function readCachedMetric(state, reader, cacheMs = SLOW_METRIC_CACHE_MS, now = Date.now(), unavailableCacheMs = cacheMs) {
|
|
169
|
+
function readCachedMetric(state, reader, cacheMs = SLOW_METRIC_CACHE_MS, now = Date.now(), unavailableCacheMs = cacheMs, timeoutMs) {
|
|
160
170
|
if (state.inFlight !== undefined)
|
|
161
171
|
return state.inFlight;
|
|
162
172
|
if (state.lastFailureAt !== undefined && now - state.lastFailureAt < unavailableCacheMs) {
|
|
@@ -165,17 +175,23 @@ function readCachedMetric(state, reader, cacheMs = SLOW_METRIC_CACHE_MS, now = D
|
|
|
165
175
|
if (now - state.lastAttemptAt < cacheMs)
|
|
166
176
|
return Promise.resolve(state.value);
|
|
167
177
|
state.lastAttemptAt = now;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
let flight;
|
|
179
|
+
flight = (async () => {
|
|
180
|
+
try {
|
|
181
|
+
const value = timeoutMs === undefined ? await reader() : await withTimeout(reader(), timeoutMs);
|
|
182
|
+
state.value = value;
|
|
183
|
+
state.lastFailureAt = undefined;
|
|
184
|
+
return value;
|
|
185
|
+
} catch {
|
|
186
|
+
state.lastFailureAt = now;
|
|
187
|
+
return state.value;
|
|
188
|
+
} finally {
|
|
189
|
+
if (state.inFlight === flight)
|
|
190
|
+
state.inFlight = undefined;
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
193
|
+
state.inFlight = flight;
|
|
194
|
+
return flight;
|
|
179
195
|
}
|
|
180
196
|
var cachedCpuTemperature = {
|
|
181
197
|
value: undefined,
|
|
@@ -238,9 +254,9 @@ async function readMetrics() {
|
|
|
238
254
|
withTimeout(si.mem(), 1500)
|
|
239
255
|
]);
|
|
240
256
|
const [temperature, graphics, network] = await Promise.allSettled([
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
257
|
+
readCachedMetric(cachedCpuTemperature, isWindows ? readWindowsCpuTemperature : () => si.cpuTemperature(), TEMPERATURE_CACHE_MS, Date.now(), TEMPERATURE_CACHE_MS, 2500),
|
|
258
|
+
readCachedMetric(cachedGraphics, () => si.graphics(), SLOW_METRIC_CACHE_MS, Date.now(), SLOW_METRIC_CACHE_MS, 2500),
|
|
259
|
+
readCachedMetric(cachedNetwork, isWindows ? readWindowsNetworkMetrics : () => si.networkStats("*"), isWindows ? NETWORK_CACHE_MS : 2000, Date.now(), OPTIONAL_SOURCE_BACKOFF_MS, 1500)
|
|
244
260
|
]);
|
|
245
261
|
const cpuPercent = load.status === "fulfilled" ? finite(load.value.currentLoad) : null;
|
|
246
262
|
const memoryTotalBytes = memory.status === "fulfilled" ? finite(memory.value.total) : null;
|
|
@@ -251,7 +267,7 @@ async function readMetrics() {
|
|
|
251
267
|
let downloadBytesPerSecond = null;
|
|
252
268
|
let uploadBytesPerSecond = null;
|
|
253
269
|
if (network.status === "fulfilled" && network.value !== undefined) {
|
|
254
|
-
const samples = network.value;
|
|
270
|
+
const samples = Array.isArray(network.value) ? network.value : [];
|
|
255
271
|
const timestamp = Date.now();
|
|
256
272
|
const rx = samples.reduce((total, item) => total + (finite(item.rx_bytes) ?? 0), 0);
|
|
257
273
|
const tx = samples.reduce((total, item) => total + (finite(item.tx_bytes) ?? 0), 0);
|
|
@@ -290,6 +306,8 @@ import { existsSync, readdirSync } from "node:fs";
|
|
|
290
306
|
import { homedir } from "node:os";
|
|
291
307
|
import { join as posixJoin, win32 } from "node:path";
|
|
292
308
|
var NERD_FONT_FILE_PATTERN = /NerdFont[A-Za-z0-9-]*[-_][A-Za-z0-9-]+\.(?:ttf|otf)$/i;
|
|
309
|
+
var MAX_FONT_SCAN_DEPTH = 2;
|
|
310
|
+
var MAX_FONT_SCAN_ENTRIES = 256;
|
|
293
311
|
function getFontDirectories(platform, home = homedir(), env = process.env) {
|
|
294
312
|
if (platform === "darwin")
|
|
295
313
|
return [posixJoin(home, "Library", "Fonts"), "/Library/Fonts", "/System/Library/Fonts"];
|
|
@@ -305,19 +323,23 @@ function isNerdFontFile(fileName) {
|
|
|
305
323
|
}
|
|
306
324
|
var isHackNerdFontFile = isNerdFontFile;
|
|
307
325
|
function hasNerdFont(platform = process.platform, home = homedir(), env = process.env) {
|
|
308
|
-
|
|
326
|
+
if (platform === "win32" && env.OPENCODE_MONITOR_NERD_FONT !== "1")
|
|
327
|
+
return false;
|
|
328
|
+
const containsFont = (directory, depth) => {
|
|
329
|
+
if (depth > MAX_FONT_SCAN_DEPTH)
|
|
330
|
+
return false;
|
|
309
331
|
if (!existsSync(directory))
|
|
310
332
|
return false;
|
|
311
333
|
try {
|
|
312
|
-
return readdirSync(directory, { withFileTypes: true }).some((entry) => {
|
|
334
|
+
return readdirSync(directory, { withFileTypes: true }).slice(0, MAX_FONT_SCAN_ENTRIES).some((entry) => {
|
|
313
335
|
const path = platform === "win32" ? win32.join(directory, entry.name) : posixJoin(directory, entry.name);
|
|
314
|
-
return entry.isFile() ? isNerdFontFile(entry.name) : entry.isDirectory() && containsFont(path);
|
|
336
|
+
return entry.isFile() ? isNerdFontFile(entry.name) : entry.isDirectory() && containsFont(path, depth + 1);
|
|
315
337
|
});
|
|
316
338
|
} catch {
|
|
317
339
|
return false;
|
|
318
340
|
}
|
|
319
341
|
};
|
|
320
|
-
return getFontDirectories(platform, home, env).some(containsFont);
|
|
342
|
+
return getFontDirectories(platform, home, env).some((directory) => containsFont(directory, 0));
|
|
321
343
|
}
|
|
322
344
|
var hasHackNerdFont = hasNerdFont;
|
|
323
345
|
var nerdFontIcons = {
|
|
@@ -341,7 +363,8 @@ function shouldUseNerdFont(platform, detected, env = process.env) {
|
|
|
341
363
|
|
|
342
364
|
// src/tui.tsx
|
|
343
365
|
var REFRESH_INTERVAL_MS = 2000;
|
|
344
|
-
var
|
|
366
|
+
var platform = process.platform;
|
|
367
|
+
var icons = getMetricIcons(shouldUseNerdFont(platform, platform === "win32" ? false : hasNerdFont()));
|
|
345
368
|
var initialMetrics = {
|
|
346
369
|
cpuPercent: null,
|
|
347
370
|
memoryUsedBytes: null,
|
|
@@ -356,33 +379,43 @@ var initialMetrics = {
|
|
|
356
379
|
downloadBytesPerSecond: null,
|
|
357
380
|
uploadBytesPerSecond: null
|
|
358
381
|
};
|
|
359
|
-
var
|
|
360
|
-
var
|
|
361
|
-
var
|
|
362
|
-
|
|
382
|
+
var METRICS_STATE_KEY = Symbol.for("opencode-monitor.system-metrics");
|
|
383
|
+
var globalMetrics = globalThis;
|
|
384
|
+
var metricsState = globalMetrics[METRICS_STATE_KEY] ?? (globalMetrics[METRICS_STATE_KEY] = {
|
|
385
|
+
...(() => {
|
|
386
|
+
const [sharedMetrics, setSharedMetrics] = createSignal(initialMetrics);
|
|
387
|
+
return {
|
|
388
|
+
sharedMetrics,
|
|
389
|
+
setSharedMetrics
|
|
390
|
+
};
|
|
391
|
+
})(),
|
|
392
|
+
metricsTimer: undefined,
|
|
393
|
+
metricsConsumers: 0,
|
|
394
|
+
refreshing: false
|
|
395
|
+
});
|
|
363
396
|
var refreshMetrics = async () => {
|
|
364
|
-
if (refreshing)
|
|
397
|
+
if (metricsState.refreshing)
|
|
365
398
|
return;
|
|
366
|
-
refreshing = true;
|
|
399
|
+
metricsState.refreshing = true;
|
|
367
400
|
try {
|
|
368
|
-
setSharedMetrics(await readMetrics());
|
|
401
|
+
metricsState.setSharedMetrics(await readMetrics());
|
|
369
402
|
} finally {
|
|
370
|
-
refreshing = false;
|
|
403
|
+
metricsState.refreshing = false;
|
|
371
404
|
}
|
|
372
405
|
};
|
|
373
406
|
function startMetricsPolling() {
|
|
374
|
-
metricsConsumers += 1;
|
|
375
|
-
if (metricsConsumers !== 1)
|
|
407
|
+
metricsState.metricsConsumers += 1;
|
|
408
|
+
if (metricsState.metricsConsumers !== 1)
|
|
376
409
|
return;
|
|
377
410
|
refreshMetrics();
|
|
378
|
-
metricsTimer = setInterval(() => void refreshMetrics(), REFRESH_INTERVAL_MS);
|
|
411
|
+
metricsState.metricsTimer = setInterval(() => void refreshMetrics(), REFRESH_INTERVAL_MS);
|
|
379
412
|
}
|
|
380
413
|
function stopMetricsPolling() {
|
|
381
|
-
metricsConsumers = Math.max(0, metricsConsumers - 1);
|
|
382
|
-
if (metricsConsumers !== 0 || metricsTimer === undefined)
|
|
414
|
+
metricsState.metricsConsumers = Math.max(0, metricsState.metricsConsumers - 1);
|
|
415
|
+
if (metricsState.metricsConsumers !== 0 || metricsState.metricsTimer === undefined)
|
|
383
416
|
return;
|
|
384
|
-
clearInterval(metricsTimer);
|
|
385
|
-
metricsTimer = undefined;
|
|
417
|
+
clearInterval(metricsState.metricsTimer);
|
|
418
|
+
metricsState.metricsTimer = undefined;
|
|
386
419
|
}
|
|
387
420
|
function systemMetricsTitle() {
|
|
388
421
|
const locale = process.env.LC_ALL ?? process.env.LANGUAGE?.split(":")[0] ?? process.env.LANG ?? Intl.DateTimeFormat().resolvedOptions().locale;
|
|
@@ -420,9 +453,9 @@ function MetricsPanel(props) {
|
|
|
420
453
|
_$insertNode(_el$6, _$createTextNode(` CPU `));
|
|
421
454
|
_$insertNode(_el$8, _el$9);
|
|
422
455
|
_$insertNode(_el$8, _el$0);
|
|
423
|
-
_$insert(_el$8, () => formatPercent(sharedMetrics().cpuPercent), _el$9);
|
|
456
|
+
_$insert(_el$8, () => formatPercent(metricsState.sharedMetrics().cpuPercent), _el$9);
|
|
424
457
|
_$insert(_el$8, () => icons.thermometer, _el$0);
|
|
425
|
-
_$insert(_el$8, () => formatTemperature(sharedMetrics().cpuTemperatureCelsius), null);
|
|
458
|
+
_$insert(_el$8, () => formatTemperature(metricsState.sharedMetrics().cpuTemperatureCelsius), null);
|
|
426
459
|
_$insertNode(_el$1, _el$10);
|
|
427
460
|
_$insertNode(_el$1, _el$11);
|
|
428
461
|
_$insertNode(_el$1, _el$13);
|
|
@@ -432,9 +465,9 @@ function MetricsPanel(props) {
|
|
|
432
465
|
_$insertNode(_el$13, _el$14);
|
|
433
466
|
_$insertNode(_el$13, _el$15);
|
|
434
467
|
_$insertNode(_el$13, _el$16);
|
|
435
|
-
_$insert(_el$13, () => formatGiB(sharedMetrics().memoryUsedBytes), _el$14);
|
|
436
|
-
_$insert(_el$13, () => formatGiB(sharedMetrics().memoryTotalBytes), _el$15);
|
|
437
|
-
_$insert(_el$13, () => formatPercent(sharedMetrics().memoryPercent), _el$16);
|
|
468
|
+
_$insert(_el$13, () => formatGiB(metricsState.sharedMetrics().memoryUsedBytes), _el$14);
|
|
469
|
+
_$insert(_el$13, () => formatGiB(metricsState.sharedMetrics().memoryTotalBytes), _el$15);
|
|
470
|
+
_$insert(_el$13, () => formatPercent(metricsState.sharedMetrics().memoryPercent), _el$16);
|
|
438
471
|
_$insertNode(_el$17, _el$18);
|
|
439
472
|
_$insertNode(_el$17, _el$19);
|
|
440
473
|
_$insertNode(_el$17, _el$21);
|
|
@@ -443,9 +476,9 @@ function MetricsPanel(props) {
|
|
|
443
476
|
_$insertNode(_el$19, _$createTextNode(` GPU `));
|
|
444
477
|
_$insertNode(_el$21, _el$22);
|
|
445
478
|
_$insertNode(_el$21, _el$23);
|
|
446
|
-
_$insert(_el$21, () => formatPercent(sharedMetrics().gpuPercent), _el$22);
|
|
479
|
+
_$insert(_el$21, () => formatPercent(metricsState.sharedMetrics().gpuPercent), _el$22);
|
|
447
480
|
_$insert(_el$21, () => icons.thermometer, _el$23);
|
|
448
|
-
_$insert(_el$21, () => formatTemperature(sharedMetrics().gpuTemperatureCelsius), null);
|
|
481
|
+
_$insert(_el$21, () => formatTemperature(metricsState.sharedMetrics().gpuTemperatureCelsius), null);
|
|
449
482
|
_$insertNode(_el$24, _el$25);
|
|
450
483
|
_$insertNode(_el$24, _el$26);
|
|
451
484
|
_$insertNode(_el$24, _el$28);
|
|
@@ -455,9 +488,9 @@ function MetricsPanel(props) {
|
|
|
455
488
|
_$insertNode(_el$28, _el$29);
|
|
456
489
|
_$insertNode(_el$28, _el$30);
|
|
457
490
|
_$insertNode(_el$28, _el$31);
|
|
458
|
-
_$insert(_el$28, () => formatGiB(sharedMetrics().gpuMemoryUsedBytes), _el$29);
|
|
459
|
-
_$insert(_el$28, () => formatGiB(sharedMetrics().gpuMemoryTotalBytes), _el$30);
|
|
460
|
-
_$insert(_el$28, () => formatPercent(sharedMetrics().gpuMemoryPercent), _el$31);
|
|
491
|
+
_$insert(_el$28, () => formatGiB(metricsState.sharedMetrics().gpuMemoryUsedBytes), _el$29);
|
|
492
|
+
_$insert(_el$28, () => formatGiB(metricsState.sharedMetrics().gpuMemoryTotalBytes), _el$30);
|
|
493
|
+
_$insert(_el$28, () => formatPercent(metricsState.sharedMetrics().gpuMemoryPercent), _el$31);
|
|
461
494
|
_$insertNode(_el$32, _el$33);
|
|
462
495
|
_$insertNode(_el$32, _el$34);
|
|
463
496
|
_$insertNode(_el$32, _el$36);
|
|
@@ -466,8 +499,8 @@ function MetricsPanel(props) {
|
|
|
466
499
|
_$insertNode(_el$34, _$createTextNode(` NET `));
|
|
467
500
|
_$insertNode(_el$36, _el$37);
|
|
468
501
|
_$insertNode(_el$36, _el$38);
|
|
469
|
-
_$insert(_el$36, () => formatRate(sharedMetrics().downloadBytesPerSecond), _el$38);
|
|
470
|
-
_$insert(_el$36, () => formatRate(sharedMetrics().uploadBytesPerSecond), null);
|
|
502
|
+
_$insert(_el$36, () => formatRate(metricsState.sharedMetrics().downloadBytesPerSecond), _el$38);
|
|
503
|
+
_$insert(_el$36, () => formatRate(metricsState.sharedMetrics().uploadBytesPerSecond), null);
|
|
471
504
|
_$effect((_p$) => {
|
|
472
505
|
var _v$ = props.theme.text, _v$2 = TextAttributes.BOLD, _v$3 = props.theme.success, _v$4 = props.theme.text, _v$5 = props.theme.textMuted, _v$6 = props.theme.success, _v$7 = props.theme.text, _v$8 = props.theme.textMuted, _v$9 = props.theme.success, _v$0 = props.theme.text, _v$1 = props.theme.textMuted, _v$10 = props.theme.success, _v$11 = props.theme.text, _v$12 = props.theme.textMuted, _v$13 = props.theme.success, _v$14 = props.theme.text, _v$15 = props.theme.textMuted;
|
|
473
506
|
_v$ !== _p$.e && (_p$.e = _$setProp(_el$2, "fg", _v$, _p$.e));
|