winhelm-mcp 1.1.0
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/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +646 -0
- package/dist/config/config-manager.d.ts +50 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +300 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/default-config.d.ts +4 -0
- package/dist/config/default-config.d.ts.map +1 -0
- package/dist/config/default-config.js +48 -0
- package/dist/config/default-config.js.map +1 -0
- package/dist/config/profiles.d.ts +16 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +208 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/engine/filesystem.d.ts +52 -0
- package/dist/engine/filesystem.d.ts.map +1 -0
- package/dist/engine/filesystem.js +499 -0
- package/dist/engine/filesystem.js.map +1 -0
- package/dist/engine/http-client.d.ts +10 -0
- package/dist/engine/http-client.d.ts.map +1 -0
- package/dist/engine/http-client.js +93 -0
- package/dist/engine/http-client.js.map +1 -0
- package/dist/engine/pdf-generator.d.ts +15 -0
- package/dist/engine/pdf-generator.d.ts.map +1 -0
- package/dist/engine/pdf-generator.js +325 -0
- package/dist/engine/pdf-generator.js.map +1 -0
- package/dist/engine/powershell-runner.d.ts +23 -0
- package/dist/engine/powershell-runner.d.ts.map +1 -0
- package/dist/engine/powershell-runner.js +148 -0
- package/dist/engine/powershell-runner.js.map +1 -0
- package/dist/engine/ripgrep.d.ts +20 -0
- package/dist/engine/ripgrep.d.ts.map +1 -0
- package/dist/engine/ripgrep.js +173 -0
- package/dist/engine/ripgrep.js.map +1 -0
- package/dist/engine/system.d.ts +67 -0
- package/dist/engine/system.d.ts.map +1 -0
- package/dist/engine/system.js +558 -0
- package/dist/engine/system.js.map +1 -0
- package/dist/engine/task-manager.d.ts +66 -0
- package/dist/engine/task-manager.d.ts.map +1 -0
- package/dist/engine/task-manager.js +203 -0
- package/dist/engine/task-manager.js.map +1 -0
- package/dist/gateway/dashboard-html.d.ts +7 -0
- package/dist/gateway/dashboard-html.d.ts.map +1 -0
- package/dist/gateway/dashboard-html.js +624 -0
- package/dist/gateway/dashboard-html.js.map +1 -0
- package/dist/gateway/preview-html.d.ts +5 -0
- package/dist/gateway/preview-html.d.ts.map +1 -0
- package/dist/gateway/preview-html.js +351 -0
- package/dist/gateway/preview-html.js.map +1 -0
- package/dist/gateway/rate-limiter.d.ts +8 -0
- package/dist/gateway/rate-limiter.d.ts.map +1 -0
- package/dist/gateway/rate-limiter.js +51 -0
- package/dist/gateway/rate-limiter.js.map +1 -0
- package/dist/gateway/server.d.ts +18 -0
- package/dist/gateway/server.d.ts.map +1 -0
- package/dist/gateway/server.js +337 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/gateway/sse-gateway.d.ts +43 -0
- package/dist/gateway/sse-gateway.d.ts.map +1 -0
- package/dist/gateway/sse-gateway.js +161 -0
- package/dist/gateway/sse-gateway.js.map +1 -0
- package/dist/gateway/streamable-gateway.d.ts +39 -0
- package/dist/gateway/streamable-gateway.d.ts.map +1 -0
- package/dist/gateway/streamable-gateway.js +176 -0
- package/dist/gateway/streamable-gateway.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +164 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/desktop-tools.d.ts +3 -0
- package/dist/tools/desktop-tools.d.ts.map +1 -0
- package/dist/tools/desktop-tools.js +280 -0
- package/dist/tools/desktop-tools.js.map +1 -0
- package/dist/tools/file-tools.d.ts +3 -0
- package/dist/tools/file-tools.d.ts.map +1 -0
- package/dist/tools/file-tools.js +433 -0
- package/dist/tools/file-tools.js.map +1 -0
- package/dist/tools/index.d.ts +12 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/network-tools.d.ts +3 -0
- package/dist/tools/network-tools.d.ts.map +1 -0
- package/dist/tools/network-tools.js +108 -0
- package/dist/tools/network-tools.js.map +1 -0
- package/dist/tools/registry.d.ts +50 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +54 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/terminal-tools.d.ts +3 -0
- package/dist/tools/terminal-tools.d.ts.map +1 -0
- package/dist/tools/terminal-tools.js +152 -0
- package/dist/tools/terminal-tools.js.map +1 -0
- package/dist/tools/tool-wrapper.d.ts +7 -0
- package/dist/tools/tool-wrapper.d.ts.map +1 -0
- package/dist/tools/tool-wrapper.js +47 -0
- package/dist/tools/tool-wrapper.js.map +1 -0
- package/dist/types/index.d.ts +261 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/file-logger.d.ts +24 -0
- package/dist/utils/file-logger.d.ts.map +1 -0
- package/dist/utils/file-logger.js +117 -0
- package/dist/utils/file-logger.js.map +1 -0
- package/dist/utils/logger.d.ts +51 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +189 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/sanitizer.d.ts +13 -0
- package/dist/utils/sanitizer.d.ts.map +1 -0
- package/dist/utils/sanitizer.js +60 -0
- package/dist/utils/sanitizer.js.map +1 -0
- package/docs/EXAMPLES.md +171 -0
- package/docs/PROFILES.md +423 -0
- package/docs/SECURITY.md +190 -0
- package/docs/TOOLS.md +366 -0
- package/manifest.json +74 -0
- package/package.json +89 -0
- package/scripts/build-exe.ps1 +37 -0
- package/scripts/manage-service.ps1 +112 -0
- package/server.json +23 -0
- package/winhelm.config.example.json +30 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import { runPowerShell } from "./powershell-runner.js";
|
|
2
|
+
import { ConfigManager } from "../config/config-manager.js";
|
|
3
|
+
/**
|
|
4
|
+
* Read text from Windows Clipboard
|
|
5
|
+
*/
|
|
6
|
+
export async function getClipboard() {
|
|
7
|
+
const result = await runPowerShell("Get-Clipboard", { timeoutMs: 5000 });
|
|
8
|
+
return result.stdout;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Set text to Windows Clipboard safely using Base64 decoding
|
|
12
|
+
*/
|
|
13
|
+
export async function setClipboard(text) {
|
|
14
|
+
const base64 = Buffer.from(text, "utf-8").toString("base64");
|
|
15
|
+
const psCmd = `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64}')) | Set-Clipboard`;
|
|
16
|
+
await runPowerShell(psCmd, { timeoutMs: 5000 });
|
|
17
|
+
return { success: true };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Take desktop screenshot using .NET System.Drawing and return as base64 PNG string
|
|
21
|
+
*/
|
|
22
|
+
export async function captureScreen() {
|
|
23
|
+
const psScript = `
|
|
24
|
+
Add-Type -AssemblyName System.Windows.Forms;
|
|
25
|
+
Add-Type -AssemblyName System.Drawing;
|
|
26
|
+
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds;
|
|
27
|
+
$bitmap = New-Object System.Drawing.Bitmap $screen.Width, $screen.Height;
|
|
28
|
+
$graphics = [System.Drawing.Graphics]::FromImage($bitmap);
|
|
29
|
+
$graphics.CopyFromScreen($screen.X, $screen.Y, 0, 0, $bitmap.Size);
|
|
30
|
+
$ms = New-Object System.IO.MemoryStream;
|
|
31
|
+
$bitmap.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png);
|
|
32
|
+
$bytes = $ms.ToArray();
|
|
33
|
+
[Convert]::ToBase64String($bytes);
|
|
34
|
+
$graphics.Dispose();
|
|
35
|
+
$bitmap.Dispose();
|
|
36
|
+
$ms.Dispose();
|
|
37
|
+
`;
|
|
38
|
+
const result = await runPowerShell(psScript, { timeoutMs: 15000 });
|
|
39
|
+
if (result.stderr && !result.stdout) {
|
|
40
|
+
throw new Error(`Screenshot failed: ${result.stderr}`);
|
|
41
|
+
}
|
|
42
|
+
return result.stdout.replace(/\s+/g, "");
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Open URL, file, or folder in Windows default application
|
|
46
|
+
*/
|
|
47
|
+
export async function openTarget(target) {
|
|
48
|
+
if (!target.startsWith("http://") && !target.startsWith("https://")) {
|
|
49
|
+
const configManager = ConfigManager.getInstance();
|
|
50
|
+
const pathCheck = configManager.isPathAllowed(target);
|
|
51
|
+
if (!pathCheck.allowed) {
|
|
52
|
+
throw new Error(pathCheck.reason);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const safeTarget = target.replace(/'/g, "''");
|
|
56
|
+
const result = await runPowerShell(`Start-Process '${safeTarget}'`, { timeoutMs: 5000 });
|
|
57
|
+
if (result.exitCode !== 0 && result.stderr) {
|
|
58
|
+
throw new Error(`Failed to open target: ${result.stderr}`);
|
|
59
|
+
}
|
|
60
|
+
return { success: true, target };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get Windows system status (RAM, CPU, Drives)
|
|
64
|
+
*/
|
|
65
|
+
export async function getSystemInfo() {
|
|
66
|
+
const psScript = `
|
|
67
|
+
$os = Get-CimInstance Win32_OperatingSystem;
|
|
68
|
+
$cpu = (Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Average).Average;
|
|
69
|
+
$drives = Get-PSDrive -PSProvider FileSystem | Select-Object Name, @{N='FreeGB';E={[math]::Round($_.Free/1GB, 2)}}, @{N='UsedGB';E={[math]::Round($_.Used/1GB, 2)}}, @{N='TotalGB';E={[math]::Round(($_.Used + $_.Free)/1GB, 2)}};
|
|
70
|
+
@{
|
|
71
|
+
ComputerName = $env:COMPUTERNAME;
|
|
72
|
+
OS = $os.Caption;
|
|
73
|
+
TotalRamGB = [math]::Round($os.TotalVisibleMemorySize / 1MB, 2);
|
|
74
|
+
FreeRamGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2);
|
|
75
|
+
UsedRamGB = [math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / 1MB, 2);
|
|
76
|
+
CpuLoadPercentage = $cpu;
|
|
77
|
+
Drives = $drives;
|
|
78
|
+
} | ConvertTo-Json -Depth 3;
|
|
79
|
+
`;
|
|
80
|
+
const result = await runPowerShell(psScript, { timeoutMs: 10000 });
|
|
81
|
+
try {
|
|
82
|
+
const parsed = JSON.parse(result.stdout);
|
|
83
|
+
const configManager = ConfigManager.getInstance();
|
|
84
|
+
const config = configManager.getConfig();
|
|
85
|
+
if (config.allowedDirectories && config.allowedDirectories.length > 0) {
|
|
86
|
+
if (Array.isArray(parsed.Drives)) {
|
|
87
|
+
parsed.Drives = parsed.Drives.filter((d) => {
|
|
88
|
+
if (!d.Name)
|
|
89
|
+
return false;
|
|
90
|
+
return configManager.isPathAllowed(d.Name + ":\\").allowed;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
parsed.AllowedDirectories = config.allowedDirectories;
|
|
94
|
+
parsed.SecurityPolicy =
|
|
95
|
+
config.allowSystemExecution === false
|
|
96
|
+
? `Access strictly restricted to: ${config.allowedDirectories.join(", ")}`
|
|
97
|
+
: `Workspace file mutations strictly isolated to: ${config.allowedDirectories.join(", ")} (PowerShell runtime execution permitted for Python/Node/Git/UV dev toolchains on C:)`;
|
|
98
|
+
}
|
|
99
|
+
return parsed;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return { raw: result.stdout };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a TCP port is in use and find owning PID
|
|
107
|
+
*/
|
|
108
|
+
export async function checkPort(port) {
|
|
109
|
+
const psScript = `
|
|
110
|
+
$conn = Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | Select-Object -First 1;
|
|
111
|
+
if ($conn) {
|
|
112
|
+
$proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue;
|
|
113
|
+
@{
|
|
114
|
+
port = ${port};
|
|
115
|
+
inUse = $true;
|
|
116
|
+
pid = $conn.OwningProcess;
|
|
117
|
+
processName = if ($proc) { $proc.ProcessName } else { "Unknown" };
|
|
118
|
+
state = $conn.State.ToString();
|
|
119
|
+
} | ConvertTo-Json;
|
|
120
|
+
} else {
|
|
121
|
+
@{
|
|
122
|
+
port = ${port};
|
|
123
|
+
inUse = $false;
|
|
124
|
+
} | ConvertTo-Json;
|
|
125
|
+
}
|
|
126
|
+
`;
|
|
127
|
+
const result = await runPowerShell(psScript, { timeoutMs: 5000 });
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(result.stdout);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return { port, inUse: false };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Kill process by PID or Name
|
|
137
|
+
*/
|
|
138
|
+
export async function killProcess(pid, name) {
|
|
139
|
+
const { ConfigManager } = await import("../config/config-manager.js");
|
|
140
|
+
if (ConfigManager.getInstance().isReadOnly()) {
|
|
141
|
+
throw new Error("Process termination is blocked: Server is operating in read-only mode.");
|
|
142
|
+
}
|
|
143
|
+
let cmd = "";
|
|
144
|
+
if (pid) {
|
|
145
|
+
cmd = `Stop-Process -Id ${pid} -Force -PassThru | Select-Object Id, ProcessName | ConvertTo-Json`;
|
|
146
|
+
}
|
|
147
|
+
else if (name) {
|
|
148
|
+
const safeName = name.replace(/'/g, "''");
|
|
149
|
+
cmd = `Stop-Process -Name '${safeName}' -Force -PassThru | Select-Object Id, ProcessName | ConvertTo-Json`;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
throw new Error("Must provide either pid or name");
|
|
153
|
+
}
|
|
154
|
+
const result = await runPowerShell(cmd, { timeoutMs: 5000 });
|
|
155
|
+
if (result.exitCode !== 0 && result.stderr) {
|
|
156
|
+
throw new Error(`Failed to kill process: ${result.stderr}`);
|
|
157
|
+
}
|
|
158
|
+
return { success: true, details: result.stdout || "Process stopped" };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get GPU and CUDA statistics (NVIDIA nvidia-smi with WMI fallback)
|
|
162
|
+
*/
|
|
163
|
+
export async function getGpuInfo() {
|
|
164
|
+
// 1. Try nvidia-smi first (standard for NVIDIA GPUs / CUDA)
|
|
165
|
+
try {
|
|
166
|
+
const nvidiaCmd = `nvidia-smi --query-gpu=index,name,driver_version,memory.total,memory.used,memory.free,temperature.gpu,utilization.gpu --format=csv,noheader,nounits`;
|
|
167
|
+
const res = await runPowerShell(nvidiaCmd, { timeoutMs: 5000 });
|
|
168
|
+
if (res.exitCode === 0 && res.stdout && res.stdout.trim()) {
|
|
169
|
+
const lines = res.stdout.trim().split(/\r?\n/).filter(Boolean);
|
|
170
|
+
const gpus = lines.map((line) => {
|
|
171
|
+
const parts = line.split(",").map((p) => p.trim());
|
|
172
|
+
return {
|
|
173
|
+
index: parseInt(parts[0], 10) || 0,
|
|
174
|
+
name: parts[1] || "NVIDIA GPU",
|
|
175
|
+
driverVersion: parts[2] || undefined,
|
|
176
|
+
memoryTotalMB: parseFloat(parts[3]) || undefined,
|
|
177
|
+
memoryUsedMB: parseFloat(parts[4]) || undefined,
|
|
178
|
+
memoryFreeMB: parseFloat(parts[5]) || undefined,
|
|
179
|
+
temperatureC: parseFloat(parts[6]) || undefined,
|
|
180
|
+
utilizationGpuPct: parseFloat(parts[7]) || undefined,
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
return { hasNvidia: true, gpus };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// nvidia-smi not available or non-Nvidia
|
|
188
|
+
}
|
|
189
|
+
// 2. Fallback to Windows WMI (Win32_VideoController) for Intel / AMD / Integrated
|
|
190
|
+
try {
|
|
191
|
+
const wmiCmd = `Get-CimInstance Win32_VideoController | Select-Object Name, DriverVersion, @{N='AdapterRAM_MB';E={[math]::Round($_.AdapterRAM/1MB, 2)}} | ConvertTo-Json -Depth 2`;
|
|
192
|
+
const res = await runPowerShell(wmiCmd, { timeoutMs: 5000 });
|
|
193
|
+
if (res.exitCode === 0 && res.stdout && res.stdout.trim()) {
|
|
194
|
+
let parsed = JSON.parse(res.stdout);
|
|
195
|
+
if (!Array.isArray(parsed))
|
|
196
|
+
parsed = [parsed];
|
|
197
|
+
const gpus = parsed.map((item, idx) => ({
|
|
198
|
+
index: idx,
|
|
199
|
+
name: item.Name || "Generic Video Controller",
|
|
200
|
+
driverVersion: item.DriverVersion,
|
|
201
|
+
memoryTotalMB: item.AdapterRAM_MB,
|
|
202
|
+
}));
|
|
203
|
+
return { hasNvidia: false, gpus };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// fallback error
|
|
208
|
+
}
|
|
209
|
+
return { hasNvidia: false, gpus: [] };
|
|
210
|
+
}
|
|
211
|
+
function mapServiceStatus(statusNumOrStr) {
|
|
212
|
+
if (typeof statusNumOrStr === "string")
|
|
213
|
+
return statusNumOrStr;
|
|
214
|
+
switch (statusNumOrStr) {
|
|
215
|
+
case 1:
|
|
216
|
+
return "Stopped";
|
|
217
|
+
case 2:
|
|
218
|
+
return "StartPending";
|
|
219
|
+
case 3:
|
|
220
|
+
return "StopPending";
|
|
221
|
+
case 4:
|
|
222
|
+
return "Running";
|
|
223
|
+
case 5:
|
|
224
|
+
return "ContinuePending";
|
|
225
|
+
case 6:
|
|
226
|
+
return "PausePending";
|
|
227
|
+
case 7:
|
|
228
|
+
return "Paused";
|
|
229
|
+
default:
|
|
230
|
+
return String(statusNumOrStr);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function mapStartType(startTypeNumOrStr) {
|
|
234
|
+
if (typeof startTypeNumOrStr === "string")
|
|
235
|
+
return startTypeNumOrStr;
|
|
236
|
+
switch (startTypeNumOrStr) {
|
|
237
|
+
case 0:
|
|
238
|
+
return "Boot";
|
|
239
|
+
case 1:
|
|
240
|
+
return "System";
|
|
241
|
+
case 2:
|
|
242
|
+
return "Automatic";
|
|
243
|
+
case 3:
|
|
244
|
+
return "Manual";
|
|
245
|
+
case 4:
|
|
246
|
+
return "Disabled";
|
|
247
|
+
default:
|
|
248
|
+
return String(startTypeNumOrStr);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* List Windows Services with optional substring filter
|
|
253
|
+
*/
|
|
254
|
+
export async function listServices(filter) {
|
|
255
|
+
const safeFilter = filter ? filter.replace(/['"*]/g, "").trim() : "";
|
|
256
|
+
const nameArg = safeFilter ? `-Name '*${safeFilter}*'` : "";
|
|
257
|
+
const psCmd = `Get-Service ${nameArg} | Select-Object -First 100 Name, DisplayName, Status, StartType | ConvertTo-Json -Depth 2`;
|
|
258
|
+
const res = await runPowerShell(psCmd, { timeoutMs: 10000 });
|
|
259
|
+
if (!res.stdout || !res.stdout.trim()) {
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
let parsed = JSON.parse(res.stdout);
|
|
264
|
+
if (!Array.isArray(parsed))
|
|
265
|
+
parsed = [parsed];
|
|
266
|
+
return parsed.map((s) => ({
|
|
267
|
+
name: s.Name || "",
|
|
268
|
+
displayName: s.DisplayName || "",
|
|
269
|
+
status: mapServiceStatus(s.Status),
|
|
270
|
+
startType: mapStartType(s.StartType),
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get detailed status of a specific Windows Service
|
|
279
|
+
*/
|
|
280
|
+
export async function getServiceStatus(serviceName) {
|
|
281
|
+
const safeName = serviceName.replace(/['"]/g, "").trim();
|
|
282
|
+
const psCmd = `Get-Service -Name '${safeName}' | Select-Object Name, DisplayName, Status, StartType, CanStop, CanPauseAndContinue | ConvertTo-Json -Depth 2`;
|
|
283
|
+
const res = await runPowerShell(psCmd, { timeoutMs: 5000 });
|
|
284
|
+
if (!res.stdout || !res.stdout.trim()) {
|
|
285
|
+
throw new Error(`Service '${serviceName}' not found`);
|
|
286
|
+
}
|
|
287
|
+
const s = JSON.parse(res.stdout);
|
|
288
|
+
return {
|
|
289
|
+
name: s.Name || safeName,
|
|
290
|
+
displayName: s.DisplayName || "",
|
|
291
|
+
status: mapServiceStatus(s.Status),
|
|
292
|
+
startType: mapStartType(s.StartType),
|
|
293
|
+
canStop: !!s.CanStop,
|
|
294
|
+
canPauseAndContinue: !!s.CanPauseAndContinue,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Control a Windows Service (start, stop, restart)
|
|
299
|
+
*/
|
|
300
|
+
export async function controlService(serviceName, action) {
|
|
301
|
+
const configManager = ConfigManager.getInstance();
|
|
302
|
+
if (configManager.isReadOnly()) {
|
|
303
|
+
throw new Error("Service modification is blocked: Server is running in read-only mode.");
|
|
304
|
+
}
|
|
305
|
+
const safeName = serviceName.replace(/['"]/g, "").trim();
|
|
306
|
+
let verb = "Start-Service";
|
|
307
|
+
if (action === "stop")
|
|
308
|
+
verb = "Stop-Service";
|
|
309
|
+
if (action === "restart")
|
|
310
|
+
verb = "Restart-Service";
|
|
311
|
+
const psCmd = `${verb} -Name '${safeName}' -PassThru | Select-Object Name, Status | ConvertTo-Json`;
|
|
312
|
+
const res = await runPowerShell(psCmd, { timeoutMs: 15000 });
|
|
313
|
+
if (res.exitCode !== 0 && res.stderr) {
|
|
314
|
+
throw new Error(`Failed to ${action} service '${serviceName}': ${res.stderr}`);
|
|
315
|
+
}
|
|
316
|
+
let currentStatus = "Unknown";
|
|
317
|
+
try {
|
|
318
|
+
const parsed = JSON.parse(res.stdout);
|
|
319
|
+
currentStatus = mapServiceStatus(parsed.Status);
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
const statusQuery = await getServiceStatus(serviceName);
|
|
323
|
+
currentStatus = statusQuery.status;
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
success: true,
|
|
327
|
+
serviceName: safeName,
|
|
328
|
+
action,
|
|
329
|
+
currentStatus,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* List running Windows processes with sorting and optional filtering
|
|
334
|
+
*/
|
|
335
|
+
export async function listProcesses(options) {
|
|
336
|
+
const limit = Math.min(Math.max(1, options?.limit || 20), 100);
|
|
337
|
+
const sortBy = options?.sortBy || "memory";
|
|
338
|
+
const filter = options?.filter ? options.filter.replace(/['"]/g, "").trim() : "";
|
|
339
|
+
let psCmd = `$procs = Get-Process;`;
|
|
340
|
+
if (filter) {
|
|
341
|
+
psCmd += `$procs = $procs | Where-Object { $_.ProcessName -like "*${filter}*" -or $_.Path -like "*${filter}*" };`;
|
|
342
|
+
}
|
|
343
|
+
if (sortBy === "cpu") {
|
|
344
|
+
psCmd += `$procs = $procs | Sort-Object CPU -Descending;`;
|
|
345
|
+
}
|
|
346
|
+
else if (sortBy === "memory") {
|
|
347
|
+
psCmd += `$procs = $procs | Sort-Object WorkingSet64 -Descending;`;
|
|
348
|
+
}
|
|
349
|
+
else if (sortBy === "name") {
|
|
350
|
+
psCmd += `$procs = $procs | Sort-Object ProcessName;`;
|
|
351
|
+
}
|
|
352
|
+
else if (sortBy === "pid") {
|
|
353
|
+
psCmd += `$procs = $procs | Sort-Object Id;`;
|
|
354
|
+
}
|
|
355
|
+
psCmd += `$procs = $procs | Select-Object -First ${limit};`;
|
|
356
|
+
psCmd += `$procs | Select-Object Id, ProcessName, @{N='WorkingSetMB';E={[math]::Round($_.WorkingSet64/1MB, 2)}}, @{N='CPUSeconds';E={if($_.CPU){[math]::Round($_.CPU, 2)}else{0}}}, Path, Description | ConvertTo-Json -Depth 2;`;
|
|
357
|
+
const res = await runPowerShell(psCmd, { timeoutMs: 10000 });
|
|
358
|
+
if (!res.stdout || !res.stdout.trim()) {
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
let parsed = JSON.parse(res.stdout);
|
|
363
|
+
if (!Array.isArray(parsed))
|
|
364
|
+
parsed = [parsed];
|
|
365
|
+
return parsed.map((p) => ({
|
|
366
|
+
pid: Number(p.Id || 0),
|
|
367
|
+
name: String(p.ProcessName || ""),
|
|
368
|
+
workingSetMB: Number(p.WorkingSetMB || 0),
|
|
369
|
+
cpuSeconds: Number(p.CPUSeconds || 0),
|
|
370
|
+
path: p.Path || undefined,
|
|
371
|
+
description: p.Description || undefined,
|
|
372
|
+
}));
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
return [];
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Query Windows Event Log for errors, warnings, or crashes
|
|
380
|
+
*/
|
|
381
|
+
export async function queryEventLog(options) {
|
|
382
|
+
const logName = (options?.logName || "Application").replace(/['"]/g, "").trim();
|
|
383
|
+
const limit = Math.min(Math.max(1, options?.limit || 20), 100);
|
|
384
|
+
const hours = Math.min(Math.max(1, options?.hours || 24), 720);
|
|
385
|
+
const level = options?.level || "Error";
|
|
386
|
+
const source = options?.source ? options.source.replace(/['"]/g, "").trim() : "";
|
|
387
|
+
const psCmd = `
|
|
388
|
+
try {
|
|
389
|
+
$filter = @{
|
|
390
|
+
LogName = '${logName}';
|
|
391
|
+
StartTime = (Get-Date).AddHours(-${hours});
|
|
392
|
+
};
|
|
393
|
+
${level === "Critical" ? "$filter['Level'] = 1;" : ""}
|
|
394
|
+
${level === "Error" ? "$filter['Level'] = 2;" : ""}
|
|
395
|
+
${level === "Warning" ? "$filter['Level'] = 3;" : ""}
|
|
396
|
+
${level === "Information" ? "$filter['Level'] = 4;" : ""}
|
|
397
|
+
${source ? `$filter['ProviderName'] = '${source}';` : ""}
|
|
398
|
+
$events = Get-WinEvent -FilterHashtable $filter -MaxEvents ${limit} -ErrorAction Stop |
|
|
399
|
+
Select-Object @{N='TimeCreated';E={$_.TimeCreated.ToString('o')}}, Id, LevelDisplayName, ProviderName, @{N='Message';E={($_.Message -replace '\\r|\\n', ' ') -replace '\\s+', ' '}};
|
|
400
|
+
$events | ConvertTo-Json -Depth 2
|
|
401
|
+
} catch {
|
|
402
|
+
Write-Output "[]"
|
|
403
|
+
}
|
|
404
|
+
`;
|
|
405
|
+
const res = await runPowerShell(psCmd, { timeoutMs: 15000 });
|
|
406
|
+
if (!res.stdout || !res.stdout.trim() || res.stdout.trim() === "[]") {
|
|
407
|
+
return [];
|
|
408
|
+
}
|
|
409
|
+
try {
|
|
410
|
+
let parsed = JSON.parse(res.stdout);
|
|
411
|
+
if (!Array.isArray(parsed))
|
|
412
|
+
parsed = [parsed];
|
|
413
|
+
return parsed.map((e) => ({
|
|
414
|
+
timeCreated: String(e.TimeCreated || ""),
|
|
415
|
+
id: Number(e.Id || 0),
|
|
416
|
+
level: String(e.LevelDisplayName || level),
|
|
417
|
+
providerName: String(e.ProviderName || ""),
|
|
418
|
+
message: String(e.Message || "").slice(0, 1000),
|
|
419
|
+
}));
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
return [];
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Inspect network adapters, local IP, gateway, DNS, and Tailscale connection
|
|
427
|
+
*/
|
|
428
|
+
export async function getNetworkInfo(includeListeningPorts = false) {
|
|
429
|
+
const os = await import("node:os");
|
|
430
|
+
const hostname = os.hostname();
|
|
431
|
+
const rawInterfaces = os.networkInterfaces();
|
|
432
|
+
const adapters = [];
|
|
433
|
+
let tailscaleIp;
|
|
434
|
+
for (const [name, addrs] of Object.entries(rawInterfaces)) {
|
|
435
|
+
if (!addrs || addrs.length === 0)
|
|
436
|
+
continue;
|
|
437
|
+
const ipv4List = [];
|
|
438
|
+
const ipv6List = [];
|
|
439
|
+
let mac = "";
|
|
440
|
+
let isInternal = false;
|
|
441
|
+
for (const addr of addrs) {
|
|
442
|
+
if (addr.family === "IPv4") {
|
|
443
|
+
ipv4List.push(addr.address);
|
|
444
|
+
if (addr.address.startsWith("100.") || name.toLowerCase().includes("tailscale")) {
|
|
445
|
+
tailscaleIp = addr.address;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else if (addr.family === "IPv6") {
|
|
449
|
+
ipv6List.push(addr.address);
|
|
450
|
+
}
|
|
451
|
+
if (addr.mac && addr.mac !== "00:00:00:00:00:00") {
|
|
452
|
+
mac = addr.mac;
|
|
453
|
+
}
|
|
454
|
+
if (addr.internal) {
|
|
455
|
+
isInternal = true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
adapters.push({
|
|
459
|
+
name,
|
|
460
|
+
ipv4: ipv4List.length > 0 ? ipv4List : undefined,
|
|
461
|
+
ipv6: ipv6List.length > 0 ? ipv6List : undefined,
|
|
462
|
+
mac: mac || undefined,
|
|
463
|
+
isInternal,
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
let defaultGateway;
|
|
467
|
+
let dnsServers;
|
|
468
|
+
try {
|
|
469
|
+
const psCmd = `Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway } | Select-Object -First 1 @{N='Gateway';E={$_.IPv4DefaultGateway.NextHop}}, @{N='DNS';E={$_.DNSServer.ServerAddresses}} | ConvertTo-Json`;
|
|
470
|
+
const res = await runPowerShell(psCmd, { timeoutMs: 5000 });
|
|
471
|
+
if (res.stdout && res.stdout.trim()) {
|
|
472
|
+
const parsed = JSON.parse(res.stdout);
|
|
473
|
+
if (parsed.Gateway)
|
|
474
|
+
defaultGateway = String(parsed.Gateway);
|
|
475
|
+
if (parsed.DNS) {
|
|
476
|
+
dnsServers = Array.isArray(parsed.DNS) ? parsed.DNS.map(String) : [String(parsed.DNS)];
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
catch {
|
|
481
|
+
// Non-fatal
|
|
482
|
+
}
|
|
483
|
+
if (!tailscaleIp) {
|
|
484
|
+
try {
|
|
485
|
+
const tailscaleRes = await runPowerShell("tailscale ip -4", { timeoutMs: 3000 });
|
|
486
|
+
if (tailscaleRes.stdout && tailscaleRes.stdout.trim().startsWith("100.")) {
|
|
487
|
+
tailscaleIp = tailscaleRes.stdout.trim();
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
catch {
|
|
491
|
+
// Tailscale not installed, ignore
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
let listeningPorts;
|
|
495
|
+
if (includeListeningPorts) {
|
|
496
|
+
try {
|
|
497
|
+
const psPorts = `Get-NetTCPConnection -State Listen | Select-Object LocalPort, OwningProcess -Unique | Select-Object -First 30 | ForEach-Object { $p = $_; $name = (Get-Process -Id $p.OwningProcess -ErrorAction SilentlyContinue).ProcessName; [PSCustomObject]@{ Port = $p.LocalPort; Pid = $p.OwningProcess; ProcessName = $name } } | ConvertTo-Json`;
|
|
498
|
+
const portRes = await runPowerShell(psPorts, { timeoutMs: 6000 });
|
|
499
|
+
if (portRes.stdout && portRes.stdout.trim()) {
|
|
500
|
+
let parsed = JSON.parse(portRes.stdout);
|
|
501
|
+
if (!Array.isArray(parsed))
|
|
502
|
+
parsed = [parsed];
|
|
503
|
+
listeningPorts = parsed.map((item) => ({
|
|
504
|
+
port: Number(item.Port),
|
|
505
|
+
pid: Number(item.Pid || 0),
|
|
506
|
+
processName: item.ProcessName || undefined,
|
|
507
|
+
}));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
// Non-fatal
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
hostname,
|
|
516
|
+
adapters,
|
|
517
|
+
defaultGateway,
|
|
518
|
+
dnsServers,
|
|
519
|
+
tailscaleIp,
|
|
520
|
+
listeningPorts,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Send native Windows Toast Notification
|
|
525
|
+
*/
|
|
526
|
+
export async function sendNotification(title, message, sound = true) {
|
|
527
|
+
const safeTitle = title.replace(/['"]/g, "").trim().slice(0, 100);
|
|
528
|
+
const safeMsg = message.replace(/['"]/g, "").trim().slice(0, 500);
|
|
529
|
+
const soundTag = sound
|
|
530
|
+
? "<audio src='ms-winsoundevent:Notification.Default' />"
|
|
531
|
+
: "<audio silent='true' />";
|
|
532
|
+
const toastXml = `<toast><visual><binding template='ToastGeneric'><text>${safeTitle}</text><text>${safeMsg}</text></binding></visual>${soundTag}</toast>`;
|
|
533
|
+
const psScript = `
|
|
534
|
+
try {
|
|
535
|
+
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
|
|
536
|
+
$xmlDoc = New-Object Windows.Data.Xml.Dom.XmlDocument
|
|
537
|
+
$xmlDoc.LoadXml("${toastXml}")
|
|
538
|
+
$toast = New-Object Windows.UI.Notifications.ToastNotification $xmlDoc
|
|
539
|
+
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("WinHelm").Show($toast)
|
|
540
|
+
} catch {
|
|
541
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
542
|
+
$balloon = New-Object System.Windows.Forms.NotifyIcon
|
|
543
|
+
$balloon.Icon = [System.Drawing.SystemIcons]::Information
|
|
544
|
+
$balloon.BalloonTipTitle = '${safeTitle}'
|
|
545
|
+
$balloon.BalloonTipText = '${safeMsg}'
|
|
546
|
+
$balloon.Visible = $true
|
|
547
|
+
$balloon.ShowBalloonTip(4000)
|
|
548
|
+
}
|
|
549
|
+
`;
|
|
550
|
+
await runPowerShell(psScript, { timeoutMs: 6000 });
|
|
551
|
+
return {
|
|
552
|
+
success: true,
|
|
553
|
+
title: safeTitle,
|
|
554
|
+
message: safeMsg,
|
|
555
|
+
timestamp: new Date().toISOString(),
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/engine/system.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
export interface BackgroundTask {
|
|
3
|
+
id: string;
|
|
4
|
+
command: string;
|
|
5
|
+
cwd: string;
|
|
6
|
+
pid: number | undefined;
|
|
7
|
+
startTime: string;
|
|
8
|
+
endTime?: string;
|
|
9
|
+
status: "running" | "completed" | "failed" | "killed";
|
|
10
|
+
exitCode?: number | null;
|
|
11
|
+
outputBuffer: string[];
|
|
12
|
+
process?: ChildProcess;
|
|
13
|
+
}
|
|
14
|
+
export interface TaskSummary {
|
|
15
|
+
id: string;
|
|
16
|
+
command: string;
|
|
17
|
+
cwd: string;
|
|
18
|
+
pid: number | undefined;
|
|
19
|
+
startTime: string;
|
|
20
|
+
endTime?: string;
|
|
21
|
+
status: BackgroundTask["status"];
|
|
22
|
+
exitCode?: number | null;
|
|
23
|
+
outputLinesCount: number;
|
|
24
|
+
}
|
|
25
|
+
export declare class TaskManager {
|
|
26
|
+
private static instance;
|
|
27
|
+
private tasks;
|
|
28
|
+
private readonly maxBufferLines;
|
|
29
|
+
private readonly maxRetainedTasks;
|
|
30
|
+
private constructor();
|
|
31
|
+
static getInstance(): TaskManager;
|
|
32
|
+
/**
|
|
33
|
+
* Start a command as a long-running background task
|
|
34
|
+
*/
|
|
35
|
+
startTask(command: string, cwd?: string): TaskSummary;
|
|
36
|
+
/**
|
|
37
|
+
* List all background tasks
|
|
38
|
+
*/
|
|
39
|
+
listTasks(): TaskSummary[];
|
|
40
|
+
/**
|
|
41
|
+
* Get buffered logs for a task
|
|
42
|
+
*/
|
|
43
|
+
getTaskLogs(taskId: string, tailLines?: number): {
|
|
44
|
+
logs: string;
|
|
45
|
+
task: TaskSummary;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Send text to standard input of a running background task
|
|
49
|
+
*/
|
|
50
|
+
sendInput(taskId: string, input: string): {
|
|
51
|
+
success: boolean;
|
|
52
|
+
};
|
|
53
|
+
private terminateProcess;
|
|
54
|
+
/**
|
|
55
|
+
* Terminate a background task
|
|
56
|
+
*/
|
|
57
|
+
killTask(taskId: string): {
|
|
58
|
+
success: boolean;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Terminate all background tasks on server shutdown
|
|
62
|
+
*/
|
|
63
|
+
killAll(): void;
|
|
64
|
+
}
|
|
65
|
+
export declare const taskManager: TaskManager;
|
|
66
|
+
//# sourceMappingURL=task-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-manager.d.ts","sourceRoot":"","sources":["../../src/engine/task-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMxE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IACnD,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAEvC,OAAO,eAAiB;IAExB,OAAc,WAAW,IAAI,WAAW,CAKvC;IAED;;OAEG;IACI,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAgB,GAAG,WAAW,CAuGlE;IAED;;OAEG;IACI,SAAS,IAAI,WAAW,EAAE,CAYhC;IAED;;OAEG;IACI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAqBvF;IAED;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAWpE;IAED,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACI,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAQpD;IAED;;OAEG;IACI,OAAO,IAAI,IAAI,CAIrB;CACF;AAED,eAAO,MAAM,WAAW,aAA4B,CAAC"}
|