/** * GitLab tools — native pi tools over the self-hosted GitLab REST API (v4). * Thin wrappers around lib/gitlab.ts. * * CONFIGURE: config/company.json → gitHost; env.sh → GITLAB_TOKEN (scope api). * DISABLE: remove/rename this file from extensions/. */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { registerTool, type ToolSpec } from "./lib/tools.ts"; import { mrCreate, pipelineStatus, codeSearch } from "./lib/gitlab.ts"; export default function gitlabToolsExtension(pi: ExtensionAPI) { const tools: ToolSpec[] = [ { name: "gitlab_mr_create", description: "Создать merge request в GitLab. Проект определяется из git remote origin (или укажи project).", errorPrefix: "gitlab", parameters: { type: "object", properties: { title: { type: "string", description: "Заголовок MR" }, sourceBranch: { type: "string", description: "Ветка-источник (по умолчанию текущая)" }, targetBranch: { type: "string", description: "Целевая ветка (по умолчанию main)" }, project: { type: "string", description: "Группа/репозиторий, например group/name. Если пусто — берётся из origin" }, removeSourceBranch: { type: "boolean", description: "Удалить ветку после мержа (default true)" }, mergeWhenPipelineSucceeds: { type: "boolean", description: "Мержить после успешного пайплайна" }, }, required: ["title"], }, run: async (p) => mrCreate({ title: p.title, sourceBranch: p.sourceBranch || undefined, targetBranch: p.targetBranch, project: p.project, removeSourceBranch: p.removeSourceBranch, mergeWhenPipelineSucceeds: p.mergeWhenPipelineSucceeds, }), }, { name: "gitlab_pipeline_status", description: "Показать статусы CI/CD пайплайнов проекта GitLab (по ветке).", errorPrefix: "gitlab", parameters: { type: "object", properties: { project: { type: "string", description: "Группа/репозиторий (обязательно; например group/name)" }, ref: { type: "string", description: "Ветка/тег, по которому фильтровать" }, perPage: { type: "number", description: "Сколько последних пайплайнов (default 10)" }, }, required: ["project"], }, run: async (p) => pipelineStatus(p.project, { ref: p.ref, perPage: p.perPage }), }, { name: "gitlab_code_search", description: "Поиск по коду в GitLab (blobs). Требует scope api/read_api у токена.", errorPrefix: "gitlab", parameters: { type: "object", properties: { query: { type: "string", description: "Строка поиска (до 512 символов)" }, project: { type: "string", description: "Ограничить поиск группой/репозиторием" }, perPage: { type: "number", description: "Макс. результатов (default 20)" }, }, required: ["query"], }, run: async (p) => codeSearch(p.query, { project: p.project, perPage: p.perPage }), }, ]; for (const t of tools) registerTool(pi, t); }