feat(doctor): add --server flag for Dolt server mode health checks (bd-dolt.2.3)

Adds bd doctor --server to diagnose Dolt server mode connections:
- Server reachability (TCP connect to host:port)
- Dolt version check (verifies it is Dolt, not vanilla MySQL)
- Database exists and is accessible
- Schema compatible (can query beads tables)
- Connection pool health metrics

Supports --json for machine-readable output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beads/crew/emma
2026-01-23 20:29:12 -08:00
committed by Steve Yegge
parent 433115725b
commit 66d994264b
3 changed files with 467 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ package main
import (
"database/sql"
"encoding/json"
"fmt"
"os"
"path/filepath"
@@ -106,6 +107,83 @@ func runDeepValidation(path string) {
}
}
// runServerHealth runs Dolt server mode health checks
func runServerHealth(path string) {
result := doctor.RunServerHealthChecks(path)
if jsonOutput {
jsonBytes, _ := json.Marshal(result)
fmt.Println(string(jsonBytes))
} else {
fmt.Println("Dolt Server Mode Health Check")
fmt.Println()
printServerHealthResult(result)
}
if !result.OverallOK {
os.Exit(1)
}
}
// printServerHealthResult prints the server health check results
func printServerHealthResult(result doctor.ServerHealthResult) {
var passCount, warnCount, failCount int
for _, check := range result.Checks {
var statusIcon string
switch check.Status {
case statusOK:
statusIcon = "✓"
passCount++
case statusWarning:
statusIcon = "⚠"
warnCount++
case statusError:
statusIcon = "✗"
failCount++
}
fmt.Printf(" %s %s", statusIcon, check.Name)
if check.Message != "" {
fmt.Printf(" %s", check.Message)
}
fmt.Println()
if check.Detail != "" {
// Indent detail lines
for _, line := range strings.Split(check.Detail, "\n") {
fmt.Printf(" └─ %s\n", line)
}
}
}
fmt.Println()
// Summary line
fmt.Printf("─────────────────────────────────────────\n")
fmt.Printf("✓ %d passed ⚠ %d warnings ✗ %d failed\n", passCount, warnCount, failCount)
// Print fixes for any errors/warnings
var fixes []doctor.DoctorCheck
for _, check := range result.Checks {
if check.Fix != "" && (check.Status == statusError || check.Status == statusWarning) {
fixes = append(fixes, check)
}
}
if len(fixes) > 0 {
fmt.Println()
fmt.Println("⚠ FIXES NEEDED")
for i, check := range fixes {
fmt.Printf(" %d. %s: %s\n", i+1, check.Name, check.Message)
fmt.Printf(" └─ %s\n", check.Fix)
}
} else if result.OverallOK {
fmt.Println()
fmt.Println("✓ All server health checks passed")
}
}
// printCheckHealthHint prints the health check hint and exits with error.
func printCheckHealthHint(issues []string) {
fmt.Fprintf(os.Stderr, "💡 bd doctor recommends a health check:\n")