Locators (edit_page_text `find`, insert_node `anchorText`) are matched against the document's plain text, so a model-supplied locator carrying markdown wrappers (**bold**, *italic*, `code`, [t](url)) or trailing emoji never matched and the edit/insert failed. Add stripInlineMarkdown() and a fallback: try the locator verbatim first (exact match wins, so literal asterisks/underscores still work), and only on zero matches retry with a markdown-stripped form. The ambiguity guard runs on the post-fallback count, and `replace` / inserted node content are never stripped, so no formatting is lost. Failed edits gain an atom-aware reason plus a bounded "closest block text" hint; the insert_node "anchor not found" error now points at plain-text anchors / anchorNodeId. New packages/mcp/src/lib/text-normalize.ts (+ unit tests); wired into json-edit.ts and node-ops.ts; tool descriptions updated. Tests: 212 pass.
43 lines
1.4 KiB
JavaScript
43 lines
1.4 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { stripInlineMarkdown } from "../../build/lib/text-normalize.js";
|
|
|
|
test("strips strong wrappers", () => {
|
|
assert.equal(stripInlineMarkdown("**в полном порядке**"), "в полном порядке");
|
|
});
|
|
|
|
test("strips emphasis and trims a trailing emoji, keeps sentence punctuation", () => {
|
|
assert.equal(stripInlineMarkdown("*Конец.* ✨"), "Конец.");
|
|
});
|
|
|
|
test("strips inline code", () => {
|
|
assert.equal(stripInlineMarkdown("`code`"), "code");
|
|
});
|
|
|
|
test("links collapse to their visible text", () => {
|
|
assert.equal(stripInlineMarkdown("[t](http://x)"), "t");
|
|
});
|
|
|
|
test("a plain string is unchanged", () => {
|
|
assert.equal(stripInlineMarkdown("just plain text"), "just plain text");
|
|
});
|
|
|
|
test("a string of only markers returns the original", () => {
|
|
assert.equal(stripInlineMarkdown("***"), "***");
|
|
});
|
|
|
|
test("nested wrappers collapse to the inner text", () => {
|
|
assert.equal(stripInlineMarkdown("**_x_**"), "x");
|
|
});
|
|
|
|
test("image syntax collapses to its alt text", () => {
|
|
assert.equal(stripInlineMarkdown(""), "alt");
|
|
});
|
|
|
|
test("a trailing flag emoji is trimmed", () => {
|
|
// Regional-indicator flags are not Extended_Pictographic, so this guards the
|
|
// explicit U+1F1E6–U+1F1FF range in the decoration-trim class.
|
|
assert.equal(stripInlineMarkdown("hello 🇺🇸").trim(), "hello");
|
|
});
|