Dashboard: Infrastructure tier with the agent computer (cloud apps)
ci / gates (push) Failing after 5s
ci / rust (push) Has been skipped
ci / sandbox-k8s (push) Has been skipped
ci / frontend (push) Has been skipped
ci / e2e (push) Has been skipped

Promote Infrastructure to a first-class tier that mirrors the Agent template:
a left rail tab + crumb, an Infra category sidebar, a center stage, and the
right slide-out computer — the SAME device chrome as the agent, driven by a
swappable app catalog.

- Parameterize the computer by a ComputerCatalog (computer/catalog.ts): grid,
  dock, icons, tile, title, render, theme. DevicePanel + HomeScreen are now
  catalog-driven; the agent computer is unchanged via agentCatalog() (today's
  grid/dock/tiles/AppRouter, extracted verbatim into computer/tiles.tsx).
- Infra catalog (computer/catalogs/infra.tsx): grid = AWS/GCP/Azure/Add, dock =
  Hosts/Status/Settings, original colored lettermark tiles (not the trademarked
  logos), placeholder app screens (computer/apps/infra/InfraApp.tsx). APP_IDS
  gains aws/gcp/azure/hosts/status.
- Infra tier in Dashboard.tsx: "infra" Tier + Server rail tab + crumb; an
  InfraSidebar/InfraStage/InfraConsole (InfraStage.tsx) mirroring the claw
  center+chat; the right pull-out is <DevicePanel catalog={INFRA_CATALOG}/> with
  the same launchers, size presets and drag-resize.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-24 07:19:31 -07:00
co-authored by Claude Opus 4.8
parent 98a9ec62ab
commit b853aab6fd
10 changed files with 558 additions and 111 deletions
@@ -0,0 +1,84 @@
// The infra computer's app catalog — the IDENTICAL device chrome as the agent
// computer, but its apps are cloud providers + infra system apps. Tiles are
// original colored lettermarks (not the providers' trademarked logos).
import { Activity, Cloud, Plus, Server, Settings } from "lucide-react";
import type { CSSProperties } from "react";
import type { AppId } from "@/lib/url/panel-params";
import { InfraApp } from "../apps/infra/InfraApp";
import type { ComputerCatalog } from "../catalog";
import { LetterTile } from "../tiles";
const TITLES: Record<string, string> = {
aws: "AWS",
gcp: "Google Cloud",
azure: "Microsoft Azure",
hosts: "Hosts",
status: "Fleet Status",
settings: "Settings",
apps: "Add Cloud",
};
const notConnected = [
{ k: "ACCOUNT", v: "— not connected" },
{ k: "REGIONS", v: "—" },
{ k: "INSTANCES", v: "—" },
];
function render(app: AppId) {
switch (app) {
case "aws":
return <InfraApp icon={Cloud} accent="#ec7211" title="AWS" blurb="Connect an AWS account to run agents on EC2, ECS / Fargate and Lambda across your regions." rows={notConnected} />;
case "gcp":
return <InfraApp icon={Cloud} accent="#1a73e8" title="Google Cloud" blurb="Connect a GCP project to run agents on Compute Engine, GKE and Cloud Run." rows={notConnected} />;
case "azure":
return <InfraApp icon={Cloud} accent="#0078d4" title="Microsoft Azure" blurb="Connect an Azure subscription to run agents on VMs, AKS and Container Apps." rows={notConnected} />;
case "hosts":
return (
<InfraApp
icon={Server}
accent="#5ec8d8"
title="Hosts"
blurb="The machines connected to your fleet. Agent containers are placed onto these nodes."
rows={[{ k: "local", v: "gw-04 · online" }]}
cta="Connect a host"
/>
);
case "status":
return <InfraApp icon={Activity} accent="#5fd08a" title="Fleet Status" blurb="Capacity, health and live container placement across all of your nodes." cta="Open status" />;
case "settings":
return <InfraApp icon={Settings} accent="#9a9aa2" title="Settings" blurb="Infrastructure preferences — default placement, quotas and provider credentials." cta="Edit settings" />;
case "apps":
return <InfraApp icon={Plus} accent="#ff8a7a" title="Add Cloud" blurb="Connect another provider — DigitalOcean, on-prem hardware, a Kubernetes cluster, and more." cta="Browse providers" />;
default:
return null;
}
}
export const INFRA_CATALOG: ComputerCatalog = {
grid: [
{ app: "aws", label: "AWS" },
{ app: "gcp", label: "GCP" },
{ app: "azure", label: "Azure" },
{ app: "apps", label: "Add Cloud" },
],
dock: [
{ app: "hosts", label: "Hosts" },
{ app: "status", label: "Status" },
{ app: "settings", label: "Settings" },
],
icon: { hosts: Server, status: Activity, settings: Settings, apps: Plus, aws: Cloud, gcp: Cloud, azure: Cloud },
tile: (app) => {
if (app === "aws") return <LetterTile text="AWS" gradient="linear-gradient(150deg,#ff9d3c 0%,#ec7211 55%,#a8430a 100%)" />;
if (app === "gcp") return <LetterTile text="GCP" gradient="linear-gradient(150deg,#5b9bff 0%,#1a73e8 55%,#0b3d91 100%)" />;
if (app === "azure") return <LetterTile text="Az" gradient="linear-gradient(150deg,#46b6ff 0%,#0078d4 55%,#004e8c 100%)" />;
return null; // hosts/status/settings/apps → default glyph / dashed plus
},
title: (app) => TITLES[app] ?? "Cloud",
render,
homeLabel: "Cloud Infrastructure",
theme: { ["--agent-wallpaper" as string]: "linear-gradient(135deg, #0f1830 0%, #18243f 100%)" } as CSSProperties,
statusColor: "#5ec8d8",
};