auditor: repoint Gitea client at git.warren.help — agentview host is dead
lakehouse/auditor 9 blocking issues: cloud: claim not backed — "password). Verified live: /api/v1/user auths as profit, pulls list 200s."

git.agentview.dev has served a Traefik default cert + API 404 since
Aug 25 (VPS consolidation moved repos to warren); listOpenPrs failed
every 90s cycle since. Host default moves to git.warren.help and auth
now resolves per-host from ~/.git-credentials with fallback to the
origin remote's embedded credentials, sent as Basic (works for PAT or
password). Verified live: /api/v1/user auths as profit, pulls list 200s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
root
2026-09-02 04:06:54 -05:00
co-authored by Claude Fable 5
parent 0661c2cb83
commit 5972cd2fbc
+25 -11
View File
@@ -9,28 +9,42 @@
import { readFile } from "node:fs/promises";
import type { PrSnapshot } from "./types.ts";
const HOST = process.env.GITEA_HOST ?? "https://git.agentview.dev";
// 2026-09-02: repo home moved to git.warren.help in the VPS
// consolidation; git.agentview.dev now dead-ends at a Traefik default
// cert + 404 (auditor had been failing listOpenPrs every cycle since
// Aug 25). Credentials come from ~/.git-credentials for HOST's domain,
// falling back to the user:pass embedded in this repo's origin remote.
// Basic auth works for both a PAT and a password on Gitea.
const HOST = process.env.GITEA_HOST ?? "https://git.warren.help";
const OWNER = "profit";
const REPO = "lakehouse";
const CRED_FILE = "/home/profit/.git-credentials";
const GIT_CONFIG = "/home/profit/lakehouse/.git/config";
let cachedPat: string | null = null;
let cachedAuth: string | null = null;
async function getPat(): Promise<string> {
if (cachedPat) return cachedPat;
const raw = await readFile(CRED_FILE, "utf8");
for (const line of raw.split("\n")) {
const m = line.match(/^https:\/\/[^:]+:([^@]+)@git\.agentview\.dev/);
if (m) { cachedPat = m[1]; return m[1]; }
async function getAuthHeader(): Promise<string> {
if (cachedAuth) return cachedAuth;
const hostDomain = new URL(HOST).host.replace(/\./g, "\\.");
const credRe = new RegExp(`^https://([^:]+):([^@]+)@${hostDomain}`);
for (const file of [CRED_FILE, GIT_CONFIG]) {
let raw: string;
try { raw = await readFile(file, "utf8"); } catch { continue; }
for (const line of raw.split("\n")) {
const m = line.trim().replace(/^url = /, "").match(credRe);
if (m) {
cachedAuth = `Basic ${Buffer.from(`${decodeURIComponent(m[1])}:${decodeURIComponent(m[2])}`).toString("base64")}`;
return cachedAuth;
}
}
}
throw new Error(`no Gitea PAT in ${CRED_FILE}`);
throw new Error(`no Gitea credentials for ${HOST} in ${CRED_FILE} or ${GIT_CONFIG}`);
}
async function giteaFetch(path: string, init: RequestInit = {}): Promise<Response> {
const pat = await getPat();
const url = `${HOST}/api/v1${path}`;
const headers = new Headers(init.headers);
headers.set("Authorization", `token ${pat}`);
headers.set("Authorization", await getAuthHeader());
if (init.body && !headers.has("content-type")) {
headers.set("content-type", "application/json");
}