Some checks failed
Notebook CI / notebook-smoke (pull_request) Failing after 2s
- gitea_client.py — reusable Gitea API client for issues, PRs, comments - health.py — fleet health monitor (load, disk, memory, processes) - notebook_runner.py — Papermill wrapper with JSON reporting - smoke_test.py — fast smoke tests and bare green-path e2e - secret_scan.py — secret leak scanner for CI gating - wizard_env.py — environment validator for bootstrapping agents - README.md — usage guide for all tools These tools are designed to be used by any wizard via python -m devkit.<tool>. Rising up as a platform, not a silo.
113 lines
3.3 KiB
Python
113 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Wizard environment validator.
|
|
Checks that a new wizard environment is ready for duty.
|
|
|
|
Usage as CLI:
|
|
python -m devkit.wizard_env
|
|
python -m devkit.wizard_env --fix
|
|
|
|
Usage as module:
|
|
from devkit.wizard_env import validate
|
|
report = validate()
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from typing import Any, Dict, List
|
|
|
|
|
|
def _has_cmd(name: str) -> bool:
|
|
return shutil.which(name) is not None
|
|
|
|
|
|
def _check_env_var(name: str) -> Dict[str, Any]:
|
|
value = os.getenv(name)
|
|
return {
|
|
"name": name,
|
|
"status": "ok" if value else "missing",
|
|
"value": value[:10] + "..." if value and len(value) > 20 else value,
|
|
}
|
|
|
|
|
|
def _check_python_pkg(name: str) -> Dict[str, Any]:
|
|
try:
|
|
__import__(name)
|
|
return {"name": name, "status": "ok"}
|
|
except ImportError:
|
|
return {"name": name, "status": "missing"}
|
|
|
|
|
|
def validate() -> Dict[str, Any]:
|
|
checks = {
|
|
"binaries": [
|
|
{"name": "python3", "status": "ok" if _has_cmd("python3") else "missing"},
|
|
{"name": "git", "status": "ok" if _has_cmd("git") else "missing"},
|
|
{"name": "curl", "status": "ok" if _has_cmd("curl") else "missing"},
|
|
{"name": "jupyter-lab", "status": "ok" if _has_cmd("jupyter-lab") else "missing"},
|
|
{"name": "papermill", "status": "ok" if _has_cmd("papermill") else "missing"},
|
|
{"name": "jupytext", "status": "ok" if _has_cmd("jupytext") else "missing"},
|
|
],
|
|
"env_vars": [
|
|
_check_env_var("GITEA_URL"),
|
|
_check_env_var("GITEA_TOKEN"),
|
|
_check_env_var("TELEGRAM_BOT_TOKEN"),
|
|
],
|
|
"python_packages": [
|
|
_check_python_pkg("requests"),
|
|
_check_python_pkg("jupyter_server"),
|
|
_check_python_pkg("nbformat"),
|
|
],
|
|
}
|
|
|
|
all_ok = all(
|
|
c["status"] == "ok"
|
|
for group in checks.values()
|
|
for c in group
|
|
)
|
|
|
|
# Hermes-specific checks
|
|
hermes_home = os.path.expanduser("~/.hermes")
|
|
checks["hermes"] = [
|
|
{"name": "config.yaml", "status": "ok" if os.path.exists(f"{hermes_home}/config.yaml") else "missing"},
|
|
{"name": "skills_dir", "status": "ok" if os.path.exists(f"{hermes_home}/skills") else "missing"},
|
|
]
|
|
|
|
all_ok = all_ok and all(c["status"] == "ok" for c in checks["hermes"])
|
|
|
|
return {
|
|
"overall": "ok" if all_ok else "incomplete",
|
|
"checks": checks,
|
|
}
|
|
|
|
|
|
def main(argv: List[str] = None) -> int:
|
|
argv = argv or sys.argv[1:]
|
|
parser = argparse.ArgumentParser(description="Wizard environment validator")
|
|
parser.add_argument("--json", action="store_true")
|
|
parser.add_argument("--fail-on-incomplete", action="store_true")
|
|
args = parser.parse_args(argv)
|
|
|
|
report = validate()
|
|
if args.json:
|
|
print(json.dumps(report, indent=2))
|
|
else:
|
|
print(f"Wizard Environment: {report['overall']}")
|
|
for group, items in report["checks"].items():
|
|
print(f"\n[{group}]")
|
|
for item in items:
|
|
status_icon = "✅" if item["status"] == "ok" else "❌"
|
|
print(f" {status_icon} {item['name']}: {item['status']}")
|
|
|
|
if args.fail_on_incomplete and report["overall"] != "ok":
|
|
return 1
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|