Updated repo onboarding

This commit is contained in:
2026-05-04 19:18:10 +02:00
parent 5429340f21
commit 47f6971c56
4 changed files with 213 additions and 12 deletions

View File

@@ -1,5 +1,7 @@
import asyncio
import json
import os
import re
import socket
import subprocess
import sys
@@ -34,6 +36,8 @@ from api.schemas.managed_repo import (
PendingInterfaceChange,
RepoCreate,
RepoDispatch,
RepoOnboardRequest,
RepoOnboardResult,
RepoPathRegister,
RepoRead,
RepoScopeHealth,
@@ -90,6 +94,77 @@ async def register_repo(
return repo
@router.post("/onboard", response_model=RepoOnboardResult)
async def onboard_repo(body: RepoOnboardRequest) -> RepoOnboardResult:
"""Run the local repo onboarding script for an accessible working copy.
The dashboard uses this for the "Add Repo" action. The path must be visible
from the State Hub host, either as a local checkout or through an ops-bridge
mounted/exposed working copy. Keep the API agent-profile based so future
native coding agents can gain their own profiles without changing callers.
"""
project_path = Path(body.project_path).expanduser()
if not project_path.exists() or not project_path.is_dir():
raise HTTPException(
status_code=400,
detail=f"project_path is not an accessible directory: {body.project_path}",
)
if not (project_path / ".git").exists():
raise HTTPException(
status_code=400,
detail=f"project_path does not look like a git working copy: {body.project_path}",
)
script = Path(__file__).parent.parent.parent / "scripts" / "register_project.sh"
cmd = ["bash", str(script), body.domain_slug, str(project_path)]
if body.agent_profile == "codex":
cmd.append("--codex")
if body.additional:
cmd.append("--additional")
env = {
**os.environ,
"API_BASE": settings.api_base,
"CUSTODIAN_SKIP_SBOM_PROMPT": "true",
}
result = await asyncio.to_thread(
subprocess.run,
cmd,
cwd=str(script.parent.parent),
env=env,
stdin=subprocess.DEVNULL,
capture_output=True,
text=True,
timeout=180,
)
stdout = result.stdout or ""
stderr = result.stderr or ""
if result.returncode != 0:
raise HTTPException(
status_code=500,
detail={
"message": "Repo onboarding failed.",
"command": cmd,
"stdout": stdout,
"stderr": stderr,
},
)
repo_slug = None
match = re.search(r"Repo slug:\s+([a-z0-9][a-z0-9-]*)", stdout)
if match:
repo_slug = match.group(1)
return RepoOnboardResult(
ok=True,
repo_slug=repo_slug,
agent_profile=body.agent_profile,
command=cmd,
stdout=stdout,
stderr=stderr,
)
@router.get("/by-fingerprint", response_model=list[RepoRead])
async def get_repo_by_fingerprint(
hash: str,