@de-otio/epimethian-mcp 6.1.1 → 6.2.1
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/dist/cli/index.js +67 -62
- package/dist/cli/index.js.map +2 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -35028,6 +35028,7 @@ __export(confluence_client_exports, {
|
|
|
35028
35028
|
ProfileNotConfiguredError: () => ProfileNotConfiguredError,
|
|
35029
35029
|
_rawCreatePage: () => _rawCreatePage,
|
|
35030
35030
|
_rawUpdatePage: () => _rawUpdatePage,
|
|
35031
|
+
_resetSiteLocaleCacheForTests: () => _resetSiteLocaleCacheForTests,
|
|
35031
35032
|
addLabels: () => addLabels,
|
|
35032
35033
|
createFooterComment: () => createFooterComment,
|
|
35033
35034
|
createInlineComment: () => createInlineComment,
|
|
@@ -35051,6 +35052,7 @@ __export(confluence_client_exports, {
|
|
|
35051
35052
|
getPageChildren: () => getPageChildren,
|
|
35052
35053
|
getPageVersionBody: () => getPageVersionBody,
|
|
35053
35054
|
getPageVersions: () => getPageVersions,
|
|
35055
|
+
getSiteDefaultLocale: () => getSiteDefaultLocale,
|
|
35054
35056
|
getSpaces: () => getSpaces,
|
|
35055
35057
|
listPages: () => listPages,
|
|
35056
35058
|
looksLikeMarkdown: () => looksLikeMarkdown,
|
|
@@ -35442,7 +35444,7 @@ async function getPage(pageId, includeBody) {
|
|
|
35442
35444
|
async function _rawCreatePage(spaceId, title, body, parentId, clientLabel) {
|
|
35443
35445
|
const cfg = await getConfig();
|
|
35444
35446
|
const pageBody = normalizeBodyForSubmit(body);
|
|
35445
|
-
const epimethianTag = `Epimethian v${"6.
|
|
35447
|
+
const epimethianTag = `Epimethian v${"6.2.1"}`;
|
|
35446
35448
|
const versionMsg = cfg.attribution && clientLabel ? `Created by ${clientLabel} (via ${epimethianTag})` : `Created by ${epimethianTag}`;
|
|
35447
35449
|
const payload = {
|
|
35448
35450
|
title,
|
|
@@ -35463,7 +35465,7 @@ async function _rawCreatePage(spaceId, title, body, parentId, clientLabel) {
|
|
|
35463
35465
|
async function _rawUpdatePage(pageId, opts) {
|
|
35464
35466
|
const cfg = await getConfig();
|
|
35465
35467
|
const newVersion = opts.version + 1;
|
|
35466
|
-
const epimethianTag = `Epimethian v${"6.
|
|
35468
|
+
const epimethianTag = `Epimethian v${"6.2.1"}`;
|
|
35467
35469
|
const effectiveClient = cfg.attribution ? opts.clientLabel : void 0;
|
|
35468
35470
|
let versionMessage;
|
|
35469
35471
|
if (opts.versionMessage && effectiveClient)
|
|
@@ -35731,6 +35733,27 @@ async function removeLabel(pageId, label) {
|
|
|
35731
35733
|
url.searchParams.set("name", label);
|
|
35732
35734
|
await confluenceRequest(url.toString(), { method: "DELETE" });
|
|
35733
35735
|
}
|
|
35736
|
+
function _resetSiteLocaleCacheForTests() {
|
|
35737
|
+
_siteLocaleCache.clear();
|
|
35738
|
+
}
|
|
35739
|
+
async function getSiteDefaultLocale(cfg) {
|
|
35740
|
+
const key = cfg.url;
|
|
35741
|
+
const cached2 = _siteLocaleCache.get(key);
|
|
35742
|
+
if (cached2 !== void 0) return cached2;
|
|
35743
|
+
const promise = (async () => {
|
|
35744
|
+
try {
|
|
35745
|
+
const res = await confluenceRequest(`${cfg.apiV1}/settings/systemInfo`);
|
|
35746
|
+
const data = await res.json();
|
|
35747
|
+
const raw = typeof data?.defaultLocale === "string" ? data.defaultLocale : void 0;
|
|
35748
|
+
if (!raw) return void 0;
|
|
35749
|
+
return raw.split(/[_-]/)[0].toLowerCase() || void 0;
|
|
35750
|
+
} catch {
|
|
35751
|
+
return void 0;
|
|
35752
|
+
}
|
|
35753
|
+
})();
|
|
35754
|
+
_siteLocaleCache.set(key, promise);
|
|
35755
|
+
return promise;
|
|
35756
|
+
}
|
|
35734
35757
|
async function getContentState(pageId) {
|
|
35735
35758
|
const cfg = await getConfig();
|
|
35736
35759
|
const url = new URL(`${cfg.apiV1}/content/${pageId}/state`);
|
|
@@ -35907,6 +35930,9 @@ function extractHeadings(storageHtml) {
|
|
|
35907
35930
|
}
|
|
35908
35931
|
return lines.length > 0 ? lines.join("\n") : "(no headings found)";
|
|
35909
35932
|
}
|
|
35933
|
+
function maskCdataForParse(storage) {
|
|
35934
|
+
return storage.replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, (m) => " ".repeat(m.length));
|
|
35935
|
+
}
|
|
35910
35936
|
function findHeadingInTree(root, headingText) {
|
|
35911
35937
|
const allHeadings = root.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
|
35912
35938
|
for (const heading2 of allHeadings) {
|
|
@@ -35921,69 +35947,47 @@ function findHeadingInTree(root, headingText) {
|
|
|
35921
35947
|
}
|
|
35922
35948
|
return null;
|
|
35923
35949
|
}
|
|
35924
|
-
function
|
|
35950
|
+
function findSectionRange(storageHtml, headingText) {
|
|
35925
35951
|
const { parse: parse5 } = require_dist2();
|
|
35926
|
-
const root = parse5(storageHtml);
|
|
35952
|
+
const root = parse5(maskCdataForParse(storageHtml));
|
|
35927
35953
|
const found = findHeadingInTree(root, headingText);
|
|
35928
35954
|
if (!found) return null;
|
|
35929
35955
|
const { siblings, startIdx, headingLevel } = found;
|
|
35930
|
-
|
|
35956
|
+
const heading2 = siblings[startIdx];
|
|
35957
|
+
let sectionEnd;
|
|
35931
35958
|
for (let i = startIdx + 1; i < siblings.length; i++) {
|
|
35932
35959
|
const node = siblings[i];
|
|
35933
35960
|
if (node.nodeType !== 1) continue;
|
|
35934
35961
|
const el = node;
|
|
35935
35962
|
const tagMatch = el.tagName?.match(/^H([1-6])$/i);
|
|
35936
35963
|
if (tagMatch && parseInt(tagMatch[1], 10) <= headingLevel) {
|
|
35937
|
-
|
|
35964
|
+
sectionEnd = el.range[0];
|
|
35938
35965
|
break;
|
|
35939
35966
|
}
|
|
35940
35967
|
}
|
|
35941
|
-
|
|
35942
|
-
|
|
35968
|
+
if (sectionEnd === void 0) {
|
|
35969
|
+
sectionEnd = startIdx + 1 < siblings.length ? siblings[siblings.length - 1].range[1] : heading2.range[1];
|
|
35970
|
+
}
|
|
35971
|
+
return {
|
|
35972
|
+
headingStart: heading2.range[0],
|
|
35973
|
+
headingEnd: heading2.range[1],
|
|
35974
|
+
sectionEnd
|
|
35975
|
+
};
|
|
35976
|
+
}
|
|
35977
|
+
function extractSection(storageHtml, headingText) {
|
|
35978
|
+
const r = findSectionRange(storageHtml, headingText);
|
|
35979
|
+
if (r === null) return null;
|
|
35980
|
+
return storageHtml.slice(r.headingStart, r.sectionEnd);
|
|
35943
35981
|
}
|
|
35944
35982
|
function extractSectionBody(storageHtml, headingText) {
|
|
35945
|
-
const
|
|
35946
|
-
|
|
35947
|
-
|
|
35948
|
-
if (!found) return null;
|
|
35949
|
-
const { siblings, startIdx, headingLevel } = found;
|
|
35950
|
-
let endIdx = siblings.length;
|
|
35951
|
-
for (let i = startIdx + 1; i < siblings.length; i++) {
|
|
35952
|
-
const node = siblings[i];
|
|
35953
|
-
if (node.nodeType !== 1) continue;
|
|
35954
|
-
const el = node;
|
|
35955
|
-
const tagMatch = el.tagName?.match(/^H([1-6])$/i);
|
|
35956
|
-
if (tagMatch && parseInt(tagMatch[1], 10) <= headingLevel) {
|
|
35957
|
-
endIdx = i;
|
|
35958
|
-
break;
|
|
35959
|
-
}
|
|
35960
|
-
}
|
|
35961
|
-
const bodyNodes = siblings.slice(startIdx + 1, endIdx);
|
|
35962
|
-
return bodyNodes.map((n) => n.toString()).join("");
|
|
35983
|
+
const r = findSectionRange(storageHtml, headingText);
|
|
35984
|
+
if (r === null) return null;
|
|
35985
|
+
return storageHtml.slice(r.headingEnd, r.sectionEnd);
|
|
35963
35986
|
}
|
|
35964
35987
|
function replaceSection(storageHtml, headingText, newContent) {
|
|
35965
|
-
const
|
|
35966
|
-
|
|
35967
|
-
|
|
35968
|
-
if (!found) return null;
|
|
35969
|
-
const { siblings, startIdx, headingLevel } = found;
|
|
35970
|
-
let endIdx = siblings.length;
|
|
35971
|
-
for (let i = startIdx + 1; i < siblings.length; i++) {
|
|
35972
|
-
const node = siblings[i];
|
|
35973
|
-
if (node.nodeType !== 1) continue;
|
|
35974
|
-
const el = node;
|
|
35975
|
-
const tagMatch = el.tagName?.match(/^H([1-6])$/i);
|
|
35976
|
-
if (tagMatch && parseInt(tagMatch[1], 10) <= headingLevel) {
|
|
35977
|
-
endIdx = i;
|
|
35978
|
-
break;
|
|
35979
|
-
}
|
|
35980
|
-
}
|
|
35981
|
-
const before = siblings.slice(0, startIdx);
|
|
35982
|
-
const heading2 = siblings[startIdx];
|
|
35983
|
-
const after = siblings.slice(endIdx);
|
|
35984
|
-
const parent = heading2.parentNode;
|
|
35985
|
-
parent.innerHTML = before.map((n) => n.toString()).join("") + heading2.toString() + newContent + after.map((n) => n.toString()).join("");
|
|
35986
|
-
return root.toString();
|
|
35988
|
+
const r = findSectionRange(storageHtml, headingText);
|
|
35989
|
+
if (r === null) return null;
|
|
35990
|
+
return storageHtml.slice(0, r.headingEnd) + newContent + storageHtml.slice(r.sectionEnd);
|
|
35987
35991
|
}
|
|
35988
35992
|
function truncateStorageFormat(storageHtml, maxLength) {
|
|
35989
35993
|
if (storageHtml.length <= maxLength) return storageHtml;
|
|
@@ -36149,7 +36153,7 @@ async function formatPage(page, optionsOrIncludeBody) {
|
|
|
36149
36153
|
}
|
|
36150
36154
|
return lines.join("\n");
|
|
36151
36155
|
}
|
|
36152
|
-
var import_turndown, CLIENT_LABEL_DISALLOWED_RE, _clientLabel, _config, ProfileNotConfiguredError, PageSchema, PagesResultSchema, SpaceSchema, SpacesResultSchema, AttachmentSchema, AttachmentsResultSchema, LabelSchema, LabelsResultSchema, ContentStateSchema, CommentSchema, CommentsResultSchema, UploadResultSchema, VersionMetadataSchema, VersionsResultSchema, V1PageVersionSchema, ConfluenceApiError, ConfluenceAuthError, ConfluencePermissionError, ConfluenceNotFoundError, ConfluenceConflictError, UserSchema, UserSearchResultSchema, ATTRIBUTION_LABEL, LEGACY_ATTRIBUTION_LABEL, DANGEROUS_TAG_RE, HTML_TAG_RE, HTML_ENTITY_RE, SAFE_MACRO_PARAMS;
|
|
36156
|
+
var import_turndown, CLIENT_LABEL_DISALLOWED_RE, _clientLabel, _config, ProfileNotConfiguredError, PageSchema, PagesResultSchema, SpaceSchema, SpacesResultSchema, AttachmentSchema, AttachmentsResultSchema, LabelSchema, LabelsResultSchema, ContentStateSchema, CommentSchema, CommentsResultSchema, UploadResultSchema, VersionMetadataSchema, VersionsResultSchema, V1PageVersionSchema, ConfluenceApiError, ConfluenceAuthError, ConfluencePermissionError, ConfluenceNotFoundError, ConfluenceConflictError, UserSchema, UserSearchResultSchema, ATTRIBUTION_LABEL, LEGACY_ATTRIBUTION_LABEL, _siteLocaleCache, DANGEROUS_TAG_RE, HTML_TAG_RE, HTML_ENTITY_RE, SAFE_MACRO_PARAMS;
|
|
36153
36157
|
var init_confluence_client = __esm({
|
|
36154
36158
|
"src/server/confluence-client.ts"() {
|
|
36155
36159
|
"use strict";
|
|
@@ -36307,6 +36311,7 @@ var init_confluence_client = __esm({
|
|
|
36307
36311
|
});
|
|
36308
36312
|
ATTRIBUTION_LABEL = "epimethian-edited";
|
|
36309
36313
|
LEGACY_ATTRIBUTION_LABEL = "epimethian-managed";
|
|
36314
|
+
_siteLocaleCache = /* @__PURE__ */ new Map();
|
|
36310
36315
|
DANGEROUS_TAG_RE = /<(ac:structured-macro|script|iframe|embed|object)[\s\S]*?<\/\1>|<(ac:structured-macro|script|iframe|embed|object)[^>]*\/>/gi;
|
|
36311
36316
|
HTML_TAG_RE = /<\/?[a-z][a-z0-9]*(?::[a-z][a-z0-9-]*)?[\s>\/]/i;
|
|
36312
36317
|
HTML_ENTITY_RE = /&(?:[a-zA-Z]+|#x?[0-9a-fA-F]+);/;
|
|
@@ -47082,11 +47087,11 @@ function parseBudget(envValue, fallback) {
|
|
|
47082
47087
|
}
|
|
47083
47088
|
return n;
|
|
47084
47089
|
}
|
|
47085
|
-
var
|
|
47090
|
+
var WINDOW_MS, DEFAULT_SESSION_BUDGET, DEFAULT_HOURLY_BUDGET, WriteBudget, WRITE_BUDGET_EXCEEDED, WriteBudgetExceededError, writeBudget;
|
|
47086
47091
|
var init_write_budget = __esm({
|
|
47087
47092
|
"src/server/write-budget.ts"() {
|
|
47088
47093
|
"use strict";
|
|
47089
|
-
|
|
47094
|
+
WINDOW_MS = 15 * 60 * 1e3;
|
|
47090
47095
|
DEFAULT_SESSION_BUDGET = 100;
|
|
47091
47096
|
DEFAULT_HOURLY_BUDGET = 25;
|
|
47092
47097
|
WriteBudget = class {
|
|
@@ -47113,7 +47118,7 @@ var init_write_budget = __esm({
|
|
|
47113
47118
|
*/
|
|
47114
47119
|
consume() {
|
|
47115
47120
|
const now = Date.now();
|
|
47116
|
-
const cutoff = now -
|
|
47121
|
+
const cutoff = now - WINDOW_MS;
|
|
47117
47122
|
this.hourlyTimestamps = this.hourlyTimestamps.filter((ts) => ts >= cutoff);
|
|
47118
47123
|
const sessionLimit = this.sessionLimit;
|
|
47119
47124
|
if (sessionLimit > 0 && this.sessionCount >= sessionLimit) {
|
|
@@ -47127,10 +47132,10 @@ var init_write_budget = __esm({
|
|
|
47127
47132
|
const hourlyLimit = this.hourlyLimit;
|
|
47128
47133
|
if (hourlyLimit > 0 && this.hourlyTimestamps.length >= hourlyLimit) {
|
|
47129
47134
|
const oldest = this.hourlyTimestamps[0];
|
|
47130
|
-
const waitMs = Math.max(0, oldest +
|
|
47135
|
+
const waitMs = Math.max(0, oldest + WINDOW_MS - now);
|
|
47131
47136
|
const waitMin = Math.ceil(waitMs / 6e4);
|
|
47132
47137
|
throw new WriteBudgetExceededError(
|
|
47133
|
-
`
|
|
47138
|
+
`Rolling write budget exhausted: ${this.hourlyTimestamps.length} writes in the last 15 min, limit ${hourlyLimit}. Window opens again in ~${waitMin} min. Raise the cap with EPIMETHIAN_WRITE_BUDGET_HOURLY=<n> (or 0 to disable).`,
|
|
47134
47139
|
"hourly",
|
|
47135
47140
|
this.hourlyTimestamps.length,
|
|
47136
47141
|
hourlyLimit
|
|
@@ -47146,7 +47151,7 @@ var init_write_budget = __esm({
|
|
|
47146
47151
|
/** Current hourly counter (for observability). */
|
|
47147
47152
|
get hourly() {
|
|
47148
47153
|
const now = Date.now();
|
|
47149
|
-
const cutoff = now -
|
|
47154
|
+
const cutoff = now - WINDOW_MS;
|
|
47150
47155
|
this.hourlyTimestamps = this.hourlyTimestamps.filter((ts) => ts >= cutoff);
|
|
47151
47156
|
return this.hourlyTimestamps.length;
|
|
47152
47157
|
}
|
|
@@ -48704,7 +48709,7 @@ __export(upgrade_exports, {
|
|
|
48704
48709
|
runUpgrade: () => runUpgrade
|
|
48705
48710
|
});
|
|
48706
48711
|
async function runUpgrade() {
|
|
48707
|
-
const currentVersion = "6.
|
|
48712
|
+
const currentVersion = "6.2.1";
|
|
48708
48713
|
console.log(`epimethian-mcp upgrade: current version v${currentVersion}`);
|
|
48709
48714
|
let pending = await getPendingUpdate();
|
|
48710
48715
|
if (!pending) {
|
|
@@ -61787,7 +61792,7 @@ ${titleFenced}${echo2}`
|
|
|
61787
61792
|
inputSchema: {}
|
|
61788
61793
|
},
|
|
61789
61794
|
async () => {
|
|
61790
|
-
let text2 = `epimethian-mcp v${"6.
|
|
61795
|
+
let text2 = `epimethian-mcp v${"6.2.1"}`;
|
|
61791
61796
|
try {
|
|
61792
61797
|
const pending = await getPendingUpdate();
|
|
61793
61798
|
if (pending) {
|
|
@@ -61818,7 +61823,7 @@ ${label} update available: v${pending.current} \u2192 v${pending.latest}. Run \`
|
|
|
61818
61823
|
const pending = await getPendingUpdate();
|
|
61819
61824
|
if (!pending) {
|
|
61820
61825
|
return toolResult(
|
|
61821
|
-
`epimethian-mcp v${"6.
|
|
61826
|
+
`epimethian-mcp v${"6.2.1"} is already up to date.`
|
|
61822
61827
|
);
|
|
61823
61828
|
}
|
|
61824
61829
|
const output = await performUpgrade(pending.latest);
|
|
@@ -61840,7 +61845,7 @@ async function startRecoveryServer(profile) {
|
|
|
61840
61845
|
const server = new McpServer(
|
|
61841
61846
|
{
|
|
61842
61847
|
name: `confluence-${profile}-setup-needed`,
|
|
61843
|
-
version: "6.
|
|
61848
|
+
version: "6.2.1"
|
|
61844
61849
|
},
|
|
61845
61850
|
{
|
|
61846
61851
|
instructions: `The Confluence profile "${profile}" referenced by CONFLUENCE_PROFILE has no keychain entry, so no Confluence tools are available. Call the setup_profile tool for instructions to create it.`
|
|
@@ -61891,21 +61896,21 @@ async function main() {
|
|
|
61891
61896
|
const serverName = config3.profile ? `confluence-${config3.profile}` : "confluence";
|
|
61892
61897
|
const server = new McpServer({
|
|
61893
61898
|
name: serverName,
|
|
61894
|
-
version: "6.
|
|
61899
|
+
version: "6.2.1"
|
|
61895
61900
|
});
|
|
61896
61901
|
await registerTools(server, config3);
|
|
61897
61902
|
const transport = new StdioServerTransport();
|
|
61898
61903
|
await server.connect(transport);
|
|
61899
61904
|
try {
|
|
61900
61905
|
const pending = await getPendingUpdate();
|
|
61901
|
-
if (pending && pending.current === "6.
|
|
61906
|
+
if (pending && pending.current === "6.2.1") {
|
|
61902
61907
|
console.error(
|
|
61903
61908
|
`epimethian-mcp: update available: v${pending.current} \u2192 v${pending.latest} (${pending.type}). Run \`epimethian-mcp upgrade\` to install.`
|
|
61904
61909
|
);
|
|
61905
61910
|
}
|
|
61906
61911
|
} catch {
|
|
61907
61912
|
}
|
|
61908
|
-
checkForUpdates("6.
|
|
61913
|
+
checkForUpdates("6.2.1").catch(() => {
|
|
61909
61914
|
});
|
|
61910
61915
|
}
|
|
61911
61916
|
|