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.
Files changed (3) hide show
  1. package/README.md +10 -10
  2. package/dist/tui.js +35 -5
  3. 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.14 --force
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.14
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.14` lo instala solo en el proyecto actual.
134
- - `opencode plugin -g opencode-system-metrics-tui@0.1.14 --force` lo instala globalmente para todos los proyectos.
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.14
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.14` installs it for the current project only.
245
- - `opencode plugin -g opencode-system-metrics-tui@0.1.14 --force` installs it globally for all projects.
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.14
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.14` instala o plugin apenas no projeto atual.
353
- - `opencode plugin -g opencode-system-metrics-tui@0.1.14 --force` instala o plugin globalmente para todos os projetos.
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.decode(table, ROWS_OFFSET + index * koffi.sizeof(row), row));
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 { stdout } = await execFileAsync("powershell.exe", [
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
- ], { windowsHide: true, timeout: WINDOWS_NETWORK_PROCESS_TIMEOUT_MS, maxBuffer: 1024 * 1024 });
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
- readCachedMetric(cachedNetwork, isWindows ? readWindowsNetworkMetrics : () => si.networkStats("*"), isWindows ? NETWORK_CACHE_MS : 2000, Date.now(), OPTIONAL_SOURCE_BACKOFF_MS, isWindows ? WINDOWS_NETWORK_OUTER_TIMEOUT_MS : DEFAULT_METRIC_TIMEOUT_MS),
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-system-metrics-tui",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "OpenCode TUI sidebar plugin for live system metrics",
5
5
  "license": "MIT",
6
6
  "type": "module",