| 206 | * @param program - The Commander program instance |
| 207 | */ |
| 208 | export function registerConfigCommand(program: Command): void { |
| 209 | const configCmd = program |
| 210 | .command('config') |
| 211 | .description('View and modify global OpenSpec configuration') |
| 212 | .option('--scope <scope>', 'Config scope (only "global" supported currently)') |
| 213 | .hook('preAction', (thisCommand) => { |
| 214 | const opts = thisCommand.opts(); |
| 215 | if (opts.scope && opts.scope !== 'global') { |
| 216 | console.error('Error: Project-local config is not yet implemented'); |
| 217 | process.exit(1); |
| 218 | } |
| 219 | }); |
| 220 | |
| 221 | // config path |
| 222 | configCmd |
| 223 | .command('path') |
| 224 | .description('Show config file location') |
| 225 | .action(() => { |
| 226 | console.log(getGlobalConfigPath()); |
| 227 | }); |
| 228 | |
| 229 | // config list |
| 230 | configCmd |
| 231 | .command('list') |
| 232 | .description('Show all current settings') |
| 233 | .option('--json', 'Output as JSON') |
| 234 | .action((options: { json?: boolean }) => { |
| 235 | const config = getGlobalConfig(); |
| 236 | |
| 237 | if (options.json) { |
| 238 | console.log(JSON.stringify(config, null, 2)); |
| 239 | } else { |
| 240 | // Read raw config to determine which values are explicit vs defaults |
| 241 | const configPath = getGlobalConfigPath(); |
| 242 | let rawConfig: Record<string, unknown> = {}; |
| 243 | try { |
| 244 | if (fs.existsSync(configPath)) { |
| 245 | rawConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8')); |
| 246 | } |
| 247 | } catch { |
| 248 | // If reading fails, treat all as defaults |
| 249 | } |
| 250 | |
| 251 | console.log(formatValueYaml(config)); |
| 252 | |
| 253 | // Annotate profile settings |
| 254 | const profileSource = rawConfig.profile !== undefined ? '(explicit)' : '(default)'; |
| 255 | const deliverySource = rawConfig.delivery !== undefined ? '(explicit)' : '(default)'; |
| 256 | console.log(`\nProfile settings:`); |
| 257 | console.log(` profile: ${config.profile} ${profileSource}`); |
| 258 | console.log(` delivery: ${config.delivery} ${deliverySource}`); |
| 259 | if (config.profile === 'core') { |
| 260 | console.log(` workflows: ${CORE_WORKFLOWS.join(', ')} (from core profile)`); |
| 261 | } else if (config.workflows && config.workflows.length > 0) { |
| 262 | console.log(` workflows: ${config.workflows.join(', ')} (explicit)`); |
| 263 | } else { |
| 264 | console.log(` workflows: (none)`); |
| 265 | } |