about-system 0.0.40 → 0.0.45
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 +11 -1
- package/dist/about-system-cli.js +1 -1
- package/dist/gpu-geekbench.json +1 -0
- package/dist/index.js +1 -1
- package/dist/system-info-api-CChFyamn.js +2396 -0
- package/dist/system-info-api-CChFyamn.js.map +1 -0
- package/dist/system-info-api.d.ts +61 -17
- package/dist/system-info-api.js +1 -1
- package/package.json +3 -3
- package/src/info/hardware.ts +246 -34
- package/src/info/memory.ts +183 -53
- package/src/info/network.ts +6 -6
- package/src/info/platform.ts +14 -1
- package/src/info/process.ts +20 -4
- package/src/info/settings.ts +7 -2
- package/src/info/software.ts +15 -3
- package/src/info/system-status.ts +67 -3
- package/src/system-info-api.ts +8 -1
- package/src/systeminfo-types.d.ts +47 -8
- package/dist/system-info-api-J8OqC6YU.js +0 -2148
- package/dist/system-info-api-J8OqC6YU.js.map +0 -1
- /package/dist/{cpu-geekbench-1k.json → cpu-geekbench.json} +0 -0
|
@@ -15,7 +15,7 @@ declare function battery(context: InfoContext): string;
|
|
|
15
15
|
* Uses fuzzy matching to find similar CPU models
|
|
16
16
|
* @param context - Info context with cache
|
|
17
17
|
* @returns Benchmark info with score and rank, or empty string
|
|
18
|
-
* @example "
|
|
18
|
+
* @example "37.9k #1", "20.5k #68"
|
|
19
19
|
*/
|
|
20
20
|
declare function bench(context: InfoContext): string;
|
|
21
21
|
|
|
@@ -102,9 +102,23 @@ declare function cpu_bench_info(context: InfoContext): string;
|
|
|
102
102
|
*/
|
|
103
103
|
declare function device(context: InfoContext): string;
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Gets disk size (used/total) for each real disk
|
|
107
|
+
* Uses `df -k` on Linux/macOS, filtering out pseudo filesystems, system/boot
|
|
108
|
+
* partitions (e.g. /boot, /System/Volumes/*), and anything under 10GB, since
|
|
109
|
+
* those aren't disks a user would care about. When exactly one real disk is
|
|
110
|
+
* found (the common case) the result omits the mount point; when multiple
|
|
111
|
+
* real disks are found (e.g. a data drive or external volume), each is
|
|
112
|
+
* labeled by its mount point.
|
|
113
|
+
* @param context - Info context with cache
|
|
114
|
+
* @returns Disk size as "used/total GB" or "mount(used/total GB) ..." or empty string
|
|
115
|
+
* @example "256/512GB", "/(100/500GB) /Volumes/Backup(900/2000GB)"
|
|
116
|
+
*/
|
|
117
|
+
declare function disk_size(context: InfoContext): string;
|
|
118
|
+
|
|
105
119
|
/**
|
|
106
120
|
* Gets root filesystem disk usage percentage
|
|
107
|
-
* Uses df command on Linux/Android
|
|
121
|
+
* Uses df command on Linux/Android/macOS
|
|
108
122
|
* @param context - Info context with cache
|
|
109
123
|
* @returns Percentage string or empty string
|
|
110
124
|
* @example "45%", "78%"
|
|
@@ -134,6 +148,24 @@ export declare function getSystemInfo(options?: SystemInfoOptions): Promise<Syst
|
|
|
134
148
|
*/
|
|
135
149
|
declare function gpu(context: InfoContext): string;
|
|
136
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Gets GPU benchmark score and rank from Geekbench 6 data
|
|
153
|
+
* Uses fuzzy matching to find similar GPU models
|
|
154
|
+
* @param context - Info context with cache
|
|
155
|
+
* @returns Benchmark info with score and rank, or empty string
|
|
156
|
+
* @example "37.9k #1", "20.5k #68"
|
|
157
|
+
*/
|
|
158
|
+
declare function gpu_bench(context: InfoContext): string;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Gets detailed GPU benchmark information from Geekbench 6 data
|
|
162
|
+
* Includes score, rank, and vendor detection
|
|
163
|
+
* @param context - Info context with cache
|
|
164
|
+
* @returns Detailed benchmark info with vendor, or empty string
|
|
165
|
+
* @example "Geekbench 6: 37.9k (Rank #1) - NVIDIA", "Geekbench 6: 20.5k (Rank #68) - AMD"
|
|
166
|
+
*/
|
|
167
|
+
declare function gpu_bench_info(context: InfoContext): string;
|
|
168
|
+
|
|
137
169
|
/**
|
|
138
170
|
* Gets the system hostname
|
|
139
171
|
* @returns Computer hostname/network name
|
|
@@ -167,7 +199,10 @@ export declare const infoFunctions: {
|
|
|
167
199
|
gpu: typeof gpu;
|
|
168
200
|
bench: typeof bench;
|
|
169
201
|
cpu_bench_info: typeof cpu_bench_info;
|
|
202
|
+
gpu_bench: typeof gpu_bench;
|
|
203
|
+
gpu_bench_info: typeof gpu_bench_info;
|
|
170
204
|
disk_used: typeof disk_used;
|
|
205
|
+
disk_size: typeof disk_size;
|
|
171
206
|
ram_used: typeof ram_used;
|
|
172
207
|
top_process: typeof top_process;
|
|
173
208
|
uptime: typeof uptime;
|
|
@@ -244,7 +279,8 @@ declare function kernel(context: InfoContext): string;
|
|
|
244
279
|
|
|
245
280
|
/**
|
|
246
281
|
* Gets system load averages
|
|
247
|
-
* Reads 1, 5, and 15 minute load averages from /proc/loadavg (Linux
|
|
282
|
+
* Reads 1, 5, and 15 minute load averages from /proc/loadavg (Linux) or
|
|
283
|
+
* os.loadavg() (macOS)
|
|
248
284
|
* @returns Space-separated load averages (1m 5m 15m) or empty string
|
|
249
285
|
* @example "0.52 0.58 0.59", "2.10 1.95 1.88"
|
|
250
286
|
*/
|
|
@@ -257,7 +293,8 @@ export declare function loadCache(): Cache_2;
|
|
|
257
293
|
|
|
258
294
|
/**
|
|
259
295
|
* Gets available memory in gigabytes
|
|
260
|
-
* Reads MemAvailable from /proc/meminfo (Linux
|
|
296
|
+
* Reads MemAvailable from /proc/meminfo (Linux) or derives it from
|
|
297
|
+
* vm_stat's free+inactive pages (macOS)
|
|
261
298
|
* @returns Available memory with "GB available" suffix or empty string
|
|
262
299
|
* @example "12GB available", "4GB available"
|
|
263
300
|
*/
|
|
@@ -265,20 +302,23 @@ declare function memory_available(): string;
|
|
|
265
302
|
|
|
266
303
|
/**
|
|
267
304
|
* Gets mounted filesystem information
|
|
268
|
-
* Lists non-system mount points with usage from df (Linux
|
|
269
|
-
*
|
|
305
|
+
* Lists non-system mount points with usage from df (Linux/macOS)
|
|
306
|
+
* On Linux, excludes /, /dev, /proc, /sys and internal /System/Volumes mounts.
|
|
307
|
+
* On macOS, APFS internal volumes (Data, VM, Preboot, Update, ...) all live
|
|
308
|
+
* under /System/Volumes and are not user-relevant, so only /Volumes (external
|
|
309
|
+
* disks, network shares, disk images) are reported.
|
|
270
310
|
* @param context - Info context with cache
|
|
271
311
|
* @returns Space-separated mount points with usage or empty string
|
|
272
|
-
* @example "/home(45%) /mnt/data(78%)", "/
|
|
312
|
+
* @example "/home(45%) /mnt/data(78%)", "/Volumes/Backup(78%)"
|
|
273
313
|
*/
|
|
274
314
|
declare function mount_points(context: InfoContext): string;
|
|
275
315
|
|
|
276
316
|
/**
|
|
277
317
|
* Gets active network interface names
|
|
278
|
-
* Lists non-loopback interfaces with IPv4 addresses (Linux only)
|
|
318
|
+
* Lists non-loopback interfaces with IPv4 addresses (Linux/macOS only)
|
|
279
319
|
* @param context - Info context with cache
|
|
280
320
|
* @returns Space-separated interface names or empty string
|
|
281
|
-
* @example "eth0 wlan0", "
|
|
321
|
+
* @example "eth0 wlan0", "en0 en1"
|
|
282
322
|
*/
|
|
283
323
|
declare function network_interfaces(context: InfoContext): string;
|
|
284
324
|
|
|
@@ -302,7 +342,7 @@ declare function packages(context: InfoContext): string;
|
|
|
302
342
|
|
|
303
343
|
/**
|
|
304
344
|
* Gets open TCP ports with service names
|
|
305
|
-
* Uses lsof to find listening TCP ports (Linux only)
|
|
345
|
+
* Uses lsof to find listening TCP ports (Linux/macOS only)
|
|
306
346
|
* @param context - Info context with cache
|
|
307
347
|
* @returns Space-separated port+process pairs or empty string
|
|
308
348
|
* @example "80http 443http 22ssh", "3000node 5432post"
|
|
@@ -324,8 +364,8 @@ declare function ram_used(context: InfoContext): string;
|
|
|
324
364
|
export declare function saveCache(cache: Cache_2): void;
|
|
325
365
|
|
|
326
366
|
/**
|
|
327
|
-
* Gets screen resolution
|
|
328
|
-
* Uses xrandr
|
|
367
|
+
* Gets screen resolution
|
|
368
|
+
* Uses xrandr on Linux (X11/Xorg only) or system_profiler on macOS
|
|
329
369
|
* @returns Resolution in WIDTHxHEIGHT format or empty string
|
|
330
370
|
* @example "1920x1080", "2560x1440", "3840x2160"
|
|
331
371
|
*/
|
|
@@ -342,7 +382,8 @@ declare function services_running(context: InfoContext): string;
|
|
|
342
382
|
|
|
343
383
|
/**
|
|
344
384
|
* Gets the current shell name
|
|
345
|
-
* Uses
|
|
385
|
+
* Uses the user's login shell (macOS/Linux), falls back to ps for the
|
|
386
|
+
* parent process shell
|
|
346
387
|
* @returns Shell name or empty string on Windows
|
|
347
388
|
* @example "bash", "zsh", "fish", "nu"
|
|
348
389
|
*/
|
|
@@ -350,7 +391,8 @@ declare function shell(context: InfoContext): string;
|
|
|
350
391
|
|
|
351
392
|
/**
|
|
352
393
|
* Gets swap memory usage
|
|
353
|
-
* Calculates swap usage from /proc/meminfo (Linux
|
|
394
|
+
* Calculates swap usage from /proc/meminfo (Linux) or `sysctl vm.swapusage`
|
|
395
|
+
* (macOS)
|
|
354
396
|
* @returns Swap usage as "percentage (size MB) swap" or empty string
|
|
355
397
|
* @example "15% (512MB) swap", "0% (0MB) swap"
|
|
356
398
|
*/
|
|
@@ -358,7 +400,9 @@ declare function swap_used(): string;
|
|
|
358
400
|
|
|
359
401
|
/**
|
|
360
402
|
* Gets system temperature in Celsius
|
|
361
|
-
* Reads from thermal zone or hwmon sensors (Linux
|
|
403
|
+
* Reads from thermal zone or hwmon sensors (Linux), or from the
|
|
404
|
+
* `osx-cpu-temp` CLI (macOS, if installed via `brew install osx-cpu-temp`) -
|
|
405
|
+
* macOS has no unprivileged API for this, so nothing is reported without it
|
|
362
406
|
* @param context - Info context with cache
|
|
363
407
|
* @returns Temperature with °C suffix or empty string
|
|
364
408
|
* @example "45°C", "62°C"
|
|
@@ -367,7 +411,7 @@ declare function temperature(context: InfoContext): string;
|
|
|
367
411
|
|
|
368
412
|
/**
|
|
369
413
|
* Gets the highest CPU-consuming process
|
|
370
|
-
* Uses ps command to find top process by CPU usage (Linux only)
|
|
414
|
+
* Uses ps command to find top process by CPU usage (Linux/macOS only)
|
|
371
415
|
* @param context - Info context with cache
|
|
372
416
|
* @returns Process info as "percentage processname" or empty string
|
|
373
417
|
* @example "8% firefox", "15% chrome", "3% systemd"
|
|
@@ -389,7 +433,7 @@ declare function user(): string;
|
|
|
389
433
|
|
|
390
434
|
/**
|
|
391
435
|
* Gets number of logged in users
|
|
392
|
-
* Uses who command to count active user sessions (Linux only)
|
|
436
|
+
* Uses who command to count active user sessions (Linux/macOS only)
|
|
393
437
|
* @returns User count with "users" suffix or empty string
|
|
394
438
|
* @example "3 users", "1 users"
|
|
395
439
|
*/
|
package/dist/system-info-api.js
CHANGED
|
@@ -2,7 +2,7 @@ import "os";
|
|
|
2
2
|
import "fs";
|
|
3
3
|
import "https";
|
|
4
4
|
import "path";
|
|
5
|
-
import { g as m, i as r, l as p, s as n } from "./system-info-api-
|
|
5
|
+
import { g as m, i as r, l as p, s as n } from "./system-info-api-CChFyamn.js";
|
|
6
6
|
export {
|
|
7
7
|
m as getSystemInfo,
|
|
8
8
|
r as infoFunctions,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "about-system",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.45",
|
|
4
4
|
"description": "A Node.js script to display key system information with emojis. Cross-platform support for Windows, macOS, and Linux with customizable output and caching.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"license": "rights.institute/prosper",
|
|
57
57
|
"repository": {
|
|
58
58
|
"type": "git",
|
|
59
|
-
"url": "https://github.com/OpenSourceAGI/
|
|
59
|
+
"url": "https://github.com/OpenSourceAGI/dev-tools-starter-agent/tree/master/packages/about-system-info"
|
|
60
60
|
},
|
|
61
|
-
"homepage": "https://github.com/OpenSourceAGI/
|
|
61
|
+
"homepage": "https://github.com/OpenSourceAGI/dev-tools-starter-agent/tree/master/packages/about-system-info",
|
|
62
62
|
"files": [
|
|
63
63
|
"dist/**/*",
|
|
64
64
|
"src/**/*.ts",
|
package/src/info/hardware.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import os from "os";
|
|
7
7
|
import fs from "fs";
|
|
8
8
|
import type { InfoContext } from "../types/internal-types";
|
|
9
|
-
import { IS_WINDOWS, IS_LINUX } from "../utils/platform";
|
|
9
|
+
import { IS_WINDOWS, IS_MAC, IS_LINUX } from "../utils/platform";
|
|
10
10
|
import { execCommand } from "../utils/command";
|
|
11
11
|
import { getCachedValue, setCachedValue } from "../cache/cache";
|
|
12
12
|
import Fuse from "fuse.js";
|
|
@@ -97,54 +97,87 @@ export function gpu(context: InfoContext): string {
|
|
|
97
97
|
if (cached !== null) return cached;
|
|
98
98
|
|
|
99
99
|
if (IS_WINDOWS) {
|
|
100
|
+
const gpus: string[] = [];
|
|
101
|
+
|
|
100
102
|
try {
|
|
101
103
|
const wmic = execCommand(
|
|
102
104
|
"wmic path win32_VideoController get name /format:list"
|
|
103
105
|
);
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
return gpu;
|
|
106
|
+
const nameMatches = wmic.matchAll(/Name=(.+)/g);
|
|
107
|
+
for (const match of nameMatches) {
|
|
108
|
+
const name = match[1].trim();
|
|
109
|
+
if (name && !name.includes("Microsoft Basic")) {
|
|
110
|
+
gpus.push(name);
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
} catch {}
|
|
113
114
|
|
|
115
|
+
if (gpus.length === 0) {
|
|
116
|
+
try {
|
|
117
|
+
const ps = execCommand(
|
|
118
|
+
"powershell.exe -Command \"Get-WmiObject -Class Win32_VideoController | Where-Object {$_.Name -notlike '*Microsoft Basic*'} | Select-Object -ExpandProperty Name\""
|
|
119
|
+
);
|
|
120
|
+
if (ps.trim()) {
|
|
121
|
+
for (const line of ps.trim().split(/\r?\n/)) {
|
|
122
|
+
const name = line.trim();
|
|
123
|
+
if (name && !name.includes("Microsoft Basic")) {
|
|
124
|
+
gpus.push(name);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch {}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (gpus.length > 0) {
|
|
132
|
+
const result = gpus.join(", ");
|
|
133
|
+
setCachedValue(context.cache, "gpu", result);
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
} else if (IS_MAC) {
|
|
114
137
|
try {
|
|
115
|
-
const
|
|
116
|
-
|
|
138
|
+
const profile = execCommand("system_profiler SPDisplaysDataType");
|
|
139
|
+
const gpus = Array.from(profile.matchAll(/Chipset Model:\s*(.+)/g)).map(
|
|
140
|
+
(match) => match[1].trim()
|
|
117
141
|
);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
142
|
+
|
|
143
|
+
if (gpus.length > 0) {
|
|
144
|
+
const result = gpus.join(", ");
|
|
145
|
+
setCachedValue(context.cache, "gpu", result);
|
|
146
|
+
return result;
|
|
122
147
|
}
|
|
123
148
|
} catch {}
|
|
124
149
|
} else if (IS_LINUX) {
|
|
125
150
|
try {
|
|
126
151
|
const lspci = execCommand("lspci");
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
152
|
+
const gpus: string[] = [];
|
|
153
|
+
const classPattern = /(?:VGA compatible controller|3D controller|Display controller)/i;
|
|
154
|
+
const gpuPattern = /(?:NVIDIA|GeForce|RTX|GTX|Quadro|Tesla|AMD|ATI|Radeon|Navi|Vega|RX|Intel.*(?:Arc|UHD|Iris|HD Graphics))/i;
|
|
155
|
+
|
|
156
|
+
for (const line of lspci.split("\n")) {
|
|
157
|
+
if (!classPattern.test(line) || !gpuPattern.test(line)) continue;
|
|
158
|
+
|
|
159
|
+
let name: string;
|
|
160
|
+
const allBrackets = line.match(/\[([^\]]+)\]/g);
|
|
161
|
+
if (allBrackets && allBrackets.length > 0) {
|
|
162
|
+
const last = allBrackets[allBrackets.length - 1];
|
|
163
|
+
name = last.replace(/^\[|\]$/g, "");
|
|
136
164
|
} else {
|
|
137
|
-
|
|
138
|
-
.replace(/^.*VGA
|
|
139
|
-
.replace(/\s*\(
|
|
165
|
+
name = line
|
|
166
|
+
.replace(/^.*(?:VGA compatible controller|3D controller|Display controller):\s*/i, "")
|
|
167
|
+
.replace(/\s*\(rev [a-f0-9]+\)\s*$/i, "")
|
|
140
168
|
.trim();
|
|
141
169
|
}
|
|
142
170
|
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
return gpu;
|
|
171
|
+
if (name && !gpus.includes(name)) {
|
|
172
|
+
gpus.push(name);
|
|
146
173
|
}
|
|
147
174
|
}
|
|
175
|
+
|
|
176
|
+
if (gpus.length > 0) {
|
|
177
|
+
const result = gpus.join(", ");
|
|
178
|
+
setCachedValue(context.cache, "gpu", result);
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
148
181
|
} catch {}
|
|
149
182
|
}
|
|
150
183
|
|
|
@@ -153,12 +186,23 @@ export function gpu(context: InfoContext): string {
|
|
|
153
186
|
}
|
|
154
187
|
|
|
155
188
|
/**
|
|
156
|
-
* Gets screen resolution
|
|
157
|
-
* Uses xrandr
|
|
189
|
+
* Gets screen resolution
|
|
190
|
+
* Uses xrandr on Linux (X11/Xorg only) or system_profiler on macOS
|
|
158
191
|
* @returns Resolution in WIDTHxHEIGHT format or empty string
|
|
159
192
|
* @example "1920x1080", "2560x1440", "3840x2160"
|
|
160
193
|
*/
|
|
161
194
|
export function screen_resolution(): string {
|
|
195
|
+
if (IS_MAC) {
|
|
196
|
+
try {
|
|
197
|
+
const profile = execCommand("system_profiler SPDisplaysDataType");
|
|
198
|
+
const resolutionMatch = profile.match(/Resolution:\s*(\d+) x (\d+)/);
|
|
199
|
+
if (resolutionMatch) {
|
|
200
|
+
return `${resolutionMatch[1]}x${resolutionMatch[2]}`;
|
|
201
|
+
}
|
|
202
|
+
} catch {}
|
|
203
|
+
return "";
|
|
204
|
+
}
|
|
205
|
+
|
|
162
206
|
if (!IS_LINUX) return "";
|
|
163
207
|
|
|
164
208
|
try {
|
|
@@ -178,7 +222,7 @@ export function screen_resolution(): string {
|
|
|
178
222
|
* Uses fuzzy matching to find similar CPU models
|
|
179
223
|
* @param context - Info context with cache
|
|
180
224
|
* @returns Benchmark info with score and rank, or empty string
|
|
181
|
-
* @example "
|
|
225
|
+
* @example "37.9k #1", "20.5k #68"
|
|
182
226
|
*/
|
|
183
227
|
export function bench(context: InfoContext): string {
|
|
184
228
|
const cached = getCachedValue(context.cache, "bench");
|
|
@@ -192,7 +236,7 @@ export function bench(context: InfoContext): string {
|
|
|
192
236
|
|
|
193
237
|
try {
|
|
194
238
|
let benchmarkPath: string;
|
|
195
|
-
const benchmarkFile = "cpu-geekbench
|
|
239
|
+
const benchmarkFile = "cpu-geekbench.json";
|
|
196
240
|
|
|
197
241
|
// Try multiple resolution strategies
|
|
198
242
|
if (fs.existsSync(benchmarkFile)) {
|
|
@@ -232,7 +276,7 @@ export function bench(context: InfoContext): string {
|
|
|
232
276
|
const match = results[0].item;
|
|
233
277
|
const score = Math.round(match.score / 100) / 10;
|
|
234
278
|
const rank = match.rank;
|
|
235
|
-
const result =
|
|
279
|
+
const result = `${score}k #${rank}`;
|
|
236
280
|
setCachedValue(context.cache, "bench", result);
|
|
237
281
|
return result;
|
|
238
282
|
}
|
|
@@ -263,7 +307,7 @@ export function cpu_bench_info(context: InfoContext): string {
|
|
|
263
307
|
|
|
264
308
|
try {
|
|
265
309
|
let benchmarkPath: string;
|
|
266
|
-
const benchmarkFile = "cpu-geekbench
|
|
310
|
+
const benchmarkFile = "cpu-geekbench.json";
|
|
267
311
|
|
|
268
312
|
// Try multiple resolution strategies
|
|
269
313
|
if (fs.existsSync(benchmarkFile)) {
|
|
@@ -331,3 +375,171 @@ export function cpu_bench_info(context: InfoContext): string {
|
|
|
331
375
|
setCachedValue(context.cache, "cpu_bench_info", "");
|
|
332
376
|
return "";
|
|
333
377
|
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Gets GPU benchmark score and rank from Geekbench 6 data
|
|
381
|
+
* Uses fuzzy matching to find similar GPU models
|
|
382
|
+
* @param context - Info context with cache
|
|
383
|
+
* @returns Benchmark info with score and rank, or empty string
|
|
384
|
+
* @example "37.9k #1", "20.5k #68"
|
|
385
|
+
*/
|
|
386
|
+
export function gpu_bench(context: InfoContext): string {
|
|
387
|
+
const cached = getCachedValue(context.cache, "gpu_bench");
|
|
388
|
+
if (cached) return cached;
|
|
389
|
+
|
|
390
|
+
const gpuName = gpu(context);
|
|
391
|
+
if (!gpuName) {
|
|
392
|
+
setCachedValue(context.cache, "gpu_bench", "");
|
|
393
|
+
return "";
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
try {
|
|
397
|
+
let benchmarkPath: string;
|
|
398
|
+
const benchmarkFile = "gpu-geekbench.json";
|
|
399
|
+
|
|
400
|
+
// Try multiple resolution strategies
|
|
401
|
+
if (fs.existsSync(benchmarkFile)) {
|
|
402
|
+
benchmarkPath = benchmarkFile;
|
|
403
|
+
} else if (fs.existsSync(`src/bench/${benchmarkFile}`)) {
|
|
404
|
+
benchmarkPath = `src/bench/${benchmarkFile}`;
|
|
405
|
+
} else if (fs.existsSync(`./bench/${benchmarkFile}`)) {
|
|
406
|
+
benchmarkPath = `./bench/${benchmarkFile}`;
|
|
407
|
+
} else {
|
|
408
|
+
// Last resort: construct path from import.meta.url
|
|
409
|
+
try {
|
|
410
|
+
const url = new URL(`./${benchmarkFile}`, import.meta.url);
|
|
411
|
+
benchmarkPath = url.pathname;
|
|
412
|
+
if (!fs.existsSync(benchmarkPath)) {
|
|
413
|
+
const distPath = url.pathname.substring(0, url.pathname.lastIndexOf('/'));
|
|
414
|
+
benchmarkPath = distPath + `/${benchmarkFile}`;
|
|
415
|
+
}
|
|
416
|
+
} catch {
|
|
417
|
+
benchmarkPath = benchmarkFile;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const benchmarkData = fs.readFileSync(benchmarkPath, "utf8");
|
|
422
|
+
const parsed = JSON.parse(benchmarkData);
|
|
423
|
+
const scores = parsed.scores as [string, number, number][];
|
|
424
|
+
|
|
425
|
+
const gpuList = scores.map((item) => ({ name: item[0], score: item[1], rank: item[2] }));
|
|
426
|
+
|
|
427
|
+
const fuse = new Fuse(gpuList, {
|
|
428
|
+
keys: ["name"],
|
|
429
|
+
threshold: 0.6,
|
|
430
|
+
minMatchCharLength: 3,
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
const results = fuse.search(gpuName);
|
|
434
|
+
if (results.length > 0) {
|
|
435
|
+
const match = results[0].item;
|
|
436
|
+
const score = Math.round(match.score / 100) / 10;
|
|
437
|
+
const rank = match.rank;
|
|
438
|
+
const result = `${score}k #${rank}`;
|
|
439
|
+
setCachedValue(context.cache, "gpu_bench", result);
|
|
440
|
+
return result;
|
|
441
|
+
}
|
|
442
|
+
} catch (e) {
|
|
443
|
+
// Silently fail
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
setCachedValue(context.cache, "gpu_bench", "");
|
|
447
|
+
return "";
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Gets detailed GPU benchmark information from Geekbench 6 data
|
|
452
|
+
* Includes score, rank, and vendor detection
|
|
453
|
+
* @param context - Info context with cache
|
|
454
|
+
* @returns Detailed benchmark info with vendor, or empty string
|
|
455
|
+
* @example "Geekbench 6: 37.9k (Rank #1) - NVIDIA", "Geekbench 6: 20.5k (Rank #68) - AMD"
|
|
456
|
+
*/
|
|
457
|
+
export function gpu_bench_info(context: InfoContext): string {
|
|
458
|
+
const cached = getCachedValue(context.cache, "gpu_bench_info");
|
|
459
|
+
if (cached) return cached;
|
|
460
|
+
|
|
461
|
+
const gpuName = gpu(context);
|
|
462
|
+
if (!gpuName) {
|
|
463
|
+
setCachedValue(context.cache, "gpu_bench_info", "");
|
|
464
|
+
return "";
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
try {
|
|
468
|
+
let benchmarkPath: string;
|
|
469
|
+
const benchmarkFile = "gpu-geekbench.json";
|
|
470
|
+
|
|
471
|
+
// Try multiple resolution strategies
|
|
472
|
+
if (fs.existsSync(benchmarkFile)) {
|
|
473
|
+
benchmarkPath = benchmarkFile;
|
|
474
|
+
} else if (fs.existsSync(`src/bench/${benchmarkFile}`)) {
|
|
475
|
+
benchmarkPath = `src/bench/${benchmarkFile}`;
|
|
476
|
+
} else if (fs.existsSync(`./bench/${benchmarkFile}`)) {
|
|
477
|
+
benchmarkPath = `./bench/${benchmarkFile}`;
|
|
478
|
+
} else {
|
|
479
|
+
// Last resort: construct path from import.meta.url
|
|
480
|
+
try {
|
|
481
|
+
const url = new URL(`./${benchmarkFile}`, import.meta.url);
|
|
482
|
+
benchmarkPath = url.pathname;
|
|
483
|
+
if (!fs.existsSync(benchmarkPath)) {
|
|
484
|
+
const distPath = url.pathname.substring(0, url.pathname.lastIndexOf('/'));
|
|
485
|
+
benchmarkPath = distPath + `/${benchmarkFile}`;
|
|
486
|
+
}
|
|
487
|
+
} catch {
|
|
488
|
+
benchmarkPath = benchmarkFile;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const benchmarkData = fs.readFileSync(benchmarkPath, "utf8");
|
|
493
|
+
const parsed = JSON.parse(benchmarkData);
|
|
494
|
+
const scores = parsed.scores as [string, number, number][];
|
|
495
|
+
|
|
496
|
+
const gpuList = scores.map((item) => ({
|
|
497
|
+
name: item[0],
|
|
498
|
+
score: item[1],
|
|
499
|
+
rank: item[2],
|
|
500
|
+
}));
|
|
501
|
+
|
|
502
|
+
const fuse = new Fuse(gpuList, {
|
|
503
|
+
keys: ["name"],
|
|
504
|
+
threshold: 0.6,
|
|
505
|
+
minMatchCharLength: 3,
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
const results = fuse.search(gpuName);
|
|
509
|
+
if (results.length > 0) {
|
|
510
|
+
const match = results[0].item;
|
|
511
|
+
const score = Math.round(match.score / 100) / 10;
|
|
512
|
+
const rank = match.rank;
|
|
513
|
+
|
|
514
|
+
// Detect vendor from GPU name
|
|
515
|
+
let vendor = "Unknown";
|
|
516
|
+
const upperName = match.name.toUpperCase();
|
|
517
|
+
if (upperName.includes("NVIDIA") || upperName.includes("GEFORCE") ||
|
|
518
|
+
upperName.includes("RTX") || upperName.includes("GTX") ||
|
|
519
|
+
upperName.includes("QUADRO") || upperName.includes("TESL") ||
|
|
520
|
+
upperName.includes("B200") || upperName.includes("H100") ||
|
|
521
|
+
upperName.includes("A100") || upperName.includes("A40") ||
|
|
522
|
+
upperName.includes("L40") || upperName.includes("L20")) {
|
|
523
|
+
vendor = "NVIDIA";
|
|
524
|
+
} else if (upperName.includes("AMD") || upperName.includes("RADEON") ||
|
|
525
|
+
upperName.includes("RX ") || upperName.includes("HD") ||
|
|
526
|
+
upperName.includes("EPYC") || upperName.includes("INSTINCT") ||
|
|
527
|
+
upperName.includes("NAVI") || upperName.includes("VEGA")) {
|
|
528
|
+
vendor = "AMD";
|
|
529
|
+
} else if (upperName.includes("INTEL") || upperName.includes("ARC") ||
|
|
530
|
+
upperName.includes("UHD") || upperName.includes("IRIS") ||
|
|
531
|
+
upperName.includes("HD GRAPHICS")) {
|
|
532
|
+
vendor = "Intel";
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const result = `Geekbench 6: ${score}k (Rank #${rank}) - ${vendor}`;
|
|
536
|
+
setCachedValue(context.cache, "gpu_bench_info", result);
|
|
537
|
+
return result;
|
|
538
|
+
}
|
|
539
|
+
} catch (e) {
|
|
540
|
+
// Silently fail
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
setCachedValue(context.cache, "gpu_bench_info", "");
|
|
544
|
+
return "";
|
|
545
|
+
}
|