Behavior-preserving cleanups: - extract shared resolveBaseUrl helper for jira/confluence base-URL logic - extract shared registerTool helper; port jira/gitlab/confluence tools to it - make scanSecrets declarative (filter/map) - collapse ok/warn pair into status() and drop double existsSync in kit-doctor Typecheck clean; npm test 71 PASS, 0 FAIL.
74 lines
3.3 KiB
TypeScript
74 lines
3.3 KiB
TypeScript
/**
|
||
* 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);
|
||
}
|