import { type } from "arktype"; import { log } from "../utils/cli.ts"; import type { ToolContext } from "./server.ts"; import { execute, tool } from "./shared.ts"; interface GiteaLabel { id: number; name?: string } export const AddLabelsParams = type({ issue_number: type.number.describe("the issue or PR number to add labels to"), labels: type.string.array().atLeastLength(1).describe("array of label names to add"), }); export function AddLabelsTool(ctx: ToolContext) { return tool({ name: "add_labels", description: "Add labels to a Gitea issue or pull request. Only use labels that already exist in the repository.", parameters: AddLabelsParams, execute: execute(async ({ issue_number, labels }) => { const allLabelsR = await ctx.gitea.request( "GET /repos/{owner}/{repo}/labels", { owner: ctx.repo.owner, repo: ctx.repo.name, limit: 50 } ); const allLabels = allLabelsR.data as GiteaLabel[]; const labelIds = labels .map((name) => allLabels.find((l) => l.name === name)?.id) .filter((id): id is number => typeof id === "number"); if (labelIds.length === 0) { return { success: true, labels: [], message: "No matching labels found in repository" }; } const r = await ctx.gitea.request( "POST /repos/{owner}/{repo}/issues/{index}/labels", { owner: ctx.repo.owner, repo: ctx.repo.name, index: issue_number, labels: labelIds } ); log.info(`ยป added labels [${labels.join(", ")}] to issue #${issue_number}`); const result = r.data as GiteaLabel[]; return { success: true, labels: result.map((l) => l.name).filter(Boolean) }; }), }); }