/** * Confluence tools — native pi tools over the corporate wiki REST API. * Thin wrappers around lib/confluence.ts. * * CONFIGURE: config/company.json → docsUrl; env.sh → CONFLUENCE_TOKEN. * DISABLE: remove/rename this file from extensions/. */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { search, pageGet, pageCreate } from "./lib/confluence.ts"; export default function confluenceToolsExtension(pi: ExtensionAPI) { const register = (name: string, description: string, parameters: Record, run: (p: any) => Promise) => { 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: `confluence error: ${msg}` }], isError: true, details: {} }; } }, }); }; register( "confluence_search", "Найти страницы в Confluence по CQL-запросу (текст/заголовок/пространство).", { type: "object", properties: { cql: { type: "string", description: 'CQL, например text="деплой" AND space = TECHRUN' }, limit: { type: "number", description: "Макс. результатов (default 25)" }, expandBody: { type: "boolean", description: "Вернуть полный текст страниц" }, }, required: ["cql"], }, async (p) => search(p.cql, { limit: p.limit, expandBody: p.expandBody }), ); register( "confluence_page_get", "Получить страницу Confluence по ID (с содержимым, если expandBody).", { type: "object", properties: { id: { type: "string", description: "ID страницы" }, expandBody: { type: "boolean", description: "Вернуть тело страницы" }, }, required: ["id"], }, async (p) => pageGet(p.id, { expandBody: p.expandBody }), ); register( "confluence_page_create", "Создать страницу в Confluence. body — HTML в Storage format.", { type: "object", properties: { spaceKey: { type: "string", description: "Ключ пространства" }, title: { type: "string", description: "Заголовок страницы" }, body: { type: "string", description: "Содержимое страницы (HTML Storage format или текст)" }, parentId: { type: "string", description: "ID родительской страницы (для вложенности)" }, }, required: ["spaceKey", "title", "body"], }, async (p) => pageCreate(p), ); }