refactor: simplify CRM MCP architecture
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .common import (
|
||||
Any,
|
||||
Check,
|
||||
InstallerError,
|
||||
Path,
|
||||
Runner,
|
||||
Which,
|
||||
_load_json_object,
|
||||
_project_root,
|
||||
asdict,
|
||||
shutil,
|
||||
subprocess,
|
||||
)
|
||||
from .project import inspect_project
|
||||
|
||||
|
||||
def doctor_project(
|
||||
project_root: str | Path | None = None,
|
||||
*,
|
||||
runner: Runner = subprocess.run,
|
||||
which: Which = shutil.which,
|
||||
python_version: tuple[int, int, int] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
root = _project_root(project_root)
|
||||
inspection = inspect_project(root, which=which, python_version=python_version)
|
||||
checks = [Check(**item) for item in inspection["checks"]]
|
||||
|
||||
config_path = root / "config.json"
|
||||
if config_path.is_file():
|
||||
try:
|
||||
config = _load_json_object(config_path)
|
||||
env_name = config.get("env")
|
||||
config_ok = isinstance(env_name, str) and bool(env_name.strip())
|
||||
detail = f"config env is {env_name!r}" if config_ok else "config.json has no non-empty env"
|
||||
except InstallerError as error:
|
||||
config_ok = False
|
||||
detail = str(error)
|
||||
else:
|
||||
config_ok = False
|
||||
detail = "config.json is missing; run prepare"
|
||||
checks.append(Check("configured_env", config_ok, True, detail))
|
||||
|
||||
uv_bin = which("uv")
|
||||
if uv_bin:
|
||||
commands = (
|
||||
[uv_bin, "lock", "--check"],
|
||||
[
|
||||
uv_bin,
|
||||
"run",
|
||||
"--no-sync",
|
||||
"python",
|
||||
"-c",
|
||||
"import mcp; import nocobase_crm_mcp",
|
||||
],
|
||||
)
|
||||
labels = ("lockfile", "python_environment")
|
||||
for label, command in zip(labels, commands, strict=True):
|
||||
try:
|
||||
result = runner(command, cwd=str(root), capture_output=True, text=True, check=False)
|
||||
ok = result.returncode == 0
|
||||
detail = "passed" if ok else f"failed with exit code {result.returncode}"
|
||||
except OSError as error:
|
||||
ok = False
|
||||
detail = str(error)
|
||||
checks.append(Check(label, ok, True, detail))
|
||||
else:
|
||||
checks.extend(
|
||||
[
|
||||
Check("lockfile", False, True, "uv was not found on PATH"),
|
||||
Check("python_environment", False, True, "uv was not found on PATH"),
|
||||
]
|
||||
)
|
||||
|
||||
return {
|
||||
"ok": all(check.ok for check in checks if check.required),
|
||||
"scope": "local-installation",
|
||||
"projectRoot": str(root),
|
||||
"checks": [asdict(check) for check in checks],
|
||||
"remainingVerification": [
|
||||
"Have the installation Agent verify the saved env through nb CLI's default redacted info output.",
|
||||
"Register the generated stdio MCP configuration in the user's client.",
|
||||
"Call the MCP tool crm_health and require ok=true.",
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user