Fleet: node hostname/IP on register + node terminal in the infra computer
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

Hostname/IP:
- Daemon reports the machine's hostname (sysinfo) + primary outbound IPv4 on each
  heartbeat. migrations/0021 adds nodes.hostname/local_ip; cm-db heartbeat stores
  them; node JSON exposes them. Cards now title on the real hostname (falling back
  to name) + show the IP, instead of the "New node" placeholder. `name` stays
  user-overridable (rename).

Terminal moved into the pull-out computer (no more per-card modal):
- New infra computer app NodeTerminalApp (computer/apps/infra) — xterm bridged to
  a node's host shell over the node control channel, filling the app window
  (mirrors the agent Terminal's layout + ResizeObserver). Added "terminal" to the
  INFRA_CATALOG grid; a ?node= panel param targets a specific node (picker when
  unset). Clicking Terminal on a node card now opens the infra computer to that
  node's shell instead of a separate full-screen window. Deleted NodeTerminal.tsx.

Rebuilt + re-hosted both daemon binaries (hostname change).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-24 20:13:15 -07:00
co-authored by Claude Opus 4.8
parent cfa16751c5
commit cf6c331b02
10 changed files with 180 additions and 96 deletions
@@ -2,12 +2,13 @@
// 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 { Activity, Cloud, Plus, Server, Settings, Terminal } from "lucide-react";
import type { CSSProperties } from "react";
import type { AppId } from "@/lib/url/panel-params";
import { InfraApp } from "../apps/infra/InfraApp";
import { NodeTerminalApp } from "../apps/infra/NodeTerminalApp";
import type { ComputerCatalog } from "../catalog";
import { LetterTile } from "../tiles";
@@ -19,6 +20,7 @@ const TITLES: Record<string, string> = {
status: "Fleet Status",
settings: "Settings",
apps: "Add Cloud",
terminal: "Terminal",
};
const notConnected = [
@@ -29,6 +31,8 @@ const notConnected = [
function render(app: AppId) {
switch (app) {
case "terminal":
return <NodeTerminalApp />;
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":
@@ -59,6 +63,7 @@ function render(app: AppId) {
export const INFRA_CATALOG: ComputerCatalog = {
grid: [
{ app: "terminal", label: "Terminal" },
{ app: "aws", label: "AWS" },
{ app: "gcp", label: "GCP" },
{ app: "azure", label: "Azure" },
@@ -69,7 +74,7 @@ export const INFRA_CATALOG: ComputerCatalog = {
{ app: "status", label: "Status" },
{ app: "settings", label: "Settings" },
],
icon: { hosts: Server, status: Activity, settings: Settings, apps: Plus, aws: Cloud, gcp: Cloud, azure: Cloud },
icon: { hosts: Server, status: Activity, settings: Settings, apps: Plus, aws: Cloud, gcp: Cloud, azure: Cloud, terminal: Terminal },
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%)" />;