Class: Rubino::CLI::DoctorCommand

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/cli/doctor_command.rb

Overview

Health check command that verifies all system components are working.

Doctor is a READ-ONLY diagnosis (#68): it must never create the home directory or the database file while checking them — a never-setup install is reported as “run ‘rubino setup’”, not silently materialized at the umask’s permissions and then declared healthy.

Exit status (#67): non-zero when one or more required checks did not pass, so CI/scripts can gate on ‘rubino doctor`.

Instance Method Summary collapse

Instance Method Details

#executeObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/rubino/cli/doctor_command.rb', line 15

def execute
  ui = Rubino.ui
  ui.info("Running system diagnostics...")
  ui.blank_line

  # Required checks score the headline verdict — these are what a CLI user
  # needs for a working install. The encryption key is SERVER-ONLY (JSON
  # API / OAuth) and a CLI-only user never touches it, so it lives in a
  # separate optional section and is NOT counted against the score (#143):
  # a healthy default install reports all-green.
  required = [
    check_config,
    check_database,
    check_migrations,
    check_directories,
    check_provider_keys,
    check_model_configured
  ]

  ui.blank_line
  ui.info("Optional (API/OAuth server):")
  optional = [check_encryption_key]

  # Document converters are an optional in-process capability (#6): report
  # which CORE formats can be read in-process (their optional gem is
  # loadable), but never let an absent gem fail doctor — pure-ruby formats
  # always work and missing extraction gems only narrow the supported set.
  check_document_converters

  # MCP servers are optional integrations (#90): report each configured
  # server's reachability best-effort, but never let a down MCP server
  # fail doctor — it is informational, not a required check, so non-MCP
  # users (and MCP users with a flaky server) still exit 0.
  check_mcp_servers if MCP.enabled?

  ui.blank_line
  passed = required.count { |c| c[:status] == :ok }
  total = required.size
  optional_unconfigured = optional.count { |c| c[:status] != :ok }

  if passed == total
    ui.success("All #{total} checks passed!")
    if optional_unconfigured.positive?
      ui.info("(#{optional_unconfigured} optional server check#{"s" if optional_unconfigured != 1} not configured — only needed to run the API/OAuth server)")
    end
  else
    ui.warning("#{passed}/#{total} required checks passed")
    # Scripts/CI gate on doctor: a failed required check must be a
    # non-zero exit, not a green 0 under a red report (#67).
    exit(1)
  end
end