Dashboard: programs list deployments; Tools page; statics on Services; editable launcher

- Programs page: each card lists the program's deployments (name · kind) instead
  of a single kind badge; kind-filter chips removed (nav is the kind lens now).
  protonmail honestly shows tool + job.
- New Tools nav page (Wrench) — programs with a tool deployment (/programs?kind=tool).
- Services page now shows statics too: /services returns service + static, and a
  static renders as a caddy-served card (KindBadge, served URL, no start/stop).
- Program detail: DeploymentsSection + deleteConfirm rebuilt over program.deployments;
  header drops the (now nonexistent) program kind.
- ServiceFields / JobFields: launcher is now an editable select (python|command|
  container|compose|node), persisted into run.launcher via the normal save.

clean pnpm build + tsc --noEmit.
This commit is contained in:
2026-07-01 12:32:09 -07:00
parent 10a86d0b6f
commit 01505328ad
13 changed files with 199 additions and 148 deletions

View File

@@ -30,8 +30,9 @@ export function ProgramDetailPage() {
// A static (caddy) deployment with build outputs is served by the gateway in
// place at its own subdomain — show where.
const buildOutputs = (deployment.manifest.build as { outputs?: string[] } | undefined)?.outputs
const isStatic = deployment.deployments.some((d) => d.kind === "static")
const servedAt =
deployment.kind === "static" && buildOutputs?.length
isStatic && buildOutputs?.length
? (subdomainUrl(deployment.id) ?? `${deployment.id}.<gateway.domain>`)
: null
@@ -41,7 +42,6 @@ export function ProgramDetailPage() {
backTo="/programs"
backLabel="Back to Programs"
name={deployment.id}
kind={deployment.kind}
stack={deployment.stack}
source={deployment.source}
>