"use client"; import { useActionState } from "react"; import { FormField, Select } from "@unlocalhosted/metalui"; import type { FormState } from "@/app/actions/types"; import { PlusIcon, ServerIcon, TagIcon } from "@/components/icons"; import { CopyIconButton, TextField } from "@/components/settings-fields"; import { PlateBody, PlateFooter } from "@/components/settings-plate"; import { Alert, Button } from "@/components/ui"; const expiries = [ { value: "30", label: "30 days" }, { value: "90", label: "90 days" }, { value: "180", label: "6 months" }, { value: "365", label: "1 year" }, { value: "never", label: "No expiration" }, ]; function Command({ children }: { children: string }) { return (
{children}
); } /** Registers a runner, then shows its token once with the commands that start it. */ export function NewRunnerForm({ action, origin, scopeText, }: { action: (prev: FormState, formData: FormData) => Promise; origin: string; scopeText: string; }) { const [state, formAction, pending] = useActionState(action, undefined); if (state?.token) { return ( <> Runner registered. Copy its token now — you won’t be able to see it again.
{state.token}

Start it on your machine

The runner is one file and needs Node.js 18+ and git. Download it, then start it with the token. Jobs run as the user that starts it, so use an account (or a VM or container) set aside for it.

{`curl -fsSLO ${origin}/vectrum-runner.mjs`} {`node vectrum-runner.mjs --url ${origin} --token ${state.token}`}

It shows up as online here within a few seconds. Jobs with runs-on: self-hosted{" "} run on any runner; use labels to pick particular ones.

); } return (

{scopeText}

} name="name" required maxLength={100} description="e.g. the machine it runs on." /> } name="labels" optional placeholder="docker, gpu" description={ <> Jobs pick runners by label with runs-on. Every runner also has{" "} self-hosted and its OS and architecture (e.g.{" "} linux, x64). } /> Token expiration