@de-otio/epimethian-mcp 5.1.1 → 5.2.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/dist/cli/index.js CHANGED
@@ -48850,6 +48850,61 @@ init_keychain();
48850
48850
  init_profiles();
48851
48851
  init_test_connection();
48852
48852
 
48853
+ // src/server/converter/escape.ts
48854
+ function escapeXmlAttr(s) {
48855
+ let out = "";
48856
+ for (let i = 0; i < s.length; i++) {
48857
+ const ch = s.charCodeAt(i);
48858
+ switch (ch) {
48859
+ case 38:
48860
+ out += "&amp;";
48861
+ break;
48862
+ case 60:
48863
+ out += "&lt;";
48864
+ break;
48865
+ case 62:
48866
+ out += "&gt;";
48867
+ break;
48868
+ case 34:
48869
+ out += "&quot;";
48870
+ break;
48871
+ case 39:
48872
+ out += "&#39;";
48873
+ break;
48874
+ default:
48875
+ if (ch >= 0 && ch <= 31 || ch >= 127 && ch <= 159) {
48876
+ out += `&#x${ch.toString(16).toUpperCase()};`;
48877
+ } else {
48878
+ out += s[i];
48879
+ }
48880
+ }
48881
+ }
48882
+ return out;
48883
+ }
48884
+ function escapeXmlText(s) {
48885
+ let out = "";
48886
+ for (let i = 0; i < s.length; i++) {
48887
+ const ch = s.charCodeAt(i);
48888
+ switch (ch) {
48889
+ case 38:
48890
+ out += "&amp;";
48891
+ break;
48892
+ case 60:
48893
+ out += "&lt;";
48894
+ break;
48895
+ case 62:
48896
+ out += "&gt;";
48897
+ break;
48898
+ default:
48899
+ out += s[i];
48900
+ }
48901
+ }
48902
+ return out;
48903
+ }
48904
+ function escapeCdata(s) {
48905
+ return s.replace(/\]\]>/g, "]]]]><![CDATA[>");
48906
+ }
48907
+
48853
48908
  // src/server/page-cache.ts
