// — writes a GitHub personal access token for one // agent into the swarm secret store. // PUTs `/api/hives/{hive}/agents/{agent}/github-account` — 204 on success, // 400/409/500 as `problem+json`, shown via `ApiErrorPanel` like // `LinkForgeAccountForm`. // // One token per agent. A blind set: no route hands a token back. // Whether one is stored shows on the agent panel (`LinkedAccounts`). import { useState } from "preact/hooks"; import { Panel } from "../ui/panel/Panel.js"; import { TextField } from "../ui/text-field/TextField.js"; import { Button } from "../ui/button/Button.js"; import { ExternalLink } from "../ui/external-link/ExternalLink.js"; import { FormStack } from "../ui/form-stack/FormStack.js"; import { FormResult } from "../ui/submit/FormResult.js"; import { useSubmit } from "../ui/submit/useSubmit.js"; export function LinkGithubAccountForm({ hive, agent, onClose, }: { hive: string; agent: string; onClose?: () => void; }) { const [token, setToken] = useState(""); const { state, submitting, run } = useSubmit(); function submit(e: Event) { e.preventDefault(); void run( () => fetch( `/api/hives/${encodeURIComponent(hive)}/agents/${encodeURIComponent(agent)}/github-account`, { method: "PUT", headers: { "content-type": "application/json" }, body: JSON.stringify({ token }), }, ), // The store holds the token; nothing here needs it. { onDone: () => setToken("") }, ); } return (

Writes the token to the swarm secret store. The agent fetches it within two minutes, and its gh and git push to github.com then authenticate with it. Use a dedicated bot account and a minimally scoped token, created at{" "} github.com/settings/tokens ; GitHub notifications also need the notifications scope.

( <> stored a github token for {agent} )} failed="failed to link the account" />
); }