Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions apps/agents/agent/channels/operator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { randomUUID } from "node:crypto";

import { defineChannel, GET, POST } from "eve/channels";

import { WEEKLY_EXAMPLES_MAINTENANCE_PROMPT } from "../lib/weekly-examples-maintenance.js";

const APP_AUTH = {
attributes: {},
authenticator: "app",
principalId: "eve:app",
principalType: "runtime"
} as const;

export default defineChannel({
routes: [
POST("/eve/v1/operator/runs", async (request, { send }) => {
const origin = request.headers.get("origin");
if (
origin !== new URL(request.url).origin ||
request.headers.get("x-operator-action") !== "run-weekly-maintenance" ||
!request.headers.get("content-type")?.startsWith("application/json")
) {
return Response.json(
{ ok: false, error: "Invalid operator request." },
{
status: 403,
headers: { "cache-control": "no-store" }
}
);
}

const session = await send(WEEKLY_EXAMPLES_MAINTENANCE_PROMPT, {
auth: APP_AUTH,
continuationToken: randomUUID(),
mode: "task",
title: "Weekly examples maintenance"
});

return Response.json(
{ cursor: 0, sessionId: session.id, state: "running" },
{ status: 202, headers: { "cache-control": "no-store" } }
);
}),
GET(
"/eve/v1/operator/runs/:sessionId/status",
async (request, { getSession, params }) => {
const cursorValue = new URL(request.url).searchParams.get("cursor");
const startIndex = cursorValue === null ? 0 : Number(cursorValue);
if (!Number.isInteger(startIndex) || startIndex < 0) {
return Response.json(
{ error: "cursor must be a non-negative integer." },
{ status: 400, headers: { "cache-control": "no-store" } }
);
}

const reader = (
await getSession(params.sessionId).getEventStream({ startIndex })
).getReader();
let cursor = startIndex;
let state: "running" | "done" | "error" = "running";
let polling = true;
const timeout = setTimeout(() => {
polling = false;
void reader.cancel();
}, 250);

try {
while (polling) {
const { done, value: event } = await reader.read();
if (done) break;
cursor += 1;
if (event.type === "session.completed") {
state = "done";
break;
}
if (event.type === "session.failed") {
state = "error";
break;
}
}
} finally {
clearTimeout(timeout);
await reader.cancel();
}

return Response.json(
{ cursor, sessionId: params.sessionId, state },
{ headers: { "cache-control": "no-store" } }
);
}
)
]
});
3 changes: 3 additions & 0 deletions apps/agents/agent/lib/weekly-examples-maintenance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const WEEKLY_EXAMPLES_MAINTENANCE_PROMPT = `Maintain every Turborepo example. Audit and update all stale dependencies, package-manager pins, Node engines, README instructions, versioned references, and inconsistent \`turbo.json\` tasks. Use exact latest stable versions, apply required best-practice migrations, regenerate lockfiles with each example's package manager, and run every relevant non-persistent validation task. Fix validation failures rather than stopping at an audit report.

When changes exist, call \`create_pull_request\` to open a draft pull request against \`vercel/turborepo\`. Summarize changed examples and validation results in the body. The tool supplies the scheduled branch, required Conventional Commit title, and commit message. If there are no changes, finish without creating a pull request.`;
7 changes: 0 additions & 7 deletions apps/agents/agent/schedules/weekly_examples_audit.md

This file was deleted.

8 changes: 8 additions & 0 deletions apps/agents/agent/schedules/weekly_examples_audit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineSchedule } from "eve/schedules";

import { WEEKLY_EXAMPLES_MAINTENANCE_PROMPT } from "../lib/weekly-examples-maintenance.js";

export default defineSchedule({
cron: "0 14 * * 1",
markdown: WEEKLY_EXAMPLES_MAINTENANCE_PROMPT
});
Loading
Loading