Skip to content

Commit 6860505

Browse files
authored
Merge pull request #67 from s2005/fix/yolo-mode-overrides
fix: ensure YOLO mode clears shell-specific overrides
2 parents 173cdb8 + 708ec30 commit 6860505

2 files changed

Lines changed: 151 additions & 104 deletions

File tree

src/utils/config.ts

Lines changed: 120 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export function loadConfig(configPath?: string, disableIfEmpty = false): ServerC
139139

140140
for (const location of configLocations) {
141141
if (!location) continue;
142-
142+
143143
try {
144144
if (fs.existsSync(location)) {
145145
const fileContent = fs.readFileSync(location, 'utf8');
@@ -170,7 +170,7 @@ export function loadConfig(configPath?: string, disableIfEmpty = false): ServerC
170170
) {
171171
config.global.security.restrictWorkingDirectory = false;
172172
}
173-
173+
174174
// Validate and process initialDir if provided
175175
if (config.global.paths.initialDir) {
176176
const normalizedInitialDir = normalizeWindowsPath(config.global.paths.initialDir);
@@ -186,15 +186,15 @@ export function loadConfig(configPath?: string, disableIfEmpty = false): ServerC
186186
config.global.paths.initialDir = undefined;
187187
}
188188
}
189-
189+
190190
// Normalize allowed paths
191191
config.global.paths.allowedPaths = normalizeAllowedPaths(
192192
config.global.paths.allowedPaths
193193
);
194194

195195
// Validate configuration at startup to catch errors early
196196
validateConfig(config);
197-
197+
198198
return config;
199199
}
200200

@@ -209,14 +209,14 @@ export function getResolvedShellConfig(
209209
if (!shell || !shell.enabled) {
210210
return null;
211211
}
212-
212+
213213
let resolved = resolveShellConfiguration(config.global, shell);
214-
214+
215215
// Special handling for WSL/Bash path inheritance
216216
if ((resolved.type === 'wsl' || resolved.type === 'bash') && resolved.wslConfig) {
217217
resolved = applyWslPathInheritance(resolved, config.global.paths.allowedPaths);
218218
}
219-
219+
220220
return resolved;
221221
}
222222

