feat: branch protection + deps caching
This commit is contained in:
@@ -11,12 +11,31 @@ const dir = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
if (!existsSync(`${dir}/node_modules`)) {
|
||||
console.error("» installing dependencies...");
|
||||
|
||||
// Try to activate pnpm via corepack (Node 24 ships corepack).
|
||||
// If that works, use pnpm with the lockfile for a fast, reproducible install.
|
||||
// Otherwise fall back to plain npm install.
|
||||
let installed = false;
|
||||
try {
|
||||
execSync("corepack enable pnpm", { stdio: "pipe" });
|
||||
execSync("pnpm install --frozen-lockfile", {
|
||||
cwd: dir,
|
||||
stdio: "inherit",
|
||||
timeout: 120_000,
|
||||
});
|
||||
installed = true;
|
||||
} catch {
|
||||
// corepack or pnpm not available
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
execSync("npm install --no-fund --no-audit", {
|
||||
cwd: dir,
|
||||
stdio: "inherit",
|
||||
timeout: 120_000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const [{ main }, core] = await Promise.all([
|
||||
import(`${dir}/main.ts`),
|
||||
|
||||
@@ -169,9 +169,18 @@ export async function main(): Promise<MainResult> {
|
||||
const modes = computeModes(agentId);
|
||||
const outputSchema = resolveOutputSchema();
|
||||
|
||||
let defaultBranch = "main";
|
||||
try {
|
||||
const repoData = await gitea.request(
|
||||
"GET /repos/{owner}/{repo}",
|
||||
{ owner: repoContext.owner, repo: repoContext.name }
|
||||
);
|
||||
defaultBranch = (repoData.data as { default_branch?: string }).default_branch ?? "main";
|
||||
} catch { /* keep "main" fallback */ }
|
||||
|
||||
toolContext = {
|
||||
agentId,
|
||||
repo: repoContext,
|
||||
repo: { ...repoContext, defaultBranch },
|
||||
payload,
|
||||
gitea,
|
||||
gitToken: botToken,
|
||||
@@ -185,17 +194,6 @@ export async function main(): Promise<MainResult> {
|
||||
tmpdir,
|
||||
};
|
||||
|
||||
let defaultBranch: string | undefined;
|
||||
try {
|
||||
const repoData = await gitea.request(
|
||||
"GET /repos/{owner}/{repo}",
|
||||
{ owner: repoContext.owner, repo: repoContext.name }
|
||||
);
|
||||
defaultBranch = (repoData.data as { default_branch?: string }).default_branch;
|
||||
} catch {
|
||||
defaultBranch = "main";
|
||||
}
|
||||
|
||||
await using mcpHttpServer = await startMcpHttpServer(toolContext, { outputSchema });
|
||||
toolContext.mcpServerUrl = mcpHttpServer.url;
|
||||
log.info(`» MCP server started at ${mcpHttpServer.url}`);
|
||||
@@ -205,7 +203,7 @@ export async function main(): Promise<MainResult> {
|
||||
|
||||
const instructions = resolveInstructions({
|
||||
payload,
|
||||
repo: { owner: repoContext.owner, name: repoContext.name, ...(defaultBranch ? { defaultBranch } : {}) },
|
||||
repo: { owner: repoContext.owner, name: repoContext.name, defaultBranch },
|
||||
modes,
|
||||
agentId,
|
||||
outputSchema,
|
||||
|
||||
+2
-2
@@ -217,7 +217,7 @@ export function classifyPushError(msg: string): PushErrorKind {
|
||||
const TRANSIENT_RETRY_DELAYS_MS = [2000, 5000];
|
||||
|
||||
export function PushBranchTool(ctx: ToolContext) {
|
||||
const defaultBranch = process.env.DEFAULT_BRANCH || "main";
|
||||
const defaultBranch = ctx.repo.defaultBranch;
|
||||
const pushPermission = ctx.payload.push;
|
||||
|
||||
return tool({
|
||||
@@ -643,7 +643,7 @@ const DeleteBranch = type({
|
||||
|
||||
export function DeleteBranchTool(ctx: ToolContext) {
|
||||
const pushPermission = ctx.payload.push;
|
||||
const defaultBranch = process.env.DEFAULT_BRANCH || "main";
|
||||
const defaultBranch = ctx.repo.defaultBranch;
|
||||
|
||||
return tool({
|
||||
name: "delete_branch",
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ import { UploadFileTool } from "./upload.ts";
|
||||
|
||||
export interface ToolContext {
|
||||
agentId: "ollama";
|
||||
repo: { owner: string; name: string };
|
||||
repo: { owner: string; name: string; defaultBranch: string };
|
||||
payload: ResolvedPayload;
|
||||
gitea: Gitea;
|
||||
gitToken: string;
|
||||
|
||||
@@ -4,7 +4,7 @@ export function buildShockbotFooter(params?: {
|
||||
model?: string | undefined;
|
||||
}): string {
|
||||
const modelPart = params?.model ? ` · \`${params.model}\`` : "";
|
||||
return `\n\n<br>\n\n---\n${FOOTER_MARKER}\n*Reviewed by [shockbot](https://git.shockvpn.com)${modelPart}*`;
|
||||
return `\n\n<br>\n\n---\n${FOOTER_MARKER}\n*Reviewed by [shockbot](https://git.shockvpn.com/shockbot)${modelPart}*`;
|
||||
}
|
||||
|
||||
export function stripExistingFooter(body: string): string {
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ export function defaultRepoSettings(): RepoSettings {
|
||||
prepushScript: null,
|
||||
stopScript: null,
|
||||
push: "restricted",
|
||||
shell: "restricted",
|
||||
shell: "disabled",
|
||||
prApproveEnabled: false,
|
||||
modeInstructions: {},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user