about-system 0.0.17 → 0.0.19
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 +390 -89
- package/dist/about-system-cli.d.ts +5 -0
- package/dist/about-system-cli.js +236 -0
- package/dist/about-system-cli.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/system-info-api-Bc0iSNdN.js +837 -0
- package/dist/system-info-api-Bc0iSNdN.js.map +1 -0
- package/dist/system-info-api.d.ts +378 -0
- package/dist/system-info-api.js +12 -0
- package/dist/system-info-api.js.map +1 -0
- package/package.json +36 -16
- package/src/about-system-cli.ts +419 -0
- package/src/cache/cache-config.ts +68 -0
- package/src/cache/cache.ts +95 -0
- package/src/index.ts +18 -0
- package/src/info/hardware.ts +173 -0
- package/src/info/memory.ts +215 -0
- package/src/info/network.ts +213 -0
- package/src/info/platform.ts +145 -0
- package/src/info/process.ts +72 -0
- package/src/info/settings.ts +209 -0
- package/src/info/software.ts +192 -0
- package/src/info/system-status.ts +152 -0
- package/src/system-info-api.ts +271 -0
- package/src/systeminfo-types.d.ts +457 -0
- package/src/types/internal-types.ts +21 -0
- package/src/utils/command.ts +47 -0
- package/src/utils/network.ts +58 -0
- package/src/utils/platform.ts +13 -0
- package/src/about-system.js +0 -1642
package/package.json
CHANGED
|
@@ -1,28 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "about-system",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
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
|
-
"main": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
6
7
|
"bin": {
|
|
7
|
-
"about-system": "./
|
|
8
|
-
"test-speed": "./src/test-speed-cloudflare.js"
|
|
8
|
+
"about-system": "./dist/about-system-cli.js"
|
|
9
9
|
},
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
-
"types": "./
|
|
14
|
-
"import": "./
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./api": {
|
|
17
|
+
"types": "./dist/system-info-api.d.ts",
|
|
18
|
+
"import": "./dist/system-info-api.js"
|
|
19
|
+
},
|
|
20
|
+
"./cli": {
|
|
21
|
+
"types": "./dist/about-system-cli.d.ts",
|
|
22
|
+
"import": "./dist/about-system-cli.js"
|
|
23
|
+
},
|
|
24
|
+
"./types": {
|
|
25
|
+
"types": "./src/systeminfo-types.d.ts"
|
|
15
26
|
}
|
|
16
27
|
},
|
|
17
28
|
"scripts": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
29
|
+
"build": "vite build",
|
|
30
|
+
"build:tsc": "tsc",
|
|
31
|
+
"dev": "vite build --watch",
|
|
32
|
+
"ship": "npm run build && npx standard-version --release-as patch; rm CHANGELOG.md; npm publish",
|
|
33
|
+
"start": "npm run build && node dist/about-system-cli.js",
|
|
34
|
+
"install-greeting": "npm run build && node dist/about-system-cli.js --install",
|
|
35
|
+
"show-settings": "npm run build && node dist/about-system-cli.js --settings-show",
|
|
36
|
+
"reset-settings": "npm run build && node dist/about-system-cli.js --settings-reset",
|
|
37
|
+
"clear-cache": "npm run build && node dist/about-system-cli.js --refresh",
|
|
38
|
+
"help": "npm run build && node dist/about-system-cli.js --help"
|
|
26
39
|
},
|
|
27
40
|
"keywords": [
|
|
28
41
|
"src/about-system",
|
|
@@ -47,7 +60,8 @@
|
|
|
47
60
|
},
|
|
48
61
|
"homepage": "https://github.com/OpenSourceAGI/StarterDOCS/tree/master/packages/about-system-info",
|
|
49
62
|
"files": [
|
|
50
|
-
"
|
|
63
|
+
"dist/**/*",
|
|
64
|
+
"src/**/*.ts",
|
|
51
65
|
"README.md",
|
|
52
66
|
"package.json"
|
|
53
67
|
],
|
|
@@ -62,6 +76,12 @@
|
|
|
62
76
|
"bin": "."
|
|
63
77
|
},
|
|
64
78
|
"dependencies": {
|
|
65
|
-
"ora": "^
|
|
79
|
+
"ora": "^9.0.0"
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@types/node": "^25.0.3",
|
|
83
|
+
"typescript": "^5.9.3",
|
|
84
|
+
"vite": "^7.3.1",
|
|
85
|
+
"vite-plugin-dts": "^4.5.4"
|
|
66
86
|
}
|
|
67
87
|
}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import os from "os";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { getSystemInfo } from "./system-info-api";
|
|
7
|
+
import type { SystemInfo, SystemInfoOptions } from "./systeminfo-types";
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
Settings,
|
|
13
|
+
DEFAULT_SETTINGS,
|
|
14
|
+
colors,
|
|
15
|
+
SETTINGS_FILE,
|
|
16
|
+
CACHE_FILE,
|
|
17
|
+
loadSettings,
|
|
18
|
+
saveSettings,
|
|
19
|
+
} from "./info/settings";
|
|
20
|
+
|
|
21
|
+
// Platform detection
|
|
22
|
+
const IS_WINDOWS = os.platform() === "win32";
|
|
23
|
+
|
|
24
|
+
function formatValue(key: string, value: string, settings: Settings): string {
|
|
25
|
+
if (!value || value.trim() === "") return "";
|
|
26
|
+
|
|
27
|
+
const color =
|
|
28
|
+
colors[settings.colors[key] as keyof typeof colors] || colors.reset;
|
|
29
|
+
const emoji = settings.display.show_emojis ? settings.emojis[key] || "" : "";
|
|
30
|
+
|
|
31
|
+
// Special handling for battery emoji
|
|
32
|
+
if (key === "battery" && settings.display.show_emojis) {
|
|
33
|
+
const batteryEmoji = value.includes("+")
|
|
34
|
+
? settings.emojis.battery_charging
|
|
35
|
+
: settings.emojis.battery;
|
|
36
|
+
return `${color}${batteryEmoji}${value}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Multicolor handling for ports
|
|
40
|
+
if (key === "ports" && settings.colors[key] === "multicolor" && value) {
|
|
41
|
+
const emoji = settings.display.show_emojis ? settings.emojis.ports : "";
|
|
42
|
+
let output = ` ${emoji}`;
|
|
43
|
+
const ports = value.split(" ");
|
|
44
|
+
const colorCodes = [31, 32, 33, 34, 35, 36];
|
|
45
|
+
ports.forEach((port, index) => {
|
|
46
|
+
const colorCode = colorCodes[index % colorCodes.length];
|
|
47
|
+
output += `\x1b[${colorCode}m${port}\x1b[0m `;
|
|
48
|
+
});
|
|
49
|
+
return output.trim();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Multicolor handling for pacman
|
|
53
|
+
if (key === "pacman" && settings.colors[key] === "multicolor" && value) {
|
|
54
|
+
const emoji = settings.display.show_emojis ? settings.emojis.pacman : "";
|
|
55
|
+
return `${color}${emoji}${value}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return `${color}${emoji}${value}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function removeAnsiCodes(str: string): string {
|
|
62
|
+
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function displaySystemInfo(
|
|
66
|
+
customDisplayOrder: string[][] | null = null
|
|
67
|
+
): Promise<void> {
|
|
68
|
+
const settings = loadSettings();
|
|
69
|
+
const displayOrder = customDisplayOrder || settings.display_order;
|
|
70
|
+
|
|
71
|
+
// Get system info
|
|
72
|
+
const info = await getSystemInfo();
|
|
73
|
+
|
|
74
|
+
// Single line mode
|
|
75
|
+
if (settings.display.single_line) {
|
|
76
|
+
const allItems: string[] = [];
|
|
77
|
+
|
|
78
|
+
for (const group of displayOrder) {
|
|
79
|
+
for (const key of group) {
|
|
80
|
+
const value = info[key as keyof SystemInfo] as string;
|
|
81
|
+
const formatted = formatValue(key, value, settings);
|
|
82
|
+
if (formatted && formatted.trim()) {
|
|
83
|
+
allItems.push(formatted);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (allItems.length > 0) {
|
|
89
|
+
console.log(allItems.join(" ") + colors.reset);
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Multi-line mode with intelligent wrapping
|
|
95
|
+
const lines: string[] = [];
|
|
96
|
+
let currentLine = "";
|
|
97
|
+
const maxLineLength = settings.display.line_wrap_length;
|
|
98
|
+
|
|
99
|
+
for (const group of displayOrder) {
|
|
100
|
+
for (const key of group) {
|
|
101
|
+
const value = info[key as keyof SystemInfo] as string;
|
|
102
|
+
const formatted = formatValue(key, value, settings);
|
|
103
|
+
|
|
104
|
+
if (formatted && formatted.trim()) {
|
|
105
|
+
const formattedLength = removeAnsiCodes(formatted).length;
|
|
106
|
+
const currentLineLength = removeAnsiCodes(currentLine).length;
|
|
107
|
+
|
|
108
|
+
if (
|
|
109
|
+
currentLine &&
|
|
110
|
+
currentLineLength + formattedLength + 1 > maxLineLength
|
|
111
|
+
) {
|
|
112
|
+
lines.push(currentLine);
|
|
113
|
+
currentLine = formatted;
|
|
114
|
+
} else {
|
|
115
|
+
currentLine = currentLine ? `${currentLine} ${formatted}` : formatted;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (currentLine) {
|
|
122
|
+
lines.push(currentLine);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Output
|
|
126
|
+
if (lines.length > 0) {
|
|
127
|
+
lines.forEach((line) => {
|
|
128
|
+
console.log(line + colors.reset);
|
|
129
|
+
});
|
|
130
|
+
} else if (settings.advanced.debug) {
|
|
131
|
+
console.log("No system information could be displayed");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function handleSettingsCommand(args: string[]): boolean {
|
|
136
|
+
const settings = loadSettings();
|
|
137
|
+
|
|
138
|
+
if (args.includes("--settings-init")) {
|
|
139
|
+
if (saveSettings(DEFAULT_SETTINGS)) {
|
|
140
|
+
console.log("Settings initialized with defaults");
|
|
141
|
+
} else {
|
|
142
|
+
console.log("Failed to initialize settings");
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (args.includes("--settings-show")) {
|
|
148
|
+
console.log("Current settings:");
|
|
149
|
+
console.log(JSON.stringify(settings, null, 2));
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (args.includes("--settings-reset")) {
|
|
154
|
+
if (saveSettings(DEFAULT_SETTINGS)) {
|
|
155
|
+
console.log("Settings reset to defaults");
|
|
156
|
+
} else {
|
|
157
|
+
console.log("Failed to reset settings");
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (args.includes("--refresh")) {
|
|
163
|
+
try {
|
|
164
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
165
|
+
fs.unlinkSync(CACHE_FILE);
|
|
166
|
+
console.log("Cache cleared");
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error("Error clearing cache:", (error as Error).message);
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const setIndex = args.indexOf("--set");
|
|
175
|
+
if (setIndex !== -1 && args[setIndex + 1] && args[setIndex + 2]) {
|
|
176
|
+
const key = args[setIndex + 1];
|
|
177
|
+
const value = args[setIndex + 2];
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const parsedValue =
|
|
181
|
+
value.startsWith("{") || value.startsWith("[")
|
|
182
|
+
? JSON.parse(value)
|
|
183
|
+
: value;
|
|
184
|
+
|
|
185
|
+
const keys = key.split(".");
|
|
186
|
+
let current: any = settings;
|
|
187
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
188
|
+
if (!current[keys[i]]) current[keys[i]] = {};
|
|
189
|
+
current = current[keys[i]];
|
|
190
|
+
}
|
|
191
|
+
current[keys[keys.length - 1]] = parsedValue;
|
|
192
|
+
|
|
193
|
+
if (saveSettings(settings)) {
|
|
194
|
+
console.log(`Setting ${key} = ${value}`);
|
|
195
|
+
} else {
|
|
196
|
+
console.log("Failed to save settings");
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error("Error setting value:", (error as Error).message);
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function installShellGreeting(): void {
|
|
208
|
+
const homeDir = os.homedir();
|
|
209
|
+
|
|
210
|
+
let configDir: string, scriptPath: string;
|
|
211
|
+
if (IS_WINDOWS) {
|
|
212
|
+
configDir = path.join(homeDir, "AppData", "Local");
|
|
213
|
+
scriptPath = path.join(configDir, "systeminfo");
|
|
214
|
+
} else {
|
|
215
|
+
configDir = path.join(homeDir, ".config");
|
|
216
|
+
scriptPath = path.join(configDir, "systeminfo");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const currentScript = path.resolve(__filename);
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
if (!fs.existsSync(configDir)) {
|
|
223
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
fs.copyFileSync(currentScript, scriptPath);
|
|
227
|
+
if (!IS_WINDOWS) {
|
|
228
|
+
fs.chmodSync(scriptPath, "755");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (IS_WINDOWS) {
|
|
232
|
+
console.log("Windows installation:");
|
|
233
|
+
console.log("1. Script copied to:", scriptPath);
|
|
234
|
+
console.log("2. To add to PowerShell profile, run:");
|
|
235
|
+
console.log(` Add-Content $PROFILE "node '${scriptPath}'"`);
|
|
236
|
+
console.log(
|
|
237
|
+
"3. To add to Command Prompt, create a batch file in your startup folder"
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const startupBat = path.join(configDir, "systeminfo-startup.bat");
|
|
241
|
+
fs.writeFileSync(startupBat, `@echo off\nnode "${scriptPath}"\n`);
|
|
242
|
+
console.log("4. Batch file created:", startupBat);
|
|
243
|
+
} else {
|
|
244
|
+
try {
|
|
245
|
+
const hushLoginPath = path.join(homeDir, ".hushlogin");
|
|
246
|
+
fs.writeFileSync(hushLoginPath, "");
|
|
247
|
+
} catch {}
|
|
248
|
+
|
|
249
|
+
const bashrcPath = path.join(homeDir, ".bashrc");
|
|
250
|
+
const bashLine = `node ${scriptPath}`;
|
|
251
|
+
|
|
252
|
+
if (fs.existsSync(bashrcPath)) {
|
|
253
|
+
const bashrc = fs.readFileSync(bashrcPath, "utf8");
|
|
254
|
+
if (!bashrc.includes("systeminfo")) {
|
|
255
|
+
fs.appendFileSync(bashrcPath, `\n${bashLine}\n`);
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
fs.writeFileSync(bashrcPath, `${bashLine}\n`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const zshrcPath = path.join(homeDir, ".zshrc");
|
|
262
|
+
if (fs.existsSync(zshrcPath)) {
|
|
263
|
+
const zshrc = fs.readFileSync(zshrcPath, "utf8");
|
|
264
|
+
if (!zshrc.includes("systeminfo")) {
|
|
265
|
+
fs.appendFileSync(zshrcPath, `\n${bashLine}\n`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const fishConfigPath = path.join(
|
|
270
|
+
homeDir,
|
|
271
|
+
".config",
|
|
272
|
+
"fish",
|
|
273
|
+
"config.fish"
|
|
274
|
+
);
|
|
275
|
+
if (fs.existsSync(fishConfigPath)) {
|
|
276
|
+
const fishConfig = fs.readFileSync(fishConfigPath, "utf8");
|
|
277
|
+
if (!fishConfig.includes("systeminfo")) {
|
|
278
|
+
fs.appendFileSync(
|
|
279
|
+
fishConfigPath,
|
|
280
|
+
`\nset -U fish_greeting ""\n${bashLine}\n`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const nushellConfigPath = path.join(
|
|
286
|
+
homeDir,
|
|
287
|
+
".config",
|
|
288
|
+
"nushell",
|
|
289
|
+
"config.nu"
|
|
290
|
+
);
|
|
291
|
+
if (fs.existsSync(nushellConfigPath)) {
|
|
292
|
+
const nushellConfig = fs.readFileSync(nushellConfigPath, "utf8");
|
|
293
|
+
if (!nushellConfig.includes("systeminfo")) {
|
|
294
|
+
fs.appendFileSync(
|
|
295
|
+
nushellConfigPath,
|
|
296
|
+
`\n$env.config.show_banner = false\n${bashLine}\n`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
console.log("Shell greeting installation completed!");
|
|
303
|
+
} catch (error) {
|
|
304
|
+
console.error("Error installing shell greeting:", (error as Error).message);
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function parseCLIMode(args: string[]): string[] | null {
|
|
310
|
+
for (const arg of args) {
|
|
311
|
+
if (!arg.startsWith("--") && arg.includes(",")) {
|
|
312
|
+
return arg
|
|
313
|
+
.split(",")
|
|
314
|
+
.map((part) => part.trim())
|
|
315
|
+
.filter((part) => part.length > 0);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
for (const arg of args) {
|
|
320
|
+
if (!arg.startsWith("--") && !arg.includes("=") && arg.length > 0) {
|
|
321
|
+
return [arg.trim()];
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function showHelp(): Promise<void> {
|
|
329
|
+
console.log(`
|
|
330
|
+
System Info Script - TypeScript Version
|
|
331
|
+
|
|
332
|
+
Usage:
|
|
333
|
+
about-system [options]
|
|
334
|
+
about-system <part1,part2,...> # CLI mode: show specific parts only
|
|
335
|
+
|
|
336
|
+
Options:
|
|
337
|
+
--help, -h Show this help message
|
|
338
|
+
--install Install as shell greeting
|
|
339
|
+
--settings-init Initialize settings file with defaults
|
|
340
|
+
--settings-show Display current settings
|
|
341
|
+
--settings-reset Reset settings to defaults
|
|
342
|
+
--refresh Clear the cache file
|
|
343
|
+
--set <key> <value> Set a configuration value (use dot notation)
|
|
344
|
+
--json Output as JSON
|
|
345
|
+
|
|
346
|
+
Examples:
|
|
347
|
+
about-system # Show all info (default)
|
|
348
|
+
about-system cpu,os # Show only CPU and OS info
|
|
349
|
+
about-system user,hostname,ip # Show user, hostname, and IP
|
|
350
|
+
about-system disk_used # Show only disk usage
|
|
351
|
+
about-system --install
|
|
352
|
+
about-system --set display.show_emojis false
|
|
353
|
+
about-system --set colors.user blue
|
|
354
|
+
about-system --set emojis.cpu "🚀 "
|
|
355
|
+
about-system --set labels.cpu "Processor"
|
|
356
|
+
about-system --json
|
|
357
|
+
|
|
358
|
+
Settings file: ${SETTINGS_FILE}
|
|
359
|
+
Cache file: ${CACHE_FILE}
|
|
360
|
+
|
|
361
|
+
Platform: ${
|
|
362
|
+
IS_WINDOWS
|
|
363
|
+
? "Windows"
|
|
364
|
+
: os.platform() === "darwin"
|
|
365
|
+
? "macOS"
|
|
366
|
+
: os.platform() === "linux"
|
|
367
|
+
? "Linux"
|
|
368
|
+
: "Unknown"
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
Available display blocks:
|
|
372
|
+
Basic: user, hostname, uptime, shell, os, kernel, device
|
|
373
|
+
Resources: disk_used, ram_used, memory_available, swap_used, top_process
|
|
374
|
+
Network: ip, iplocal, city, domain, isp, network_interfaces
|
|
375
|
+
Hardware: cpu, gpu, temperature, battery, screen_resolution
|
|
376
|
+
System: load_average, users_logged_in, mount_points, services_running
|
|
377
|
+
Tools: pacman, ports, containers
|
|
378
|
+
`);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async function main(): Promise<void> {
|
|
382
|
+
const args = process.argv.slice(2);
|
|
383
|
+
|
|
384
|
+
if (handleSettingsCommand(args)) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
389
|
+
await showHelp();
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (args.includes("--install")) {
|
|
394
|
+
installShellGreeting();
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (args.includes("--json")) {
|
|
399
|
+
const info = await getSystemInfo();
|
|
400
|
+
console.log(JSON.stringify(info, null, 2));
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const cliParts = parseCLIMode(args);
|
|
405
|
+
if (cliParts) {
|
|
406
|
+
const customDisplayOrder = [cliParts];
|
|
407
|
+
await displaySystemInfo(customDisplayOrder);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
await displaySystemInfo();
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
main().catch((error) => {
|
|
415
|
+
console.error("Error:", error.message);
|
|
416
|
+
process.exit(1);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
export { displaySystemInfo, installShellGreeting };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache configuration and constants
|
|
3
|
+
* @module cache-config
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import os from "os";
|
|
7
|
+
import path from "path";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Cache file location in system's temporary directory
|
|
11
|
+
* @constant
|
|
12
|
+
*/
|
|
13
|
+
export const CACHE_FILE = path.join(os.tmpdir(), "systeminfo-cache.json");
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Cache duration configuration for different system information types
|
|
17
|
+
* Values are in milliseconds
|
|
18
|
+
*
|
|
19
|
+
* @constant
|
|
20
|
+
* @property {number} ip - IP information cache (5 minutes)
|
|
21
|
+
* @property {number} cpu - CPU information cache (24 hours)
|
|
22
|
+
* @property {number} gpu - GPU information cache (24 hours)
|
|
23
|
+
* @property {number} os - OS information cache (24 hours)
|
|
24
|
+
* @property {number} device - Device information cache (24 hours)
|
|
25
|
+
* @property {number} kernel - Kernel information cache (1 hour)
|
|
26
|
+
* @property {number} pacman - Package managers cache (10 minutes)
|
|
27
|
+
* @property {number} ports - Open ports cache (5 minutes)
|
|
28
|
+
* @property {number} containers - Docker containers cache (5 minutes)
|
|
29
|
+
* @property {number} top_process - Top process cache (5 seconds)
|
|
30
|
+
* @property {number} disk_used - Disk usage cache (1 minute)
|
|
31
|
+
* @property {number} ram_used - RAM usage cache (10 seconds)
|
|
32
|
+
* @property {number} services_running - Services cache (5 minutes)
|
|
33
|
+
* @property {number} temperature - Temperature cache (30 seconds)
|
|
34
|
+
* @property {number} battery - Battery status cache (1 minute)
|
|
35
|
+
* @property {number} network_interfaces - Network interfaces cache (5 minutes)
|
|
36
|
+
* @property {number} mount_points - Mount points cache (10 minutes)
|
|
37
|
+
*/
|
|
38
|
+
export const CACHE_DURATION = {
|
|
39
|
+
ip: 5 * 60 * 1000,
|
|
40
|
+
cpu: 24 * 60 * 60 * 1000,
|
|
41
|
+
gpu: 24 * 60 * 60 * 1000,
|
|
42
|
+
os: 24 * 60 * 60 * 1000,
|
|
43
|
+
device: 24 * 60 * 60 * 1000,
|
|
44
|
+
kernel: 60 * 60 * 1000,
|
|
45
|
+
pacman: 10 * 60 * 1000,
|
|
46
|
+
ports: 5 * 60 * 1000,
|
|
47
|
+
containers: 5 * 60 * 1000,
|
|
48
|
+
top_process: 5 * 1000,
|
|
49
|
+
disk_used: 60 * 1000,
|
|
50
|
+
ram_used: 10 * 1000,
|
|
51
|
+
services_running: 5 * 60 * 1000,
|
|
52
|
+
temperature: 30 * 1000,
|
|
53
|
+
battery: 60 * 1000,
|
|
54
|
+
network_interfaces: 5 * 60 * 1000,
|
|
55
|
+
mount_points: 10 * 60 * 1000,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Default IPInfo.io API token for geolocation
|
|
60
|
+
* @constant
|
|
61
|
+
*/
|
|
62
|
+
export const DEFAULT_IPINFO_TOKEN = "da2d6cc4baa5d1";
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Default network request timeout in milliseconds
|
|
66
|
+
* @constant
|
|
67
|
+
*/
|
|
68
|
+
export const DEFAULT_NETWORK_TIMEOUT = 5000;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache management utilities
|
|
3
|
+
* @module cache
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import { CACHE_FILE, CACHE_DURATION } from "./cache-config";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents a cached value with timestamp
|
|
11
|
+
* @interface CacheEntry
|
|
12
|
+
*/
|
|
13
|
+
export interface CacheEntry {
|
|
14
|
+
/** The cached value */
|
|
15
|
+
value: any;
|
|
16
|
+
/** Unix timestamp when the value was cached */
|
|
17
|
+
timestamp: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Cache storage structure
|
|
22
|
+
* @interface Cache
|
|
23
|
+
*/
|
|
24
|
+
export interface Cache {
|
|
25
|
+
[key: string]: CacheEntry;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Loads cache from disk
|
|
30
|
+
* @returns {Cache} Cached data or empty object if cache doesn't exist or is corrupted
|
|
31
|
+
*/
|
|
32
|
+
export function loadCache(): Cache {
|
|
33
|
+
try {
|
|
34
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
35
|
+
return JSON.parse(fs.readFileSync(CACHE_FILE, "utf8"));
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
// Corrupted cache - return empty object
|
|
39
|
+
}
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Saves cache to disk
|
|
45
|
+
* @param {Cache} cache - Cache object to save
|
|
46
|
+
*/
|
|
47
|
+
export function saveCache(cache: Cache): void {
|
|
48
|
+
try {
|
|
49
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
// Silently fail if can't write cache
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Checks if a cache entry is still valid based on configured duration
|
|
57
|
+
* @param {CacheEntry} cacheEntry - The cache entry to validate
|
|
58
|
+
* @param {string} key - The key name to determine cache duration
|
|
59
|
+
* @returns {boolean} True if cache is still valid
|
|
60
|
+
*/
|
|
61
|
+
export function isCacheValid(cacheEntry: CacheEntry, key: string): boolean {
|
|
62
|
+
if (!cacheEntry || !cacheEntry.timestamp) return false;
|
|
63
|
+
const age = Date.now() - cacheEntry.timestamp;
|
|
64
|
+
const maxAge = CACHE_DURATION[key as keyof typeof CACHE_DURATION] || 60000;
|
|
65
|
+
return age < maxAge;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves a value from cache if valid
|
|
70
|
+
* @param {Cache} cache - Cache object
|
|
71
|
+
* @param {string} key - Key to retrieve
|
|
72
|
+
* @returns {any} Cached value or null if not found/expired
|
|
73
|
+
*/
|
|
74
|
+
export function getCachedValue(cache: Cache, key: string): any {
|
|
75
|
+
if (!cache[key]) return null;
|
|
76
|
+
const cacheEntry = cache[key];
|
|
77
|
+
if (!isCacheValid(cacheEntry, key)) {
|
|
78
|
+
delete cache[key];
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return cacheEntry.value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Stores a value in cache with current timestamp
|
|
86
|
+
* @param {Cache} cache - Cache object
|
|
87
|
+
* @param {string} key - Key to store under
|
|
88
|
+
* @param {any} value - Value to cache
|
|
89
|
+
*/
|
|
90
|
+
export function setCachedValue(cache: Cache, key: string, value: any): void {
|
|
91
|
+
cache[key] = {
|
|
92
|
+
value,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
};
|
|
95
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Main entry point for about-system package
|
|
3
|
+
*
|
|
4
|
+
* Exports the system information API for programmatic use.
|
|
5
|
+
* For CLI usage, use the 'about-system' command directly.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { getSystemInfo } from 'about-system';
|
|
10
|
+
*
|
|
11
|
+
* const info = await getSystemInfo();
|
|
12
|
+
* console.log(info.cpu);
|
|
13
|
+
* console.log(info.ram_used);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export { getSystemInfo, loadCache, saveCache } from './system-info-api.js';
|
|
18
|
+
export type { SystemInfo, SystemInfoOptions, Platform, GetSystemInfoFunction, DisplaySystemInfoFunction, PlatformAvailability } from './systeminfo-types.js';
|