refactor(extensions): simplify lib helpers, tool registration and kit-doctor
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.
This commit is contained in:
@@ -6,69 +6,57 @@
|
||||
* 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 { search, pageGet, pageCreate } from "./lib/confluence.ts";
|
||||
|
||||
export default function confluenceToolsExtension(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: `confluence error: ${msg}` }], isError: true, details: {} };
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
register(
|
||||
"confluence_search",
|
||||
"Найти страницы в Confluence по CQL-запросу (текст/заголовок/пространство).",
|
||||
const tools: ToolSpec[] = [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
cql: { type: "string", description: 'CQL, например text="деплой" AND space = TECHRUN' },
|
||||
limit: { type: "number", description: "Макс. результатов (default 25)" },
|
||||
expandBody: { type: "boolean", description: "Вернуть полный текст страниц" },
|
||||
name: "confluence_search",
|
||||
description: "Найти страницы в Confluence по CQL-запросу (текст/заголовок/пространство).",
|
||||
errorPrefix: "confluence",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
cql: { type: "string", description: 'CQL, например text="деплой" AND space = TECHRUN' },
|
||||
limit: { type: "number", description: "Макс. результатов (default 25)" },
|
||||
expandBody: { type: "boolean", description: "Вернуть полный текст страниц" },
|
||||
},
|
||||
required: ["cql"],
|
||||
},
|
||||
required: ["cql"],
|
||||
run: async (p) => search(p.cql, { limit: p.limit, expandBody: p.expandBody }),
|
||||
},
|
||||
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: "Вернуть тело страницы" },
|
||||
name: "confluence_page_get",
|
||||
description: "Получить страницу Confluence по ID (с содержимым, если expandBody).",
|
||||
errorPrefix: "confluence",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: { type: "string", description: "ID страницы" },
|
||||
expandBody: { type: "boolean", description: "Вернуть тело страницы" },
|
||||
},
|
||||
required: ["id"],
|
||||
},
|
||||
required: ["id"],
|
||||
run: async (p) => pageGet(p.id, { expandBody: p.expandBody }),
|
||||
},
|
||||
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 родительской страницы (для вложенности)" },
|
||||
name: "confluence_page_create",
|
||||
description: "Создать страницу в Confluence. body — HTML в Storage format.",
|
||||
errorPrefix: "confluence",
|
||||
parameters: {
|
||||
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"],
|
||||
},
|
||||
required: ["spaceKey", "title", "body"],
|
||||
run: async (p) => pageCreate(p),
|
||||
},
|
||||
async (p) => pageCreate(p),
|
||||
);
|
||||
];
|
||||
|
||||
for (const t of tools) registerTool(pi, t);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user