From 117f3405ce1eefe38d18d2e65ff0793ebe382790 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Thu, 5 Feb 2026 22:16:58 -0800 Subject: [PATCH] feat(cli): implement config display command --- src/cli/config-cmd.test.ts | 19 +++++++++++++++++++ src/cli/config-cmd.ts | 28 +++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/cli/config-cmd.test.ts diff --git a/src/cli/config-cmd.test.ts b/src/cli/config-cmd.test.ts new file mode 100644 index 0000000..f895736 --- /dev/null +++ b/src/cli/config-cmd.test.ts @@ -0,0 +1,19 @@ +import { describe, it, expect } from 'vitest'; +import { formatConfig } from './config-cmd.js'; + +describe('config command', () => { + it('formats config as indented JSON with redacted secrets', () => { + const config = { + telegram: { bot_token: 'secret-123', allowed_chat_ids: [123] }, + models: { default: { provider: 'anthropic', model: 'claude', api_key: 'sk-abc' } }, + server: { port: 18800 }, + }; + + const output = formatConfig(config); + expect(output).toContain('"bot_token": "***"'); + expect(output).toContain('"api_key": "***"'); + expect(output).toContain('"port": 18800'); + expect(output).not.toContain('secret-123'); + expect(output).not.toContain('sk-abc'); + }); +}); diff --git a/src/cli/config-cmd.ts b/src/cli/config-cmd.ts index de56609..d8689f6 100644 --- a/src/cli/config-cmd.ts +++ b/src/cli/config-cmd.ts @@ -1,12 +1,34 @@ import type { Command } from 'commander'; +import { loadConfigSafe, getConfigPath, redactSecrets } from './shared.js'; + +/** Format config for display: redact secrets, return as JSON. */ +export function formatConfig(config: Record): string { + const redacted = redactSecrets(config); + return JSON.stringify(redacted, null, 2); +} export function registerConfigCommand(program: Command): void { program .command('config') .description('Show resolved configuration (secrets redacted)') .option('-c, --config ', 'Config file path') - .action(async (_opts: { config?: string }) => { - console.error('Not yet implemented'); - process.exit(1); + .option('--raw', 'Show unredacted config (dangerous)') + .action(async (opts: { config?: string; raw?: boolean }) => { + const configPath = opts.config ?? getConfigPath(); + const { config, error } = loadConfigSafe(configPath); + + if (!config) { + console.error(error); + process.exit(1); + } + + console.log(`Config loaded from: ${configPath}`); + console.log(''); + + if (opts.raw) { + console.log(JSON.stringify(config, null, 2)); + } else { + console.log(formatConfig(config as unknown as Record)); + } }); }