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.
Files changed (125) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/LICENSE +21 -0
  3. package/README.md +646 -0
  4. package/dist/config/config-manager.d.ts +50 -0
  5. package/dist/config/config-manager.d.ts.map +1 -0
  6. package/dist/config/config-manager.js +300 -0
  7. package/dist/config/config-manager.js.map +1 -0
  8. package/dist/config/default-config.d.ts +4 -0
  9. package/dist/config/default-config.d.ts.map +1 -0
  10. package/dist/config/default-config.js +48 -0
  11. package/dist/config/default-config.js.map +1 -0
  12. package/dist/config/profiles.d.ts +16 -0
  13. package/dist/config/profiles.d.ts.map +1 -0
  14. package/dist/config/profiles.js +208 -0
  15. package/dist/config/profiles.js.map +1 -0
  16. package/dist/engine/filesystem.d.ts +52 -0
  17. package/dist/engine/filesystem.d.ts.map +1 -0
  18. package/dist/engine/filesystem.js +499 -0
  19. package/dist/engine/filesystem.js.map +1 -0
  20. package/dist/engine/http-client.d.ts +10 -0
  21. package/dist/engine/http-client.d.ts.map +1 -0
  22. package/dist/engine/http-client.js +93 -0
  23. package/dist/engine/http-client.js.map +1 -0
  24. package/dist/engine/pdf-generator.d.ts +15 -0
  25. package/dist/engine/pdf-generator.d.ts.map +1 -0
  26. package/dist/engine/pdf-generator.js +325 -0
  27. package/dist/engine/pdf-generator.js.map +1 -0
  28. package/dist/engine/powershell-runner.d.ts +23 -0
  29. package/dist/engine/powershell-runner.d.ts.map +1 -0
  30. package/dist/engine/powershell-runner.js +148 -0
  31. package/dist/engine/powershell-runner.js.map +1 -0
  32. package/dist/engine/ripgrep.d.ts +20 -0
  33. package/dist/engine/ripgrep.d.ts.map +1 -0
  34. package/dist/engine/ripgrep.js +173 -0
  35. package/dist/engine/ripgrep.js.map +1 -0
  36. package/dist/engine/system.d.ts +67 -0
  37. package/dist/engine/system.d.ts.map +1 -0
  38. package/dist/engine/system.js +558 -0
  39. package/dist/engine/system.js.map +1 -0
  40. package/dist/engine/task-manager.d.ts +66 -0
  41. package/dist/engine/task-manager.d.ts.map +1 -0
  42. package/dist/engine/task-manager.js +203 -0
  43. package/dist/engine/task-manager.js.map +1 -0
  44. package/dist/gateway/dashboard-html.d.ts +7 -0
  45. package/dist/gateway/dashboard-html.d.ts.map +1 -0
  46. package/dist/gateway/dashboard-html.js +624 -0
  47. package/dist/gateway/dashboard-html.js.map +1 -0
  48. package/dist/gateway/preview-html.d.ts +5 -0
  49. package/dist/gateway/preview-html.d.ts.map +1 -0
  50. package/dist/gateway/preview-html.js +351 -0
  51. package/dist/gateway/preview-html.js.map +1 -0
  52. package/dist/gateway/rate-limiter.d.ts +8 -0
  53. package/dist/gateway/rate-limiter.d.ts.map +1 -0
  54. package/dist/gateway/rate-limiter.js +51 -0
  55. package/dist/gateway/rate-limiter.js.map +1 -0
  56. package/dist/gateway/server.d.ts +18 -0
  57. package/dist/gateway/server.d.ts.map +1 -0
  58. package/dist/gateway/server.js +337 -0
  59. package/dist/gateway/server.js.map +1 -0
  60. package/dist/gateway/sse-gateway.d.ts +43 -0
  61. package/dist/gateway/sse-gateway.d.ts.map +1 -0
  62. package/dist/gateway/sse-gateway.js +161 -0
  63. package/dist/gateway/sse-gateway.js.map +1 -0
  64. package/dist/gateway/streamable-gateway.d.ts +39 -0
  65. package/dist/gateway/streamable-gateway.d.ts.map +1 -0
  66. package/dist/gateway/streamable-gateway.js +176 -0
  67. package/dist/gateway/streamable-gateway.js.map +1 -0
  68. package/dist/index.d.ts +5 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +164 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/tools/desktop-tools.d.ts +3 -0
  73. package/dist/tools/desktop-tools.d.ts.map +1 -0
  74. package/dist/tools/desktop-tools.js +280 -0
  75. package/dist/tools/desktop-tools.js.map +1 -0
  76. package/dist/tools/file-tools.d.ts +3 -0
  77. package/dist/tools/file-tools.d.ts.map +1 -0
  78. package/dist/tools/file-tools.js +433 -0
  79. package/dist/tools/file-tools.js.map +1 -0
  80. package/dist/tools/index.d.ts +12 -0
  81. package/dist/tools/index.d.ts.map +1 -0
  82. package/dist/tools/index.js +16 -0
  83. package/dist/tools/index.js.map +1 -0
  84. package/dist/tools/network-tools.d.ts +3 -0
  85. package/dist/tools/network-tools.d.ts.map +1 -0
  86. package/dist/tools/network-tools.js +108 -0
  87. package/dist/tools/network-tools.js.map +1 -0
  88. package/dist/tools/registry.d.ts +50 -0
  89. package/dist/tools/registry.d.ts.map +1 -0
  90. package/dist/tools/registry.js +54 -0
  91. package/dist/tools/registry.js.map +1 -0
  92. package/dist/tools/terminal-tools.d.ts +3 -0
  93. package/dist/tools/terminal-tools.d.ts.map +1 -0
  94. package/dist/tools/terminal-tools.js +152 -0
  95. package/dist/tools/terminal-tools.js.map +1 -0
  96. package/dist/tools/tool-wrapper.d.ts +7 -0
  97. package/dist/tools/tool-wrapper.d.ts.map +1 -0
  98. package/dist/tools/tool-wrapper.js +47 -0
  99. package/dist/tools/tool-wrapper.js.map +1 -0
  100. package/dist/types/index.d.ts +261 -0
  101. package/dist/types/index.d.ts.map +1 -0
  102. package/dist/types/index.js +2 -0
  103. package/dist/types/index.js.map +1 -0
  104. package/dist/utils/file-logger.d.ts +24 -0
  105. package/dist/utils/file-logger.d.ts.map +1 -0
  106. package/dist/utils/file-logger.js +117 -0
  107. package/dist/utils/file-logger.js.map +1 -0
  108. package/dist/utils/logger.d.ts +51 -0
  109. package/dist/utils/logger.d.ts.map +1 -0
  110. package/dist/utils/logger.js +189 -0
  111. package/dist/utils/logger.js.map +1 -0
  112. package/dist/utils/sanitizer.d.ts +13 -0
  113. package/dist/utils/sanitizer.d.ts.map +1 -0
  114. package/dist/utils/sanitizer.js +60 -0
  115. package/dist/utils/sanitizer.js.map +1 -0
  116. package/docs/EXAMPLES.md +171 -0
  117. package/docs/PROFILES.md +423 -0
  118. package/docs/SECURITY.md +190 -0
  119. package/docs/TOOLS.md +366 -0
  120. package/manifest.json +74 -0
  121. package/package.json +89 -0
  122. package/scripts/build-exe.ps1 +37 -0
  123. package/scripts/manage-service.ps1 +112 -0
  124. package/server.json +23 -0
  125. package/winhelm.config.example.json +30 -0
