import { useState, type FormEvent } from "react"; import { Link } from "react-router"; import { api, ApiError, type Agent, type Project } from "../api"; import { useFetch, ago, fmtDate } from "../hooks"; import { Badge, Empty, ErrorBox, Loading, Td } from "../components/ui"; import { useMe } from "../App"; export default function Projects() { const { me } = useMe(); const { data, error, loading, reload } = useFetch<{ projects: Project[] }>("projects"); const agents = useFetch<{ agents: Agent[] }>("agents"); const [form, setForm] = useState({ slug: "", name: "", policy_mode: "development" }); const [ag, setAg] = useState({ name: "", kind: "claude-code", project_id: "default", execute: true, discover: true, export: false }); const [err, setErr] = useState(null); const canWrite = me?.role === "admin" || me?.role === "operator"; const create = async (e: FormEvent) => { e.preventDefault(); setErr(null); try { await api("projects", { body: form }); setForm({ slug: "", name: "", policy_mode: "development" }); reload(); } catch (ex) { setErr(ex as ApiError); } }; const createAgent = async (e: FormEvent) => { e.preventDefault(); setErr(null); try { await api("agents", { body: { name: ag.name, kind: ag.kind, project_id: ag.project_id, permissions: { execute: ag.execute, discover: ag.discover, export: ag.export } } }); setAg({ ...ag, name: "" }); agents.reload(); } catch (ex) { setErr(ex as ApiError); } }; return (

Agents & Projects

Projects

{loading && } {data && data.projects.length === 0 && No projects.} {data && data.projects.length > 0 && {data.projects.map((p) => )}
ProjectModeExecutions24 hDatasetsAgents
{p.name} {p.slug}{p.executions ?? 0}{p.executions_24h ?? 0}{p.datasets ?? 0}{p.agents ?? 0}
} {canWrite &&

New project

setForm({ ...form, slug: e.target.value })} />
setForm({ ...form, name: e.target.value })} />
}

Agents

{agents.loading && } {agents.data && agents.data.agents.length === 0 && No agents yet. Agents are created on first execution (agent_name) or below.} {agents.data && agents.data.agents.length > 0 && {agents.data.agents.map((a) => )}
AgentProjectPermissionsBudget/dayExecutionsLast seen
{a.name} {a.kind}{a.project_slug ?? "—"}{Object.entries(a.permissions).filter(([, v]) => v).map(([k]) => k).join(", ") || "none"}{a.budget?.max_executions_per_day ?? "—"}{a.executions ?? 0} ({a.executions_24h ?? 0} / 24 h){a.last_seen_at ? ago(a.last_seen_at) : fmtDate(a.created_at)}
} {canWrite &&

New agent

setAg({ ...ag, name: e.target.value })} />
setAg({ ...ag, kind: e.target.value })} />
{(["execute", "discover", "export"] as const).map((k) => )}
}
); }