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,50 @@
|
|
|
1
|
+
import type { ServerConfig } from "../types/index.js";
|
|
2
|
+
export interface CommandLogEntry {
|
|
3
|
+
id: string;
|
|
4
|
+
timestamp: string;
|
|
5
|
+
command: string;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
exitCode: number;
|
|
8
|
+
durationMs: number;
|
|
9
|
+
timedOut: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function isWildcardAllowAll(dirs: string[] | undefined): boolean;
|
|
12
|
+
export declare class ConfigManager {
|
|
13
|
+
private static instance;
|
|
14
|
+
private config;
|
|
15
|
+
private configFilePath;
|
|
16
|
+
private executionHistory;
|
|
17
|
+
private readonly maxHistoryLength;
|
|
18
|
+
private constructor();
|
|
19
|
+
private loadConfigSync;
|
|
20
|
+
static getInstance(customConfigPath?: string): ConfigManager;
|
|
21
|
+
static resetInstance(customConfigPath?: string): ConfigManager;
|
|
22
|
+
getConfigFilePath(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Initialize config by reading from file, custom path, or in-memory override object
|
|
25
|
+
*/
|
|
26
|
+
init(configOrPath?: string | Partial<ServerConfig>): Promise<void>;
|
|
27
|
+
isReadOnly(): boolean;
|
|
28
|
+
getConfig(): Readonly<ServerConfig>;
|
|
29
|
+
updateConfig(updates: Partial<ServerConfig>, persist?: boolean): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Validate if a command is allowed to run
|
|
32
|
+
*/
|
|
33
|
+
isCommandAllowed(command: string): {
|
|
34
|
+
allowed: boolean;
|
|
35
|
+
reason?: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Validate if a filesystem path is permitted under allowedDirectories
|
|
39
|
+
*/
|
|
40
|
+
isPathAllowed(targetPath: string): {
|
|
41
|
+
allowed: boolean;
|
|
42
|
+
reason?: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Record command execution for auditing
|
|
46
|
+
*/
|
|
47
|
+
logExecution(entry: CommandLogEntry): void;
|
|
48
|
+
getHistory(): ReadonlyArray<CommandLogEntry>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=config-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAMtE;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAO;IAExC,OAAO,eA8BN;IAED,OAAO,CAAC,cAAc;IAkBtB,OAAc,WAAW,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,aAAa,CAOlE;IAED,OAAc,aAAa,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,aAAa,CAGpE;IAEM,iBAAiB,IAAI,MAAM,CAEjC;IAED;;OAEG;IACU,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyD9E;IAEM,UAAU,IAAI,OAAO,CAE3B;IAEM,SAAS,IAAI,QAAQ,CAAC,YAAY,CAAC,CAEzC;IAEY,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAYxF;IAED;;OAEG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAmD9E;IAED;;OAEG;IACI,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAuE9E;IAED;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAKhD;IAEM,UAAU,IAAI,aAAa,CAAC,eAAe,CAAC,CAElD;CACF"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { existsSync, realpathSync, readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import { DEFAULT_CONFIG, DEFAULT_BLOCKED_PATTERNS } from "./default-config.js";
|
|
6
|
+
export function isWildcardAllowAll(dirs) {
|
|
7
|
+
if (!dirs || dirs.length === 0)
|
|
8
|
+
return false;
|
|
9
|
+
return dirs.some((d) => {
|
|
10
|
+
const trimmed = d.trim().toLowerCase();
|
|
11
|
+
return trimmed === "*" || trimmed === "all";
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export class ConfigManager {
|
|
15
|
+
static instance = null;
|
|
16
|
+
config;
|
|
17
|
+
configFilePath;
|
|
18
|
+
executionHistory = [];
|
|
19
|
+
maxHistoryLength = 500;
|
|
20
|
+
constructor(customConfigPath) {
|
|
21
|
+
this.config = { ...DEFAULT_CONFIG };
|
|
22
|
+
if (customConfigPath) {
|
|
23
|
+
this.configFilePath = path.resolve(customConfigPath);
|
|
24
|
+
this.loadConfigSync();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Check multiple candidate locations so external MCP clients (Claude/Cursor) find it regardless of CWD
|
|
28
|
+
const candidates = [
|
|
29
|
+
path.resolve(process.cwd(), "winhelm.config.json"),
|
|
30
|
+
path.resolve(process.cwd(), "win-commander.config.json"),
|
|
31
|
+
process.argv[1] ? path.resolve(path.dirname(process.argv[1]), "..", "winhelm.config.json") : "",
|
|
32
|
+
process.argv[1] ? path.resolve(path.dirname(process.argv[1]), "winhelm.config.json") : "",
|
|
33
|
+
process.execPath ? path.resolve(path.dirname(process.execPath), "..", "winhelm.config.json") : "",
|
|
34
|
+
process.execPath ? path.resolve(path.dirname(process.execPath), "winhelm.config.json") : "",
|
|
35
|
+
path.join(os.homedir(), ".winhelm", "config.json"),
|
|
36
|
+
path.join(os.homedir(), ".win-commander", "config.json"),
|
|
37
|
+
].filter(Boolean);
|
|
38
|
+
let chosen = candidates[0];
|
|
39
|
+
for (const c of candidates) {
|
|
40
|
+
if (existsSync(c)) {
|
|
41
|
+
chosen = c;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
this.configFilePath = chosen;
|
|
46
|
+
this.loadConfigSync();
|
|
47
|
+
}
|
|
48
|
+
loadConfigSync() {
|
|
49
|
+
if (this.configFilePath && existsSync(this.configFilePath)) {
|
|
50
|
+
try {
|
|
51
|
+
const raw = readFileSync(this.configFilePath, "utf-8");
|
|
52
|
+
const cleanRaw = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
|
|
53
|
+
if (!cleanRaw.trim())
|
|
54
|
+
return;
|
|
55
|
+
const parsed = JSON.parse(cleanRaw);
|
|
56
|
+
this.config = {
|
|
57
|
+
...this.config,
|
|
58
|
+
...parsed,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error(`[ConfigManager] FATAL: Syntax error in configuration file (${this.configFilePath}):`, err.message);
|
|
63
|
+
throw new Error(`Failed to parse configuration file (${this.configFilePath}): ${err.message}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
static getInstance(customConfigPath) {
|
|
68
|
+
if (!ConfigManager.instance) {
|
|
69
|
+
ConfigManager.instance = new ConfigManager(customConfigPath);
|
|
70
|
+
}
|
|
71
|
+
else if (customConfigPath && ConfigManager.instance.configFilePath !== path.resolve(customConfigPath)) {
|
|
72
|
+
ConfigManager.instance = new ConfigManager(customConfigPath);
|
|
73
|
+
}
|
|
74
|
+
return ConfigManager.instance;
|
|
75
|
+
}
|
|
76
|
+
static resetInstance(customConfigPath) {
|
|
77
|
+
ConfigManager.instance = new ConfigManager(customConfigPath);
|
|
78
|
+
return ConfigManager.instance;
|
|
79
|
+
}
|
|
80
|
+
getConfigFilePath() {
|
|
81
|
+
return this.configFilePath;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initialize config by reading from file, custom path, or in-memory override object
|
|
85
|
+
*/
|
|
86
|
+
async init(configOrPath) {
|
|
87
|
+
if (configOrPath && typeof configOrPath === "object") {
|
|
88
|
+
this.config = {
|
|
89
|
+
...this.config,
|
|
90
|
+
...configOrPath,
|
|
91
|
+
};
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof configOrPath === "string") {
|
|
95
|
+
this.configFilePath = path.resolve(configOrPath);
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
if (existsSync(this.configFilePath)) {
|
|
99
|
+
const raw = await fs.readFile(this.configFilePath, "utf-8");
|
|
100
|
+
const cleanRaw = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
|
|
101
|
+
if (cleanRaw.trim()) {
|
|
102
|
+
const parsed = JSON.parse(cleanRaw);
|
|
103
|
+
this.config = {
|
|
104
|
+
...this.config,
|
|
105
|
+
...parsed,
|
|
106
|
+
};
|
|
107
|
+
console.log(`[ConfigManager] Loaded configuration from ${this.configFilePath}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (typeof configOrPath === "string") {
|
|
111
|
+
console.warn(`[ConfigManager] Specified config file not found: ${this.configFilePath}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
console.error(`[ConfigManager] FATAL: Could not read config file (${this.configFilePath}):`, err.message);
|
|
116
|
+
throw new Error(`Failed to load configuration file (${this.configFilePath}): ${err.message}`);
|
|
117
|
+
}
|
|
118
|
+
// Apply environment variables overrides
|
|
119
|
+
if (process.env.MCP_AUTH_TOKEN) {
|
|
120
|
+
this.config.authToken = process.env.MCP_AUTH_TOKEN;
|
|
121
|
+
}
|
|
122
|
+
if (process.env.MCP_ALLOWED_DIRECTORIES) {
|
|
123
|
+
this.config.allowedDirectories = process.env.MCP_ALLOWED_DIRECTORIES.split(",")
|
|
124
|
+
.map((p) => p.trim())
|
|
125
|
+
.filter(Boolean);
|
|
126
|
+
}
|
|
127
|
+
if (process.env.MCP_BLOCKED_COMMANDS) {
|
|
128
|
+
const extraBlocked = process.env.MCP_BLOCKED_COMMANDS.split(",")
|
|
129
|
+
.map((c) => c.trim().toLowerCase())
|
|
130
|
+
.filter(Boolean);
|
|
131
|
+
this.config.blockedCommands = Array.from(new Set([...this.config.blockedCommands, ...extraBlocked]));
|
|
132
|
+
}
|
|
133
|
+
if (process.env.MCP_ALLOWED_HOSTS) {
|
|
134
|
+
const extraHosts = process.env.MCP_ALLOWED_HOSTS.split(",")
|
|
135
|
+
.map((h) => h.trim().toLowerCase())
|
|
136
|
+
.filter(Boolean);
|
|
137
|
+
const existing = this.config.allowedHosts || [];
|
|
138
|
+
this.config.allowedHosts = Array.from(new Set([...existing, ...extraHosts]));
|
|
139
|
+
}
|
|
140
|
+
if (process.env.MCP_READ_ONLY === "true" || process.env.MCP_READ_ONLY === "1") {
|
|
141
|
+
this.config.readOnly = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
isReadOnly() {
|
|
145
|
+
return !!this.config.readOnly;
|
|
146
|
+
}
|
|
147
|
+
getConfig() {
|
|
148
|
+
return this.config;
|
|
149
|
+
}
|
|
150
|
+
async updateConfig(updates, persist = false) {
|
|
151
|
+
this.config = { ...this.config, ...updates };
|
|
152
|
+
if (!persist)
|
|
153
|
+
return;
|
|
154
|
+
try {
|
|
155
|
+
const dir = path.dirname(this.configFilePath);
|
|
156
|
+
if (!existsSync(dir)) {
|
|
157
|
+
await fs.mkdir(dir, { recursive: true });
|
|
158
|
+
}
|
|
159
|
+
await fs.writeFile(this.configFilePath, JSON.stringify(this.config, null, 2), "utf-8");
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
console.error(`[ConfigManager] Failed to persist config to ${this.configFilePath}:`, err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Validate if a command is allowed to run
|
|
167
|
+
*/
|
|
168
|
+
isCommandAllowed(command) {
|
|
169
|
+
const normalized = command.trim().toLowerCase();
|
|
170
|
+
for (const blocked of this.config.blockedCommands) {
|
|
171
|
+
if (normalized.includes(blocked.toLowerCase())) {
|
|
172
|
+
return {
|
|
173
|
+
allowed: false,
|
|
174
|
+
reason: `Command execution blocked by security policy: matches blocked pattern "${blocked}"`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Check regex blocked patterns
|
|
179
|
+
const patterns = this.config.blockedCommandPatterns || DEFAULT_BLOCKED_PATTERNS;
|
|
180
|
+
for (const pattern of patterns) {
|
|
181
|
+
try {
|
|
182
|
+
const regex = new RegExp(pattern, "i");
|
|
183
|
+
if (regex.test(command)) {
|
|
184
|
+
return {
|
|
185
|
+
allowed: false,
|
|
186
|
+
reason: `Command execution blocked by security policy: matches dangerous pattern "${pattern}"`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// ignore invalid custom regex pattern
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// If allowSystemExecution is explicitly false, strictly block referencing unallowed drives in commands
|
|
195
|
+
if (this.config.allowSystemExecution === false) {
|
|
196
|
+
if (this.config.allowedDirectories &&
|
|
197
|
+
this.config.allowedDirectories.length > 0 &&
|
|
198
|
+
!isWildcardAllowAll(this.config.allowedDirectories)) {
|
|
199
|
+
const driveMatches = command.match(/\b([a-zA-Z]):(?=[\\/\s"']|$)/g);
|
|
200
|
+
if (driveMatches) {
|
|
201
|
+
for (const match of driveMatches) {
|
|
202
|
+
const driveLetter = match[0].toUpperCase() + ":\\";
|
|
203
|
+
const check = this.isPathAllowed(driveLetter);
|
|
204
|
+
if (!check.allowed) {
|
|
205
|
+
return {
|
|
206
|
+
allowed: false,
|
|
207
|
+
reason: `Command execution blocked: references forbidden drive "${match}" outside allowedDirectories (${this.config.allowedDirectories.join(", ")})`,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return { allowed: true };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate if a filesystem path is permitted under allowedDirectories
|
|
218
|
+
*/
|
|
219
|
+
isPathAllowed(targetPath) {
|
|
220
|
+
if (isWildcardAllowAll(this.config.allowedDirectories)) {
|
|
221
|
+
return { allowed: true };
|
|
222
|
+
}
|
|
223
|
+
if (!this.config.allowedDirectories || this.config.allowedDirectories.length === 0) {
|
|
224
|
+
return {
|
|
225
|
+
allowed: false,
|
|
226
|
+
reason: `Access to path "${targetPath}" is blocked: no allowedDirectories configured. Set allowedDirectories to specific paths, or ["*"] to allow all (not recommended for public exposure).`,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
let resolvedTarget = path.resolve(targetPath);
|
|
230
|
+
// Resolve symlinks / junctions to prevent directory traversal escapes
|
|
231
|
+
try {
|
|
232
|
+
if (existsSync(resolvedTarget)) {
|
|
233
|
+
resolvedTarget = realpathSync(resolvedTarget);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// If file doesn't exist yet, resolve the nearest existing parent directory
|
|
237
|
+
let cur = path.dirname(resolvedTarget);
|
|
238
|
+
while (cur && !existsSync(cur)) {
|
|
239
|
+
const parent = path.dirname(cur);
|
|
240
|
+
if (parent === cur)
|
|
241
|
+
break;
|
|
242
|
+
cur = parent;
|
|
243
|
+
}
|
|
244
|
+
if (existsSync(cur)) {
|
|
245
|
+
const realCur = realpathSync(cur);
|
|
246
|
+
const rel = path.relative(cur, resolvedTarget);
|
|
247
|
+
resolvedTarget = path.resolve(realCur, rel);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// fallback to path.resolve if realpath fails
|
|
253
|
+
}
|
|
254
|
+
const normTarget = resolvedTarget.toLowerCase();
|
|
255
|
+
const targetWithSep = normTarget.endsWith(path.sep)
|
|
256
|
+
? normTarget
|
|
257
|
+
: normTarget + path.sep;
|
|
258
|
+
const isAllowed = this.config.allowedDirectories.some((dir) => {
|
|
259
|
+
let cleanDir = dir.trim();
|
|
260
|
+
// Handle drive letter variations e.g. "D:", "D", "d:\", "d:/"
|
|
261
|
+
if (/^[a-zA-Z]:?[\\/]?$/.test(cleanDir)) {
|
|
262
|
+
cleanDir = cleanDir[0].toUpperCase() + ":\\";
|
|
263
|
+
}
|
|
264
|
+
let resolvedDir = path.resolve(cleanDir);
|
|
265
|
+
try {
|
|
266
|
+
if (existsSync(resolvedDir)) {
|
|
267
|
+
resolvedDir = realpathSync(resolvedDir);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// fallback
|
|
272
|
+
}
|
|
273
|
+
let normDir = resolvedDir.toLowerCase();
|
|
274
|
+
if (!normDir.endsWith(path.sep)) {
|
|
275
|
+
normDir += path.sep;
|
|
276
|
+
}
|
|
277
|
+
return targetWithSep.startsWith(normDir) || normTarget === normDir.slice(0, -1);
|
|
278
|
+
});
|
|
279
|
+
if (!isAllowed) {
|
|
280
|
+
return {
|
|
281
|
+
allowed: false,
|
|
282
|
+
reason: `Access to path "${targetPath}" is forbidden by allowedDirectories policy. Allowed roots: ${this.config.allowedDirectories.join(", ")}`,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
return { allowed: true };
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Record command execution for auditing
|
|
289
|
+
*/
|
|
290
|
+
logExecution(entry) {
|
|
291
|
+
this.executionHistory.push(entry);
|
|
292
|
+
if (this.executionHistory.length > this.maxHistoryLength) {
|
|
293
|
+
this.executionHistory.shift();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
getHistory() {
|
|
297
|
+
return this.executionHistory;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=config-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAY/E,MAAM,UAAU,kBAAkB,CAAC,IAA0B;IAC3D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvC,OAAO,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,KAAK,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAyB,IAAI,CAAC;IAC7C,MAAM,CAAe;IACrB,cAAc,CAAS;IACvB,gBAAgB,GAAsB,EAAE,CAAC;IAChC,gBAAgB,GAAG,GAAG,CAAC;IAExC,YAAoB,gBAAyB;QAC3C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;QAEpC,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACrD,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,uGAAuG;QACvG,MAAM,UAAU,GAAG;YACjB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAqB,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,2BAA2B,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE;YAC/F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE;YACzF,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE;YACjG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE;YAC3F,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,EAAE,aAAa,CAAC;SACzD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAElB,IAAI,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClB,MAAM,GAAG,CAAC,CAAC;gBACX,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;QAC7B,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAEO,cAAc;QACpB,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBACnE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;oBAAE,OAAO;gBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACpC,IAAI,CAAC,MAAM,GAAG;oBACZ,GAAG,IAAI,CAAC,MAAM;oBACd,GAAG,MAAM;iBACV,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,8DAA8D,IAAI,CAAC,cAAc,IAAI,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;gBAC7H,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,CAAC,cAAc,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5G,CAAC;QACH,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,gBAAyB;QACjD,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC5B,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,gBAAgB,IAAI,aAAa,CAAC,QAAQ,CAAC,cAAc,KAAK,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACxG,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,aAAa,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,MAAM,CAAC,aAAa,CAAC,gBAAyB;QACnD,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC7D,OAAO,aAAa,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,iBAAiB;QACtB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAAC,YAA6C;QAC7D,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrD,IAAI,CAAC,MAAM,GAAG;gBACZ,GAAG,IAAI,CAAC,MAAM;gBACd,GAAG,YAAY;aAChB,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBACnE,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;oBACpB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACpC,IAAI,CAAC,MAAM,GAAG;wBACZ,GAAG,IAAI,CAAC,MAAM;wBACd,GAAG,MAAM;qBACV,CAAC;oBACF,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;gBAClF,CAAC;YACH,CAAC;iBAAM,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,oDAAoD,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,sDAAsD,IAAI,CAAC,cAAc,IAAI,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;YACrH,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,CAAC,cAAc,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3G,CAAC;QAED,wCAAwC;QACxC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACrD,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,CAAC,GAAG,CAAC;iBAC5E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC;iBAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;iBAClC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QACvG,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC;iBACxD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;iBAClC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,EAAE,CAAC;YAC9E,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC9B,CAAC;IACH,CAAC;IAEM,UAAU;QACf,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,OAA8B,EAAE,OAAO,GAAG,KAAK;QACvE,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3C,CAAC;YACD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACzF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,+CAA+C,IAAI,CAAC,cAAc,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,OAAe;QACrC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAChD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAClD,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAC/C,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,0EAA0E,OAAO,GAAG;iBAC7F,CAAC;YACJ,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,sBAAsB,IAAI,wBAAwB,CAAC;QAChF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACvC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBACxB,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,MAAM,EAAE,4EAA4E,OAAO,GAAG;qBAC/F,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,sCAAsC;YACxC,CAAC;QACH,CAAC;QAED,uGAAuG;QACvG,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,KAAK,KAAK,EAAE,CAAC;YAC/C,IACE,IAAI,CAAC,MAAM,CAAC,kBAAkB;gBAC9B,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;gBACzC,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EACnD,CAAC;gBACD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACpE,IAAI,YAAY,EAAE,CAAC;oBACjB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;wBACjC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC;wBACnD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;wBAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;4BACnB,OAAO;gCACL,OAAO,EAAE,KAAK;gCACd,MAAM,EAAE,0DAA0D,KAAK,iCAAiC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;6BACrJ,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,UAAkB;QACrC,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnF,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,mBAAmB,UAAU,wJAAwJ;aAC9L,CAAC;QACJ,CAAC;QAED,IAAI,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,sEAAsE;QACtE,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC/B,cAAc,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,2EAA2E;gBAC3E,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBACvC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBACjC,IAAI,MAAM,KAAK,GAAG;wBAAE,MAAM;oBAC1B,GAAG,GAAG,MAAM,CAAC;gBACf,CAAC;gBACD,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;oBAClC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;oBAC/C,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,6CAA6C;QAC/C,CAAC;QAED,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC;QAChD,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;YACjD,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YAC5D,IAAI,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YAC1B,8DAA8D;YAC9D,IAAI,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACxC,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC;YAC/C,CAAC;YAED,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC;gBACH,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC5B,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,WAAW;YACb,CAAC;YAED,IAAI,OAAO,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC;YACtB,CAAC;YAED,OAAO,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,mBAAmB,UAAU,+DAA+D,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aAChJ,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,KAAsB;QACxC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACzD,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAEM,UAAU;QACf,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-config.d.ts","sourceRoot":"","sources":["../../src/config/default-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAmB5C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,YA0B5B,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const DEFAULT_BLOCKED_PATTERNS = [
|
|
2
|
+
"\\bdiskpart(\\b|\\.exe)",
|
|
3
|
+
"\\binitialize-disk\\b",
|
|
4
|
+
"\\bclear-disk\\b",
|
|
5
|
+
"\\bformat-volume\\b",
|
|
6
|
+
"\\bformat-disk\\b",
|
|
7
|
+
"\\breg(\\s+|\\.exe\\s+)delete\\s+hklm",
|
|
8
|
+
"\\bbcdedit(\\b|\\.exe)",
|
|
9
|
+
"\\bbootrec(\\b|\\.exe)",
|
|
10
|
+
"\\bnet(\\s+|\\.exe\\s+)user\\s+.*\\/add",
|
|
11
|
+
"\\btakeown(\\s+|\\.exe\\s+).*(/f|-f)",
|
|
12
|
+
"\\bicacls(\\s+|\\.exe\\s+).*(\\/grant|-grant)",
|
|
13
|
+
"\\bmimikatz",
|
|
14
|
+
"\\bprocdump.*lsass",
|
|
15
|
+
"comsvcs\\.dll",
|
|
16
|
+
"\\bformat(\\s+|\\.com\\s+)[a-zA-Z]:",
|
|
17
|
+
"\\brmdir(\\s+|\\.exe\\s+).*[\\/\\-]s",
|
|
18
|
+
"\\bdel(\\s+|\\.exe\\s+).*[\\/\\-]s.*[\\/\\-]q.*[a-zA-Z]:\\\\",
|
|
19
|
+
"\\bremove-item\\b.*-recurse.*-force.*[a-zA-Z]:\\\\",
|
|
20
|
+
];
|
|
21
|
+
export const DEFAULT_CONFIG = {
|
|
22
|
+
blockedCommands: [
|
|
23
|
+
"format-volume",
|
|
24
|
+
"format-disk",
|
|
25
|
+
"clear-disk",
|
|
26
|
+
"stop-computer",
|
|
27
|
+
"restart-computer",
|
|
28
|
+
"rmdir /s /q c:\\",
|
|
29
|
+
"del /f /s /q c:\\",
|
|
30
|
+
"remove-item -recurse -force c:\\",
|
|
31
|
+
],
|
|
32
|
+
blockedCommandPatterns: [...DEFAULT_BLOCKED_PATTERNS],
|
|
33
|
+
allowedDirectories: [], // Empty means BLOCKED by default (fail-closed). Use ["*"] or ["all"] to allow full access.
|
|
34
|
+
allowSystemExecution: true, // Allows invoking runtimes on C: (Python/Node/Git) while restricting workspace file writes
|
|
35
|
+
fileReadLineLimit: 2000,
|
|
36
|
+
defaultTimeoutMs: 60000,
|
|
37
|
+
telemetryEnabled: false,
|
|
38
|
+
authToken: null,
|
|
39
|
+
readOnly: false,
|
|
40
|
+
rateLimitPerMinute: 120,
|
|
41
|
+
profile: "full",
|
|
42
|
+
allowedHosts: ["localhost", "127.0.0.1", "[::1]", "*.ts.net"],
|
|
43
|
+
searchExcludeDirs: ["dist", "logs", "build", "out"],
|
|
44
|
+
preferPwsh: true,
|
|
45
|
+
sessionIdleTimeoutMs: 45 * 60 * 1000,
|
|
46
|
+
maxConcurrentSessions: 100,
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=default-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-config.js","sourceRoot":"","sources":["../../src/config/default-config.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAa;IAChD,yBAAyB;IACzB,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,mBAAmB;IACnB,uCAAuC;IACvC,wBAAwB;IACxB,wBAAwB;IACxB,yCAAyC;IACzC,sCAAsC;IACtC,+CAA+C;IAC/C,aAAa;IACb,oBAAoB;IACpB,eAAe;IACf,qCAAqC;IACrC,sCAAsC;IACtC,8DAA8D;IAC9D,oDAAoD;CACrD,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,eAAe,EAAE;QACf,eAAe;QACf,aAAa;QACb,YAAY;QACZ,eAAe;QACf,kBAAkB;QAClB,kBAAkB;QAClB,mBAAmB;QACnB,kCAAkC;KACnC;IACD,sBAAsB,EAAE,CAAC,GAAG,wBAAwB,CAAC;IACrD,kBAAkB,EAAE,EAAE,EAAE,2FAA2F;IACnH,oBAAoB,EAAE,IAAI,EAAE,2FAA2F;IACvH,iBAAiB,EAAE,IAAI;IACvB,gBAAgB,EAAE,KAAK;IACvB,gBAAgB,EAAE,KAAK;IACvB,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,KAAK;IACf,kBAAkB,EAAE,GAAG;IACvB,OAAO,EAAE,MAAM;IACf,YAAY,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC;IAC7D,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IACnD,UAAU,EAAE,IAAI;IAChB,oBAAoB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACpC,qBAAqB,EAAE,GAAG;CAC3B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WinHelm Tool Profiles
|
|
3
|
+
* Allows AI agents to load only required tools to optimize context window and tokens
|
|
4
|
+
*/
|
|
5
|
+
export type ToolProfile = "full" | "core" | "dev" | "sysadmin" | "minimal" | "custom";
|
|
6
|
+
export interface ProfileDefinition {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
tools: string[];
|
|
10
|
+
includesResource: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const PROFILES: Record<ToolProfile, ProfileDefinition>;
|
|
13
|
+
export declare function resolveCustomTools(baseProfile?: ToolProfile, toolsArg?: string, configCustomTools?: string[]): string[] | undefined;
|
|
14
|
+
export declare function isToolInProfile(toolName: string, profile?: ToolProfile, customTools?: string[]): boolean;
|
|
15
|
+
export declare function isValidProfile(profile: string): profile is ToolProfile;
|
|
16
|
+
//# sourceMappingURL=profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAsK3D,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,WAAW,GAAE,WAAoB,EACjC,QAAQ,CAAC,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAC3B,MAAM,EAAE,GAAG,SAAS,CA0BtB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAoB,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAMhH;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,WAAW,CAEtE"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WinHelm Tool Profiles
|
|
3
|
+
* Allows AI agents to load only required tools to optimize context window and tokens
|
|
4
|
+
*/
|
|
5
|
+
export const PROFILES = {
|
|
6
|
+
minimal: {
|
|
7
|
+
name: "Minimal",
|
|
8
|
+
description: "6 essential tools for small models (Claude Haiku, Llama 8B, local LLMs) with ~85% token reduction",
|
|
9
|
+
tools: [
|
|
10
|
+
"terminal_run",
|
|
11
|
+
"file_read",
|
|
12
|
+
"file_write",
|
|
13
|
+
"file_list",
|
|
14
|
+
"file_search",
|
|
15
|
+
"system_info",
|
|
16
|
+
],
|
|
17
|
+
includesResource: false,
|
|
18
|
+
},
|
|
19
|
+
core: {
|
|
20
|
+
name: "Core",
|
|
21
|
+
description: "15 essential tools for daily coding and file operations",
|
|
22
|
+
tools: [
|
|
23
|
+
"terminal_run",
|
|
24
|
+
"file_read",
|
|
25
|
+
"file_write",
|
|
26
|
+
"file_edit",
|
|
27
|
+
"file_list",
|
|
28
|
+
"file_search",
|
|
29
|
+
"file_copy",
|
|
30
|
+
"file_move",
|
|
31
|
+
"file_tail",
|
|
32
|
+
"file_hash",
|
|
33
|
+
"file_delete_safe",
|
|
34
|
+
"system_info",
|
|
35
|
+
"gpu_info",
|
|
36
|
+
"process_list",
|
|
37
|
+
"port_check",
|
|
38
|
+
],
|
|
39
|
+
includesResource: false,
|
|
40
|
+
},
|
|
41
|
+
dev: {
|
|
42
|
+
name: "Developer",
|
|
43
|
+
description: "28 tools for software engineering, background tasks, ripgrep, archives, HTTP API testing, PDF reports, and previews",
|
|
44
|
+
tools: [
|
|
45
|
+
"terminal_run",
|
|
46
|
+
"file_read",
|
|
47
|
+
"file_write",
|
|
48
|
+
"file_edit",
|
|
49
|
+
"file_list",
|
|
50
|
+
"file_search",
|
|
51
|
+
"file_copy",
|
|
52
|
+
"file_move",
|
|
53
|
+
"file_tail",
|
|
54
|
+
"file_hash",
|
|
55
|
+
"file_delete_safe",
|
|
56
|
+
"system_info",
|
|
57
|
+
"gpu_info",
|
|
58
|
+
"process_list",
|
|
59
|
+
"port_check",
|
|
60
|
+
"terminal_task_start",
|
|
61
|
+
"terminal_task_list",
|
|
62
|
+
"terminal_task_logs",
|
|
63
|
+
"terminal_task_send",
|
|
64
|
+
"terminal_task_kill",
|
|
65
|
+
"file_search_ripgrep",
|
|
66
|
+
"archive_zip",
|
|
67
|
+
"archive_unzip",
|
|
68
|
+
"http_ping",
|
|
69
|
+
"http_request",
|
|
70
|
+
"pdf_generate",
|
|
71
|
+
"system_open",
|
|
72
|
+
"file_preview",
|
|
73
|
+
],
|
|
74
|
+
includesResource: true,
|
|
75
|
+
},
|
|
76
|
+
sysadmin: {
|
|
77
|
+
name: "System Admin",
|
|
78
|
+
description: "37 tools for IT management, services, event logs, network, background tasks, ripgrep, archives, and desktop automation (all except pdf_generate)",
|
|
79
|
+
tools: [
|
|
80
|
+
"terminal_run",
|
|
81
|
+
"file_read",
|
|
82
|
+
"file_write",
|
|
83
|
+
"file_edit",
|
|
84
|
+
"file_list",
|
|
85
|
+
"file_search",
|
|
86
|
+
"file_copy",
|
|
87
|
+
"file_move",
|
|
88
|
+
"file_tail",
|
|
89
|
+
"file_hash",
|
|
90
|
+
"file_delete_safe",
|
|
91
|
+
"system_info",
|
|
92
|
+
"gpu_info",
|
|
93
|
+
"process_list",
|
|
94
|
+
"port_check",
|
|
95
|
+
"process_kill",
|
|
96
|
+
"eventlog_query",
|
|
97
|
+
"network_info",
|
|
98
|
+
"service_list",
|
|
99
|
+
"service_status",
|
|
100
|
+
"service_control",
|
|
101
|
+
"screen_capture",
|
|
102
|
+
"system_open",
|
|
103
|
+
"clipboard_get",
|
|
104
|
+
"clipboard_set",
|
|
105
|
+
"notification_send",
|
|
106
|
+
"http_ping",
|
|
107
|
+
"http_request",
|
|
108
|
+
"terminal_task_start",
|
|
109
|
+
"terminal_task_list",
|
|
110
|
+
"terminal_task_logs",
|
|
111
|
+
"terminal_task_send",
|
|
112
|
+
"terminal_task_kill",
|
|
113
|
+
"file_search_ripgrep",
|
|
114
|
+
"archive_zip",
|
|
115
|
+
"archive_unzip",
|
|
116
|
+
"file_preview",
|
|
117
|
+
],
|
|
118
|
+
includesResource: true,
|
|
119
|
+
},
|
|
120
|
+
full: {
|
|
121
|
+
name: "Full Suite",
|
|
122
|
+
description: "All 38 native Windows tools and interactive preview resources",
|
|
123
|
+
tools: [
|
|
124
|
+
"terminal_run",
|
|
125
|
+
"terminal_task_start",
|
|
126
|
+
"terminal_task_list",
|
|
127
|
+
"terminal_task_logs",
|
|
128
|
+
"terminal_task_send",
|
|
129
|
+
"terminal_task_kill",
|
|
130
|
+
"file_read",
|
|
131
|
+
"file_write",
|
|
132
|
+
"file_edit",
|
|
133
|
+
"file_list",
|
|
134
|
+
"file_search",
|
|
135
|
+
"file_delete_safe",
|
|
136
|
+
"file_move",
|
|
137
|
+
"file_copy",
|
|
138
|
+
"archive_zip",
|
|
139
|
+
"archive_unzip",
|
|
140
|
+
"file_tail",
|
|
141
|
+
"file_hash",
|
|
142
|
+
"file_search_ripgrep",
|
|
143
|
+
"pdf_generate",
|
|
144
|
+
"file_preview",
|
|
145
|
+
"clipboard_get",
|
|
146
|
+
"clipboard_set",
|
|
147
|
+
"screen_capture",
|
|
148
|
+
"system_open",
|
|
149
|
+
"notification_send",
|
|
150
|
+
"system_info",
|
|
151
|
+
"gpu_info",
|
|
152
|
+
"process_list",
|
|
153
|
+
"process_kill",
|
|
154
|
+
"port_check",
|
|
155
|
+
"eventlog_query",
|
|
156
|
+
"service_list",
|
|
157
|
+
"service_status",
|
|
158
|
+
"service_control",
|
|
159
|
+
"http_ping",
|
|
160
|
+
"http_request",
|
|
161
|
+
"network_info",
|
|
162
|
+
],
|
|
163
|
+
includesResource: true,
|
|
164
|
+
},
|
|
165
|
+
custom: {
|
|
166
|
+
name: "Custom",
|
|
167
|
+
description: "User-defined tool selection via --tools or config.json",
|
|
168
|
+
tools: [],
|
|
169
|
+
includesResource: true,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
export function resolveCustomTools(baseProfile = "full", toolsArg, configCustomTools) {
|
|
173
|
+
if (!toolsArg && (!configCustomTools || configCustomTools.length === 0)) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const rawList = toolsArg
|
|
177
|
+
? toolsArg.split(",").map((t) => t.trim()).filter(Boolean)
|
|
178
|
+
: configCustomTools || [];
|
|
179
|
+
const hasAdd = rawList.some((t) => t.startsWith("+"));
|
|
180
|
+
const hasRemove = rawList.some((t) => t.startsWith("-"));
|
|
181
|
+
if (hasAdd || hasRemove) {
|
|
182
|
+
const baseTools = new Set((PROFILES[baseProfile] || PROFILES.full).tools);
|
|
183
|
+
for (const item of rawList) {
|
|
184
|
+
if (item.startsWith("+")) {
|
|
185
|
+
baseTools.add(item.slice(1).trim());
|
|
186
|
+
}
|
|
187
|
+
else if (item.startsWith("-")) {
|
|
188
|
+
baseTools.delete(item.slice(1).trim());
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
baseTools.add(item);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return Array.from(baseTools);
|
|
195
|
+
}
|
|
196
|
+
return rawList;
|
|
197
|
+
}
|
|
198
|
+
export function isToolInProfile(toolName, profile = "full", customTools) {
|
|
199
|
+
if (customTools && customTools.length > 0) {
|
|
200
|
+
return customTools.includes(toolName);
|
|
201
|
+
}
|
|
202
|
+
const p = PROFILES[profile] || PROFILES.full;
|
|
203
|
+
return p.tools.includes(toolName);
|
|
204
|
+
}
|
|
205
|
+
export function isValidProfile(profile) {
|
|
206
|
+
return profile in PROFILES;
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=profiles.js.map
|