Fix tool install-state, inherit program description, declutter Tools cards
- Tool detail showed installed tools as 'Not installed': /deployments/{name}
populated 'installed' for path deployments but left 'active' null, and
ToolDetail keyed off 'active'. Now the endpoint sets active=installed for path,
and ToolDetail reads 'installed' directly (verified: on-PATH ⇒ True, else False).
- A deployment now inherits its program's description by default: copied at
creation (CLI create + API _save_deployment on new deployments) + a one-time
patchup of existing ones (29 deployments).
- Tools page cards no longer list deployments (ProgramCard showDeployments=false) —
the lens already scopes to the tool; the deployment list is a Programs-catalog thing.
This commit is contained in:
@@ -273,18 +273,27 @@ async def delete_program(name: str, cascade: bool = False) -> dict:
|
||||
def _save_deployment(name: str, config_dict: dict) -> dict:
|
||||
"""Validate a deployment (any manager) and persist it to config.deployments."""
|
||||
_require_repo()
|
||||
config = get_config()
|
||||
config_dict = dict(config_dict)
|
||||
|
||||
# On CREATE (a new deployment) with no description of its own, inherit the
|
||||
# referenced program's description — a deployment reads as its program by
|
||||
# default. Edits keep whatever the user set (including a cleared field).
|
||||
if name not in config.deployments and not config_dict.get("description"):
|
||||
prog = config_dict.get("program")
|
||||
if prog and prog in config.programs and config.programs[prog].description:
|
||||
config_dict["description"] = config.programs[prog].description
|
||||
|
||||
try:
|
||||
dep_data = _normalize_deployment_dict({**config_dict, "id": name})
|
||||
_DEPLOYMENT_ADAPTER.validate_python(dep_data)
|
||||
dep = _DEPLOYMENT_ADAPTER.validate_python(
|
||||
_normalize_deployment_dict({**config_dict, "id": name})
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail=f"Invalid deployment config: {e}",
|
||||
)
|
||||
config = get_config()
|
||||
config.deployments[name] = _DEPLOYMENT_ADAPTER.validate_python(
|
||||
_normalize_deployment_dict({**config_dict, "id": name})
|
||||
)
|
||||
config.deployments[name] = dep
|
||||
save_config(config)
|
||||
return {"ok": True, "deployment": name}
|
||||
|
||||
|
||||
@@ -77,10 +77,13 @@ def _summary_from_deployed(name: str, deployed: object) -> DeploymentSummary:
|
||||
timer=has_timer,
|
||||
)
|
||||
|
||||
# A PATH-managed deployment (a tool) is "installed" when it's on PATH.
|
||||
# A PATH-managed deployment (a tool) is "installed" — and thus active — when
|
||||
# it's on PATH. (systemd/caddy liveness comes from the health/status stream.)
|
||||
installed: bool | None = None
|
||||
active: bool | None = None
|
||||
if deployed.manager == "path":
|
||||
installed = shutil.which(name) is not None
|
||||
active = installed
|
||||
|
||||
category = "job" if deployed.schedule else "service"
|
||||
|
||||
@@ -99,6 +102,7 @@ def _summary_from_deployed(name: str, deployed: object) -> DeploymentSummary:
|
||||
systemd=systemd_info,
|
||||
schedule=deployed.schedule,
|
||||
installed=installed,
|
||||
active=active,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user