By request: one agent in Matrix, not several. Removes matrixBot.js, router.js (chat-vs-code-task classifier), litellm.js (claude-agent's own LiteLLM client), the matrix-bot-sdk dependency, runChatTask() and its gitea.js branch/PR helpers (createBranch/createPullRequest — only ever called from the now-removed chat flow), and every Matrix/LiteLLM env var from claude-agent's compose service. claude-agent already left the control room manually before this merge. It keeps its Gitea-webhook-triggered PR review, which never touched Matrix or LiteLLM to begin with. Makes PR #12 (the claude-bot/Hermes cross-reply cascade fix) moot — the bug can't happen once claude-agent has no Matrix client at all. Close #12 without merging once this lands.
62 lines
1.8 KiB
JavaScript
62 lines
1.8 KiB
JavaScript
import express from "express";
|
|
import crypto from "node:crypto";
|
|
import { postPRComment } from "./gitea.js";
|
|
import { reviewPullRequest } from "./runner.js";
|
|
|
|
const app = express();
|
|
app.use(
|
|
express.json({
|
|
verify: (req, _res, buf) => {
|
|
req.rawBody = buf;
|
|
},
|
|
})
|
|
);
|
|
|
|
const PORT = process.env.PORT || 3001;
|
|
const WEBHOOK_SECRET = process.env.GITEA_WEBHOOK_SECRET;
|
|
|
|
function verifySignature(req) {
|
|
if (!WEBHOOK_SECRET) return false;
|
|
const sig = req.get("X-Gitea-Signature");
|
|
if (!sig) return false;
|
|
const expected = crypto.createHmac("sha256", WEBHOOK_SECRET).update(req.rawBody).digest("hex");
|
|
const sigBuf = Buffer.from(sig, "hex");
|
|
const expBuf = Buffer.from(expected, "hex");
|
|
return sigBuf.length === expBuf.length && crypto.timingSafeEqual(sigBuf, expBuf);
|
|
}
|
|
|
|
app.get("/healthz", (_req, res) => res.send("ok"));
|
|
|
|
app.post("/webhooks/gitea", async (req, res) => {
|
|
if (!verifySignature(req)) {
|
|
return res.status(401).send("bad signature");
|
|
}
|
|
// Ack immediately — Gitea has a short webhook timeout and the review itself takes a while.
|
|
res.status(202).send("accepted");
|
|
|
|
const event = req.get("X-Gitea-Event");
|
|
const body = req.body;
|
|
|
|
try {
|
|
if (event === "pull_request" && ["opened", "synchronize"].includes(body.action)) {
|
|
const { repository, pull_request: pr } = body;
|
|
const [owner, repo] = repository.full_name.split("/");
|
|
const review = await reviewPullRequest({
|
|
owner,
|
|
repo,
|
|
ref: pr.head.sha,
|
|
cloneUrl: repository.clone_url,
|
|
prTitle: pr.title,
|
|
prBody: pr.body || "",
|
|
});
|
|
await postPRComment(owner, repo, pr.number, review);
|
|
}
|
|
} catch (err) {
|
|
console.error("webhook handling failed:", err);
|
|
}
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`claude-agent listening on :${PORT}`);
|
|
});
|