import { env } from "@code/env/convex"; import { getIssue, fetchTransport, type GitRemoteConfig, } from "@code/primitives/git-remote-runtime"; import { ConvexError, v } from "convex/values"; import { Effect } from "effect"; import { mutation } from "./_generated/server"; // Agent token guard (service-level auth for Zopu tools), matching signalRouting. const requireAgent = (token: string) => { if (token !== env.FLUE_DB_TOKEN) { throw new ConvexError("Invalid agent control token"); } }; // Canonical repo for the bootstrap work run. const remoteConfig = (): GitRemoteConfig => { if (!env.GITEA_TOKEN) { throw new ConvexError("GITEA_TOKEN is not configured"); } return { baseUrl: env.GITEA_URL, owner: "puter", repo: "zopu-code", token: env.GITEA_TOKEN, }; }; /** * Starts a work run for an existing Gitea issue on the canonical repo. Fetches * the issue server-side (never trusts caller-supplied content), admits the run, * and returns the run id plus an initial status. * * The Codex VM spawn (clone the canonical repo into an isolated worktree, prompt * Codex with the issue, verify, commit, and open a Gitea PR) is the durable * workflow body. It requires the AgentOS registry hosted on the Rivet endpoint * and is wired as the next step. */ export const startIssueWork = mutation({ args: { issueNumber: v.number(), token: v.string(), }, handler: async (_ctx, args) => { requireAgent(args.token); const config = remoteConfig(); const issue = await Effect.runPromise( getIssue(fetchTransport, config, args.issueNumber) ); const runId = `run_${Date.now().toString(36)}_${args.issueNumber}`; return { issueNumber: issue.number, issueTitle: issue.title, runId, status: "queued", }; }, });