// Gitea PR open. Reads PAT from ~/.git-credentials (set up by the // credential-helper flow). All PRs open as DRAFT so J reviews before // merge — never auto-merge. import { readFile } from "node:fs/promises"; const GITEA_HOST = "https://git.agentview.dev"; const REPO_OWNER = "profit"; const REPO_NAME = "lakehouse"; const CRED_FILE = "/home/profit/.git-credentials"; async function readPat(): Promise { const raw = await readFile(CRED_FILE, "utf8"); for (const line of raw.split("\n")) { const m = line.match(/^https:\/\/[^:]+:([^@]+)@git\.agentview\.dev/); if (m) return m[1]; } throw new Error(`no Gitea PAT found in ${CRED_FILE}`); } export interface OpenPrInput { branch: string; // head branch (just pushed) base?: string; // default "main" title: string; body: string; } export interface OpenPrResult { number: number; html_url: string; } export async function openPr(input: OpenPrInput): Promise { const pat = await readPat(); const url = `${GITEA_HOST}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/pulls`; const payload = { title: input.title, body: input.body, head: input.branch, base: input.base ?? "main", // Gitea uses "draft" flag — always on for bot PRs. draft: true, }; const r = await fetch(url, { method: "POST", headers: { "content-type": "application/json", "Authorization": `token ${pat}`, }, body: JSON.stringify(payload), signal: AbortSignal.timeout(30000), }); if (!r.ok) { throw new Error(`Gitea ${r.status}: ${await r.text()}`); } const j = await r.json() as any; return { number: j.number, html_url: j.html_url }; }