48854
48909
  var PageCache = class {
48855
48910
  cache = /* @__PURE__ */ new Map();
@@ -48959,6 +49014,10 @@ var PageCache = class {
48959
49014
  var pageCache = new PageCache();
48960
49015
 
48961
49016
  // src/server/confluence-client.ts
49017
+ var _clientLabel;
49018
+ function setClientLabel(label) {
49019
+ _clientLabel = label ? label.slice(0, 80) : void 0;
49020
+ }
48962
49021
  var _config = null;
48963
49022
  async function resolveCredentials() {
48964
49023
  const profileEnv = process.env.CONFLUENCE_PROFILE || "";
@@ -49262,10 +49321,11 @@ async function getPage(pageId, includeBody) {
49262
49321
  }
49263
49322
  return page;
49264
49323
  }
49265
- async function createPage(spaceId, title, body, parentId) {
49324
+ async function createPage(spaceId, title, body, parentId, clientLabel) {
49266
49325
  const cfg = await getConfig();
49267
- const cleanBody = stripAttributionFooter(toStorageFormat(body));
49268
- const pageBody = cfg.attribution ? cleanBody + "\n" + buildAttributionFooter("created") : cleanBody;
49326
+ const pageBody = stripAttributionFooter(toStorageFormat(body));
49327
+ const epimethianTag = `Epimethian v${"5.2.0"}`;
49328
+ const versionMsg = cfg.attribution && clientLabel ? `Created by ${clientLabel} (via ${epimethianTag})` : `Created by ${epimethianTag}`;
49269
49329
  const payload = {
49270
49330
  title,
49271
49331
  spaceId,
@@ -49274,14 +49334,14 @@ async function createPage(spaceId, title, body, parentId) {
49274
49334
  representation: "storage",
49275
49335
  value: pageBody
49276
49336
  },
49277
- version: { message: `Created by Epimethian v${"5.1.1"}` }
49337
+ version: { message: versionMsg }
49278
49338
  };
49279
49339
  if (parentId) payload.parentId = parentId;
49280
49340
  const raw = await v2Post("/pages", payload);
49281
49341
  const page = PageSchema.parse(raw);
49282
49342
  pageCache.set(page.id, page.version?.number ?? 1, pageBody);
49283
49343
  try {
49284
- await addLabels(page.id, [ATTRIBUTION_LABEL]);
49344
+ await ensureAttributionLabel(page.id);
49285
49345
  } catch {
49286
49346
  }
49287
49347
  return page;
@@ -49289,7 +49349,17 @@ async function createPage(spaceId, title, body, parentId) {
49289
49349
  async function updatePage(pageId, opts) {
49290
49350
  const cfg = await getConfig();
49291
49351
  const newVersion = opts.version + 1;
49292
- const versionMessage = opts.versionMessage ? `${opts.versionMessage} (via Epimethian v${"5.1.1"})` : `Updated by Epimethian v${"5.1.1"}`;
49352
+ const epimethianTag = `Epimethian v${"5.2.0"}`;
49353
+ const effectiveClient = cfg.attribution ? opts.clientLabel : void 0;
49354
+ let versionMessage;
49355
+ if (opts.versionMessage && effectiveClient)
49356
+ versionMessage = `${opts.versionMessage} (${effectiveClient} via ${epimethianTag})`;
49357
+ else if (opts.versionMessage)
49358
+ versionMessage = `${opts.versionMessage} (via ${epimethianTag})`;
49359
+ else if (effectiveClient)
49360
+ versionMessage = `Updated by ${effectiveClient} (via ${epimethianTag})`;
49361
+ else
49362
+ versionMessage = `Updated by ${epimethianTag}`;
49293
49363
  const payload = {
49294
49364
  id: pageId,
49295
49365
  status: "current",
@@ -49297,8 +49367,7 @@ async function updatePage(pageId, opts) {
49297
49367
  version: { number: newVersion, message: versionMessage }
49298
49368
  };
49299
49369
  if (opts.body) {
49300
- const cleanBody = stripAttributionFooter(toStorageFormat(opts.body));
49301
- const pageBody = cfg.attribution ? cleanBody + "\n" + buildAttributionFooter("updated") : cleanBody;
49370
+ const pageBody = stripAttributionFooter(toStorageFormat(opts.body));
49302
49371
  payload.body = {
49303
49372
  representation: "storage",
49304
49373
  value: pageBody
@@ -49318,12 +49387,11 @@ async function updatePage(pageId, opts) {
49318
49387
  }
49319
49388
  const page = PageSchema.parse(raw);
49320
49389
  if (opts.body) {
49321
- const cleanBody = stripAttributionFooter(toStorageFormat(opts.body));
49322
- const pageBody = cfg.attribution ? cleanBody + "\n" + buildAttributionFooter("updated") : cleanBody;
49390
+ const pageBody = stripAttributionFooter(toStorageFormat(opts.body));
49323
49391
  pageCache.set(pageId, newVersion, pageBody);
49324
49392
  }
49325
49393
  try {
49326
- await addLabels(page.id, [ATTRIBUTION_LABEL]);
49394
+ await ensureAttributionLabel(page.id);
49327
49395
  } catch {
49328
49396
  }
49329
49397
  return { page, newVersion };
@@ -49495,12 +49563,14 @@ async function uploadAttachment(pageId, fileData, filename, comment2) {
49495
49563
  if (!att) throw new Error("Attachment uploaded but no details returned.");
49496
49564
  return { title: att.title, id: att.id, fileSize: att.extensions?.fileSize };
49497
49565
  }
49498
- var GITHUB_URL = "https://github.com/de-otio/epimethian-mcp";
49499
- var ATTRIBUTION_LABEL = "epimethian-managed";
49500
- var ATTRIBUTION_START = "<!-- epimethian-attribution-start -->";
49501
- var ATTRIBUTION_END = "<!-- epimethian-attribution-end -->";
49502
- function buildAttributionFooter(action) {
49503
- return ATTRIBUTION_START + `<p style="font-size:9px;color:#999;margin-top:2em;"><em>This page was ${action} with <a href="${GITHUB_URL}">Epimethian</a> v${"5.1.1"}.</em></p>` + ATTRIBUTION_END;
49566
+ var ATTRIBUTION_LABEL = "epimethian-edited";
49567
+ var LEGACY_ATTRIBUTION_LABEL = "epimethian-managed";
49568
+ async function ensureAttributionLabel(pageId) {
49569
+ await addLabels(pageId, [ATTRIBUTION_LABEL]);
49570
+ const labels = await getLabels(pageId);
49571
+ if (labels.some((l) => l.name === LEGACY_ATTRIBUTION_LABEL)) {
49572
+ await removeLabel(pageId, LEGACY_ATTRIBUTION_LABEL);
49573
+ }
49504
49574
  }
49505
49575
  function stripAttributionFooter(body) {
49506
49576
  return body.replace(
@@ -49593,8 +49663,10 @@ async function getCommentReplies(commentId, type) {
49593
49663
  return CommentsResultSchema.parse(raw).results;
49594
49664
  }
49595
49665
  async function createFooterComment(pageId, body, parentCommentId) {
49666
+ const cfg = await getConfig();
49596
49667
  const sanitized = sanitizeCommentBody(toStorageFormat(body));
49597
- const attributed = `<p><em>[AI-generated via Epimethian]</em></p>${sanitized}`;
49668
+ const label = cfg.attribution ? _clientLabel : void 0;
49669
+ const attributed = label ? `<p><em>[AI-generated by ${escapeXmlText(label)} via Epimethian]</em></p>${sanitized}` : `<p><em>[AI-generated via Epimethian]</em></p>${sanitized}`;
49598
49670
  const payload = parentCommentId ? {
49599
49671
  parentCommentId,
49600
49672
  body: { representation: "storage", value: attributed }
@@ -49606,8 +49678,10 @@ async function createFooterComment(pageId, body, parentCommentId) {
49606
49678
  return CommentSchema.parse(raw);
49607
49679
  }
49608
49680
  async function createInlineComment(pageId, body, textSelection, textSelectionMatchIndex = 0, parentCommentId) {
49681
+ const cfg = await getConfig();
49609
49682
  const sanitized = sanitizeCommentBody(toStorageFormat(body));
49610
- const attributed = `<p><em>[AI-generated via Epimethian]</em></p>${sanitized}`;
49683
+ const label = cfg.attribution ? _clientLabel : void 0;
49684
+ const attributed = label ? `<p><em>[AI-generated by ${escapeXmlText(label)} via Epimethian]</em></p>${sanitized}` : `<p><em>[AI-generated via Epimethian]</em></p>${sanitized}`;
49611
49685
  if (parentCommentId) {
49612
49686
  const raw2 = await v2Post("/inline-comments", {
49613
49687
  parentCommentId,
@@ -55737,61 +55811,6 @@ function container_plugin(md, name, options2) {
55737
55811
  var import_gray_matter = __toESM(require_gray_matter());
55738
55812
  var import_crypto = require("crypto");
55739
55813
 
55740
- // src/server/converter/escape.ts
55741
- function escapeXmlAttr(s) {
55742
- let out = "";
55743
- for (let i = 0; i < s.length; i++) {
55744
- const ch = s.charCodeAt(i);
55745
- switch (ch) {
55746
- case 38:
55747
- out += "&amp;";
55748
- break;
55749
- case 60:
55750
- out += "&lt;";
55751
- break;
55752
- case 62:
55753
- out += "&gt;";
55754
- break;
55755
- case 34:
55756
- out += "&quot;";
55757
- break;
55758
- case 39:
55759
- out += "&#39;";
55760
- break;
55761
- default:
55762
- if (ch >= 0 && ch <= 31 || ch >= 127 && ch <= 159) {
55763
- out += `&#x${ch.toString(16).toUpperCase()};`;
55764
- } else {
55765
- out += s[i];
55766
- }
55767
- }
55768
- }
55769
- return out;
55770
- }
55771
- function escapeXmlText(s) {
55772
- let out = "";
55773
- for (let i = 0; i < s.length; i++) {
55774
- const ch = s.charCodeAt(i);
55775
- switch (ch) {
55776
- case 38:
55777
- out += "&amp;";
55778
- break;
55779
- case 60:
55780
- out += "&lt;";
55781
- break;
55782
- case 62:
55783
- out += "&gt;";
55784
- break;
55785
- default:
55786
- out += s[i];
55787
- }
55788
- }
55789
- return out;
55790
- }
55791
- function escapeCdata(s) {
55792
- return s.replace(/\]\]>/g, "]]]]><![CDATA[>");
55793
- }
55794
-
55795
55814
  // src/server/converter/url-parser.ts
55796
55815
  var DEFAULT_PORTS = {
55797
55816
  "http:": "80",
@@ -56865,6 +56884,11 @@ function errorRecord(operation, pageId, err, extra) {
56865
56884
  }
56866
56885
 
56867
56886
  // src/server/index.ts
56887
+ function getClientLabel(server) {
56888
+ const client = server.server.getClientVersion();
56889
+ const raw = client?.title || client?.name || void 0;
56890
+ return raw ? raw.slice(0, 80) : void 0;
56891
+ }
56868
56892
  function escapeXml(s) {
56869
56893
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
56870
56894
  }
@@ -57024,7 +57048,8 @@ function registerTools(server, config3) {
57024
57048
  title: currentPage.title,
57025
57049
  body: newBody,
57026
57050
  version: version2,
57027
- versionMessage: opts.versionMessage
57051
+ versionMessage: opts.versionMessage,
57052
+ clientLabel: getClientLabel(server)
57028
57053
  });
57029
57054
  return { page, newVersion, oldLen: currentStorage.length, newLen: newBody.length };
57030
57055
  }
@@ -57060,7 +57085,7 @@ function registerTools(server, config3) {
57060
57085
  });
57061
57086
  }
57062
57087
  const spaceId = await resolveSpaceId(space_key);
57063
- const page = await createPage(spaceId, title, finalBody, parent_id);
57088
+ const page = await createPage(spaceId, title, finalBody, parent_id, getClientLabel(server));
57064
57089
  logMutation({
57065
57090
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
57066
57091
  operation: "create_page",
@@ -57227,7 +57252,8 @@ ${truncated}`);
57227
57252
  body: finalStorage,
57228
57253
  version: version2,
57229
57254
  versionMessage: effectiveVersionMessage,
57230
- previousBody: currentStorage
57255
+ previousBody: currentStorage,
57256
+ clientLabel: getClientLabel(server)
57231
57257
  });
57232
57258
  logMutation({
57233
57259
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -57310,7 +57336,8 @@ ${truncated}`);
57310
57336
  body: newFullBody,
57311
57337
  version: version2,
57312
57338
  versionMessage: version_message,
57313
- previousBody: fullBody
57339
+ previousBody: fullBody,
57340
+ clientLabel: getClientLabel(server)
57314
57341
  });
57315
57342
  logMutation({
57316
57343
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -57714,7 +57741,8 @@ ${macro}` : macro;
57714
57741
  title: current.title,
57715
57742
  body: newBody,
57716
57743
  version: current.version?.number ?? 0,
57717
- versionMessage: `Added diagram: ${filename}`
57744
+ versionMessage: `Added diagram: ${filename}`,
57745
+ clientLabel: getClientLabel(server)
57718
57746
  });
57719
57747
  return toolResult(
57720
57748
  `Diagram "${filename}" added to page ${page.title} (ID: ${page.id}, version: ${newVersion})` + echo
@@ -57954,6 +57982,7 @@ ${lines}`);
57954
57982
  async ({ page_id, body, type, parent_comment_id, text_selection, text_selection_match_index }) => {
57955
57983
  const blocked = writeGuard("create_comment", config3);
57956
57984
  if (blocked) return blocked;
57985
+ setClientLabel(getClientLabel(server));
57957
57986
  try {
57958
57987
  let comment2;
57959
57988
  if (type === "inline") {
@@ -58232,7 +58261,8 @@ ${result.diff}${truncNote}` + echo
58232
58261
  title: currentPage.title,
58233
58262
  body: historical.rawBody,
58234
58263
  version: current_version,
58235
- versionMessage: version_message ?? `Revert to version ${target_version}`
58264
+ versionMessage: version_message ?? `Revert to version ${target_version}`,
58265
+ clientLabel: getClientLabel(server)
58236
58266
  });
58237
58267
  logMutation({
58238
58268
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -58323,7 +58353,7 @@ ${lines.join("\n")}${echo2}`
58323
58353
  description: "Return the epimethian-mcp server version.",
58324
58354
  inputSchema: {}
58325
58355
  },
58326
- async () => toolResult(`epimethian-mcp v${"5.1.1"}`)
58356
+ async () => toolResult(`epimethian-mcp v${"5.2.0"}`)
58327
58357
  );
58328
58358
  }
58329
58359
  async function main() {
@@ -58336,7 +58366,7 @@ async function main() {
58336
58366
  const serverName = config3.profile ? `confluence-${config3.profile}` : "confluence";
58337
58367
  const server = new McpServer({
58338
58368
  name: serverName,
58339
- version: "5.1.1"
58369
+ version: "5.2.0"
58340
58370
  });
58341
58371
  registerTools(server, config3);
58342
58372
  const transport = new StdioServerTransport();