Files
pi-kit/extensions/gitlab-tools.ts
T

78 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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 { mrCreate, pipelineStatus, codeSearch, deriveProjectFromOrigin } from "./lib/gitlab.ts";
export default function gitlabToolsExtension(pi: ExtensionAPI) {
const register = (name: string, description: string, parameters: Record<string, unknown>, run: (p: any) => Promise<unknown>) => {
pi.registerTool({
name,
label: name,
description,
parameters: parameters as any,
async execute(_id: string, params: unknown) {
try {
const out = await run(params ?? {});
return { content: [{ type: "text", text: JSON.stringify(out ?? {}, null, 2) }], details: {} };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
return { content: [{ type: "text", text: `gitlab error: ${msg}` }], isError: true, details: {} };
}
},
});
};
register(
"gitlab_mr_create",
"Создать merge request в GitLab. Проект определяется из git remote origin (или укажи project).",
{
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"],
},
async (p) => mrCreate({ title: p.title, sourceBranch: p.sourceBranch || undefined, targetBranch: p.targetBranch, project: p.project, removeSourceBranch: p.removeSourceBranch, mergeWhenPipelineSucceeds: p.mergeWhenPipelineSucceeds }),
);
register(
"gitlab_pipeline_status",
"Показать статусы CI/CD пайплайнов проекта GitLab (по ветке).",
{
type: "object",
properties: {
project: { type: "string", description: "Группа/репозиторий (обязательно; например group/name)" },
ref: { type: "string", description: "Ветка/тег, по которому фильтровать" },
perPage: { type: "number", description: "Сколько последних пайплайнов (default 10)" },
},
required: ["project"],
},
async (p) => pipelineStatus(p.project, { ref: p.ref, perPage: p.perPage }),
);
register(
"gitlab_code_search",
"Поиск по коду в GitLab (blobs). Требует scope api/read_api у токена.",
{
type: "object",
properties: {
query: { type: "string", description: "Строка поиска (до 512 символов)" },
project: { type: "string", description: "Ограничить поиск группой/репозиторием" },
perPage: { type: "number", description: "Макс. результатов (default 20)" },
},
required: ["query"],
},
async (p) => codeSearch(p.query, { project: p.project, perPage: p.perPage }),
);
}