Skip to content

feat: autodetect installed client tools in the npx install wizard#76

Merged
philcunliffe merged 1 commit into
masterfrom
feat/autodetect-install-wizard
May 29, 2026
Merged

feat: autodetect installed client tools in the npx install wizard#76
philcunliffe merged 1 commit into
masterfrom
feat/autodetect-install-wizard

Conversation

@philcunliffe
Copy link
Copy Markdown
Contributor

What

The interactive npx hypaware picker now autodetects installed client tools and pre-selects them, instead of opening with every box unchecked. It also defaults the export to local-parquet.

Before After
Detected claude/codex unchecked pre-checked, labelled · detected
Export default (interactive) keep-local local-parquet (matches --yes)

Scope & rules

  • Autodetect covers the two client sources only (claude, codex). raw-anthropic, raw-openai, and otel are manual integration modes with nothing installed to detect, so they're never auto-checked (but remain in the list).
  • Signal: the client's config-home directory exists — ~/.claude, and $CODEX_HOME ?? ~/.codex. Stats the directory, not settings.json, so HypAware writing settings.json on attach never self-triggers.
  • Pre-check only: detection seeds initial checkbox state; the user can untick anything and tick undetected sources by hand.
  • Interactive only: when picks are supplied (--yes / --dry-run / presets) selection stays explicit and deterministic — detection is skipped entirely (structurally, not by convention).
  • local-parquet default is a plain default, not autodetect; it aligns the interactive picker with the already-documented --yes default.

Changes

  • src/core/cli/detect.js (new) — detectClientSources({ env }).
  • src/core/daemon/client_settings_path.js (new) — extracted the pure resolveClientSettingsPath (handles $CLAUDE_HOME/$CODEX_HOME) so the detector reuses it without status.js's heavy import graph; status.js re-exports it so existing import sites are unchanged.
  • src/core/cli/walkthrough.js — run detector on the interactive branch, pre-check detected sources + local-parquet, thread checked through tuiPromptFactory, record sources_detected/detected_sources on the walkthrough.start span. Detector injectable for tests.
  • src/core/cli/types.d.tschecked? on WalkthroughOption, detect? override on RunPickerWalkthroughOptions.
  • CONTEXT.md (new) — glossary: client source vs raw proxy source, autodetect vs default.

A code comment notes the future descriptor-driven migration path (read attach_probe.settings_file from clientDescriptors) for if/when the picker becomes plugin-driven — deliberately not done now, since at first run only bundled plugins exist and PICKER_SOURCES is itself hardcoded.

Tests

  • test/core/detect.test.js — present/absent/both/empty, $CODEX_HOME override, file-not-a-dir.
  • test/core/walkthrough-detect.test.js — preselection + · detected labels + export default, nothing-detected, picks-skip-detection.
  • Updated the end-to-end TUI happy test for the new local-parquet default.

Verification

  • npm run typecheck — clean
  • npm run lint — 245 files OK
  • npm test665 pass, 0 fail

Note: the walkthrough_picker_to_first_query hermetic smoke is red on master (gateway 404 from the echo upstream) — pre-existing and unrelated to this change (confirmed by running it on a clean tree). Flagging separately.

🤖 Generated with Claude Code

The interactive `npx hypaware` picker now inspects the system and
pre-selects sources whose tool is present, instead of opening with
everything unchecked. It also defaults the export to local-parquet,
aligning the interactive path with the documented `--yes` default.

Autodetect covers the two client sources only (claude, codex) — the
raw proxy sources and otel are manual integration modes with nothing
installed to detect, so they are never auto-checked. Detection is a
pre-check the user can freely undo; it only seeds initial checkbox
state. It runs only on the interactive branch — when picks are
supplied (`--yes` / `--dry-run` / presets) selection stays explicit
and deterministic.

- detect.js: detectClientSources stats each client's config-home dir
  (~/.claude, $CODEX_HOME ?? ~/.codex), reusing resolveClientSettingsPath
  for env-home overrides. Stats the directory, not settings.json, so the
  adapter writing settings.json on attach never self-triggers.
- client_settings_path.js: extracted the pure resolver so the detector
  reuses it without status.js's heavier import graph; status.js
  re-exports it to keep existing import sites stable.
- walkthrough.js: pre-check detected sources (with a "· detected"
  label), pre-check local-parquet, thread `checked` through the TUI
  multiselect, and record sources_detected on the walkthrough.start span.
- CONTEXT.md: glossary for client source vs raw proxy source, autodetect
  vs default.

Tests: detector unit tests (present/absent/both/empty, $CODEX_HOME,
file-not-dir) and picker preselection tests (labels + export default,
nothing-detected, picks-skip-detection).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@philcunliffe
Copy link
Copy Markdown
Contributor Author

Dual-agent review — approve

  • Verdict: approve
  • Risk class: low

Blast radius computed inline (mol-pr-blast-radius not dispatched — hypaware rig suspended). Advisory only: no merge attempted.

Risk capstone

Cross-reference: reviewer findings that intersect high-risk surfaces