@@ -0,0 +1,117 @@
1
+ import fs from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { sanitizeText } from "./sanitizer.js";
5
+ export class FileLogger {
6
+ static instance = null;
7
+ logDir;
8
+ maxRetentionDays = 7;
9
+ writeQueue = Promise.resolve();
10
+ constructor() {
11
+ this.logDir = path.resolve(process.cwd(), "logs");
12
+ }
13
+ static getInstance() {
14
+ if (!FileLogger.instance) {
15
+ FileLogger.instance = new FileLogger();
16
+ }
17
+ return FileLogger.instance;
18
+ }
19
+ getTodayLogFileName() {
20
+ const d = new Date();
21
+ const yyyy = d.getFullYear();
22
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
23
+ const dd = String(d.getDate()).padStart(2, "0");
24
+ return `winhelm-${yyyy}-${mm}-${dd}.log`;
25
+ }
26
+ /**
27
+ * Append log entry to persistent log file asynchronously
28
+ */
29
+ log(entry) {
30
+ // Chain writes to guarantee sequential, non-corrupting file writes
31
+ this.writeQueue = this.writeQueue
32
+ .then(async () => {
33
+ if (!existsSync(this.logDir)) {
34
+ await fs.mkdir(this.logDir, { recursive: true });
35
+ }
36
+ const fileName = this.getTodayLogFileName();
37
+ const filePath = path.join(this.logDir, fileName);
38
+ const sanitizedTitle = sanitizeText(entry.title);
39
+ const sanitizedDetail = entry.detail ? sanitizeText(entry.detail) : "";
40
+ const sanitizedEntry = {
41
+ ...entry,
42
+ title: sanitizedTitle,
43
+ detail: sanitizedDetail,
44
+ };
45
+ const line = JSON.stringify(sanitizedEntry) + "\n";
46
+ await fs.appendFile(filePath, line, "utf-8");
47
+ // Check if rotation or cleanup needed occasionally
48
+ if (Math.random() < 0.05) {
49
+ await this.cleanOldLogs();
50
+ }
51
+ })
52
+ .catch((err) => {
53
+ // Never throw from file logger to prevent crashing the server
54
+ console.error("[FileLogger] Error writing log file:", err.message);
55
+ });
56
+ }
57
+ /**
58
+ * Remove log files older than maxRetentionDays
59
+ */
60
+ async cleanOldLogs() {
61
+ try {
62
+ if (!existsSync(this.logDir))
63
+ return;
64
+ const files = await fs.readdir(this.logDir);
65
+ const now = Date.now();
66
+ const maxAgeMs = this.maxRetentionDays * 24 * 60 * 60 * 1000;
67
+ for (const file of files) {
68
+ if (file.endsWith(".log")) {
69
+ const fullPath = path.join(this.logDir, file);
70
+ const stat = await fs.stat(fullPath);
71
+ if (now - stat.mtimeMs > maxAgeMs) {
72
+ await fs.unlink(fullPath);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ catch {
78
+ // ignore cleanup errors
79
+ }
80
+ }
81
+ /**
82
+ * Export audit logs in JSON or CSV format
83
+ */
84
+ async exportLogs(format = "json") {
85
+ const todayFile = path.join(this.logDir, this.getTodayLogFileName());
86
+ let rawContent = "";
87
+ if (existsSync(todayFile)) {
88
+ rawContent = await fs.readFile(todayFile, "utf-8");
89
+ }
90
+ const lines = rawContent.split(/\r?\n/).filter(Boolean);
91
+ const entries = [];
92
+ for (const line of lines) {
93
+ try {
94
+ entries.push(JSON.parse(line));
95
+ }
96
+ catch {
97
+ // ignore parse error on bad line
98
+ }
99
+ }
100
+ if (format === "csv") {
101
+ const headers = ["Timestamp", "Type", "Level", "Title", "Status", "DurationMs", "Detail"];
102
+ const rows = entries.map((e) => [
103
+ `"${e.timestamp}"`,
104
+ `"${e.type}"`,
105
+ `"${e.level}"`,
106
+ `"${(e.title || "").replace(/"/g, '""')}"`,
107
+ `"${e.status ?? ""}"`,
108
+ e.durationMs ?? 0,
109
+ `"${(e.detail || "").replace(/"/g, '""')}"`,
110
+ ]);
111
+ return [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");
112
+ }
113
+ return JSON.stringify(entries, null, 2);
114
+ }
115
+ }
116
+ export const fileLogger = FileLogger.getInstance();
117
+ //# sourceMappingURL=file-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-logger.js","sourceRoot":"","sources":["../../src/utils/file-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ export interface LogEntry {
2
+ id: string;
3
+ timestamp: string;
4
+ type: "tool" | "req" | "security" | "system" | "error";
5
+ level: "info" | "warn" | "error" | "success";
6
+ title: string;
7
+ detail?: string;
8
+ durationMs?: number;
9
+ status?: string | number;
10
+ }
11
+ export declare class Logger {
12
+ private static instance;
13
+ private logs;
14
+ private readonly maxLogs;
15
+ private constructor();
16
+ static getInstance(): Logger;
17
+ private getFormattedTime;
18
+ private addLog;
19
+ getRecentLogs(limit?: number): LogEntry[];
20
+ clearLogs(): void;
21
+ /**
22
+ * Log incoming & completed HTTP requests
23
+ */
24
+ req(method: string, url: string, statusCode: number, durationMs: number, ip?: string, sessionId?: string): void;
25
+ /**
26
+ * Log tool invocation start
27
+ */
28
+ toolStart(name: string, args: Record<string, any>): void;
29
+ /**
30
+ * Log tool invocation success
31
+ */
32
+ toolDone(name: string, durationMs: number, summary?: string): void;
33
+ /**
34
+ * Log tool invocation failure
35
+ */
36
+ toolFail(name: string, durationMs: number, error: string): void;
37
+ /**
38
+ * Log security events (e.g. command blocked, path denied, unauthorized)
39
+ */
40
+ security(message: string, detail?: string): void;
41
+ /**
42
+ * General info message
43
+ */
44
+ info(message: string, detail?: string): void;
45
+ /**
46
+ * Error message
47
+ */
48
+ error(message: string, detail?: string): void;
49
+ }
50
+ export declare const logger: Logger;
51
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAkBD,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAuB;IAC9C,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAO;IAE/B,OAAO,eAAiB;IAExB,OAAc,WAAW,IAAI,MAAM,CAKlC;IAED,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,MAAM;IAqBP,aAAa,CAAC,KAAK,SAAM,GAAG,QAAQ,EAAE,CAE5C;IAEM,SAAS,IAAI,IAAI,CAEvB;IAED;;OAEG;IACI,GAAG,CACR,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,EAAE,SAAM,EACR,SAAS,CAAC,EAAE,MAAM,GACjB,IAAI,CA0BN;IAED;;OAEG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAwB9D;IAED;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAgBxE;IAED;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAcrE;IAED;;OAEG;IACI,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAatD;IAED;;OAEG;IACI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAYlD;IAED;;OAEG;IACI,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAYnD;CACF;AAED,eAAO,MAAM,MAAM,QAAuB,CAAC"}
@@ -0,0 +1,189 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { sanitizeText } from "./sanitizer.js";
3
+ import { fileLogger } from "./file-logger.js";
4
+ // ANSI Escape Codes for Terminal Colors
5
+ const C = {
6
+ reset: "\x1b[0m",
7
+ bold: "\x1b[1m",
8
+ dim: "\x1b[2m",
9
+ green: "\x1b[32m",
10
+ yellow: "\x1b[33m",
11
+ blue: "\x1b[34m",
12
+ magenta: "\x1b[35m",
13
+ cyan: "\x1b[36m",
14
+ red: "\x1b[31m",
15
+ gray: "\x1b[90m",
16
+ bgRed: "\x1b[41m",
17
+ bgGreen: "\x1b[42m",
18
+ };
19
+ export class Logger {
20
+ static instance = null;
21
+ logs = [];
22
+ maxLogs = 200;
23
+ constructor() { }
24
+ static getInstance() {
25
+ if (!Logger.instance) {
26
+ Logger.instance = new Logger();
27
+ }
28
+ return Logger.instance;
29
+ }
30
+ getFormattedTime() {
31
+ const d = new Date();
32
+ const pad = (n, s = 2) => String(n).padStart(s, "0");
33
+ const h = pad(d.getHours());
34
+ const m = pad(d.getMinutes());
35
+ const s = pad(d.getSeconds());
36
+ const ms = pad(d.getMilliseconds(), 3);
37
+ return `${h}:${m}:${s}.${ms}`;
38
+ }
39
+ addLog(entry) {
40
+ const cleanTitle = sanitizeText(entry.title);
41
+ const cleanDetail = entry.detail ? sanitizeText(entry.detail) : undefined;
42
+ const fullEntry = {
43
+ id: randomUUID(),
44
+ timestamp: new Date().toISOString(),
45
+ ...entry,
46
+ title: cleanTitle,
47
+ detail: cleanDetail,
48
+ };
49
+ this.logs.unshift(fullEntry);
50
+ if (this.logs.length > this.maxLogs) {
51
+ this.logs.pop();
52
+ }
53
+ // Persist to rotating disk log
54
+ fileLogger.log(fullEntry);
55
+ }
56
+ getRecentLogs(limit = 100) {
57
+ return this.logs.slice(0, limit);
58
+ }
59
+ clearLogs() {
60
+ this.logs = [];
61
+ }
62
+ /**
63
+ * Log incoming & completed HTTP requests
64
+ */
65
+ req(method, url, statusCode, durationMs, ip = "-", sessionId) {
66
+ const time = this.getFormattedTime();
67
+ let statusColor = C.green;
68
+ let level = "info";
69
+ if (statusCode >= 500) {
70
+ statusColor = C.red;
71
+ level = "error";
72
+ }
73
+ else if (statusCode >= 400) {
74
+ statusColor = C.yellow;
75
+ level = "warn";
76
+ }
77
+ const sessTag = sessionId ? `${C.gray}[sess:${sessionId.slice(0, 8)}]${C.reset} ` : "";
78
+ const cleanUrl = sanitizeText(url);
79
+ const line = `${C.gray}[${time}]${C.reset} ${C.cyan}[HTTP]${C.reset} ${C.bold}${method}${C.reset} ${cleanUrl} ${statusColor}${statusCode}${C.reset} ${C.dim}(${durationMs}ms)${C.reset} ${sessTag}${C.gray}${ip}${C.reset}`;
80
+ console.log(line);
81
+ this.addLog({
82
+ type: "req",
83
+ level,
84
+ title: `${method} ${url}`,
85
+ detail: `IP: ${ip}${sessionId ? ` | Session: ${sessionId}` : ""}`,
86
+ durationMs,
87
+ status: statusCode,
88
+ });
89
+ }
90
+ /**
91
+ * Log tool invocation start
92
+ */
93
+ toolStart(name, args) {
94
+ const time = this.getFormattedTime();
95
+ // Sanitize parameters so long content/base64 doesn't spam console
96
+ const cleanArgs = {};
97
+ for (const [key, val] of Object.entries(args || {})) {
98
+ if (typeof val === "string" && val.length > 80) {
99
+ cleanArgs[key] = val.slice(0, 77) + "...";
100
+ }
101
+ else {
102
+ cleanArgs[key] = val;
103
+ }
104
+ }
105
+ const preview = sanitizeText(JSON.stringify(cleanArgs));
106
+ console.log(`${C.gray}[${time}]${C.reset} ${C.magenta}[TOOL-START]${C.reset} ${C.bold}${name}${C.reset} ${C.dim}${preview}${C.reset}`);
107
+ this.addLog({
108
+ type: "tool",
109
+ level: "info",
110
+ title: `tool_call: ${name}`,
111
+ detail: preview,
112
+ status: "RUNNING",
113
+ });
114
+ }
115
+ /**
116
+ * Log tool invocation success
117
+ */
118
+ toolDone(name, durationMs, summary) {
119
+ const time = this.getFormattedTime();
120
+ const cleanSummary = summary ? sanitizeText(summary) : undefined;
121
+ const sum = cleanSummary ? ` ${C.dim}-> ${cleanSummary.slice(0, 90)}${cleanSummary.length > 90 ? "..." : ""}${C.reset}` : "";
122
+ console.log(`${C.gray}[${time}]${C.reset} ${C.green}[TOOL-DONE]${C.reset} ${C.bold}${name}${C.reset} ${C.green}✔ OK${C.reset} ${C.dim}(${durationMs}ms)${C.reset}${sum}`);
123
+ this.addLog({
124
+ type: "tool",
125
+ level: "success",
126
+ title: `tool_done: ${name}`,
127
+ detail: cleanSummary ? cleanSummary.slice(0, 150) : "Success",
128
+ durationMs,
129
+ status: "SUCCESS",
130
+ });
131
+ }
132
+ /**
133
+ * Log tool invocation failure
134
+ */
135
+ toolFail(name, durationMs, error) {
136
+ const time = this.getFormattedTime();
137
+ console.log(`${C.gray}[${time}]${C.reset} ${C.red}[TOOL-FAIL]${C.reset} ${C.bold}${name}${C.reset} ${C.red}✖ ERROR${C.reset} ${C.dim}(${durationMs}ms)${C.reset} ${C.red}${error}${C.reset}`);
138
+ this.addLog({
139
+ type: "tool",
140
+ level: "error",
141
+ title: `tool_fail: ${name}`,
142
+ detail: error,
143
+ durationMs,
144
+ status: "FAILED",
145
+ });
146
+ }
147
+ /**
148
+ * Log security events (e.g. command blocked, path denied, unauthorized)
149
+ */
150
+ security(message, detail) {
151
+ const time = this.getFormattedTime();
152
+ console.warn(`${C.gray}[${time}]${C.reset} ${C.yellow}${C.bold}[SECURITY]${C.reset} ${C.yellow}⚠️ ${message}${C.reset}${detail ? ` ${C.dim}(${detail})${C.reset}` : ""}`);
153
+ this.addLog({
154
+ type: "security",
155
+ level: "warn",
156
+ title: message,
157
+ detail,
158
+ status: "BLOCKED",
159
+ });
160
+ }
161
+ /**
162
+ * General info message
163
+ */
164
+ info(message, detail) {
165
+ const time = this.getFormattedTime();
166
+ console.log(`${C.gray}[${time}]${C.reset} ${C.blue}[INFO]${C.reset} ${message}${detail ? ` ${C.dim}${detail}${C.reset}` : ""}`);
167
+ this.addLog({
168
+ type: "system",
169
+ level: "info",
170
+ title: message,
171
+ detail,
172
+ });
173
+ }
174
+ /**
175
+ * Error message
176
+ */
177
+ error(message, detail) {
178
+ const time = this.getFormattedTime();
179
+ console.error(`${C.gray}[${time}]${C.reset} ${C.red}[ERROR]${C.reset} ${C.bold}${message}${C.reset}${detail ? ` ${C.dim}${detail}${C.reset}` : ""}`);
180
+ this.addLog({
181
+ type: "error",
182
+ level: "error",
183
+ title: message,
184
+ detail,
185
+ });
186
+ }
187
+ }
188
+ export const logger = Logger.getInstance();
189
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Secret & Credential Redaction Utility for WinCommander
3
+ * Automatically detects and masks sensitive keys, tokens, and credentials in logs and outputs.
4
+ */
5
+ /**
6
+ * Mask sensitive credentials within a text string
7
+ */
8
+ export declare function sanitizeText(text: string): string;
9
+ /**
10
+ * Deep-sanitize objects, payloads, or argument maps
11
+ */
12
+ export declare function sanitizeObject<T>(obj: T): T;
13
+ //# sourceMappingURL=sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsBjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAiC3C"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Secret & Credential Redaction Utility for WinCommander
3
+ * Automatically detects and masks sensitive keys, tokens, and credentials in logs and outputs.
4
+ */
5
+ /**
6
+ * Mask sensitive credentials within a text string
7
+ */
8
+ export function sanitizeText(text) {
9
+ if (!text || typeof text !== "string")
10
+ return text;
11
+ return text
12
+ // Bearer tokens
13
+ .replace(/(bearer\s+)([a-zA-Z0-9_\-\.]{8,})/gi, (_m, p, s) => `${p}${"*".repeat(Math.min(s.length, 12))}`)
14
+ // AWS Access Key ID (AKIA...)
15
+ .replace(/\b(AKIA)([0-9A-Z]{16})\b/g, (_m, p, s) => `${p}${"*".repeat(Math.min(s.length, 12))}`)
16
+ // API keys (sk-..., ghp_...)
17
+ .replace(/(sk-[a-zA-Z0-9_\-]{4})([a-zA-Z0-9_\-]+)/gi, (_m, p) => `${p}${"*".repeat(12)}`)
18
+ .replace(/(gh[pousr]_[a-zA-Z0-9]{4})([a-zA-Z0-9]+)/gi, (_m, p) => `${p}${"*".repeat(12)}`)
19
+ // JSON quoted keys like "authToken": "...", "password": "...", "x-api-key": "..."
20
+ .replace(/((\\")|["'])([\w\-]*?(?:token|password|passwd|secret|api[_-]?key|auth(?!(?:or|ors)\b))[\w\-]*?)\1(\s*:\s*)((\\")|["'])([^"'\r\n]+?)\5/gi, (_m, q1, _g2, k, colon, q2, _g5, v) => `${q1}${k}${q1}${colon}${q2}${"*".repeat(Math.min(v.length, 12))}${q2}`)
21
+ // Query/unquoted fields like password=xyz, token=xyz
22
+ .replace(/((?:token|api[_-]?key|secret|password|passwd|auth(?!(?:or|ors)\b))\s*[:=]\s*["']?)([^"'&\s]{4,})(["']?)/gi, (_m, p, s, suf) => `${p}${"*".repeat(Math.min(s.length, 12))}${suf}`)
23
+ // CLI flags e.g. --auth xyz
24
+ .replace(/(--(?:auth|token|password|secret)\s+)([^\s]{4,})/gi, (_m, p, s) => `${p}${"*".repeat(Math.min(s.length, 12))}`)
25
+ // Basic Auth in URLs
26
+ .replace(/(https?:\/\/[^:]+:)([^@]+)(@)/gi, (_m, p, _s, at) => `${p}********${at}`);
27
+ }
28
+ /**
29
+ * Deep-sanitize objects, payloads, or argument maps
30
+ */
31
+ export function sanitizeObject(obj) {
32
+ if (obj === null || obj === undefined)
33
+ return obj;
34
+ if (typeof obj === "string") {
35
+ return sanitizeText(obj);
36
+ }
37
+ if (Array.isArray(obj)) {
38
+ return obj.map((item) => sanitizeObject(item));
39
+ }
40
+ if (typeof obj === "object") {
41
+ const cleanObj = {};
42
+ for (const [key, val] of Object.entries(obj)) {
43
+ const lowerKey = key.toLowerCase();
44
+ if (lowerKey.includes("password") ||
45
+ lowerKey.includes("token") ||
46
+ lowerKey.includes("secret") ||
47
+ (lowerKey.includes("auth") && !lowerKey.includes("author")) ||
48
+ (lowerKey.includes("key") && !lowerKey.includes("keyboard"))) {
49
+ if (typeof val === "string") {
50
+ cleanObj[key] = "************";
51
+ continue;
52
+ }
53
+ }
54
+ cleanObj[key] = sanitizeObject(val);
55
+ }
56
+ return cleanObj;
57
+ }
58
+ return obj;
59
+ }
60
+ //# sourceMappingURL=sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../../src/utils/sanitizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,171 @@
1
+ # WinHelm MCP — Real-World Agent Workflows & Use Cases
2
+
3
+ This guide demonstrates concrete workflows for LLM coding agents (e.g. Claude Desktop, Cursor, Cline, Windsurf) using WinHelm tools across different profiles.
4
+
5
+ ---
6
+
7
+ ## Use Case 1: Autonomous Build, Test, and Self-Healing
8
+ **Recommended Profile:** `dev` (28 tools)
9
+
10
+ When an AI agent needs to compile a large project, monitor progress in the background, and fix build errors without blocking the conversation:
11
+
12
+ ### Step 1: Start background build task
13
+ The agent starts the build asynchronously:
14
+
15
+ **Tool:** `terminal_task_start`
16
+ ```json
17
+ {
18
+ "command": "npm run build",
19
+ "cwd": "D:\\Projects\\MyWebApp"
20
+ }
21
+ ```
22
+ *WinHelm returns Task ID `a4f891b2` immediately.*
23
+
24
+ ### Step 2: Poll live progress
25
+ The agent checks progress after 3 seconds:
26
+
27
+ **Tool:** `terminal_task_logs`
28
+ ```json
29
+ {
30
+ "task_id": "a4f891b2",
31
+ "tail_lines": 15
32
+ }
33
+ ```
34
+ *Output shows a TypeScript compilation error in `src/utils.ts:42`.*
35
+
36
+ ### Step 3: Surgically fix the code
37
+ The agent patches the specific line without touching adjacent lines:
38
+
39
+ **Tool:** `file_edit`
40
+ ```json
41
+ {
42
+ "path": "D:\\Projects\\MyWebApp\\src\\utils.ts",
43
+ "old_text": "const port = process.env.PORT || undefined;",
44
+ "new_text": "const port = Number(process.env.PORT) || 8080;"
45
+ }
46
+ ```
47
+
48
+ ### Step 4: Verify test passes
49
+ The agent executes the test suite synchronously:
50
+
51
+ **Tool:** `terminal_run`
52
+ ```json
53
+ {
54
+ "command": "npm test",
55
+ "cwd": "D:\\Projects\\MyWebApp"
56
+ }
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Use Case 2: System Health Inspection & Troubleshooting
62
+ **Recommended Profile:** `sysadmin` (37 tools)
63
+
64
+ When an AI agent is asked: *"Why is my Windows computer sluggish or why did my application crash?"*
65
+
66
+ ### Step 1: Check hardware utilization
67
+ **Tool:** `system_info`
68
+ ```json
69
+ {}
70
+ ```
71
+ *Returns CPU utilization %, RAM usage (Total/Used/Free), OS version, and allowed drive capacities.*
72
+
73
+ ### Step 2: Query GPU telemetry
74
+ **Tool:** `gpu_info`
75
+ ```json
76
+ {}
77
+ ```
78
+ *Returns NVIDIA GPU name, driver version, temperature, and VRAM utilization.*
79
+
80
+ ### Step 3: Identify resource-heavy processes
81
+ **Tool:** `process_list`
82
+ ```json
83
+ {
84
+ "sort_by": "memory",
85
+ "limit": 10
86
+ }
87
+ ```
88
+ *Returns top 10 processes sorted by RAM usage.*
89
+
90
+ ### Step 4: Query Windows Event Log for crashes
91
+ **Tool:** `eventlog_query`
92
+ ```json
93
+ {
94
+ "log_name": "Application",
95
+ "level": "Error",
96
+ "limit": 5
97
+ }
98
+ ```
99
+ *Identifies exact exception codes, faulted module names, and crash timestamps.*
100
+
101
+ ### Step 5: Notify the developer
102
+ **Tool:** `notification_send`
103
+ ```json
104
+ {
105
+ "title": "WinHelm Diagnostic Complete",
106
+ "message": "Found memory leak in rogue node.exe process (PID 4120). Recommending process_kill.",
107
+ "sound": true
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Use Case 3: Code Search & Automated PDF Report
114
+ **Recommended Profile:** `dev` (28 tools) or `full` (38 tools)
115
+
116
+ When an agent performs an audit and generates a client-ready PDF document:
117
+
118
+ ### Step 1: High-speed code search across project
119
+ **Tool:** `file_search_ripgrep`
120
+ ```json
121
+ {
122
+ "query": "TODO|FIXME|SECURITY",
123
+ "path": "D:\\mcp\\winhelm-mcp",
124
+ "page_size": 20
125
+ }
126
+ ```
127
+
128
+ ### Step 2: Write markdown report
129
+ **Tool:** `file_write`
130
+ ```json
131
+ {
132
+ "path": "D:\\AuditReport.md",
133
+ "content": "# Codebase Audit Report\n\nFound 3 unresolved TODOs in codebase..."
134
+ }
135
+ ```
136
+
137
+ ### Step 3: Compile report to PDF using native Chromium
138
+ **Tool:** `pdf_generate`
139
+ ```json
140
+ {
141
+ "source_path": "D:\\AuditReport.md",
142
+ "pdf_path": "D:\\AuditReport.pdf",
143
+ "title": "Security & Code Audit Report"
144
+ }
145
+ ```
146
+ *Generates formatted, print-ready PDF using headless Microsoft Edge or Google Chrome.*
147
+
148
+ ---
149
+
150
+ ## Use Case 4: Safe File Operations & Archival
151
+ **Recommended Profile:** `dev` (28 tools) or `core` (15 tools)
152
+
153
+ Safe file management that avoids accidental permanent loss:
154
+
155
+ ### Step 1: Zip backup before modifying
156
+ **Tool:** `archive_zip`
157
+ ```json
158
+ {
159
+ "source_dir": "D:\\Projects\\ImportantData",
160
+ "zip_path": "D:\\Backups\\ImportantData-2026-09-27.zip"
161
+ }
162
+ ```
163
+
164
+ ### Step 2: Recycle old temporary files (safe delete)
165
+ **Tool:** `file_delete_safe`
166
+ ```json
167
+ {
168
+ "path": "D:\\Projects\\TempCache"
169
+ }
170
+ ```
171
+ *Item is moved to Windows Recycle Bin where it can be restored if needed.*