Files
fission-ai__openspec/openspec/changes/archive/2025-12-21-add-config-command/proposal.md
Tabish Bidiwale 971f8ca4a3 feat(cli): add openspec config command for global configuration management (#382)
* feat(cli): add openspec config command for global configuration management

Implements the `openspec config` command with subcommands:
- `path`: Show config file location
- `list [--json]`: Show all current settings
- `get <key>`: Get a specific value (raw output for scripting)
- `set <key> <value> [--string]`: Set a value with auto type coercion
- `unset <key>`: Remove a key (revert to default)
- `reset --all [-y]`: Reset configuration to defaults
- `edit`: Open config in $EDITOR/$VISUAL

Key features:
- Dot notation for nested key access (e.g., featureFlags.someFlag)
- Auto type coercion (true/false → boolean, numbers → number)
- --string flag to force string storage
- Zod schema validation with unknown field passthrough
- Reserved --scope flag for future project-local config
- Windows-compatible editor spawning with proper path quoting
- Shell completion registry integration

* test(config): add additional unit tests for validation and coercion

- Add tests for unknown fields with various types
- Add test to verify error message path for featureFlags
- Add test for number values rejection in featureFlags
- Add config set simulation tests to verify full coerce → set → validate flow

* fix(config): avoid shell parsing in config edit to handle paths with spaces

Use spawn with shell: false and pass configPath as an argument instead
of building a shell command string. This correctly handles spaces in
both the EDITOR path and config file path on all platforms.

* chore(openspec): archive add-config-command and create cli-config spec

Move completed change to archive and apply spec deltas to create
the cli-config specification documenting the config command interface.

* Validate config keys on set
2025-12-22 18:29:25 +11:00

2.2 KiB

Why

Users need a way to view and modify their global OpenSpec settings without manually editing JSON files. The global-config spec provides the foundation, but there's no user-facing interface to interact with the config. A dedicated openspec config command provides discoverability and ease of use.

What Changes

Add openspec config subcommand with the following operations:

openspec config path                          # Show config file location
openspec config list [--json]                 # Show all current settings
openspec config get <key>                     # Get a specific value (raw, scriptable)
openspec config set <key> <value> [--string]  # Set a value (auto-coerce types)
openspec config unset <key>                   # Remove a key (revert to default)
openspec config reset --all [-y]              # Reset everything to defaults
openspec config edit                          # Open config in $EDITOR

Key design decisions:

  • Key naming: Use camelCase to match JSON structure (e.g., featureFlags.someFlag)
  • Nested keys: Support dot notation for nested access
  • Type coercion: Auto-detect types by default; --string flag forces string storage
  • Scriptable output: get prints raw value only (no labels) for easy piping
  • Zod validation: Use zod for config schema validation and type safety
  • Future-proofing: Reserve --scope global|project flag for potential project-local config

Example usage:

$ openspec config path
/Users/me/.config/openspec/config.json

$ openspec config list
featureFlags: {}

$ openspec config set featureFlags.enableTelemetry false
Set featureFlags.enableTelemetry = false

$ openspec config get featureFlags.enableTelemetry
false

$ openspec config list --json
{
  "featureFlags": {}
}

$ openspec config unset featureFlags.enableTelemetry
Unset featureFlags.enableTelemetry (reverted to default)

$ openspec config edit
# Opens $EDITOR with config.json

Impact

  • Affected specs: New cli-config capability
  • Affected code:
    • New src/commands/config.ts
    • New src/core/config-schema.ts (zod schema)
    • Update CLI entry point to register config command
  • Dependencies: Requires global-config spec (already implemented)