Move verbose into Config; drop resolveVerbose

Verbose was awkwardly a separate runKeeper argument with a separate
resolveVerbose helper, even though it's just another tunable on the
same precedence ladder as the numeric fields. This commit collapses it.

Changes:

- Config gains 'readonly verbose: boolean'. DEFAULT_CONFIG sets it to
  false.
- resolveConfig now returns the full Config including verbose. Verbose
  layers with the same 'first defined value wins' precedence as the
  numeric fields.
- resolveVerbose is gone.
- ParsedCliArgs.verbose becomes boolean | undefined: undefined when -V
  was not passed, true when it was. parseCliArgs maps accordingly.
  This lets the layered resolver treat verbose uniformly.
- runKeeper takes a single Config arg. The internal logger reads from
  config.verbose at the top of runKeeper.
- move.ts no longer plumbs verbose separately; the single resolved
  Config drives everything.
- README How-it-works and Files-table entries updated to match.

Behavior verified for all five verbose-precedence cases (no file/no
flag, no file/-V, file:true/no flag, file:false/-V, file:false/no
flag) and config-error scenarios remain intact.
This commit is contained in:
2026-06-17 12:45:46 -05:00
parent ccc136f727
commit 940113019d
5 changed files with 52 additions and 52 deletions
+5 -5
View File
@@ -11,9 +11,9 @@
* Logging policy:
* - The startup banner in `runKeeper` is unconditional so the user always
* sees confirmation that the process is alive.
* - Every per-sweep / interrupt / bounds log is gated by `verbose` so the
* default is quiet. Errors stay on `console.error` (unconditional, raised
* by the entry point on unhandled rejection).
* - Every per-sweep / interrupt / bounds log is gated by `config.verbose`
* so the default is quiet. Errors stay on `console.error` (unconditional,
* raised by the entry point on unhandled rejection).
*/
import { mouse, Point, screen } from "@nut-tree-fork/nut-js";
@@ -144,8 +144,8 @@ async function simulateActivity(config: Config, log: ReturnType<typeof makeLogge
* next position check matches), and on a user-interrupted sweep the next
* iteration sees the user's new position and correctly resets the clock.
*/
export async function runKeeper(config: Config, verbose: boolean): Promise<void> {
const log = makeLogger(verbose);
export async function runKeeper(config: Config): Promise<void> {
const log = makeLogger(config.verbose);
log.info("Teams Status Keeper started. Press Ctrl+C to stop.");
let lastPos: Point = await mouse.getPosition();