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
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-related system information functions
|
|
3
|
+
* @module info/platform
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import os from "os";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import type { InfoContext } from "../types/internal-types";
|
|
9
|
+
import { IS_WINDOWS, IS_MAC, IS_LINUX } from "../utils/platform";
|
|
10
|
+
import { execCommand, commandExists } from "../utils/command";
|
|
11
|
+
import { getCachedValue, setCachedValue } from "../cache/cache";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Gets the current username
|
|
15
|
+
* @returns Current system username
|
|
16
|
+
*/
|
|
17
|
+
export function user(): string {
|
|
18
|
+
return os.userInfo().username;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Gets the system hostname
|
|
23
|
+
* @returns Computer hostname/network name
|
|
24
|
+
*/
|
|
25
|
+
export function hostname(): string {
|
|
26
|
+
return os.hostname();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Gets operating system name and version
|
|
31
|
+
* Platform-specific detection for Windows, macOS, and Linux
|
|
32
|
+
* @param context - Info context with cache
|
|
33
|
+
* @returns OS name and version string
|
|
34
|
+
* @example "Windows 11 Pro", "macOS Ventura 13.2.1", "Ubuntu 22.04.3 LTS"
|
|
35
|
+
*/
|
|
36
|
+
export function os_info(context: InfoContext): string {
|
|
37
|
+
const cached = getCachedValue(context.cache, "os");
|
|
38
|
+
if (cached) return cached;
|
|
39
|
+
|
|
40
|
+
const platform = os.platform();
|
|
41
|
+
const release = os.release();
|
|
42
|
+
let osName = "";
|
|
43
|
+
|
|
44
|
+
if (IS_WINDOWS) {
|
|
45
|
+
try {
|
|
46
|
+
const version = execCommand("ver");
|
|
47
|
+
const match = version.match(/Microsoft Windows \[Version ([^\]]+)\]/);
|
|
48
|
+
osName = match ? `Windows ${match[1]}` : `Windows ${release}`;
|
|
49
|
+
} catch {
|
|
50
|
+
osName = `Windows ${release}`;
|
|
51
|
+
}
|
|
52
|
+
} else if (IS_MAC) {
|
|
53
|
+
osName = `macOS ${release}`;
|
|
54
|
+
} else if (IS_LINUX) {
|
|
55
|
+
try {
|
|
56
|
+
const osRelease = fs.readFileSync("/etc/os-release", "utf8");
|
|
57
|
+
const nameMatch = osRelease.match(/^NAME="([^"]+)"/m);
|
|
58
|
+
const versionMatch = osRelease.match(/^VERSION_ID="([^"]+)"/m);
|
|
59
|
+
osName = nameMatch ? nameMatch[1] : "Linux";
|
|
60
|
+
if (versionMatch) osName += ` ${versionMatch[1]}`;
|
|
61
|
+
} catch {
|
|
62
|
+
osName = `Linux ${release}`;
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
osName = `${platform} ${release}`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
setCachedValue(context.cache, "os", osName);
|
|
69
|
+
return osName;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Gets kernel version string
|
|
74
|
+
* Returns the operating system kernel version from os.release()
|
|
75
|
+
* @param context - Info context with cache
|
|
76
|
+
* @returns Kernel version string
|
|
77
|
+
* @example "5.15.0-56-generic", "6.11.11-valve12-1-neptune"
|
|
78
|
+
*/
|
|
79
|
+
export function kernel(context: InfoContext): string {
|
|
80
|
+
const cached = getCachedValue(context.cache, "kernel");
|
|
81
|
+
if (cached) return cached;
|
|
82
|
+
|
|
83
|
+
const kernel = os.release();
|
|
84
|
+
setCachedValue(context.cache, "kernel", kernel);
|
|
85
|
+
return kernel;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Gets device or computer model name
|
|
90
|
+
* Uses WMI on Windows, DMI on Linux, getprop on Android
|
|
91
|
+
* @param context - Info context with cache
|
|
92
|
+
* @returns Device model name or empty string
|
|
93
|
+
* @example "Dell OptiPlex 7090", "MacBook Pro 16-inch", "Valve Steam Deck"
|
|
94
|
+
*/
|
|
95
|
+
export function device(context: InfoContext): string {
|
|
96
|
+
const cached = getCachedValue(context.cache, "device");
|
|
97
|
+
if (cached !== null) return cached;
|
|
98
|
+
|
|
99
|
+
if (IS_WINDOWS) {
|
|
100
|
+
try {
|
|
101
|
+
const wmic = execCommand("wmic csproduct get name /format:list");
|
|
102
|
+
const nameMatch = wmic.match(/Name=(.+)/);
|
|
103
|
+
if (nameMatch) {
|
|
104
|
+
const device = nameMatch[1].trim();
|
|
105
|
+
if (device && device !== "") {
|
|
106
|
+
setCachedValue(context.cache, "device", device);
|
|
107
|
+
return device;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} catch {}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const ps = execCommand(
|
|
114
|
+
'powershell.exe -Command "Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Model"'
|
|
115
|
+
);
|
|
116
|
+
if (ps.trim()) {
|
|
117
|
+
const device = ps.trim();
|
|
118
|
+
setCachedValue(context.cache, "device", device);
|
|
119
|
+
return device;
|
|
120
|
+
}
|
|
121
|
+
} catch {}
|
|
122
|
+
} else if (IS_LINUX) {
|
|
123
|
+
try {
|
|
124
|
+
if (commandExists("getprop")) {
|
|
125
|
+
const device = execCommand("getprop ro.product.model");
|
|
126
|
+
if (device) {
|
|
127
|
+
setCachedValue(context.cache, "device", device);
|
|
128
|
+
return device;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const dmiPath = "/sys/devices/virtual/dmi/id/product_name";
|
|
133
|
+
if (fs.existsSync(dmiPath)) {
|
|
134
|
+
const device = fs.readFileSync(dmiPath, "utf8").trim();
|
|
135
|
+
if (device) {
|
|
136
|
+
setCachedValue(context.cache, "device", device);
|
|
137
|
+
return device;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} catch {}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
setCachedValue(context.cache, "device", "");
|
|
144
|
+
return "";
|
|
145
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-related system information functions
|
|
3
|
+
* @module info/process
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import os from "os";
|
|
7
|
+
import type { InfoContext } from "../types/internal-types";
|
|
8
|
+
import { IS_LINUX } from "../utils/platform";
|
|
9
|
+
import { execCommand } from "../utils/command";
|
|
10
|
+
import { getCachedValue, setCachedValue } from "../cache/cache";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Gets the highest CPU-consuming process
|
|
14
|
+
* Uses ps command to find top process by CPU usage (Linux only)
|
|
15
|
+
* @param context - Info context with cache
|
|
16
|
+
* @returns Process info as "percentage processname" or empty string
|
|
17
|
+
* @example "8% firefox", "15% chrome", "3% systemd"
|
|
18
|
+
*/
|
|
19
|
+
export function top_process(context: InfoContext): string {
|
|
20
|
+
const cached = getCachedValue(context.cache, "top_process");
|
|
21
|
+
if (cached !== null) return cached;
|
|
22
|
+
|
|
23
|
+
if (IS_LINUX) {
|
|
24
|
+
try {
|
|
25
|
+
const ps = execCommand("ps -eo pcpu,comm --sort=-%cpu --no-headers");
|
|
26
|
+
const lines = ps.split("\n");
|
|
27
|
+
if (lines.length > 0) {
|
|
28
|
+
const topProcess = lines[0].trim().replace(/\s+/, " ").split(" ");
|
|
29
|
+
const cpu = topProcess[0].replace(/\.\d+/, "%");
|
|
30
|
+
const process = topProcess[1].split("/").pop();
|
|
31
|
+
const result = `${cpu} ${process}`;
|
|
32
|
+
setCachedValue(context.cache, "top_process", result);
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
} catch {}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setCachedValue(context.cache, "top_process", "");
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Gets system uptime since last boot
|
|
44
|
+
* @returns Uptime formatted as "Xd Yh Zm"
|
|
45
|
+
* @example "2d 14h 23m", "0d 3h 45m"
|
|
46
|
+
*/
|
|
47
|
+
export function uptime(): string {
|
|
48
|
+
const uptimeSeconds = os.uptime();
|
|
49
|
+
const days = Math.floor(uptimeSeconds / 86400);
|
|
50
|
+
const hours = Math.floor((uptimeSeconds % 86400) / 3600);
|
|
51
|
+
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
|
|
52
|
+
return `${days}d ${hours}h ${minutes}m`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Gets number of logged in users
|
|
57
|
+
* Uses who command to count active user sessions (Linux only)
|
|
58
|
+
* @returns User count with "users" suffix or empty string
|
|
59
|
+
* @example "3 users", "1 users"
|
|
60
|
+
*/
|
|
61
|
+
export function users_logged_in(): string {
|
|
62
|
+
if (!IS_LINUX) return "";
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const who = execCommand("who");
|
|
66
|
+
const users = who.split("\n").filter((line) => line.trim()).length;
|
|
67
|
+
if (users > 0) {
|
|
68
|
+
return `${users} users`;
|
|
69
|
+
}
|
|
70
|
+
} catch {}
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings configuration and management
|
|
3
|
+
* @module info/settings
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from "path";
|
|
7
|
+
import os from "os";
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import process from "process";
|
|
10
|
+
|
|
11
|
+
// Settings file paths
|
|
12
|
+
export const SETTINGS_FILE = path.join(
|
|
13
|
+
os.homedir(),
|
|
14
|
+
".config",
|
|
15
|
+
"systeminfo-settings.json"
|
|
16
|
+
);
|
|
17
|
+
export const CACHE_FILE = path.join(os.tmpdir(), "systeminfo-cache.json");
|
|
18
|
+
|
|
19
|
+
// Color codes
|
|
20
|
+
export const colors = {
|
|
21
|
+
reset: "\x1b[0m",
|
|
22
|
+
red: "\x1b[38;5;196m",
|
|
23
|
+
orange: "\x1b[38;5;208m",
|
|
24
|
+
yellow: "\x1b[38;5;226m",
|
|
25
|
+
green: "\x1b[38;5;46m",
|
|
26
|
+
blue: "\x1b[38;5;39m",
|
|
27
|
+
cyan: "\x1b[38;5;51m",
|
|
28
|
+
purple: "\x1b[38;5;171m",
|
|
29
|
+
magenta: "\x1b[38;5;213m",
|
|
30
|
+
gray: "\x1b[38;5;250m",
|
|
31
|
+
lightblue: "\x1b[38;5;220m",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Default settings
|
|
35
|
+
export const DEFAULT_SETTINGS = {
|
|
36
|
+
display_order: [
|
|
37
|
+
["user", "hostname", "os", "device", "kernel", "cpu", "gpu"],
|
|
38
|
+
[
|
|
39
|
+
"disk_used",
|
|
40
|
+
"ram_used",
|
|
41
|
+
"top_process",
|
|
42
|
+
"uptime",
|
|
43
|
+
"temperature",
|
|
44
|
+
"battery",
|
|
45
|
+
"load_average",
|
|
46
|
+
],
|
|
47
|
+
["ip", "iplocal", "city", "domain", "isp"],
|
|
48
|
+
["shell", "pacman", "services_running", "containers"],
|
|
49
|
+
],
|
|
50
|
+
colors: {
|
|
51
|
+
user: "red",
|
|
52
|
+
hostname: "orange",
|
|
53
|
+
disk_used: "purple",
|
|
54
|
+
ram_used: "yellow",
|
|
55
|
+
top_process: "magenta",
|
|
56
|
+
uptime: "cyan",
|
|
57
|
+
ip: "green",
|
|
58
|
+
iplocal: "yellow",
|
|
59
|
+
city: "green",
|
|
60
|
+
domain: "gray",
|
|
61
|
+
isp: "lightblue",
|
|
62
|
+
os: "gray",
|
|
63
|
+
cpu: "orange",
|
|
64
|
+
gpu: "yellow",
|
|
65
|
+
device: "yellow",
|
|
66
|
+
kernel: "green",
|
|
67
|
+
shell: "orange",
|
|
68
|
+
pacman: "multicolor",
|
|
69
|
+
ports: "multicolor",
|
|
70
|
+
containers: "green",
|
|
71
|
+
memory_available: "blue",
|
|
72
|
+
swap_used: "purple",
|
|
73
|
+
load_average: "red",
|
|
74
|
+
users_logged_in: "cyan",
|
|
75
|
+
network_interfaces: "yellow",
|
|
76
|
+
mount_points: "gray",
|
|
77
|
+
services_running: "green",
|
|
78
|
+
temperature: "red",
|
|
79
|
+
battery: "green",
|
|
80
|
+
screen_resolution: "blue",
|
|
81
|
+
},
|
|
82
|
+
emojis: {
|
|
83
|
+
user: "👤 ",
|
|
84
|
+
hostname: "🏠 ",
|
|
85
|
+
ip: "🌎 ",
|
|
86
|
+
iplocal: "🌐 ",
|
|
87
|
+
city: "📍 ",
|
|
88
|
+
domain: "🔗 ",
|
|
89
|
+
isp: "👮 ",
|
|
90
|
+
os: "⚡ ",
|
|
91
|
+
cpu: "📈 ",
|
|
92
|
+
gpu: "🎮 ",
|
|
93
|
+
device: "💻 ",
|
|
94
|
+
kernel: "🔧 ",
|
|
95
|
+
shell: "🐚 ",
|
|
96
|
+
pacman: "🚀 ",
|
|
97
|
+
disk_used: "📁 ",
|
|
98
|
+
ram_used: "💾 ",
|
|
99
|
+
top_process: "🔝 ",
|
|
100
|
+
uptime: "⏱️ ",
|
|
101
|
+
ports: "🔌 ",
|
|
102
|
+
containers: "📦 ",
|
|
103
|
+
memory_available: "🧠 ",
|
|
104
|
+
swap_used: "🔄 ",
|
|
105
|
+
load_average: "⚖️ ",
|
|
106
|
+
users_logged_in: "👥 ",
|
|
107
|
+
network_interfaces: "🌐 ",
|
|
108
|
+
mount_points: "📂 ",
|
|
109
|
+
services_running: "⚙️ ",
|
|
110
|
+
temperature: "🌡️ ",
|
|
111
|
+
battery_charging: "🔌 ",
|
|
112
|
+
battery: "🔋 ",
|
|
113
|
+
screen_resolution: "🖥️ ",
|
|
114
|
+
},
|
|
115
|
+
labels: {
|
|
116
|
+
user: "User",
|
|
117
|
+
hostname: "Host",
|
|
118
|
+
ip: "IP",
|
|
119
|
+
iplocal: "Local IP",
|
|
120
|
+
city: "City",
|
|
121
|
+
domain: "Domain",
|
|
122
|
+
isp: "ISP",
|
|
123
|
+
os: "OS",
|
|
124
|
+
cpu: "CPU",
|
|
125
|
+
gpu: "GPU",
|
|
126
|
+
device: "Device",
|
|
127
|
+
kernel: "Kernel",
|
|
128
|
+
shell: "Shell",
|
|
129
|
+
pacman: "Packages",
|
|
130
|
+
disk_used: "Disk",
|
|
131
|
+
ram_used: "RAM",
|
|
132
|
+
top_process: "Top",
|
|
133
|
+
uptime: "Uptime",
|
|
134
|
+
ports: "Ports",
|
|
135
|
+
containers: "Containers",
|
|
136
|
+
memory_available: "Memory",
|
|
137
|
+
swap_used: "Swap",
|
|
138
|
+
load_average: "Load",
|
|
139
|
+
users_logged_in: "Users",
|
|
140
|
+
network_interfaces: "Network",
|
|
141
|
+
mount_points: "Mounts",
|
|
142
|
+
services_running: "Services",
|
|
143
|
+
temperature: "Temp",
|
|
144
|
+
battery_charging: "Battery",
|
|
145
|
+
battery: "Battery",
|
|
146
|
+
screen_resolution: "Resolution",
|
|
147
|
+
},
|
|
148
|
+
display: {
|
|
149
|
+
show_emojis: true,
|
|
150
|
+
single_line: false,
|
|
151
|
+
line_wrap_length: process?.stdout?.columns || 100,
|
|
152
|
+
},
|
|
153
|
+
network: {
|
|
154
|
+
show_offline_message: true,
|
|
155
|
+
},
|
|
156
|
+
advanced: {
|
|
157
|
+
debug: false,
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export interface Settings {
|
|
162
|
+
display_order: string[][];
|
|
163
|
+
colors: Record<string, string>;
|
|
164
|
+
emojis: Record<string, string>;
|
|
165
|
+
labels: Record<string, string>;
|
|
166
|
+
display: {
|
|
167
|
+
show_emojis: boolean;
|
|
168
|
+
single_line: boolean;
|
|
169
|
+
line_wrap_length: number;
|
|
170
|
+
};
|
|
171
|
+
network: {
|
|
172
|
+
show_offline_message: boolean;
|
|
173
|
+
};
|
|
174
|
+
advanced: {
|
|
175
|
+
debug: boolean;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Loads settings from the configuration file
|
|
181
|
+
* @returns Settings object (defaults merged with user settings)
|
|
182
|
+
*/
|
|
183
|
+
export function loadSettings(): Settings {
|
|
184
|
+
try {
|
|
185
|
+
if (fs.existsSync(SETTINGS_FILE)) {
|
|
186
|
+
const settings = JSON.parse(fs.readFileSync(SETTINGS_FILE, "utf8"));
|
|
187
|
+
return { ...DEFAULT_SETTINGS, ...settings };
|
|
188
|
+
}
|
|
189
|
+
} catch {}
|
|
190
|
+
return DEFAULT_SETTINGS;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Saves settings to the configuration file
|
|
195
|
+
* @param settings - The settings object to save
|
|
196
|
+
* @returns True if successful, false otherwise
|
|
197
|
+
*/
|
|
198
|
+
export function saveSettings(settings: Settings): boolean {
|
|
199
|
+
try {
|
|
200
|
+
const configDir = path.dirname(SETTINGS_FILE);
|
|
201
|
+
if (!fs.existsSync(configDir)) {
|
|
202
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
203
|
+
}
|
|
204
|
+
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2));
|
|
205
|
+
return true;
|
|
206
|
+
} catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Software and package-related system information functions
|
|
3
|
+
* @module info/software
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import process from "process";
|
|
7
|
+
import type { InfoContext } from "../types/internal-types";
|
|
8
|
+
import { IS_LINUX } from "../utils/platform";
|
|
9
|
+
import { execCommand, commandExists } from "../utils/command";
|
|
10
|
+
import { getCachedValue, setCachedValue } from "../cache/cache";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Gets the current shell name
|
|
14
|
+
* Uses ps command to find parent process shell (Linux/Unix only)
|
|
15
|
+
* @returns Shell name or empty string on Windows
|
|
16
|
+
* @example "bash", "zsh", "fish", "nu"
|
|
17
|
+
*/
|
|
18
|
+
export function shell(context: InfoContext): string {
|
|
19
|
+
const cached = getCachedValue(context.cache, "shell");
|
|
20
|
+
if (cached !== null) return cached;
|
|
21
|
+
|
|
22
|
+
if (IS_LINUX) {
|
|
23
|
+
try {
|
|
24
|
+
const ppid = process.ppid;
|
|
25
|
+
const shellName = execCommand(`ps -p ${ppid} -o comm=`).split("/").pop();
|
|
26
|
+
if (shellName) {
|
|
27
|
+
setCachedValue(context.cache, "shell", shellName);
|
|
28
|
+
return shellName;
|
|
29
|
+
}
|
|
30
|
+
} catch {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setCachedValue(context.cache, "shell", "");
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Gets available package managers and development tools
|
|
39
|
+
* Checks for package managers (apt, yum, npm, etc.) and editors (nvim, hx)
|
|
40
|
+
* @param context - Info context with cache
|
|
41
|
+
* @returns Space-separated list of available commands
|
|
42
|
+
* @example "apt npm docker nvim", "yay pacman bun hx"
|
|
43
|
+
*/
|
|
44
|
+
export function packages(context: InfoContext): string {
|
|
45
|
+
const cached = getCachedValue(context.cache, "packages");
|
|
46
|
+
if (cached !== null) return cached;
|
|
47
|
+
|
|
48
|
+
const commands = [
|
|
49
|
+
"apt",
|
|
50
|
+
"npm",
|
|
51
|
+
"uv",
|
|
52
|
+
"docker",
|
|
53
|
+
"hx",
|
|
54
|
+
"nvim",
|
|
55
|
+
"bun",
|
|
56
|
+
"yay",
|
|
57
|
+
"pacman",
|
|
58
|
+
"yum",
|
|
59
|
+
"dnf",
|
|
60
|
+
"zypper",
|
|
61
|
+
"emerge",
|
|
62
|
+
"apk",
|
|
63
|
+
"snap",
|
|
64
|
+
"flatpak",
|
|
65
|
+
];
|
|
66
|
+
const available = commands.filter((cmd) => commandExists(cmd));
|
|
67
|
+
|
|
68
|
+
const result = available.join(" ");
|
|
69
|
+
setCachedValue(context.cache, "packages", result);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Gets versions of common software tools
|
|
75
|
+
* @param context - Info context with cache
|
|
76
|
+
* @returns Formatted string of tool versions
|
|
77
|
+
* @example "node:20.1.0 git:2.34.1"
|
|
78
|
+
*/
|
|
79
|
+
export function common_versions(context: InfoContext): string {
|
|
80
|
+
const cached = getCachedValue(context.cache, "common_versions");
|
|
81
|
+
if (cached !== null) return cached;
|
|
82
|
+
|
|
83
|
+
const tools = [
|
|
84
|
+
{
|
|
85
|
+
cmd: "node",
|
|
86
|
+
args: "--version",
|
|
87
|
+
clean: (v: string) => v.replace(/^v/, ""),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
cmd: "git",
|
|
91
|
+
args: "--version",
|
|
92
|
+
clean: (v: string) => v.replace("git version ", ""),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
cmd: "docker",
|
|
96
|
+
args: "--version",
|
|
97
|
+
clean: (v: string) => v.replace(/Docker version ([^,]+),.*/, "$1"),
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
cmd: "python3",
|
|
101
|
+
args: "--version",
|
|
102
|
+
clean: (v: string) => v.replace("Python ", ""),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
cmd: "go",
|
|
106
|
+
args: "version",
|
|
107
|
+
clean: (v: string) => v.replace("go version go", "").split(" ")[0],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
cmd: "rustc",
|
|
111
|
+
args: "--version",
|
|
112
|
+
clean: (v: string) => v.replace("rustc ", "").split(" ")[0],
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
const versions: string[] = [];
|
|
117
|
+
|
|
118
|
+
for (const tool of tools) {
|
|
119
|
+
if (commandExists(tool.cmd)) {
|
|
120
|
+
try {
|
|
121
|
+
const output = execCommand(`${tool.cmd} ${tool.args}`);
|
|
122
|
+
const version = tool.clean(output).trim();
|
|
123
|
+
if (version) {
|
|
124
|
+
versions.push(`${tool.cmd}:${version}`);
|
|
125
|
+
}
|
|
126
|
+
} catch {}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const result = versions.join(" ");
|
|
131
|
+
setCachedValue(context.cache, "common_versions", result);
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Gets running Docker container names
|
|
136
|
+
* Lists active Docker containers with their names
|
|
137
|
+
* @param context - Info context with cache
|
|
138
|
+
* @returns Space-separated container names or empty string
|
|
139
|
+
* @example "nginx redis postgres", "web-app db-server"
|
|
140
|
+
*/
|
|
141
|
+
export function containers(context: InfoContext): string {
|
|
142
|
+
const cached = getCachedValue(context.cache, "containers");
|
|
143
|
+
if (cached !== null) return cached;
|
|
144
|
+
|
|
145
|
+
if (!commandExists("docker")) {
|
|
146
|
+
setCachedValue(context.cache, "containers", "");
|
|
147
|
+
return "";
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const containerCount = execCommand("docker ps -q")
|
|
152
|
+
.split("\n")
|
|
153
|
+
.filter((line) => line.trim()).length;
|
|
154
|
+
if (containerCount === 0) {
|
|
155
|
+
setCachedValue(context.cache, "containers", "");
|
|
156
|
+
return "";
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const containers = execCommand(
|
|
160
|
+
'docker ps --format "{{.Names}}\t{{.Ports}}"'
|
|
161
|
+
);
|
|
162
|
+
const lines = containers.split("\n").filter((line) => line.trim());
|
|
163
|
+
|
|
164
|
+
const containerInfo: string[] = [];
|
|
165
|
+
|
|
166
|
+
lines.forEach((line) => {
|
|
167
|
+
const [name, ports] = line.split("\t");
|
|
168
|
+
if (name) {
|
|
169
|
+
containerInfo.push(name);
|
|
170
|
+
|
|
171
|
+
if (ports) {
|
|
172
|
+
const portMatches = ports.match(/->(\d+(-\d+)?)\//g);
|
|
173
|
+
if (portMatches) {
|
|
174
|
+
const uniquePorts = [
|
|
175
|
+
...new Set(
|
|
176
|
+
portMatches.map((p) => p.replace(/->\d+(-\d+)?\//, ""))
|
|
177
|
+
),
|
|
178
|
+
];
|
|
179
|
+
containerInfo.push(...uniquePorts);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const result = containerInfo.join(" ");
|
|
186
|
+
setCachedValue(context.cache, "containers", result);
|
|
187
|
+
return result;
|
|
188
|
+
} catch {}
|
|
189
|
+
|
|
190
|
+
setCachedValue(context.cache, "containers", "");
|
|
191
|
+
return "";
|
|
192
|
+
}
|