opencode-system-metrics-tui 0.1.14 → 0.1.16
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 +10 -10
- package/dist/tui.js +35 -5
- 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.16 --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. The helper below skips OpenCode when the expected artifact is already current. Verify the actual installed artifact afterward:
|
|
@@ -120,7 +120,7 @@ npm publish --access public
|
|
|
120
120
|
En otro equipo:
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
opencode plugin opencode-system-metrics-tui@0.1.
|
|
123
|
+
opencode plugin opencode-system-metrics-tui@0.1.16
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
El paquete exporta tanto la raíz (`opencode-system-metrics-tui`) como `./tui`; ambas rutas cargan el mismo bundle TUI.
|
|
@@ -130,8 +130,8 @@ El instalador de OpenCode configura el plugin TUI automáticamente. Reinicia Ope
|
|
|
130
130
|
Publicar en npm e instalar en OpenCode son pasos distintos:
|
|
131
131
|
|
|
132
132
|
- `npm publish --access public` publica el paquete en npm.
|
|
133
|
-
- `opencode plugin opencode-system-metrics-tui@0.1.
|
|
134
|
-
- `opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
133
|
+
- `opencode plugin opencode-system-metrics-tui@0.1.16` lo instala solo en el proyecto actual.
|
|
134
|
+
- `opencode plugin -g opencode-system-metrics-tui@0.1.16 --force` lo instala globalmente para todos los proyectos.
|
|
135
135
|
|
|
136
136
|
### Verificación
|
|
137
137
|
|
|
@@ -231,7 +231,7 @@ npm publish --access public
|
|
|
231
231
|
On another machine:
|
|
232
232
|
|
|
233
233
|
```bash
|
|
234
|
-
opencode plugin opencode-system-metrics-tui@0.1.
|
|
234
|
+
opencode plugin opencode-system-metrics-tui@0.1.16
|
|
235
235
|
```
|
|
236
236
|
|
|
237
237
|
The package exports both the root (`opencode-system-metrics-tui`) and `./tui`; both paths load the same TUI bundle.
|
|
@@ -241,8 +241,8 @@ The OpenCode installer configures the TUI plugin automatically. Restart OpenCode
|
|
|
241
241
|
Publishing to npm and installing in OpenCode are separate steps:
|
|
242
242
|
|
|
243
243
|
- `npm publish --access public` publishes the package to npm.
|
|
244
|
-
- `opencode plugin opencode-system-metrics-tui@0.1.
|
|
245
|
-
- `opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
244
|
+
- `opencode plugin opencode-system-metrics-tui@0.1.16` installs it for the current project only.
|
|
245
|
+
- `opencode plugin -g opencode-system-metrics-tui@0.1.16 --force` installs it globally for all projects.
|
|
246
246
|
|
|
247
247
|
### Verification
|
|
248
248
|
|
|
@@ -339,7 +339,7 @@ npm publish --access public
|
|
|
339
339
|
Em outro computador:
|
|
340
340
|
|
|
341
341
|
```bash
|
|
342
|
-
opencode plugin opencode-system-metrics-tui@0.1.
|
|
342
|
+
opencode plugin opencode-system-metrics-tui@0.1.16
|
|
343
343
|
```
|
|
344
344
|
|
|
345
345
|
O pacote exporta tanto a raiz (`opencode-system-metrics-tui`) quanto `./tui`; os dois caminhos carregam o mesmo bundle TUI.
|
|
@@ -349,8 +349,8 @@ O instalador do OpenCode configura o plugin TUI automaticamente. Reinicie o Open
|
|
|
349
349
|
Publicar no npm e instalar no OpenCode são etapas diferentes:
|
|
350
350
|
|
|
351
351
|
- `npm publish --access public` publica o pacote no npm.
|
|
352
|
-
- `opencode plugin opencode-system-metrics-tui@0.1.
|
|
353
|
-
- `opencode plugin -g opencode-system-metrics-tui@0.1.
|
|
352
|
+
- `opencode plugin opencode-system-metrics-tui@0.1.16` instala o plugin apenas no projeto atual.
|
|
353
|
+
- `opencode plugin -g opencode-system-metrics-tui@0.1.16 --force` instala o plugin globalmente para todos os projetos.
|
|
354
354
|
|
|
355
355
|
### Verificação
|
|
356
356
|
|
package/dist/tui.js
CHANGED
|
@@ -47,6 +47,9 @@ var IF_OPER_STATUS_UP = 1;
|
|
|
47
47
|
var NET_IF_ACCESS_LOOPBACK = 1;
|
|
48
48
|
var ROWS_OFFSET = 8;
|
|
49
49
|
var nativeReader;
|
|
50
|
+
function isWindowsNetworkReaderAvailable(bunVersion) {
|
|
51
|
+
return bunVersion === undefined;
|
|
52
|
+
}
|
|
50
53
|
function toUint64(value) {
|
|
51
54
|
if (typeof value === "bigint" && value >= 0n)
|
|
52
55
|
return value;
|
|
@@ -80,6 +83,17 @@ function networkRate(current, previous, elapsedMs) {
|
|
|
80
83
|
const tx = current.tx >= previous.tx ? current.tx - previous.tx : 0n;
|
|
81
84
|
return { rx: Number(rx) / seconds, tx: Number(tx) / seconds };
|
|
82
85
|
}
|
|
86
|
+
function decodeNativeIfRow(koffi, row, table, offset) {
|
|
87
|
+
const decode = (field, type) => koffi.decode(table, offset + koffi.offsetof(row, field), type);
|
|
88
|
+
return {
|
|
89
|
+
InterfaceAndOperStatusFlags: decode("InterfaceAndOperStatusFlags", "uint8"),
|
|
90
|
+
OperStatus: decode("OperStatus", "uint32"),
|
|
91
|
+
Type: decode("Type", "uint32"),
|
|
92
|
+
AccessType: decode("AccessType", "uint32"),
|
|
93
|
+
InOctets: decode("InOctets", "uint64"),
|
|
94
|
+
OutOctets: decode("OutOctets", "uint64")
|
|
95
|
+
};
|
|
96
|
+
}
|
|
83
97
|
function defineNativeReader(koffi) {
|
|
84
98
|
const guid = koffi.struct("MIB_GUID", {
|
|
85
99
|
Data1: "uint32",
|
|
@@ -145,7 +159,7 @@ function defineNativeReader(koffi) {
|
|
|
145
159
|
const count = Number(koffi.decode(table, 0, "uint32"));
|
|
146
160
|
if (!Number.isSafeInteger(count) || count < 0 || count > 4096)
|
|
147
161
|
throw new Error(`Invalid interface count: ${count}`);
|
|
148
|
-
return Array.from({ length: count }, (_, index) => koffi
|
|
162
|
+
return Array.from({ length: count }, (_, index) => decodeNativeIfRow(koffi, row, table, ROWS_OFFSET + index * koffi.sizeof(row)));
|
|
149
163
|
} finally {
|
|
150
164
|
freeMibTable(table);
|
|
151
165
|
}
|
|
@@ -156,6 +170,10 @@ async function loadNativeReader() {
|
|
|
156
170
|
return defineNativeReader(loaded.default ?? loaded);
|
|
157
171
|
}
|
|
158
172
|
async function readWindowsNetworkCounters() {
|
|
173
|
+
const bunVersion = process.versions.bun;
|
|
174
|
+
if (!isWindowsNetworkReaderAvailable(bunVersion)) {
|
|
175
|
+
throw new Error("Native Windows network metrics are unavailable on Bun");
|
|
176
|
+
}
|
|
159
177
|
nativeReader ??= loadNativeReader();
|
|
160
178
|
return mapWindowsNetworkRows((await nativeReader)());
|
|
161
179
|
}
|
|
@@ -362,6 +380,14 @@ var runCommand = async (command, args, timeoutMs) => {
|
|
|
362
380
|
const { stdout } = await execFileAsync(command, args, { timeout: timeoutMs, maxBuffer: 1024 * 1024 });
|
|
363
381
|
return stdout;
|
|
364
382
|
};
|
|
383
|
+
var runWindowsCommand = (command, args, timeoutMs) => new Promise((resolve, reject) => {
|
|
384
|
+
execFile(command, args, { windowsHide: true, timeout: timeoutMs, maxBuffer: 1024 * 1024 }, (error, stdout) => {
|
|
385
|
+
if (error !== null)
|
|
386
|
+
reject(error);
|
|
387
|
+
else
|
|
388
|
+
resolve(stdout);
|
|
389
|
+
});
|
|
390
|
+
});
|
|
365
391
|
async function detectMacHardwareArchitecture(runner = runCommand, processArchitecture = process.arch) {
|
|
366
392
|
try {
|
|
367
393
|
const output = (await runner("sysctl", ["-in", "hw.optional.arm64"], MAC_METRIC_TIMEOUT_MS)).trim();
|
|
@@ -451,13 +477,13 @@ function parseWindowsNetworkOutput(stdout) {
|
|
|
451
477
|
tx_bytes: finite(item.SentBytes) ?? 0
|
|
452
478
|
}));
|
|
453
479
|
}
|
|
454
|
-
async function readWindowsNetworkFallback() {
|
|
455
|
-
const
|
|
480
|
+
async function readWindowsNetworkFallback(runner = runWindowsCommand) {
|
|
481
|
+
const stdout = await runner("powershell.exe", [
|
|
456
482
|
"-NoProfile",
|
|
457
483
|
"-NonInteractive",
|
|
458
484
|
"-Command",
|
|
459
485
|
"Get-NetAdapterStatistics | Select-Object Name,ReceivedBytes,SentBytes | ConvertTo-Json -Compress"
|
|
460
|
-
],
|
|
486
|
+
], WINDOWS_NETWORK_PROCESS_TIMEOUT_MS);
|
|
461
487
|
return parseWindowsNetworkOutput(stdout);
|
|
462
488
|
}
|
|
463
489
|
var previousNetwork;
|
|
@@ -497,6 +523,7 @@ var SLOW_METRIC_CACHE_MS = 1e4;
|
|
|
497
523
|
var TEMPERATURE_CACHE_MS = 1e4;
|
|
498
524
|
var OPTIONAL_SOURCE_BACKOFF_MS = 30000;
|
|
499
525
|
var isWindows = process.platform === "win32";
|
|
526
|
+
var isBun = process.versions.bun !== undefined;
|
|
500
527
|
var isMac = process.platform === "darwin";
|
|
501
528
|
var NETWORK_CACHE_MS = 2000;
|
|
502
529
|
var macHardwareArchitecture;
|
|
@@ -641,6 +668,9 @@ async function readWindowsCpuTemperature() {
|
|
|
641
668
|
return value === undefined ? undefined : { main: value };
|
|
642
669
|
}
|
|
643
670
|
async function readMetrics() {
|
|
671
|
+
const networkMetric = readCachedMetric(cachedNetwork, isWindows ? readWindowsNetworkMetrics : () => si.networkStats("*"), isWindows ? NETWORK_CACHE_MS : 2000, Date.now(), isWindows && isBun ? NETWORK_CACHE_MS : OPTIONAL_SOURCE_BACKOFF_MS, isWindows ? WINDOWS_NETWORK_OUTER_TIMEOUT_MS : DEFAULT_METRIC_TIMEOUT_MS);
|
|
672
|
+
if (isWindows && isBun)
|
|
673
|
+
await networkMetric;
|
|
644
674
|
const [native, hardwareArchitecture] = await Promise.allSettled([
|
|
645
675
|
withTimeout(readNativeMetrics(), isWindows ? WINDOWS_MEMORY_TIMEOUT_MS : DEFAULT_METRIC_TIMEOUT_MS),
|
|
646
676
|
readMacHardwareArchitecture()
|
|
@@ -662,7 +692,7 @@ async function readMetrics() {
|
|
|
662
692
|
const [temperature, graphics, network, mac] = await Promise.allSettled([
|
|
663
693
|
readCachedMetric(cachedCpuTemperature, isWindows ? readWindowsCpuTemperature : () => si.cpuTemperature(), TEMPERATURE_CACHE_MS, Date.now(), TEMPERATURE_CACHE_MS, 2500),
|
|
664
694
|
readCachedMetric(cachedGraphics, () => si.graphics(), SLOW_METRIC_CACHE_MS, Date.now(), SLOW_METRIC_CACHE_MS, 2500),
|
|
665
|
-
|
|
695
|
+
networkMetric,
|
|
666
696
|
isMac ? readCachedMetric(cachedMacMetrics, () => readMacMetrics(), SLOW_METRIC_CACHE_MS, Date.now(), OPTIONAL_SOURCE_BACKOFF_MS, MAC_METRIC_TIMEOUT_MS) : Promise.resolve(undefined)
|
|
667
697
|
]);
|
|
668
698
|
const memoryUsedBytes = fallbackMemoryUsedBytes ?? (memoryTotalBytes !== null && memoryAvailableBytes !== null ? Math.max(0, memoryTotalBytes - memoryAvailableBytes) : null);
|