Commit graph

7 commits

Author SHA1 Message Date
JerrettDavis
301563f11d test(init): make verbose stderr assertion click-version-agnostic
The test added in bb91cfe used ``CliRunner(mix_stderr=False)`` to keep
stderr separate from stdout for assertion purposes. That parameter was
removed in Click 8.2. The repo's pyproject.toml pins ``click>=8.1.0``,
so either Click 8.1 (needs mix_stderr) or Click 8.2+ (must omit it)
could appear in CI.

Switch to reading ``result.stderr`` when the attribute is populated,
falling back to ``result.output`` (combined stream) otherwise. This
covers every Click 8.x variant without branching on the installed
version.

Verified in the Docker e2e image (Click 8.3.3): all 45 tests in
tests/test_cli/test_init_cli.py pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 16:19:17 -05:00
JerrettDavis
bb91cfe688 feat(init): add -v/--verbose flag for debug diagnostics
When users hit an init regression it's opaque why: no visible state
about which agents were probed, which paths were written, which
subprocesses ran. Add a top-level flag to ``headroom init`` that routes
debug-level logging from the ``headroom.cli.init`` logger to stderr.

Instrumented decision points:

* detect_init_targets / _probe_init_targets — scope + per-target
  shutil.which result
* _write_json, _ensure_claude_hooks, _ensure_copilot_hooks,
  _ensure_codex_hooks, _ensure_codex_provider — file paths being written
* _apply_user_env — chosen scope (windows vs unix) and env-var keys
* _run_checked — each subprocess command + exit code + truncated
  stdout/stderr (useful when ``claude plugin install`` fails)
* _run_init_targets — target dispatch order and resolved profile
* top-level init callback — all flag values and invoked_subcommand

Log output goes to stderr so stdout stays clean for pipes. The handler
attached by ``_enable_verbose_logging`` is idempotent - nested
subcommand invocations don't duplicate output. The logger does not
propagate to the root logger, so enabling ``headroom init -v`` does not
affect the rest of the process.

The flag is declared on the parent Click group. Subcommands (claude,
codex, copilot, openclaw) inherit the enabled logger automatically
because the group callback runs before dispatch.

Added tests cover:

* ``init -v`` emits the expected markers to stderr, including
  ``detect_init_targets``, ``global_scope=True``, and each agent name
* ``_enable_verbose_logging`` is safe to call repeatedly (handler
  remains singular)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:59:57 -05:00
JerrettDavis
4c062319f0 fix(init): guide users when no agents are auto-detected
Fixes #245.

Running ``headroom init -g`` with no supported agents on PATH previously
produced a single-line ClickException that read like the -g flag had
been removed:

    Error: No supported user init targets were auto-detected. Specify one explicitly.

This left reporter #245 concluding the feature was gone. Replace that
message with a structured diagnostic that:

* states which scope (user / local) was tried
* lists every target probed (claude, codex, copilot, openclaw) and the
  shutil.which() result for each
* explicitly confirms that -g / --global is still a supported flag
* shows the concrete per-target invocation for each agent
  (``headroom init -g claude``, ...) so the user knows the escape hatch

The implementation factors ``detect_init_targets`` into a ``_probe_init_targets``
helper that returns ``[(name, which_result)]``. ``detect_init_targets``
keeps its existing signature so the test suite and external imports
aren't broken; the new helper backs both the auto-detection path and
the diagnostic error formatter.

Unit tests in tests/test_cli/test_init_cli.py cover:
* the end-to-end message shape (structural markers + every target name +
  the example invocation)
* the local-scope variant omitting global-only agents (copilot / openclaw)
* that found binaries are surfaced with their absolute path so users can
  debug cases where shutil.which returns an unexpected result

No behavior change when at least one target is detected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:55:12 -05:00
JerrettDavis
9ba9a59f78 test: isolate windows init branches from os globals
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 21:11:03 -05:00
JerrettDavis
c1b648664e test: raise init command branch coverage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 20:59:24 -05:00
JerrettDavis
a278a7b0ba test: cover init install flows end to end
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 20:15:11 -05:00
JerrettDavis
3a999d1562 feat: add durable init command for agent hooks
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 19:39:06 -05:00