Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ pick the new config up on their next ucode run.
| Command | Description |
|---------|-------------|
| `ucode status` | Show current workspace, base URLs, managed config files, and selected models |
| `ucode doctor` | Diagnose the local setup (uv, npm, Databricks CLI, workspace, credentials, agent CLIs, tracing) and offer to fix any problems found |
| `ucode usage` | Show AI Gateway usage summary, plus your budget spend against its alert threshold when the workspace reports one |
| `ucode usage --warehouse-id <id>` | Query a specific SQL warehouse instead of discovering one |
| `ucode revert` | Clear saved state and restore backed-up config files |
Expand Down
32 changes: 32 additions & 0 deletions src/ucode/agents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,38 @@ def ensure_tool_binary_available(tool: str) -> None:
)


def tool_binary_installed(tool: str) -> bool:
"""True when the agent's CLI binary is on PATH. Read-only — for ``ucode doctor``."""
return bool(shutil.which(TOOL_SPECS[tool]["binary"]))


def tool_update_available(tool: str) -> tuple[str, str] | None:
"""Return ``(current, latest)`` when a newer agent CLI is published, else None.
Read-only wrapper over the per-agent update check — for ``ucode doctor``."""
return _MODULES[tool].is_update_available()


def update_tool_binary(tool: str) -> bool:
"""Install the latest agent CLI, returning True on success. Public entry
point over the internal updater so ``ucode doctor`` can apply the fix."""
return _update_installed_tool_binary(tool)


def tracing_mlflow_ok() -> bool:
"""True when the `mlflow` CLI that Claude tracing needs is installed and in
the supported version range. Read-only — for ``ucode doctor``."""
current = claude._installed_mlflow_version()
return bool(
current and claude.MINIMUM_MLFLOW_VERSION <= current < claude.MAXIMUM_MLFLOW_VERSION
)


def ensure_tracing_mlflow_cli() -> bool:
"""Install/repair the pinned `mlflow` CLI for Claude tracing, returning True
on success. Public entry point so ``ucode doctor`` can apply the fix."""
return claude._ensure_mlflow_cli()


def ensure_bootstrap_dependencies(
tool: str,
*,
Expand Down
12 changes: 12 additions & 0 deletions src/ucode/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,18 @@ def revert_cmd() -> None:
raise typer.Exit(1) from None


@app.command("doctor")
def doctor_cmd() -> None:
"""Diagnose the local ucode setup and offer to fix any problems found."""
from ucode.doctor import doctor

try:
doctor()
except RuntimeError as exc:
print_err(str(exc))
raise typer.Exit(1) from None


@app.command("usage")
def usage_cmd(
warehouse_id: Annotated[
Expand Down
32 changes: 32 additions & 0 deletions src/ucode/databricks.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,38 @@ def ensure_databricks_cli_version() -> None:
ensure_databricks_cli_version()


def databricks_cli_version() -> tuple[int, int, int] | None:
"""Return the installed Databricks CLI's (major, minor, patch), or None if
the CLI is absent or its version can't be read/parsed. Unlike
``ensure_databricks_cli_version`` this only reports — it never upgrades — so
``ucode doctor`` can decide what to recommend."""
if not shutil.which("databricks"):
return None
try:
result = run(
["databricks", "--version"],
check=False,
capture_output=True,
text=True,
timeout=10,
)
except (OSError, subprocess.TimeoutExpired):
return None
raw = result.stdout or result.stderr or ""
output = (raw if isinstance(raw, str) else raw.decode(errors="replace")).strip()
return _parse_databricks_cli_version(output)


def upgrade_databricks_cli() -> bool:
"""Upgrade an already-installed Databricks CLI to the latest release.
Returns True on success, False if the installer failed."""
try:
_run_databricks_cli_installer(brew_subcommand="upgrade")
except RuntimeError:
return False
return True


def install_databricks_cli() -> None:
if shutil.which("databricks"):
ensure_databricks_cli_version()
Expand Down
Loading
Loading