From fe8d0f287fac70a9dc1bc8364d70dad85f1b7c97 Mon Sep 17 00:00:00 2001 From: "Ben Houston (via MyCoder)" Date: Tue, 11 Mar 2025 20:33:09 +0000 Subject: [PATCH 1/2] Fix issue #191: Improve config clear command and add documentation about config file locations --- packages/cli/src/commands/config.ts | 73 ++++++++++++++++++++++++----- packages/cli/src/settings/config.ts | 10 +++- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/packages/cli/src/commands/config.ts b/packages/cli/src/commands/config.ts index ff463c2..006e11e 100644 --- a/packages/cli/src/commands/config.ts +++ b/packages/cli/src/commands/config.ts @@ -1,3 +1,5 @@ +import * as path from 'path'; + import chalk from 'chalk'; import { Logger } from 'mycoder-agent'; @@ -8,6 +10,7 @@ import { updateConfig, getConfigAtLevel, clearConfigAtLevel, + clearConfigKey, ConfigLevel, } from '../settings/config.js'; import { nameToLogIndex } from '../utils/nameToLogIndex.js'; @@ -19,6 +22,10 @@ export interface ConfigOptions extends SharedOptions { key?: string; value?: string; all?: boolean; + global?: boolean; + g?: boolean; + verbose?: boolean; + v?: boolean; } export const command: CommandModule = { @@ -45,6 +52,18 @@ export const command: CommandModule = { type: 'boolean', default: false, }) + .option('global', { + alias: 'g', + describe: 'Use global configuration instead of project-level', + type: 'boolean', + default: false, + }) + .option('verbose', { + alias: 'v', + describe: 'Show detailed information including config file paths', + type: 'boolean', + default: false, + }) .example('$0 config list', 'List all configuration values') .example( '$0 config get githubMode', @@ -115,6 +134,35 @@ export const command: CommandModule = { // Handle 'list' command if (argv.command === 'list') { logger.info('Current configuration:'); + + // Show config file locations + const { + getSettingsDir, + getProjectSettingsDir, + } = require('../settings/settings.js'); + const globalConfigPath = path.join(getSettingsDir(), 'config.json'); + const projectDir = getProjectSettingsDir(); + const projectConfigPath = projectDir + ? path.join(projectDir, 'config.json') + : 'Not available'; + + logger.info(`Global config file: ${chalk.blue(globalConfigPath)}`); + logger.info(`Project config file: ${chalk.blue(projectConfigPath)}`); + logger.info(''); + + // Show config file paths in verbose mode + if (argv.verbose || argv.v) { + const { getProjectConfigFile } = await import('../settings/config.js'); + const { getSettingsDir } = await import('../settings/settings.js'); + const globalConfigPath = path.join(getSettingsDir(), 'config.json'); + const projectConfigPath = getProjectConfigFile(); + + logger.info(`Global config: ${chalk.blue(globalConfigPath)}`); + logger.info( + `Project config: ${projectConfigPath ? chalk.blue(projectConfigPath) : chalk.dim('(not set)')}`, + ); + logger.info(''); + } const defaultConfig = getDefaultConfig(); // Get all valid config keys @@ -276,15 +324,8 @@ export const command: CommandModule = { return; } - // Get the current config, create a new object without the specified key - const currentConfig = getConfig(); - const { [argv.key]: _, ...newConfig } = currentConfig as Record< - string, - any - >; - - // Update the config file with the new object - updateConfig(newConfig); + // Clear the specified key from the configuration at the current level + clearConfigKey(argv.key, configLevel); // Get the default value that will now be used const defaultValue = @@ -297,13 +338,23 @@ export const command: CommandModule = { // Determine where the new value is coming from const isDefaultAfterClear = JSON.stringify(newValue) === JSON.stringify(defaultValue); + + // Get the actual config values at each level + const globalConfig = getConfigAtLevel(ConfigLevel.GLOBAL); + const projectConfig = getConfigAtLevel(ConfigLevel.PROJECT); + + // Check if key exists AND has a non-default value in each level const afterClearInGlobal = !isDefaultAfterClear && - argv.key in getConfigAtLevel(ConfigLevel.GLOBAL); + argv.key in globalConfig && + JSON.stringify(globalConfig[argv.key]) !== JSON.stringify(defaultValue); + const afterClearInProject = !isDefaultAfterClear && !afterClearInGlobal && - argv.key in getConfigAtLevel(ConfigLevel.PROJECT); + argv.key in projectConfig && + JSON.stringify(projectConfig[argv.key]) !== + JSON.stringify(defaultValue); let sourceDisplay = ''; if (isDefaultAfterClear) { diff --git a/packages/cli/src/settings/config.ts b/packages/cli/src/settings/config.ts index 159954b..7a8b6a8 100644 --- a/packages/cli/src/settings/config.ts +++ b/packages/cli/src/settings/config.ts @@ -275,9 +275,17 @@ export const clearConfigKey = ( } // Create a new config without the specified key - const { [key]: _, ...newConfig } = currentLevelConfig as Record; + const { [key]: removedValue, ...newConfig } = currentLevelConfig as Record< + string, + any + >; + console.log(`Removed value for key ${key}:`, removedValue); // Write the updated config back to the file + console.log(`Clearing key ${key} from ${targetFile}`); + console.log(`Original config:`, JSON.stringify(currentLevelConfig, null, 2)); + console.log(`New config without key:`, JSON.stringify(newConfig, null, 2)); + fs.writeFileSync(targetFile, JSON.stringify(newConfig, null, 2)); // Return the new merged configuration From 06c10f5669b82ef020fa6c44a1160583899300aa Mon Sep 17 00:00:00 2001 From: "Ben Houston (via MyCoder)" Date: Tue, 11 Mar 2025 23:44:51 +0000 Subject: [PATCH 2/2] Fix ConfigOptions interface by removing aliases and correctly typing properties with defaults --- packages/cli/src/commands/config.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/commands/config.ts b/packages/cli/src/commands/config.ts index 006e11e..6cfd8d1 100644 --- a/packages/cli/src/commands/config.ts +++ b/packages/cli/src/commands/config.ts @@ -21,11 +21,9 @@ export interface ConfigOptions extends SharedOptions { command: 'get' | 'set' | 'list' | 'clear'; key?: string; value?: string; - all?: boolean; - global?: boolean; - g?: boolean; - verbose?: boolean; - v?: boolean; + all: boolean; // Has default value in builder, so it's always defined + global: boolean; // Has default value in builder, so it's always defined + verbose: boolean; // Has default value in builder, so it's always defined } export const command: CommandModule = {