import { z } from "zod";
import { limitAccountWrite, limitWrite } from "../../limits";
import { createScratchFromFiles, createScratchRepo, deploySiteRef } from "../../sites/api";
import type { ScratchResult } from "../../sites/api";
import { defineTool, repoArgs, scopedRepo } from "./base";
const MAX_FILES = 500;
const MAX_FILE_CHARS = 1024 * 1024;
function scratchText(result: ScratchResult): string {
return `Live at ${result.url ?? "(sites disabled)"} until ${new Date(result.expiresAt).toISOString()}. Claim it at ${result.claimUrl} (keep the claim token secret).`;
}
const deploySiteTool = defineTool({
name: "deploy_site",
title: "Deploy site",
description:
"Deploy a repository's site from a branch: its production branch goes live, any other branch deploys a preview on its own host. Requires contents:write.",
input: z.object({
...repoArgs,
ref: z.string().max(250).optional().describe("Branch; defaults to the site's production branch"),
}),
write: true,
async run({ caller }, args) {
const { repo } = await scopedRepo(caller, args.owner, args.repo, "contents", "write");
await limitWrite(caller.viewer);
const result = await deploySiteRef(repo, { ref: args.ref, actorId: caller.viewer.id });
return {
structured: { deployment_id: result.deploymentId, environment: result.environment, url: result.url },
text: `Queued ${result.environment} deploy ${result.deploymentId}; it will be served at ${result.url ?? "(sites disabled)"}.`,
repoId: repo.id,
};
},
});
const scratchSiteTool = defineTool({
name: "create_scratch_site",
title: "Create scratch site",
description:
"Publish files as a temporary site (24 h, up to 500 files and 10 MiB) with a one-time claim token; include _worker.js for a dynamic Worker. Anyone signed in can claim it to keep it.",