"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import { Bot, ExternalLink, KeyRound, Plus, RefreshCw, Trash2, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { api, type Agent } from "@/lib/api"; import { formatDate } from "@/lib/utils"; export default function AgentsPage() { const [agents, setAgents] = useState(null); const [error, setError] = useState(null); async function load() { try { const list = await api.listAgents(); list.sort((a, b) => (b.updatedAt || "").localeCompare(a.updatedAt || "")); setAgents(list); setError(null); } catch (e) { setError(e instanceof Error ? e.message : "failed to load"); } } useEffect(() => { load(); }, []); async function onDelete(id: string) { if (!confirm("Remove this agent?")) return; try { await api.deleteAgent(id); await load(); } catch (e) { alert(e instanceof Error ? e.message : "delete failed"); } } return (

Agents

Agent repositories Langship watches and deploys. Add a git URL — we track the ref and trigger pipelines on push.

{error && ( {error} )} {agents === null ? ( ) : agents.length === 0 ? ( ) : (
{agents.map((a) => (
{a.name} {a.ref || "main"}
{a.hasPat && ( PAT )} {a.webhookInstalled && ( webhook )}
{a.repoUrl}
added {formatDate(a.createdAt)}
))}
)}
); } function SkeletonGrid() { return (
{Array.from({ length: 3 }).map((_, i) => (
))}
); } function EmptyState() { return (

No agents yet

Add a git repository containing your agent code.

); }