@de-otio/epimethian-mcp 6.6.1 → 6.6.2

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
@@ -35481,7 +35481,7 @@ async function getPage(pageId, includeBody) {
35481
35481
  async function _rawCreatePage(spaceId, title, body, parentId, clientLabel) {
35482
35482
  const cfg = await getConfig();
35483
35483
  const pageBody = normalizeBodyForSubmit(body);
35484
- const epimethianTag = `Epimethian v${"6.6.1"}`;
35484
+ const epimethianTag = `Epimethian v${"6.6.2"}`;
35485
35485
  const versionMsg = cfg.attribution && clientLabel ? `Created by ${clientLabel} (via ${epimethianTag})` : `Created by ${epimethianTag}`;
35486
35486
  const payload = {
35487
35487
  title,
@@ -35502,7 +35502,7 @@ async function _rawCreatePage(spaceId, title, body, parentId, clientLabel) {
35502
35502
  async function _rawUpdatePage(pageId, opts) {
35503
35503
  const cfg = await getConfig();
35504
35504
  const newVersion = opts.version + 1;
35505
- const epimethianTag = `Epimethian v${"6.6.1"}`;
35505
+ const epimethianTag = `Epimethian v${"6.6.2"}`;
35506
35506
  const effectiveClient = cfg.attribution ? opts.clientLabel : void 0;
35507
35507
  let versionMessage;
35508
35508
  if (opts.versionMessage && effectiveClient)
@@ -47896,17 +47896,30 @@ Token tail: ...${last8} Expires: ${isoExpires} Audit ID: ${err.auditId}
47896
47896
  The token is single-use, bound to this exact diff and page version,
47897
47897
  and invalidated by any competing write to this page. If validation
47898
47898
  fails, mint a new one by re-calling without \`confirm_token\`.`;
47899
+ const tokenInText = process.env.EPIMETHIAN_TOKEN_IN_TEXT === "true";
47900
+ const finalText = tokenInText ? text2 + `
47901
+
47902
+ [FALLBACK] Full token (EPIMETHIAN_TOKEN_IN_TEXT=true): ${err.token}` : text2;
47899
47903
  const structuredContent = {
47904
+ kind: "confirmation_required",
47900
47905
  confirm_token: err.token,
47901
47906
  audit_id: err.auditId,
47902
47907
  expires_at: isoExpires,
47903
- page_id: params.pageId
47908
+ page_id: params.pageId,
47909
+ human_summary: err.humanSummary
47904
47910
  };
47905
47911
  if (params.deletionSummary) {
47906
- structuredContent.deletion_summary = params.deletionSummary;
47912
+ structuredContent.deletion_summary = {
47913
+ tocs: params.deletionSummary.tocs,
47914
+ links: params.deletionSummary.links,
47915
+ structured_macros: params.deletionSummary.structuredMacros,
47916
+ code_macros: params.deletionSummary.codeMacros,
47917
+ plain_elements: params.deletionSummary.plainElements,
47918
+ other: params.deletionSummary.other
47919
+ };
47907
47920
  }
47908
47921
  return {
47909
- content: [{ type: "text", text: text2 }],
47922
+ content: [{ type: "text", text: finalText }],
47910
47923
  isError: true,
47911
47924
  structuredContent
47912
47925
  };
@@ -48986,7 +48999,7 @@ var init_client_configs = __esm({
48986
48999
  null,
48987
49000
  2
48988
49001
  ),
48989
- warning: "VS Code extension \u2264 2.1.123 does not honour elicitation requests; if write tools fail with NO_USER_RESPONSE, set `EPIMETHIAN_BYPASS_ELICITATION=true`."
49002
+ warning: "VS Code extension \u2264 2.1.123 does not honour elicitation requests; if write tools fail with NO_USER_RESPONSE, set `EPIMETHIAN_BYPASS_ELICITATION=true`.\n\nv6.6.2 declares an `outputSchema` on every write tool, so a spec-compliant client should now surface the soft-confirm `structuredContent` to the agent. If your version of Claude Code drops content blocks when structuredContent is present (issue #15412), set `EPIMETHIAN_TOKEN_IN_TEXT=true` as a fallback \u2014 this restores the human-readable explanation by also putting the full token in the text block."
48990
49003
  },
48991
49004
  {
48992
49005
  id: "cursor",
@@ -49937,7 +49950,7 @@ __export(upgrade_exports, {
49937
49950
  runUpgrade: () => runUpgrade
49938
49951
  });
49939
49952
  async function runUpgrade() {
49940
- const currentVersion = "6.6.1";
49953
+ const currentVersion = "6.6.2";
49941
49954
  console.log(`epimethian-mcp upgrade: current version v${currentVersion}`);
49942
49955
  let pending = await getPendingUpdate();
49943
49956
  if (!pending) {
@@ -61110,6 +61123,47 @@ var versionField = external_exports.union([
61110
61123
  external_exports.literal("current")
61111
61124
  ]);
61112
61125
 
61126
+ // src/server/output-schema.ts
61127
+ init_zod();
61128
+ var deletionSummarySchema = external_exports.object({
61129
+ tocs: external_exports.number().int().nonnegative(),
61130
+ links: external_exports.number().int().nonnegative(),
61131
+ structured_macros: external_exports.number().int().nonnegative(),
61132
+ code_macros: external_exports.number().int().nonnegative(),
61133
+ plain_elements: external_exports.number().int().nonnegative(),
61134
+ other: external_exports.number().int().nonnegative()
61135
+ });
61136
+ var confirmationRequiredArm = external_exports.object({
61137
+ kind: external_exports.literal("confirmation_required"),
61138
+ confirm_token: external_exports.string().min(1),
61139
+ audit_id: external_exports.string().min(1),
61140
+ expires_at: external_exports.string().min(1),
61141
+ page_id: external_exports.string().min(1),
61142
+ human_summary: external_exports.string(),
61143
+ deletion_summary: deletionSummarySchema.optional()
61144
+ });
61145
+ var writeSuccessArm = external_exports.object({
61146
+ kind: external_exports.literal("written"),
61147
+ page_id: external_exports.string().min(1),
61148
+ new_version: external_exports.number().int().positive(),
61149
+ body_bytes_before: external_exports.number().int().nonnegative().optional(),
61150
+ body_bytes_after: external_exports.number().int().nonnegative().optional(),
61151
+ title: external_exports.string().optional()
61152
+ });
61153
+ var deleteSuccessArm = external_exports.object({
61154
+ kind: external_exports.literal("deleted"),
61155
+ page_id: external_exports.string().min(1),
61156
+ last_version: external_exports.number().int().positive().optional()
61157
+ });
61158
+ var writeOutputSchema = external_exports.discriminatedUnion("kind", [
61159
+ writeSuccessArm,
61160
+ confirmationRequiredArm
61161
+ ]);
61162
+ var deleteOutputSchema = external_exports.discriminatedUnion("kind", [
61163
+ deleteSuccessArm,
61164
+ confirmationRequiredArm
61165
+ ]);
61166
+
61113
61167
  // src/server/index.ts
61114
61168
  init_update_orchestrator();
61115
61169
  init_tokeniser();
@@ -61876,6 +61930,11 @@ ${truncated}${truncationNote(origLen)}`
61876
61930
  source: sourceSchema,
61877
61931
  confirm_token: external_exports.string().optional().describe("Soft-confirmation token from a prior SOFT_CONFIRMATION_REQUIRED response. Single-use; bound to this exact diff and page version.")
61878
61932
  },
61933
+ // v6.6.2 §3.1 — declared so spec-compliant clients forward our
61934
+ // structuredContent payload to the agent (the soft-confirmation
61935
+ // round-trip relied on this from the start; v6.6.0/6.6.1 emitted
61936
+ // structuredContent without a schema so most clients dropped it).
61937
+ outputSchema: writeOutputSchema,
61879
61938
  annotations: { destructiveHint: false, idempotentHint: false }
61880
61939
  },
61881
61940
  async ({ page_id, title, version: version2, body, version_message, confirm_deletions, replace_body, confirm_shrinkage, confirm_structure_loss, allow_raw_html, confluence_base_url, source, confirm_token }) => {
@@ -61972,14 +62031,34 @@ ${truncated}${truncationNote(origLen)}`
61972
62031
  const badgeResult = await markPageUnverified(submitted.page.id, cfg);
61973
62032
  if (badgeResult.warning) warnings.push(badgeResult.warning);
61974
62033
  if (isTitleOnly) {
61975
- return toolResult(
62034
+ const titleOnlyResult = toolResult(
61976
62035
  appendWarnings(`Updated: ${submitted.page.title} (ID: ${submitted.page.id}, version: ${submitted.newVersion}, title only, body unchanged)`, warnings) + echo
61977
62036
  );
62037
+ return {
62038
+ ...titleOnlyResult,
62039
+ structuredContent: {
62040
+ kind: "written",
62041
+ page_id,
62042
+ new_version: submitted.newVersion,
62043
+ title: submitted.page.title
62044
+ }
62045
+ };
61978
62046
  }
61979
62047
  const removalNote = submitted.deletedTokens.length > 0 ? `; removed ${submitted.deletedTokens.length} preserved macro${submitted.deletedTokens.length === 1 ? "" : "s"}: ${submitted.deletedTokens.map((t) => t.fingerprint).join(", ")}` : "";
61980
- return toolResult(
62048
+ const bodyUpdateResult = toolResult(
61981
62049
  appendWarnings(`Updated: ${submitted.page.title} (ID: ${submitted.page.id}, version: ${submitted.newVersion}, body: ${submitted.oldLen}\u2192${submitted.newLen} chars${removalNote})`, warnings) + echo
61982
62050
  );
62051
+ return {
62052
+ ...bodyUpdateResult,
62053
+ structuredContent: {
62054
+ kind: "written",
62055
+ page_id,
62056
+ new_version: submitted.newVersion,
62057
+ body_bytes_before: submitted.oldLen,
62058
+ body_bytes_after: submitted.newLen,
62059
+ title: submitted.page.title
62060
+ }
62061
+ };
61983
62062
  } catch (err) {
61984
62063
  if (err instanceof SoftConfirmationRequiredError) {
61985
62064
  return formatSoftConfirmationResult(err, { pageId: page_id });
@@ -62005,6 +62084,10 @@ ${truncated}${truncationNote(origLen)}`
62005
62084
  source: sourceSchema,
62006
62085
  confirm_token: external_exports.string().optional().describe("Soft-confirmation token from a prior SOFT_CONFIRMATION_REQUIRED response. Single-use; bound to this exact page version.")
62007
62086
  },
62087
+ // v6.6.2 §3.1 — declared so spec-compliant clients forward our
62088
+ // structuredContent payload (especially the soft-confirm token)
62089
+ // to the agent.
62090
+ outputSchema: deleteOutputSchema,
62008
62091
  annotations: { destructiveHint: true, idempotentHint: true }
62009
62092
  },
62010
62093
  async ({ page_id, version: version2, source, confirm_token }) => {
@@ -62070,7 +62153,15 @@ ${truncated}${truncationNote(origLen)}`
62070
62153
  ...version2 !== void 0 ? { oldVersion: version2 } : {},
62071
62154
  source: effectiveSource
62072
62155
  });
62073
- return toolResult(`Deleted page ${page_id}` + echo);
62156
+ const deletedResult = toolResult(`Deleted page ${page_id}` + echo);
62157
+ return {
62158
+ ...deletedResult,
62159
+ structuredContent: {
62160
+ kind: "deleted",
62161
+ page_id,
62162
+ ...version2 !== void 0 ? { last_version: version2 } : {}
62163
+ }
62164
+ };
62074
62165
  } catch (err) {
62075
62166
  if (err instanceof SoftConfirmationRequiredError) {
62076
62167
  return formatSoftConfirmationResult(err, { pageId: page_id });
@@ -62114,6 +62205,9 @@ ${truncated}${truncationNote(origLen)}`
62114
62205
  confirm_deletions: external_exports.boolean().default(false).describe("Set to true to acknowledge that your markdown removes preserved macros, emoticons, or rich elements from this section. Required when any preserved element would be deleted."),
62115
62206
  confirm_token: external_exports.string().optional().describe("Soft-confirmation token from a prior SOFT_CONFIRMATION_REQUIRED response. Single-use; bound to this exact diff and page version.")
62116
62207
  },
62208
+ // v6.6.2 §3.1 — declared so spec-compliant clients forward our
62209
+ // structuredContent payload to the agent.
62210
+ outputSchema: writeOutputSchema,
62117
62211
  annotations: { destructiveHint: false, idempotentHint: false }
62118
62212
  },
62119
62213
  async ({ page_id, section, body, find_replace, version: version2, version_message, confirm_deletions, confirm_token }) => {
@@ -62187,12 +62281,23 @@ ${truncated}${truncationNote(origLen)}`
62187
62281
  const badgeResult2 = await markPageUnverified(submitted2.page.id, cfg);
62188
62282
  if (badgeResult2.warning) warnings2.push(badgeResult2.warning);
62189
62283
  const pairCount = find_replace.length;
62190
- return toolResult(
62284
+ const findReplaceResult = toolResult(
62191
62285
  appendWarnings(
62192
62286
  `Updated section "${section}" in: ${submitted2.page.title} (ID: ${submitted2.page.id}, version: ${submitted2.newVersion}; applied ${pairCount} find/replace substitution${pairCount === 1 ? "" : "s"})`,
62193
62287
  warnings2
62194
62288
  ) + echo
62195
62289
  );
62290
+ return {
62291
+ ...findReplaceResult,
62292
+ structuredContent: {
62293
+ kind: "written",
62294
+ page_id,
62295
+ new_version: submitted2.newVersion,
62296
+ body_bytes_before: submitted2.oldLen,
62297
+ body_bytes_after: submitted2.newLen,
62298
+ title: submitted2.page.title
62299
+ }
62300
+ };
62196
62301
  }
62197
62302
  if (confirm_deletions) {
62198
62303
  const deletionSummary = tryForecastDeletions(currentSectionBody, body, cfg.url);
@@ -62261,9 +62366,20 @@ ${truncated}${truncationNote(origLen)}`
62261
62366
  const badgeResult = await markPageUnverified(submitted.page.id, cfg);
62262
62367
  if (badgeResult.warning) warnings.push(badgeResult.warning);
62263
62368
  const removalNote = submitted.deletedTokens.length > 0 ? `; removed ${submitted.deletedTokens.length} preserved macro${submitted.deletedTokens.length === 1 ? "" : "s"}: ${submitted.deletedTokens.map((t) => t.fingerprint).join(", ")}` : "";
62264
- return toolResult(
62369
+ const sectionBodyResult = toolResult(
62265
62370
  appendWarnings(`Updated section "${section}" in: ${submitted.page.title} (ID: ${submitted.page.id}, version: ${submitted.newVersion}${removalNote})`, warnings) + echo
62266
62371
  );
62372
+ return {
62373
+ ...sectionBodyResult,
62374
+ structuredContent: {
62375
+ kind: "written",
62376
+ page_id,
62377
+ new_version: submitted.newVersion,
62378
+ body_bytes_before: submitted.oldLen,
62379
+ body_bytes_after: submitted.newLen,
62380
+ title: submitted.page.title
62381
+ }
62382
+ };
62267
62383
  } catch (err) {
62268
62384
  if (err instanceof SoftConfirmationRequiredError) {
62269
62385
  return formatSoftConfirmationResult(err, { pageId: page_id });
@@ -62451,6 +62567,9 @@ ${truncated}${truncationNote(origLen)}`
62451
62567
  confluence_base_url: external_exports.string().url().optional().describe("Override the Confluence base URL used by the link rewriter."),
62452
62568
  confirm_token: external_exports.string().optional().describe("Soft-confirmation token from a prior SOFT_CONFIRMATION_REQUIRED response. Single-use; bound to this exact diff and page version.")
62453
62569
  },
62570
+ // v6.6.2 \u00a73.1 \u2014 declared so spec-compliant clients forward our
62571
+ // structuredContent payload to the agent.
62572
+ outputSchema: writeOutputSchema,
62454
62573
  annotations: { destructiveHint: false, idempotentHint: false }
62455
62574
  },
62456
62575
  async ({ page_id, version: version2, content, separator, version_message, allow_raw_html, confluence_base_url }) => {
@@ -62471,7 +62590,18 @@ ${truncated}${truncationNote(origLen)}`
62471
62590
  if (labelResult.warning) warnings.push(labelResult.warning);
62472
62591
  const badgeResult = await markPageUnverified(page.id, cfg);
62473
62592
  if (badgeResult.warning) warnings.push(badgeResult.warning);
62474
- return toolResult(appendWarnings(`Prepended to: ${page.title} (ID: ${page.id}, version: ${newVersion}, body: ${oldLen}\u2192${newLen} chars)`, warnings) + echo);
62593
+ const prependResult = toolResult(appendWarnings(`Prepended to: ${page.title} (ID: ${page.id}, version: ${newVersion}, body: ${oldLen}\u2192${newLen} chars)`, warnings) + echo);
62594
+ return {
62595
+ ...prependResult,
62596
+ structuredContent: {
62597
+ kind: "written",
62598
+ page_id,
62599
+ new_version: newVersion,
62600
+ body_bytes_before: oldLen,
62601
+ body_bytes_after: newLen,
62602
+ title: page.title
62603
+ }
62604
+ };
62475
62605
  } catch (err) {
62476
62606
  if (err instanceof SoftConfirmationRequiredError) {
62477
62607
  return formatSoftConfirmationResult(err, { pageId: page_id });
@@ -62501,6 +62631,9 @@ ${truncated}${truncationNote(origLen)}`
62501
62631
  confluence_base_url: external_exports.string().url().optional().describe("Override the Confluence base URL used by the link rewriter."),
62502
62632
  confirm_token: external_exports.string().optional().describe("Soft-confirmation token from a prior SOFT_CONFIRMATION_REQUIRED response. Single-use; bound to this exact diff and page version.")
62503
62633
  },
62634
+ // v6.6.2 \u00a73.1 \u2014 declared so spec-compliant clients forward our
62635
+ // structuredContent payload to the agent.
62636
+ outputSchema: writeOutputSchema,
62504
62637
  annotations: { destructiveHint: false, idempotentHint: false }
62505
62638
  },
62506
62639
  async ({ page_id, version: version2, content, separator, version_message, allow_raw_html, confluence_base_url }) => {
@@ -62521,7 +62654,18 @@ ${truncated}${truncationNote(origLen)}`
62521
62654
  if (labelResult.warning) warnings.push(labelResult.warning);
62522
62655
  const badgeResult = await markPageUnverified(page.id, cfg);
62523
62656
  if (badgeResult.warning) warnings.push(badgeResult.warning);
62524
- return toolResult(appendWarnings(`Appended to: ${page.title} (ID: ${page.id}, version: ${newVersion}, body: ${oldLen}\u2192${newLen} chars)`, warnings) + echo);
62657
+ const appendResult = toolResult(appendWarnings(`Appended to: ${page.title} (ID: ${page.id}, version: ${newVersion}, body: ${oldLen}\u2192${newLen} chars)`, warnings) + echo);
62658
+ return {
62659
+ ...appendResult,
62660
+ structuredContent: {
62661
+ kind: "written",
62662
+ page_id,
62663
+ new_version: newVersion,
62664
+ body_bytes_before: oldLen,
62665
+ body_bytes_after: newLen,
62666
+ title: page.title
62667
+ }
62668
+ };
62525
62669
  } catch (err) {
62526
62670
  if (err instanceof SoftConfirmationRequiredError) {
62527
62671
  return formatSoftConfirmationResult(err, { pageId: page_id });
@@ -63680,7 +63824,7 @@ ${titleFenced}${echo2}`
63680
63824
  inputSchema: {}
63681
63825
  },
63682
63826
  async () => {
63683
- let text2 = `epimethian-mcp v${"6.6.1"}`;
63827
+ let text2 = `epimethian-mcp v${"6.6.2"}`;
63684
63828
  try {
63685
63829
  const pending = await getPendingUpdate();
63686
63830
  if (pending) {
@@ -63711,7 +63855,7 @@ ${label} update available: v${pending.current} \u2192 v${pending.latest}. Run \`
63711
63855
  const pending = await getPendingUpdate();
63712
63856
  if (!pending) {
63713
63857
  return toolResult(
63714
- `epimethian-mcp v${"6.6.1"} is already up to date.`
63858
+ `epimethian-mcp v${"6.6.2"} is already up to date.`
63715
63859
  );
63716
63860
  }
63717
63861
  const output = await performUpgrade(pending.latest);
@@ -63733,7 +63877,7 @@ async function startRecoveryServer(profile) {
63733
63877
  const server = new McpServer(
63734
63878
  {
63735
63879
  name: `confluence-${profile}-setup-needed`,
63736
- version: "6.6.1"
63880
+ version: "6.6.2"
63737
63881
  },
63738
63882
  {
63739
63883
  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.`
@@ -63784,21 +63928,21 @@ async function main() {
63784
63928
  const serverName = config3.profile ? `confluence-${config3.profile}` : "confluence";
63785
63929
  const server = new McpServer({
63786
63930
  name: serverName,
63787
- version: "6.6.1"
63931
+ version: "6.6.2"
63788
63932
  });
63789
63933
  await registerTools(server, config3);
63790
63934
  const transport = new StdioServerTransport();
63791
63935
  await server.connect(transport);
63792
63936
  try {
63793
63937
  const pending = await getPendingUpdate();
63794
- if (pending && pending.current === "6.6.1") {
63938
+ if (pending && pending.current === "6.6.2") {
63795
63939
  console.error(
63796
63940
  `epimethian-mcp: update available: v${pending.current} \u2192 v${pending.latest} (${pending.type}). Run \`epimethian-mcp upgrade\` to install.`
63797
63941
  );
63798
63942
  }
63799
63943
  } catch {
63800
63944
  }
63801
- checkForUpdates("6.6.1").catch(() => {
63945
+ checkForUpdates("6.6.2").catch(() => {
63802
63946
  });
63803
63947
  }
63804
63948