- Remove console StreamHandler from get_logger() — say() already handles
console output via click.echo(); having both caused every message to
appear twice
- Move GRM_LOG_LEVEL filtering into ui.say() via _console_level() so
console verbosity is still user-controllable while the log file always
captures everything at DEBUG
- Remove [GRM] prefix from say() calls — no longer needed without
duplicate logger output, giving cleaner user-facing messages
- Update test_logging_config.py: remove console handler tests and
_level_from_env tests (now in test_ui.py), expect 1 handler only
- Add test_ui.py coverage for _console_level and say() level filtering
- Update README to document single-path console output via click.echo
- 116 tests, 100% coverage, pyright clean, ruff clean
- Create ui.py with say() helper that routes messages to both click.echo()
(console/stdout, user-facing) and logging.getLogger('grm') (file audit trail)
- Update executor.py: replace logger.info() with say() for start, status, done
messages; use say(level=ERROR, err=True) before raising AnsibleError
- Update report.py: replace logger.info() with say() for operation report lines
- Update all unit tests to patch say() instead of using capsys or get_logger
- Add test_ui.py with coverage for say() calling both click.echo and logging
- 117 tests, 100% coverage, pyright clean, ruff clean