Source Finding (severity, evidence) Intersects
Codex Error Handling & Resilience (minor) — detection failures silently treated as "nothing detected"; detect.js:61-66, walkthrough.js:646-650 New feature surface (detect.js); best-effort by design; low blast radius
Codex Concurrency/Ordering (minor) — parallel Set writes make detected_sources order nondeterministic; detect.js:57-64 Telemetry attribute only; no functional blast radius
Codex Fix-validation INCOMPLETE — local-parquet export default applied only in TUI path; legacy HYP_NO_TUI=1/non-TUI still defaults keep-local; walkthrough.js:696-704,475-477 Partial delivery of a stated PR goal; non-TUI path only

Notes

  • Change is additive and well-tested (detect.test.js, walkthrough-detect.test.js, walkthrough-tui-happy.test.js); detection is failure-safe; non-interactive/preset flows explicitly unchanged; status.js is a verified extract+re-export keeping existing import sites stable.
  • No reviewer finding lands on a high-blast-radius shared surface; all sit on the feature's own new code or on telemetry attributes.
Codex review

Fix Validations

Autodetect is skipped for explicit/non-interactive picks

  • Status: correct
  • Evidence: src/core/cli/walkthrough.js:641, src/core/cli/walkthrough.js:644-651, src/core/cli/walkthrough.js:670-672, test/core/walkthrough-detect.test.js:92-105
  • Assessment: Detection only runs when opts.picks is absent, and the dedicated test confirms the injected detector is not called when picks are provided.

Detected client sources are pre-checked and labeled in TUI flow

  • Status: correct
  • Evidence: src/core/cli/walkthrough.js:682-687, src/core/cli/walkthrough.js:418-427, test/core/walkthrough-detect.test.js:44-52
  • Assessment: The picker options are annotated with checked and · detected, and tests assert both UI label/state and resulting selected sources.

Interactive export default alignment to local-parquet

  • Status: incomplete
  • Evidence: src/core/cli/walkthrough.js:696-704, src/core/cli/walkthrough.js:475-477, src/core/cli/walkthrough.js:377, src/core/cli/walkthrough.js:707, test/core/walkthrough-tui-happy.test.js:175-203
  • Assessment: Alignment is true for TUI multiselect, but legacy interactive mode (HYP_NO_TUI=1 / non-TUI path) still defaults to keep-local on empty input.

Findings

Error Handling & Resilience

  • Severity: minor
  • Confidence: high
  • Evidence: src/core/cli/detect.js:61-66, src/core/cli/walkthrough.js:646-650, src/core/cli/walkthrough.js:662
  • Why it matters: Filesystem/detector failures are silently treated as “nothing detected,” which masks real environment problems (permissions, IO errors) as normal absence.
  • Suggested fix: Log detection failures at debug level (error code/message) and emit a span attribute indicating detection errors occurred.

Concurrency, Ordering & State Safety

  • Severity: minor
  • Confidence: medium
  • Evidence: src/core/cli/detect.js:57-64, src/core/cli/walkthrough.js:661
  • Why it matters: Parallel stats race when adding to Set, so detected_sources ordering can vary (claude,codex vs codex,claude), creating telemetry noise and brittle downstream assertions.
  • Suggested fix: Normalize before emit, e.g. detected_sources: [...detected].sort().join(',').

No Finding

  • Behavioral Correctness
  • Change Impact / Blast Radius
  • Security Surface
  • Resource Lifecycle & Cleanup
  • Release Safety
  • Test Evidence Quality
  • Architectural Consistency
  • Debuggability & Operability

Evidence Bundle

  • Changed hot paths: src/core/cli/walkthrough.js (interactive flow/prompt defaults), src/core/cli/detect.js (filesystem autodetect), src/core/daemon/client_settings_path.js + src/core/daemon/status.js (settings-path contract reuse/re-export)
  • Impacted callers: src/core/cli/walkthrough.js:645-647 (detector invocation), src/core/cli/walkthrough.js:475-477 (TUI vs legacy routing), src/core/daemon/status.js:574 (continued export surface for resolveClientSettingsPath)
  • Impacted tests: test/core/detect.test.js:18-75, test/core/walkthrough-detect.test.js:24-107, test/core/walkthrough-tui-happy.test.js:89-112, test/core/walkthrough-tui-happy.test.js:175-203
  • Unresolved uncertainty: I did not execute the test suite in this review pass; behavior claims are based on static diff/caller tracing only.
Claude review

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

(3 candidate findings were raised by the parallel scan but all scored below the
0.80 confidence threshold and were filtered: inline import('...') types in
test/core/walkthrough-detect.test.js [75 — verbatim CLAUDE.md violation but
style-only], walkthrough.finish span missing sources_detected [50],
detect.js JSDoc parenthetical omitting $CLAUDE_HOME [50].)

🤖 Generated with Claude Code


Reports: /Users/phil/testcity/.gc/pr-pipeline/reviews/pr-76 · manual dual-review (faithful to mol-pr-dual-review)

@philcunliffe philcunliffe merged commit 85a8563 into master May 29, 2026
6 checks passed
@philcunliffe philcunliffe deleted the feat/autodetect-install-wizard branch May 29, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant