@agentforge/tools 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -9
- package/dist/index.cjs +514 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -1
- package/dist/index.d.ts +99 -1
- package/dist/index.js +506 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1058,6 +1058,506 @@ function createSlackTools(config = {}) {
|
|
|
1058
1058
|
};
|
|
1059
1059
|
}
|
|
1060
1060
|
var slackTools = [sendSlackMessage, notifySlack, getSlackChannels, getSlackMessages];
|
|
1061
|
+
|
|
1062
|
+
// src/web/confluence/auth.ts
|
|
1063
|
+
function createGetConfiguredAuth(apiKey, email, siteUrl) {
|
|
1064
|
+
return function getConfiguredAuth() {
|
|
1065
|
+
const ATLASSIAN_API_KEY = apiKey || process.env.ATLASSIAN_API_KEY || "";
|
|
1066
|
+
const ATLASSIAN_EMAIL = email || process.env.ATLASSIAN_EMAIL || "";
|
|
1067
|
+
const ATLASSIAN_SITE_URL = (siteUrl || process.env.ATLASSIAN_SITE_URL || "").replace(/\/$/, "");
|
|
1068
|
+
if (!ATLASSIAN_API_KEY || !ATLASSIAN_EMAIL || !ATLASSIAN_SITE_URL) {
|
|
1069
|
+
throw new Error(
|
|
1070
|
+
"Confluence credentials not configured. Set ATLASSIAN_API_KEY, ATLASSIAN_EMAIL, and ATLASSIAN_SITE_URL in config or environment variables."
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1073
|
+
return { ATLASSIAN_API_KEY, ATLASSIAN_EMAIL, ATLASSIAN_SITE_URL };
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
function createGetConfiguredAuthHeader(getConfiguredAuth) {
|
|
1077
|
+
return function getConfiguredAuthHeader() {
|
|
1078
|
+
const { ATLASSIAN_API_KEY, ATLASSIAN_EMAIL } = getConfiguredAuth();
|
|
1079
|
+
const auth = Buffer.from(`${ATLASSIAN_EMAIL}:${ATLASSIAN_API_KEY}`).toString("base64");
|
|
1080
|
+
return `Basic ${auth}`;
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
function getConfig() {
|
|
1084
|
+
const ATLASSIAN_API_KEY = process.env.ATLASSIAN_API_KEY || "";
|
|
1085
|
+
const ATLASSIAN_EMAIL = process.env.ATLASSIAN_EMAIL || "";
|
|
1086
|
+
const ATLASSIAN_SITE_URL = (process.env.ATLASSIAN_SITE_URL || "").replace(/\/$/, "");
|
|
1087
|
+
if (!ATLASSIAN_API_KEY || !ATLASSIAN_EMAIL || !ATLASSIAN_SITE_URL) {
|
|
1088
|
+
throw new Error("Confluence credentials not configured. Set ATLASSIAN_API_KEY, ATLASSIAN_EMAIL, and ATLASSIAN_SITE_URL in .env");
|
|
1089
|
+
}
|
|
1090
|
+
return { ATLASSIAN_API_KEY, ATLASSIAN_EMAIL, ATLASSIAN_SITE_URL };
|
|
1091
|
+
}
|
|
1092
|
+
function getAuthHeader() {
|
|
1093
|
+
const { ATLASSIAN_API_KEY, ATLASSIAN_EMAIL } = getConfig();
|
|
1094
|
+
const auth = Buffer.from(`${ATLASSIAN_EMAIL}:${ATLASSIAN_API_KEY}`).toString("base64");
|
|
1095
|
+
return `Basic ${auth}`;
|
|
1096
|
+
}
|
|
1097
|
+
function createSearchConfluenceTool(getAuth, getAuthHeader2, logger4) {
|
|
1098
|
+
return core.toolBuilder().name("search-confluence").description("Search for pages in Confluence using keywords or CQL (Confluence Query Language). Returns matching pages with titles, IDs, and excerpts.").category(core.ToolCategory.WEB).tag("confluence").tag("search").tag("knowledge-base").usageNotes("Use this to find relevant documentation, policies, or information in Confluence. You can search by keywords or use CQL for advanced queries (e.g., 'space=AI AND type=page'). Use get-confluence-page to retrieve full content of specific pages.").suggests(["get-confluence-page"]).schema(zod.z.object({
|
|
1099
|
+
query: zod.z.string().describe("Search query or CQL expression (e.g., 'payment processing' or 'space=BL3 AND title~payment')"),
|
|
1100
|
+
limit: zod.z.number().optional().describe("Maximum number of results to return (default: 10, max: 25)")
|
|
1101
|
+
})).implement(async ({ query, limit = 10 }) => {
|
|
1102
|
+
logger4.info("search-confluence called", { query, limit });
|
|
1103
|
+
try {
|
|
1104
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1105
|
+
const response = await axios__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/search`, {
|
|
1106
|
+
headers: {
|
|
1107
|
+
Authorization: getAuthHeader2(),
|
|
1108
|
+
Accept: "application/json"
|
|
1109
|
+
},
|
|
1110
|
+
params: {
|
|
1111
|
+
cql: query,
|
|
1112
|
+
limit: Math.min(limit, 25),
|
|
1113
|
+
expand: "space,version"
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
const { ATLASSIAN_SITE_URL: siteUrl } = getAuth();
|
|
1117
|
+
const results = response.data.results.map((page) => ({
|
|
1118
|
+
id: page.id,
|
|
1119
|
+
title: page.title,
|
|
1120
|
+
type: page.type,
|
|
1121
|
+
space: page.space?.name || "Unknown",
|
|
1122
|
+
spaceKey: page.space?.key || "",
|
|
1123
|
+
url: `${siteUrl}/wiki${page._links.webui}`,
|
|
1124
|
+
lastModified: page.version?.when || ""
|
|
1125
|
+
}));
|
|
1126
|
+
if (results.length === 0) {
|
|
1127
|
+
logger4.warn("search-confluence returned NO RESULTS - this is a valid outcome, agent should not retry", {
|
|
1128
|
+
query,
|
|
1129
|
+
limit,
|
|
1130
|
+
totalSize: response.data.totalSize
|
|
1131
|
+
});
|
|
1132
|
+
} else {
|
|
1133
|
+
logger4.info("search-confluence result", {
|
|
1134
|
+
query,
|
|
1135
|
+
resultCount: results.length,
|
|
1136
|
+
totalSize: response.data.totalSize,
|
|
1137
|
+
titles: results.map((r) => r.title).slice(0, 3)
|
|
1138
|
+
// Log first 3 titles
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
return JSON.stringify({
|
|
1142
|
+
success: true,
|
|
1143
|
+
count: results.length,
|
|
1144
|
+
total: response.data.totalSize,
|
|
1145
|
+
results
|
|
1146
|
+
});
|
|
1147
|
+
} catch (error) {
|
|
1148
|
+
logger4.error("search-confluence error", {
|
|
1149
|
+
query,
|
|
1150
|
+
error: error.response?.data?.message || error.message,
|
|
1151
|
+
status: error.response?.status
|
|
1152
|
+
});
|
|
1153
|
+
return JSON.stringify({
|
|
1154
|
+
success: false,
|
|
1155
|
+
error: error.response?.data?.message || error.message
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
}).build();
|
|
1159
|
+
}
|
|
1160
|
+
function createGetConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
1161
|
+
return core.toolBuilder().name("get-confluence-page").description("Get the full content of a specific Confluence page by its ID. Returns the page title, content (in storage format), space, and metadata.").category(core.ToolCategory.WEB).tag("confluence").tag("page").tag("content").usageNotes("Use this after search-confluence to retrieve the full content of a specific page. The page ID can be found in search results.").requires(["search-confluence"]).schema(zod.z.object({
|
|
1162
|
+
page_id: zod.z.string().describe("The Confluence page ID (from search results)")
|
|
1163
|
+
})).implement(async ({ page_id }) => {
|
|
1164
|
+
logger4.info("get-confluence-page called", { page_id });
|
|
1165
|
+
try {
|
|
1166
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1167
|
+
const response = await axios__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`, {
|
|
1168
|
+
headers: {
|
|
1169
|
+
Authorization: getAuthHeader2(),
|
|
1170
|
+
Accept: "application/json"
|
|
1171
|
+
},
|
|
1172
|
+
params: {
|
|
1173
|
+
expand: "body.storage,space,version,history"
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
const page = response.data;
|
|
1177
|
+
logger4.info("get-confluence-page result", {
|
|
1178
|
+
page_id,
|
|
1179
|
+
title: page.title,
|
|
1180
|
+
space: page.space?.name,
|
|
1181
|
+
contentLength: page.body?.storage?.value?.length || 0
|
|
1182
|
+
});
|
|
1183
|
+
return JSON.stringify({
|
|
1184
|
+
success: true,
|
|
1185
|
+
page: {
|
|
1186
|
+
id: page.id,
|
|
1187
|
+
title: page.title,
|
|
1188
|
+
type: page.type,
|
|
1189
|
+
space: page.space?.name || "Unknown",
|
|
1190
|
+
spaceKey: page.space?.key || "",
|
|
1191
|
+
content: page.body?.storage?.value || "",
|
|
1192
|
+
url: `${ATLASSIAN_SITE_URL}/wiki${page._links.webui}`,
|
|
1193
|
+
created: page.history?.createdDate || "",
|
|
1194
|
+
lastModified: page.version?.when || "",
|
|
1195
|
+
version: page.version?.number || 1
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
} catch (error) {
|
|
1199
|
+
logger4.error("get-confluence-page error", {
|
|
1200
|
+
page_id,
|
|
1201
|
+
error: error.response?.data?.message || error.message,
|
|
1202
|
+
status: error.response?.status
|
|
1203
|
+
});
|
|
1204
|
+
return JSON.stringify({
|
|
1205
|
+
success: false,
|
|
1206
|
+
error: error.response?.data?.message || error.message
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
}).build();
|
|
1210
|
+
}
|
|
1211
|
+
function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger4) {
|
|
1212
|
+
return core.toolBuilder().name("list-confluence-spaces").description("List all available Confluence spaces. Returns space names, keys, types, and descriptions to help identify where to search for information.").category(core.ToolCategory.WEB).tag("confluence").tag("spaces").tag("list").usageNotes("Use this first to discover available spaces before searching. Helps narrow down searches to specific areas (e.g., 'AI', 'BL3', 'Finance').").follows(["search-confluence"]).schema(zod.z.object({
|
|
1213
|
+
limit: zod.z.number().optional().describe("Maximum number of spaces to return (default: 25)")
|
|
1214
|
+
})).implement(async ({ limit = 25 }) => {
|
|
1215
|
+
logger4.info("list-confluence-spaces called", { limit });
|
|
1216
|
+
try {
|
|
1217
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1218
|
+
const response = await axios__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/space`, {
|
|
1219
|
+
headers: {
|
|
1220
|
+
Authorization: getAuthHeader2(),
|
|
1221
|
+
Accept: "application/json"
|
|
1222
|
+
},
|
|
1223
|
+
params: {
|
|
1224
|
+
limit
|
|
1225
|
+
}
|
|
1226
|
+
});
|
|
1227
|
+
const spaces = response.data.results.map((space) => ({
|
|
1228
|
+
key: space.key,
|
|
1229
|
+
name: space.name,
|
|
1230
|
+
type: space.type,
|
|
1231
|
+
description: space.description?.plain?.value || "",
|
|
1232
|
+
url: `${ATLASSIAN_SITE_URL}/wiki${space._links.webui}`
|
|
1233
|
+
}));
|
|
1234
|
+
logger4.info("list-confluence-spaces result", {
|
|
1235
|
+
spaceCount: spaces.length,
|
|
1236
|
+
spaceKeys: spaces.map((s) => s.key).slice(0, 5)
|
|
1237
|
+
// Log first 5 space keys
|
|
1238
|
+
});
|
|
1239
|
+
return JSON.stringify({
|
|
1240
|
+
success: true,
|
|
1241
|
+
count: spaces.length,
|
|
1242
|
+
spaces
|
|
1243
|
+
});
|
|
1244
|
+
} catch (error) {
|
|
1245
|
+
logger4.error("list-confluence-spaces error", {
|
|
1246
|
+
error: error.response?.data?.message || error.message,
|
|
1247
|
+
status: error.response?.status
|
|
1248
|
+
});
|
|
1249
|
+
return JSON.stringify({
|
|
1250
|
+
success: false,
|
|
1251
|
+
error: error.response?.data?.message || error.message
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
}).build();
|
|
1255
|
+
}
|
|
1256
|
+
function createGetSpacePagesTool(getAuth, getAuthHeader2, logger4) {
|
|
1257
|
+
return core.toolBuilder().name("get-space-pages").description("Get all pages from a specific Confluence space by space key. Useful for browsing content in a particular area.").category(core.ToolCategory.WEB).tag("confluence").tag("space").tag("pages").usageNotes("Use this to explore all pages in a specific space. Get the space key from list-confluence-spaces first.").requires(["list-confluence-spaces"]).schema(zod.z.object({
|
|
1258
|
+
space_key: zod.z.string().describe("The space key (e.g., 'AI', 'BL3', 'FIN')"),
|
|
1259
|
+
limit: zod.z.number().optional().describe("Maximum number of pages to return (default: 25)")
|
|
1260
|
+
})).implement(async ({ space_key, limit = 25 }) => {
|
|
1261
|
+
logger4.info("get-space-pages called", { space_key, limit });
|
|
1262
|
+
try {
|
|
1263
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1264
|
+
const response = await axios__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`, {
|
|
1265
|
+
headers: {
|
|
1266
|
+
Authorization: getAuthHeader2(),
|
|
1267
|
+
Accept: "application/json"
|
|
1268
|
+
},
|
|
1269
|
+
params: {
|
|
1270
|
+
spaceKey: space_key,
|
|
1271
|
+
type: "page",
|
|
1272
|
+
limit,
|
|
1273
|
+
expand: "version"
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
const pages = response.data.results.map((page) => ({
|
|
1277
|
+
id: page.id,
|
|
1278
|
+
title: page.title,
|
|
1279
|
+
url: `${ATLASSIAN_SITE_URL}/wiki${page._links.webui}`,
|
|
1280
|
+
lastModified: page.version?.when || ""
|
|
1281
|
+
}));
|
|
1282
|
+
if (pages.length === 0) {
|
|
1283
|
+
logger4.warn("get-space-pages returned NO PAGES - this is a valid outcome, agent should not retry", {
|
|
1284
|
+
space_key,
|
|
1285
|
+
limit
|
|
1286
|
+
});
|
|
1287
|
+
} else {
|
|
1288
|
+
logger4.info("get-space-pages result", {
|
|
1289
|
+
space_key,
|
|
1290
|
+
pageCount: pages.length,
|
|
1291
|
+
titles: pages.map((p) => p.title).slice(0, 3)
|
|
1292
|
+
// Log first 3 titles
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
return JSON.stringify({
|
|
1296
|
+
success: true,
|
|
1297
|
+
space: space_key,
|
|
1298
|
+
count: pages.length,
|
|
1299
|
+
pages
|
|
1300
|
+
});
|
|
1301
|
+
} catch (error) {
|
|
1302
|
+
logger4.error("get-space-pages error", {
|
|
1303
|
+
space_key,
|
|
1304
|
+
error: error.response?.data?.message || error.message,
|
|
1305
|
+
status: error.response?.status
|
|
1306
|
+
});
|
|
1307
|
+
return JSON.stringify({
|
|
1308
|
+
success: false,
|
|
1309
|
+
error: error.response?.data?.message || error.message
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
}).build();
|
|
1313
|
+
}
|
|
1314
|
+
function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
1315
|
+
return core.toolBuilder().name("create-confluence-page").description("Create a new page in a Confluence space. Requires space key, page title, and content (in HTML storage format).").category(core.ToolCategory.WEB).tag("confluence").tag("create").tag("write").usageNotes("Use this to create new documentation pages. Content should be in Confluence storage format (HTML). Get the space key from list-confluence-spaces first. Be mindful of creating duplicate pages.").requires(["list-confluence-spaces"]).schema(zod.z.object({
|
|
1316
|
+
space_key: zod.z.string().describe("The space key where the page will be created (e.g., 'AI', 'BL3')"),
|
|
1317
|
+
title: zod.z.string().describe("The title of the new page"),
|
|
1318
|
+
content: zod.z.string().describe("The page content in HTML format (Confluence storage format)"),
|
|
1319
|
+
parent_page_id: zod.z.string().optional().describe("Optional parent page ID to create this as a child page")
|
|
1320
|
+
})).implement(async ({ space_key, title, content, parent_page_id }) => {
|
|
1321
|
+
logger4.info("create-confluence-page called", { space_key, title, hasParent: !!parent_page_id });
|
|
1322
|
+
try {
|
|
1323
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1324
|
+
const pageData = {
|
|
1325
|
+
type: "page",
|
|
1326
|
+
title,
|
|
1327
|
+
space: { key: space_key },
|
|
1328
|
+
body: {
|
|
1329
|
+
storage: {
|
|
1330
|
+
value: content,
|
|
1331
|
+
representation: "storage"
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1335
|
+
if (parent_page_id) {
|
|
1336
|
+
pageData.ancestors = [{ id: parent_page_id }];
|
|
1337
|
+
}
|
|
1338
|
+
const response = await axios__default.default.post(
|
|
1339
|
+
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`,
|
|
1340
|
+
pageData,
|
|
1341
|
+
{
|
|
1342
|
+
headers: {
|
|
1343
|
+
Authorization: getAuthHeader2(),
|
|
1344
|
+
"Content-Type": "application/json"
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
);
|
|
1348
|
+
logger4.info("create-confluence-page result", {
|
|
1349
|
+
page_id: response.data.id,
|
|
1350
|
+
title: response.data.title,
|
|
1351
|
+
space: space_key
|
|
1352
|
+
});
|
|
1353
|
+
return JSON.stringify({
|
|
1354
|
+
success: true,
|
|
1355
|
+
page: {
|
|
1356
|
+
id: response.data.id,
|
|
1357
|
+
title: response.data.title,
|
|
1358
|
+
space: space_key,
|
|
1359
|
+
url: `${ATLASSIAN_SITE_URL}/wiki${response.data._links.webui}`,
|
|
1360
|
+
version: response.data.version?.number || 1
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
} catch (error) {
|
|
1364
|
+
logger4.error("create-confluence-page error", {
|
|
1365
|
+
space_key,
|
|
1366
|
+
title,
|
|
1367
|
+
error: error.response?.data?.message || error.message,
|
|
1368
|
+
status: error.response?.status
|
|
1369
|
+
});
|
|
1370
|
+
return JSON.stringify({
|
|
1371
|
+
success: false,
|
|
1372
|
+
error: error.response?.data?.message || error.message
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
}).build();
|
|
1376
|
+
}
|
|
1377
|
+
function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
1378
|
+
return core.toolBuilder().name("update-confluence-page").description("Update an existing Confluence page's content. Requires page ID, new title, and new content.").category(core.ToolCategory.WEB).tag("confluence").tag("update").tag("write").usageNotes("Use this to update existing documentation. You must provide the page ID (from search results). The tool will automatically handle version incrementing. Always get the current page content first to avoid overwriting important information.").requires(["get-confluence-page"]).schema(zod.z.object({
|
|
1379
|
+
page_id: zod.z.string().describe("The ID of the page to update"),
|
|
1380
|
+
title: zod.z.string().describe("The new title for the page"),
|
|
1381
|
+
content: zod.z.string().describe("The new content in HTML format (Confluence storage format)")
|
|
1382
|
+
})).implement(async ({ page_id, title, content }) => {
|
|
1383
|
+
logger4.info("update-confluence-page called", { page_id, title });
|
|
1384
|
+
try {
|
|
1385
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1386
|
+
const getResponse = await axios__default.default.get(
|
|
1387
|
+
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1388
|
+
{
|
|
1389
|
+
headers: {
|
|
1390
|
+
Authorization: getAuthHeader2()
|
|
1391
|
+
},
|
|
1392
|
+
params: { expand: "version" }
|
|
1393
|
+
}
|
|
1394
|
+
);
|
|
1395
|
+
const currentVersion = getResponse.data.version.number;
|
|
1396
|
+
const updateResponse = await axios__default.default.put(
|
|
1397
|
+
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1398
|
+
{
|
|
1399
|
+
type: "page",
|
|
1400
|
+
title,
|
|
1401
|
+
version: { number: currentVersion + 1 },
|
|
1402
|
+
body: {
|
|
1403
|
+
storage: {
|
|
1404
|
+
value: content,
|
|
1405
|
+
representation: "storage"
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
},
|
|
1409
|
+
{
|
|
1410
|
+
headers: {
|
|
1411
|
+
Authorization: getAuthHeader2(),
|
|
1412
|
+
"Content-Type": "application/json"
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
);
|
|
1416
|
+
logger4.info("update-confluence-page result", {
|
|
1417
|
+
page_id,
|
|
1418
|
+
title: updateResponse.data.title,
|
|
1419
|
+
previousVersion: currentVersion,
|
|
1420
|
+
newVersion: updateResponse.data.version.number
|
|
1421
|
+
});
|
|
1422
|
+
return JSON.stringify({
|
|
1423
|
+
success: true,
|
|
1424
|
+
page: {
|
|
1425
|
+
id: updateResponse.data.id,
|
|
1426
|
+
title: updateResponse.data.title,
|
|
1427
|
+
url: `${ATLASSIAN_SITE_URL}/wiki${updateResponse.data._links.webui}`,
|
|
1428
|
+
version: updateResponse.data.version.number,
|
|
1429
|
+
previousVersion: currentVersion
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
} catch (error) {
|
|
1433
|
+
logger4.error("update-confluence-page error", {
|
|
1434
|
+
page_id,
|
|
1435
|
+
title,
|
|
1436
|
+
error: error.response?.data?.message || error.message,
|
|
1437
|
+
status: error.response?.status
|
|
1438
|
+
});
|
|
1439
|
+
return JSON.stringify({
|
|
1440
|
+
success: false,
|
|
1441
|
+
error: error.response?.data?.message || error.message
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
}).build();
|
|
1445
|
+
}
|
|
1446
|
+
function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
1447
|
+
return core.toolBuilder().name("archive-confluence-page").description("Archive a Confluence page by moving it to trash. The page can be restored by space admins. Note: UI may require a note explaining why the page was archived.").category(core.ToolCategory.WEB).tag("confluence").tag("archive").tag("delete").usageNotes("Use this to archive outdated or obsolete documentation. The page is moved to trash, not permanently deleted. Space admins can restore it if needed. Be very careful - only archive pages that are truly obsolete.").conflicts(["create-confluence-page"]).schema(zod.z.object({
|
|
1448
|
+
page_id: zod.z.string().describe("The ID of the page to archive"),
|
|
1449
|
+
reason: zod.z.string().optional().describe("Optional reason for archiving (for audit trail)")
|
|
1450
|
+
})).implement(async ({ page_id, reason }) => {
|
|
1451
|
+
logger4.info("archive-confluence-page called", { page_id, reason });
|
|
1452
|
+
try {
|
|
1453
|
+
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1454
|
+
const getResponse = await axios__default.default.get(
|
|
1455
|
+
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1456
|
+
{
|
|
1457
|
+
headers: {
|
|
1458
|
+
Authorization: getAuthHeader2()
|
|
1459
|
+
},
|
|
1460
|
+
params: { expand: "version,body.storage,space" }
|
|
1461
|
+
}
|
|
1462
|
+
);
|
|
1463
|
+
const currentVersion = getResponse.data.version.number;
|
|
1464
|
+
const pageData = getResponse.data;
|
|
1465
|
+
await axios__default.default.put(
|
|
1466
|
+
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1467
|
+
{
|
|
1468
|
+
version: { number: currentVersion + 1 },
|
|
1469
|
+
title: pageData.title,
|
|
1470
|
+
type: "page",
|
|
1471
|
+
status: "trashed",
|
|
1472
|
+
body: pageData.body,
|
|
1473
|
+
space: { key: pageData.space.key }
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
headers: {
|
|
1477
|
+
Authorization: getAuthHeader2(),
|
|
1478
|
+
"Content-Type": "application/json"
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
);
|
|
1482
|
+
logger4.info("archive-confluence-page result", {
|
|
1483
|
+
page_id,
|
|
1484
|
+
title: pageData.title,
|
|
1485
|
+
previousVersion: currentVersion,
|
|
1486
|
+
newVersion: currentVersion + 1
|
|
1487
|
+
});
|
|
1488
|
+
return JSON.stringify({
|
|
1489
|
+
success: true,
|
|
1490
|
+
archived: {
|
|
1491
|
+
id: page_id,
|
|
1492
|
+
title: pageData.title,
|
|
1493
|
+
previousVersion: currentVersion,
|
|
1494
|
+
newVersion: currentVersion + 1,
|
|
1495
|
+
reason: reason || "Archived via API",
|
|
1496
|
+
note: "Page moved to trash. Space admins can restore it from the Confluence UI."
|
|
1497
|
+
}
|
|
1498
|
+
});
|
|
1499
|
+
} catch (error) {
|
|
1500
|
+
logger4.error("archive-confluence-page error", {
|
|
1501
|
+
page_id,
|
|
1502
|
+
error: error.response?.data?.message || error.message,
|
|
1503
|
+
status: error.response?.status
|
|
1504
|
+
});
|
|
1505
|
+
return JSON.stringify({
|
|
1506
|
+
success: false,
|
|
1507
|
+
error: error.response?.data?.message || error.message
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
}).build();
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
// src/web/confluence/index.ts
|
|
1514
|
+
var logLevel2 = process.env.LOG_LEVEL?.toLowerCase() || core.LogLevel.INFO;
|
|
1515
|
+
var logger2 = core.createLogger("[tools:confluence]", { level: logLevel2 });
|
|
1516
|
+
var searchConfluence = createSearchConfluenceTool(getConfig, getAuthHeader, logger2);
|
|
1517
|
+
var getConfluencePage = createGetConfluencePageTool(getConfig, getAuthHeader, logger2);
|
|
1518
|
+
var listConfluenceSpaces = createListConfluenceSpacesTool(getConfig, getAuthHeader, logger2);
|
|
1519
|
+
var getSpacePages = createGetSpacePagesTool(getConfig, getAuthHeader, logger2);
|
|
1520
|
+
var createConfluencePage = createCreateConfluencePageTool(getConfig, getAuthHeader, logger2);
|
|
1521
|
+
var updateConfluencePage = createUpdateConfluencePageTool(getConfig, getAuthHeader, logger2);
|
|
1522
|
+
var archiveConfluencePage = createArchiveConfluencePageTool(getConfig, getAuthHeader, logger2);
|
|
1523
|
+
var confluenceTools = [
|
|
1524
|
+
// Read tools
|
|
1525
|
+
searchConfluence,
|
|
1526
|
+
getConfluencePage,
|
|
1527
|
+
listConfluenceSpaces,
|
|
1528
|
+
getSpacePages,
|
|
1529
|
+
// Write tools
|
|
1530
|
+
createConfluencePage,
|
|
1531
|
+
updateConfluencePage,
|
|
1532
|
+
archiveConfluencePage
|
|
1533
|
+
];
|
|
1534
|
+
function createConfluenceTools(config = {}) {
|
|
1535
|
+
const {
|
|
1536
|
+
apiKey,
|
|
1537
|
+
email,
|
|
1538
|
+
siteUrl,
|
|
1539
|
+
logLevel: customLogLevel
|
|
1540
|
+
} = config;
|
|
1541
|
+
const getConfiguredAuth = createGetConfiguredAuth(apiKey, email, siteUrl);
|
|
1542
|
+
const getConfiguredAuthHeader = createGetConfiguredAuthHeader(getConfiguredAuth);
|
|
1543
|
+
const toolLogger = customLogLevel ? core.createLogger("tools:confluence", { level: customLogLevel }) : logger2;
|
|
1544
|
+
const searchConfluence2 = createSearchConfluenceTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1545
|
+
const getConfluencePage2 = createGetConfluencePageTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1546
|
+
const listConfluenceSpaces2 = createListConfluenceSpacesTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1547
|
+
const getSpacePages2 = createGetSpacePagesTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1548
|
+
const createConfluencePage2 = createCreateConfluencePageTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1549
|
+
const updateConfluencePage2 = createUpdateConfluencePageTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1550
|
+
const archiveConfluencePage2 = createArchiveConfluencePageTool(getConfiguredAuth, getConfiguredAuthHeader, toolLogger);
|
|
1551
|
+
return {
|
|
1552
|
+
searchConfluence: searchConfluence2,
|
|
1553
|
+
getConfluencePage: getConfluencePage2,
|
|
1554
|
+
listConfluenceSpaces: listConfluenceSpaces2,
|
|
1555
|
+
getSpacePages: getSpacePages2,
|
|
1556
|
+
createConfluencePage: createConfluencePage2,
|
|
1557
|
+
updateConfluencePage: updateConfluencePage2,
|
|
1558
|
+
archiveConfluencePage: archiveConfluencePage2
|
|
1559
|
+
};
|
|
1560
|
+
}
|
|
1061
1561
|
var jsonParser = core.toolBuilder().name("json-parser").description("Parse JSON string into an object. Validates JSON syntax and returns parsed data or error details.").category(core.ToolCategory.UTILITY).tags(["json", "parse", "data"]).schema(zod.z.object({
|
|
1062
1562
|
json: zod.z.string().describe("JSON string to parse"),
|
|
1063
1563
|
strict: zod.z.boolean().default(true).describe("Use strict JSON parsing (no trailing commas, etc.)")
|
|
@@ -2282,8 +2782,8 @@ var AskHumanInputSchema = zod.z.object({
|
|
|
2282
2782
|
*/
|
|
2283
2783
|
suggestions: zod.z.array(zod.z.string()).optional().describe("Suggested responses for the human")
|
|
2284
2784
|
});
|
|
2285
|
-
var
|
|
2286
|
-
var
|
|
2785
|
+
var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || core.LogLevel.INFO;
|
|
2786
|
+
var logger3 = core.createLogger("askHuman", { level: logLevel3 });
|
|
2287
2787
|
function createAskHumanTool() {
|
|
2288
2788
|
return core.toolBuilder().name("ask-human").description(
|
|
2289
2789
|
"Ask a human for input or approval. Use this when you need human guidance, approval for a critical action, or clarification on ambiguous requirements. The agent execution will pause until the human responds."
|
|
@@ -2316,13 +2816,13 @@ function createAskHumanTool() {
|
|
|
2316
2816
|
suggestions: validatedInput.suggestions,
|
|
2317
2817
|
status: "pending"
|
|
2318
2818
|
};
|
|
2319
|
-
|
|
2819
|
+
logger3.debug("About to call interrupt()", { humanRequest });
|
|
2320
2820
|
let response;
|
|
2321
2821
|
try {
|
|
2322
2822
|
response = interrupt(humanRequest);
|
|
2323
|
-
|
|
2823
|
+
logger3.debug("interrupt() returned successfully", { response, responseType: typeof response });
|
|
2324
2824
|
} catch (error) {
|
|
2325
|
-
|
|
2825
|
+
logger3.debug("interrupt() threw error (expected for GraphInterrupt)", {
|
|
2326
2826
|
errorType: error?.constructor?.name,
|
|
2327
2827
|
error: error instanceof Error ? error.message : String(error)
|
|
2328
2828
|
});
|
|
@@ -2350,13 +2850,17 @@ var askHumanTool = createAskHumanTool();
|
|
|
2350
2850
|
exports.AskHumanInputSchema = AskHumanInputSchema;
|
|
2351
2851
|
exports.DuckDuckGoProvider = DuckDuckGoProvider;
|
|
2352
2852
|
exports.SerperProvider = SerperProvider;
|
|
2853
|
+
exports.archiveConfluencePage = archiveConfluencePage;
|
|
2353
2854
|
exports.arrayFilter = arrayFilter;
|
|
2354
2855
|
exports.arrayGroupBy = arrayGroupBy;
|
|
2355
2856
|
exports.arrayMap = arrayMap;
|
|
2356
2857
|
exports.arraySort = arraySort;
|
|
2357
2858
|
exports.askHumanTool = askHumanTool;
|
|
2358
2859
|
exports.calculator = calculator;
|
|
2860
|
+
exports.confluenceTools = confluenceTools;
|
|
2359
2861
|
exports.createAskHumanTool = createAskHumanTool;
|
|
2862
|
+
exports.createConfluencePage = createConfluencePage;
|
|
2863
|
+
exports.createConfluenceTools = createConfluenceTools;
|
|
2360
2864
|
exports.createDuckDuckGoProvider = createDuckDuckGoProvider;
|
|
2361
2865
|
exports.createSerperProvider = createSerperProvider;
|
|
2362
2866
|
exports.createSlackTools = createSlackTools;
|
|
@@ -2381,8 +2885,10 @@ exports.fileExists = fileExists;
|
|
|
2381
2885
|
exports.fileReader = fileReader;
|
|
2382
2886
|
exports.fileSearch = fileSearch;
|
|
2383
2887
|
exports.fileWriter = fileWriter;
|
|
2888
|
+
exports.getConfluencePage = getConfluencePage;
|
|
2384
2889
|
exports.getSlackChannels = getSlackChannels;
|
|
2385
2890
|
exports.getSlackMessages = getSlackMessages;
|
|
2891
|
+
exports.getSpacePages = getSpacePages;
|
|
2386
2892
|
exports.htmlParser = htmlParser;
|
|
2387
2893
|
exports.httpClient = httpClient;
|
|
2388
2894
|
exports.httpGet = httpGet;
|
|
@@ -2395,6 +2901,7 @@ exports.jsonStringify = jsonStringify;
|
|
|
2395
2901
|
exports.jsonToCsv = jsonToCsv;
|
|
2396
2902
|
exports.jsonToXml = jsonToXml;
|
|
2397
2903
|
exports.jsonValidator = jsonValidator;
|
|
2904
|
+
exports.listConfluenceSpaces = listConfluenceSpaces;
|
|
2398
2905
|
exports.mathFunctions = mathFunctions;
|
|
2399
2906
|
exports.notifySlack = notifySlack;
|
|
2400
2907
|
exports.objectOmit = objectOmit;
|
|
@@ -2409,6 +2916,7 @@ exports.pathRelative = pathRelative;
|
|
|
2409
2916
|
exports.pathResolve = pathResolve;
|
|
2410
2917
|
exports.phoneValidator = phoneValidator;
|
|
2411
2918
|
exports.randomNumber = randomNumber;
|
|
2919
|
+
exports.searchConfluence = searchConfluence;
|
|
2412
2920
|
exports.searchResultSchema = searchResultSchema;
|
|
2413
2921
|
exports.sendSlackMessage = sendSlackMessage;
|
|
2414
2922
|
exports.slackTools = slackTools;
|
|
@@ -2420,6 +2928,7 @@ exports.stringReplace = stringReplace;
|
|
|
2420
2928
|
exports.stringSplit = stringSplit;
|
|
2421
2929
|
exports.stringSubstring = stringSubstring;
|
|
2422
2930
|
exports.stringTrim = stringTrim;
|
|
2931
|
+
exports.updateConfluencePage = updateConfluencePage;
|
|
2423
2932
|
exports.urlBuilder = urlBuilder;
|
|
2424
2933
|
exports.urlQueryParser = urlQueryParser;
|
|
2425
2934
|
exports.urlValidator = urlValidator;
|