Matt Toohey 1b628a56cb feat: add doctor health-check UI and backend to preferences dialog (#21)
* feat: add doctor health-check backend commands

* feat: add doctor health-check UI to preferences dialog

Port the doctor feature frontend from staged into React components that
match goose2's patterns (Tailwind CSS, lucide-react, cn() utility).

New files:
- src/shared/api/doctor.ts: Tauri API bindings for run_doctor and
  run_doctor_fix commands
- src/features/settings/ui/DoctorCheckRow.tsx: Individual check row
  component with status icons, fix command dialog, and external link
  support
- src/features/settings/ui/DoctorSettings.tsx: Doctor panel with
  auto-run on mount, re-run button, copy debug report, and
  tool/agent section grouping

Modified:
- src/features/settings/ui/SettingsModal.tsx: Add Doctor tab with
  Stethoscope icon between Appearance and General nav items

* fix: add right padding to doctor header to avoid overlap with close button

The Re-run and Copy details buttons in the Doctor settings panel were
rendered behind the modal's X close button due to insufficient clearance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: align doctor panel heading and nav position with other settings panels

Remove the inline Stethoscope icon from the Doctor heading to match
the plain h3 style used by all other settings panels. Move the Doctor
nav item to sit between Projects and About in the sidebar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: refresh ACP providers after doctor checks and fixes

After running doctor checks or applying a fix, call discoverAcpProviders()
so newly-installed agents appear in the agent selector without requiring
an app reload. This matches the Staged implementation where
DoctorSettingsPanel.svelte calls refreshProviders() after runChecks().

Add a runChecksAndRefresh wrapper that awaits runChecks() then calls
discoverAcpProviders(), guarded by the existing mountedRef check. Use it
in all three call sites: useEffect on mount, Re-run button onClick, and
the onFixed callback passed to DoctorCheckRow.

* fix: use Tauri opener plugin instead of window.open for external URLs

Replace window.open(url, '_blank') with openUrl() from
@tauri-apps/plugin-opener in DoctorCheckRow. In a Tauri webview,
window.open is unreliable for opening URLs in the system browser.
The opener plugin uses the native OS handler and is already configured
in the Tauri backend (opener:default capability).

- Add @tauri-apps/plugin-opener as a frontend dependency
- Import openUrl from @tauri-apps/plugin-opener
- Replace window.open(check.fixUrl, '_blank') with void openUrl(check.fixUrl)

* fix: use ID-based fix execution instead of passing shell commands over IPC

The frontend previously sent raw shell command strings to the backend's
run_doctor_fix handler, which would execute them directly. This is a
security concern as the IPC boundary should not accept arbitrary commands.

Now the backend is the single source of truth for fix commands. The
frontend sends only a check ID and fix type ("command" or "bridge"),
and the backend looks up the corresponding command from the static
AgentCheckInfo definitions or hardcoded tool check commands. Unknown
IDs or fix types are rejected with an error.

- Add fix_type field to DoctorCheck struct (set alongside fix_command)
- Add lookup_fix_command() that maps check_id + fix_type to a command
- Rewrite run_doctor_fix to accept (check_id, fix_type) instead of a
  raw command string
- Update frontend API and DoctorCheckRow to pass check.id + check.fixType

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve doctor code review comments

- Replace stringly-typed fix_type (Option<String>) with a FixType enum
  on both backend and frontend, making invalid states unrepresentable
  and eliminating the wildcard fallback in lookup_fix_command
- Collapse duplicate "not installed" fallback branches in
  check_agent_install into a single branch that conditionally appends
  the main-binary search output
- Align fix confirmation dialog with existing dialog patterns: add
  role="dialog", aria-modal, aria-label, Escape key handler, and match
  the class ordering used by other confirmation dialogs in the codebase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:59:31 +11:00
S
Description
an open-source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM
Apache-2.0 2 GiB
Languages
Rust 63.6%
TypeScript 29.6%
JavaScript 1.7%
Shell 1.6%
Python 1.5%
Other 1.8%