"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import { ArrowLeft, Eye, EyeOff, KeyRound, Save } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { api } from "@/lib/api"; export default function NewAgentPage() { const router = useRouter(); const [repoUrl, setRepoUrl] = useState(""); const [pat, setPat] = useState(""); const [showPat, setShowPat] = useState(false); const [error, setError] = useState(null); const [saving, setSaving] = useState(false); async function onSave() { setSaving(true); setError(null); try { const url = repoUrl.trim(); if (!url) throw new Error("Repository URL is required"); await api.createAgent({ repoUrl: url, pat: pat.trim() || undefined }); router.push("/agents"); } catch (e) { setError(e instanceof Error ? e.message : "save failed"); } finally { setSaving(false); } } return (

Add agent

Link a git repository that contains your agent code. The PAT is stored encrypted server-side and used only for git operations.

Repository HTTPS or SSH URL — public repos can leave the PAT blank.
setRepoUrl(e.target.value)} placeholder="https://github.com/org/agent-repo.git" spellCheck={false} autoComplete="off" />

Name is auto-derived from the repo path (e.g.{" "} org/repo).

setPat(e.target.value)} placeholder="ghp_… or glpat_…" spellCheck={false} autoComplete="new-password" className="pr-10 font-mono text-xs" />

Required for private repos. Scope:{" "} repo read access is enough. Never returned by the API after save.

{error && (

{error}

)}
); }