feat(config): add get and unset commands - #36067
Conversation
mxnstrexgl
left a comment
There was a problem hiding this comment.
LGTM — automated review passed. No security, quality, or test coverage issues detected.
teknium1
left a comment
There was a problem hiding this comment.
Thanks for implementing the missing scriptable config operations. The feature remains needed on current main, but this branch predates several config and parser changes.
Problems
- The active parser now lives in
hermes_cli/subcommands/config.py:12-49and is wired fromhermes_cli/main.py:13161; the PR edits the extracted historical block instead (hermes_cli/main.py:12782-12796). unset_config_value()catches config read failures as{}athermes_cli/config.py:5850-5854and can rewrite the file at line 5868. Current main deliberately fail-closes config replacements throughatomic_config_write()athermes_cli/config.py:6720-6743.- The new
_CONFIG_TO_ENV_SYNCathermes_cli/config.py:3330-3352duplicates an incomplete subset of current main'sTERMINAL_CONFIG_ENV_MAP/terminal_config_env_var_for_key()(hermes_cli/config.py:6814-6857). - Unset needs the managed-scope guard that current
set_config_value()applies athermes_cli/config.py:8110-8120.
Suggested changes
- Port parser registration to
hermes_cli/subcommands/config.pyand test parser acceptance. - Reuse current managed-scope, atomic-write, and terminal-env mapping helpers; add regression coverage for unreadable config and a newer terminal mapping.
Automated hermes-sweeper review.
| # config edit | ||
| config_subparsers.add_parser("edit", help="Open config file in editor") | ||
|
|
||
| # config get |
There was a problem hiding this comment.
Current main no longer builds config subcommands here: build_config_parser() in hermes_cli/subcommands/config.py is invoked from hermes_cli/main.py:13161. Port these argparse additions to that builder so the commands are reachable after salvage.
|
|
||
| _MISSING = object() | ||
|
|
||
| _CONFIG_TO_ENV_SYNC = { |
There was a problem hiding this comment.
Do not introduce another terminal mapping here. Current main has the authoritative TERMINAL_CONFIG_ENV_MAP and terminal_config_env_var_for_key() helper; this subset misses newer mappings such as docker_network, so unset would leave their mirrored .env values stale.
| try: | ||
| with open(config_path, encoding="utf-8") as f: | ||
| user_config = yaml.safe_load(f) or {} | ||
| except Exception: |
There was a problem hiding this comment.
This must fail closed rather than treating an unreadable or malformed existing config as {}. Current main's atomic_config_write() protects this exact overwrite class; use that guard before any rewrite.
|
|
||
| def unset_config_value(key: str): | ||
| """Remove a user-set configuration or .env value.""" | ||
| if is_managed(): |
There was a problem hiding this comment.
Please also apply the per-key managed-scope guard used by current set_config_value(). is_managed() covers the package-manager lock, but does not protect administrator-pinned individual config keys.
|
Merged via #65540 (rebase-merged onto current main, head commit 53adb3f) — your commit was re-applied onto the refactored subcommands/config.py parser with your authorship preserved; env-mirror sync now routes through the canonical TERMINAL_CONFIG_ENV_MAP instead of a duplicate dict. Thanks for the contribution! |
What does this PR do?
Adds scriptable
hermes config get <key>andhermes config unset <key>commands so the existingconfig setflow has matching read and removal operations.config getreads the resolved config tree, supports dotted dict/list paths, prints scalars directly, and supports--jsonfor structured values.config unsetremoves user-set YAML paths, supports env-backed keys written byconfig set, and clears mirrored terminal env values such asTERMINAL_ENVwhen unsettingterminal.backend.Freshness / duplicate screening before opening:
type/feature,comp/cli,area/config,P3, with no comments indicating duplicate/fixed/wontfix.36037-> no results.hermes config get unset,config get config unset config_command,scriptable config read undo,unset configuration value,configuration CRUD-> no implementation PRs.config get <key>-> found docs: replace invalid 'hermes config get <key>' with 'hermes config s… #30390 and docs: fix stale CLI references #31648, both doc-cleanup/stale-reference PRs, not implementations.origin/main(eb3cf9750eb8395c158be5cb929604041d1b03b5) thathermes config getandhermes config unsetare invalid parser choices.Fixes #36037
Related Issue
Fixes #36037
Type of Change
Changes Made
hermes config get <key> [--json].hermes config unset <key>._tokenYAML paths, env-backed unsets, and terminal env cleanup.get/unset.How to Test
uv run --extra dev pytest tests/hermes_cli/test_set_config_value.py tests/hermes_cli/test_placeholder_usage.py tests/tools/test_terminal_config_env_sync.py -q-> 53 passed.uv run --extra dev python -m ruff check hermes_cli/config.py hermes_cli/main.py tests/hermes_cli/test_set_config_value.py tests/tools/test_terminal_config_env_sync.py-> All checks passed.git diff --check-> no output.HERMES_HOMECLI smoke:config set terminal.backend docker,config get terminal.backend,config get terminal --json,config unset terminal.backend,config get terminal.backend-> printeddocker, structured JSON, unset confirmation, then resolved defaultlocal.Codex review-mode wrapper:
/tmp/codex-review.HRjau6.txtfound null-value handling bug; fixed./tmp/codex-review.KSlomm.txtfound missing env-key handling bug; fixed./tmp/codex-review.0F3nhj.txtfound dotted_tokenYAML-path classification bug; fixed./tmp/codex-review.WKCYbL.txtended clean: no actionable correctness issues.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings)cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/A