@@ -264,21 +264,21 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
264264
const userShell = userConfig.shells?.powershell;
265265
const baseShell: BaseShellConfig = defaultConfig.shells.powershell
266266
? {
267-
...defaultConfig.shells.powershell,
268-
overrides: defaultConfig.shells.powershell.overrides
269-
? {
270-
...defaultConfig.shells.powershell.overrides,
271-
restrictions: defaultConfig.shells.powershell.overrides.restrictions
272-
? { ...defaultConfig.shells.powershell.overrides.restrictions }
273-
: undefined
274-
}
275-
: undefined
276-
}
267+
...defaultConfig.shells.powershell,
268+
overrides: defaultConfig.shells.powershell.overrides
269+
? {
270+
...defaultConfig.shells.powershell.overrides,
271+
restrictions: defaultConfig.shells.powershell.overrides.restrictions
272+
? { ...defaultConfig.shells.powershell.overrides.restrictions }
273+
: undefined
274+
}
275+
: undefined
276+
}
277277
: {
278-
type: 'powershell',
279-
enabled: false,
280-
executable: { command: '', args: [] }
281-
};
278+
type: 'powershell',
279+
enabled: false,
280+
executable: { command: '', args: [] }
281+
};
282282
if (userShell && !userShell.overrides?.restrictions && baseShell.overrides?.restrictions) {
283283
const { restrictions, ...rest } = baseShell.overrides;
284284
baseShell.overrides = Object.keys(rest).length > 0 ? rest : undefined;
@@ -289,8 +289,8 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
289289
// Override with user config
290290
...(userConfig.shells?.powershell || {}),
291291
// Ensure required properties
292-
enabled: (userConfig.shells?.powershell?.enabled !== undefined) ?
293-
userConfig.shells.powershell.enabled :
292+
enabled: (userConfig.shells?.powershell?.enabled !== undefined) ?
293+
userConfig.shells.powershell.enabled :
294294
(baseShell.enabled !== undefined ? baseShell.enabled : true)
295295
};
296296
// Ensure executable is properly set
@@ -303,21 +303,21 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
303303
const userShell = userConfig.shells?.cmd;
304304
const baseShell: BaseShellConfig = defaultConfig.shells.cmd
305305
? {
306-
...defaultConfig.shells.cmd,
307-
overrides: defaultConfig.shells.cmd.overrides
308-
? {
309-
...defaultConfig.shells.cmd.overrides,
310-
restrictions: defaultConfig.shells.cmd.overrides.restrictions
311-
? { ...defaultConfig.shells.cmd.overrides.restrictions }
312-
: undefined
313-
}
314-
: undefined
315-
}
306+
...defaultConfig.shells.cmd,
307+
overrides: defaultConfig.shells.cmd.overrides
308+
? {
309+
...defaultConfig.shells.cmd.overrides,
310+
restrictions: defaultConfig.shells.cmd.overrides.restrictions
311+
? { ...defaultConfig.shells.cmd.overrides.restrictions }
312+
: undefined
313+
}
314+
: undefined
315+
}
316316
: {
317-
type: 'cmd',
318-
enabled: false,
319-
executable: { command: '', args: [] }
320-
};
317+
type: 'cmd',
318+
enabled: false,
319+
executable: { command: '', args: [] }
320+
};
321321
if (userShell && !userShell.overrides?.restrictions && baseShell.overrides?.restrictions) {
322322
const { restrictions, ...rest } = baseShell.overrides;
323323
baseShell.overrides = Object.keys(rest).length > 0 ? rest : undefined;
@@ -328,8 +328,8 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
328328
// Override with user config
329329
...(userConfig.shells?.cmd || {}),
330330
// Ensure required properties
331-
enabled: (userConfig.shells?.cmd?.enabled !== undefined) ?
332-
userConfig.shells.cmd.enabled :
331+
enabled: (userConfig.shells?.cmd?.enabled !== undefined) ?
332+
userConfig.shells.cmd.enabled :
333333
(baseShell.enabled !== undefined ? baseShell.enabled : true)
334334
};
335335
// Ensure executable is properly set
@@ -342,21 +342,21 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
342342
const userShell = userConfig.shells?.gitbash;
343343
const baseShell: BaseShellConfig = defaultConfig.shells.gitbash
344344
? {
345-
...defaultConfig.shells.gitbash,
346-
overrides: defaultConfig.shells.gitbash.overrides
347-
? {
348-
...defaultConfig.shells.gitbash.overrides,
349-
restrictions: defaultConfig.shells.gitbash.overrides.restrictions
350-
? { ...defaultConfig.shells.gitbash.overrides.restrictions }
351-
: undefined
352-
}
353-
: undefined
354-
}
345+
...defaultConfig.shells.gitbash,
346+
overrides: defaultConfig.shells.gitbash.overrides
347+
? {
348+
...defaultConfig.shells.gitbash.overrides,
349+
restrictions: defaultConfig.shells.gitbash.overrides.restrictions
350+
? { ...defaultConfig.shells.gitbash.overrides.restrictions }
351+
: undefined
352+
}
353+
: undefined
354+
}
355355
: {
356-
type: 'gitbash',
357-
enabled: false,
358-
executable: { command: '', args: [] }
359-
};
356+
type: 'gitbash',
357+
enabled: false,
358+
executable: { command: '', args: [] }
359+
};
360360
if (userShell && !userShell.overrides?.restrictions && baseShell.overrides?.restrictions) {
361361
const { restrictions, ...rest } = baseShell.overrides;
362362
baseShell.overrides = Object.keys(rest).length > 0 ? rest : undefined;
@@ -367,8 +367,8 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
367367
// Override with user config
368368
...(userConfig.shells?.gitbash || {}),
369369
// Ensure required properties
370-
enabled: (userConfig.shells?.gitbash?.enabled !== undefined) ?
371-
userConfig.shells.gitbash.enabled :
370+
enabled: (userConfig.shells?.gitbash?.enabled !== undefined) ?
371+
userConfig.shells.gitbash.enabled :
372372
(baseShell.enabled !== undefined ? baseShell.enabled : true)
373373
};
374374
// Ensure executable is properly set
@@ -381,25 +381,25 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
381381
const userShell = userConfig.shells?.bash;
382382
const baseShell: WslShellConfig = defaultConfig.shells.bash
383383
? {
384-
...defaultConfig.shells.bash,
385-
overrides: defaultConfig.shells.bash.overrides
386-
? {
387-
...defaultConfig.shells.bash.overrides,
388-
restrictions: defaultConfig.shells.bash.overrides.restrictions
389-
? { ...defaultConfig.shells.bash.overrides.restrictions }
390-
: undefined
391-
}
392-
: undefined
393-
}
394-
: {
395-
type: 'bash',
396-
enabled: false,
397-
executable: { command: '', args: [] },
398-
wslConfig: {
399-
mountPoint: '/mnt/',
400-
inheritGlobalPaths: true
384+
...defaultConfig.shells.bash,
385+
overrides: defaultConfig.shells.bash.overrides
386+
? {
387+
...defaultConfig.shells.bash.overrides,
388+
restrictions: defaultConfig.shells.bash.overrides.restrictions
389+
? { ...defaultConfig.shells.bash.overrides.restrictions }
390+
: undefined
401391
}
402-
} as WslShellConfig;
392+
: undefined
393+
}
394+
: {
395+
type: 'bash',
396+
enabled: false,
397+
executable: { command: '', args: [] },
398+
wslConfig: {
399+
mountPoint: '/mnt/',
400+
inheritGlobalPaths: true
401+
}
402+
} as WslShellConfig;
403403
if (userShell && !userShell.overrides?.restrictions && baseShell.overrides?.restrictions) {
404404
const { restrictions, ...rest } = baseShell.overrides;
405405
baseShell.overrides = Object.keys(rest).length > 0 ? rest : undefined;
@@ -431,25 +431,25 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
431431
const userShell = userConfig.shells?.wsl;
432432
const baseShell: WslShellConfig = defaultConfig.shells.wsl
433433
? {
434-
...defaultConfig.shells.wsl,
435-
overrides: defaultConfig.shells.wsl.overrides
436-
? {
437-
...defaultConfig.shells.wsl.overrides,
438-
restrictions: defaultConfig.shells.wsl.overrides.restrictions
439-
? { ...defaultConfig.shells.wsl.overrides.restrictions }
440-
: undefined
441-
}
442-
: undefined,
443-
}
444-
: {
445-
type: 'wsl',
446-
enabled: false,
447-
executable: { command: '', args: [] },
448-
wslConfig: {
449-
mountPoint: '/mnt/',
450-
inheritGlobalPaths: true
434+
...defaultConfig.shells.wsl,
435+
overrides: defaultConfig.shells.wsl.overrides
436+
? {
437+
...defaultConfig.shells.wsl.overrides,
438+
restrictions: defaultConfig.shells.wsl.overrides.restrictions
439+
? { ...defaultConfig.shells.wsl.overrides.restrictions }
440+
: undefined
451441
}
452-
};
442+
: undefined,
443+
}
444+
: {
445+
type: 'wsl',
446+
enabled: false,
447+
executable: { command: '', args: [] },
448+
wslConfig: {
449+
mountPoint: '/mnt/',
450+
inheritGlobalPaths: true
451+
}
452+
};
453453
if (userShell && !userShell.overrides?.restrictions && baseShell.overrides?.restrictions) {
454454
const { restrictions, ...rest } = baseShell.overrides;
455455
baseShell.overrides = Object.keys(rest).length > 0 ? rest : undefined;
@@ -460,20 +460,20 @@ export function mergeConfigs(defaultConfig: ServerConfig, userConfig: Partial<Se
460460
// Override with user config
461461
...(userConfig.shells?.wsl || {}),
462462
// Ensure required properties
463-
enabled: (userConfig.shells?.wsl?.enabled !== undefined) ?
464-
userConfig.shells.wsl.enabled :
463+
enabled: (userConfig.shells?.wsl?.enabled !== undefined) ?
464+
userConfig.shells.wsl.enabled :
465465
(baseShell.enabled !== undefined ? baseShell.enabled : true),
466466
// Ensure wslConfig exists with default values if not provided
467467
wslConfig: {
468468
...((baseShell as any).wslConfig || {}),
469469
...((userConfig.shells?.wsl as any)?.wslConfig || {}),
470-
mountPoint: ((userConfig.shells?.wsl as any)?.wslConfig?.mountPoint !== undefined) ?
471-
(userConfig.shells?.wsl as any).wslConfig.mountPoint :
470+
mountPoint: ((userConfig.shells?.wsl as any)?.wslConfig?.mountPoint !== undefined) ?
471+
(userConfig.shells?.wsl as any).wslConfig.mountPoint :
472472
((baseShell as any).wslConfig?.mountPoint || '/mnt/'),
473-
inheritGlobalPaths: ((userConfig.shells?.wsl as any)?.wslConfig?.inheritGlobalPaths !== undefined) ?
474-
(userConfig.shells?.wsl as any).wslConfig.inheritGlobalPaths :
475-
((baseShell as any).wslConfig?.inheritGlobalPaths !== undefined ?
476-
(baseShell as any).wslConfig.inheritGlobalPaths : true)
473+
inheritGlobalPaths: ((userConfig.shells?.wsl as any)?.wslConfig?.inheritGlobalPaths !== undefined) ?
474+
(userConfig.shells?.wsl as any).wslConfig.inheritGlobalPaths :
475+
((baseShell as any).wslConfig?.inheritGlobalPaths !== undefined ?
476+
(baseShell as any).wslConfig.inheritGlobalPaths : true)
477477
}
478478
};
479479
// Ensure executable is properly set
@@ -616,21 +616,21 @@ export function validateConfig(config: ServerConfig): void {
616616
// Helper function to create a default config file
617617
export function createDefaultConfig(configPath: string): void {
618618
const dirPath = path.dirname(configPath);
619-
619+
620620
if (!fs.existsSync(dirPath)) {
621621
fs.mkdirSync(dirPath, { recursive: true });
622622
}
623623

624624
// Create a JSON-safe version of the config (excluding functions)
625625
const configForSave = JSON.parse(JSON.stringify(DEFAULT_CONFIG));
626-
626+
627627
// Remove validatePath functions as they can't be serialized to JSON
628628
for (const shellName in configForSave.shells) {
629629
if (configForSave.shells[shellName]) {
630630
delete configForSave.shells[shellName].validatePath;
631631
}
632632
}
633-
633+
634634
fs.writeFileSync(configPath, JSON.stringify(configForSave, null, 2));
635635
}
636636

@@ -756,7 +756,7 @@ export function applyCliLogging(
756756
logDirectory?: string
757757
): void {
758758
// Check if any valid logging option is provided
759-
const hasValidOptions =
759+
const hasValidOptions =
760760
(maxOutputLines !== undefined && maxOutputLines > 0) ||
761761
enableTruncation !== undefined ||
762762
enableLogResources !== undefined ||
@@ -808,7 +808,7 @@ export function applyCliUnsafeMode(
808808

809809
const mode = unsafe ? 'unsafe' : 'yolo';
810810

811-
// Disable all safety checks first
811+
// Disable all global safety checks first
812812
config.global.security.enableInjectionProtection = false;
813813
config.global.restrictions.blockedCommands = [];
814814
config.global.restrictions.blockedArguments = [];
@@ -820,4 +820,20 @@ export function applyCliUnsafeMode(
820820
} else {
821821
config.global.security.restrictWorkingDirectory = true;
822822
}
823+
824+
// Clear shell-specific overrides
825+
for (const shellName of Object.keys(config.shells)) {
826+
const shell = config.shells[shellName as keyof ServerConfig['shells']];
827+
if (shell && shell.overrides) {
828+
if (shell.overrides.security) {
829+
shell.overrides.security.enableInjectionProtection = false;
830+
}
831+
832+
if (shell.overrides.restrictions) {
833+
shell.overrides.restrictions.blockedCommands = [];
834+
shell.overrides.restrictions.blockedArguments = [];
835+
shell.overrides.restrictions.blockedOperators = [];
836+
}
837+
}
838+
}
823839
}

0 commit comments

Comments
 (0)