Zopu dev bootstrap: git runtimes, Codex agent-os, dev agent
Merge t3code/explore-primitives-package onto master.
This commit is contained in:
@@ -7,6 +7,8 @@ const app = defineApp({
|
||||
NATIVE_APP_URL: v.optional(v.string()),
|
||||
SITE_URL: v.string(),
|
||||
FLUE_DB_TOKEN: v.string(),
|
||||
GITEA_URL: v.optional(v.string()),
|
||||
GITEA_TOKEN: v.optional(v.string()),
|
||||
},
|
||||
});
|
||||
app.use(betterAuth);
|
||||
|
||||
64
packages/backend/convex/workflows.ts
Normal file
64
packages/backend/convex/workflows.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
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",
|
||||
};
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user