@superdoc/mcp 1.2.0-next.7 → 1.2.0-next.9

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.
Files changed (2) hide show
  1. package/dist/index.js +119 -40
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31314,7 +31314,7 @@ var init_host = __esm(() => {
31314
31314
  });
31315
31315
 
31316
31316
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31317
- var SDK_VERSION = "2.15.0-next.7";
31317
+ var SDK_VERSION = "2.15.0-next.9";
31318
31318
 
31319
31319
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31320
31320
  import { chmodSync, existsSync } from "node:fs";
@@ -31891,7 +31891,7 @@ var init_embedded_tools_generated = __esm(() => {
31891
31891
  "tools": [
31892
31892
  {
31893
31893
  "toolName": "superdoc_get_content",
31894
- "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
31894
+ "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
31895
31895
  "inputSchema": {
31896
31896
  "type": "object",
31897
31897
  "properties": {
@@ -38169,7 +38169,7 @@ var init_embedded_tools_generated = __esm(() => {
38169
38169
  },
38170
38170
  {
38171
38171
  "toolName": "superdoc_mutations",
38172
- "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
38172
+ "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:\\"select\\" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
38173
38173
  "inputSchema": {
38174
38174
  "type": "object",
38175
38175
  "properties": {
@@ -42255,7 +42255,7 @@ var init_embedded_tools_generated = __esm(() => {
42255
42255
  "type": "function",
42256
42256
  "function": {
42257
42257
  "name": "superdoc_get_content",
42258
- "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
42258
+ "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
42259
42259
  "parameters": {
42260
42260
  "type": "object",
42261
42261
  "properties": {
@@ -48137,7 +48137,7 @@ var init_embedded_tools_generated = __esm(() => {
48137
48137
  "type": "function",
48138
48138
  "function": {
48139
48139
  "name": "superdoc_mutations",
48140
- "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
48140
+ "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:\\"select\\" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
48141
48141
  "parameters": {
48142
48142
  "type": "object",
48143
48143
  "properties": {
@@ -51875,7 +51875,7 @@ var init_embedded_tools_generated = __esm(() => {
51875
51875
  "tools": [
51876
51876
  {
51877
51877
  "name": "superdoc_get_content",
51878
- "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
51878
+ "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
51879
51879
  "input_schema": {
51880
51880
  "type": "object",
51881
51881
  "properties": {
@@ -57733,7 +57733,7 @@ var init_embedded_tools_generated = __esm(() => {
57733
57733
  },
57734
57734
  {
57735
57735
  "name": "superdoc_mutations",
57736
- "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
57736
+ "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:\\"select\\" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
57737
57737
  "input_schema": {
57738
57738
  "type": "object",
57739
57739
  "properties": {
@@ -61469,7 +61469,7 @@ var init_embedded_tools_generated = __esm(() => {
61469
61469
  "type": "function",
61470
61470
  "function": {
61471
61471
  "name": "superdoc_get_content",
61472
- "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
61472
+ "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
61473
61473
  "parameters": {
61474
61474
  "type": "object",
61475
61475
  "properties": {
@@ -67351,7 +67351,7 @@ var init_embedded_tools_generated = __esm(() => {
67351
67351
  "type": "function",
67352
67352
  "function": {
67353
67353
  "name": "superdoc_mutations",
67354
- "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
67354
+ "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:\\"select\\" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
67355
67355
  "parameters": {
67356
67356
  "type": "object",
67357
67357
  "properties": {
@@ -71089,7 +71089,7 @@ var init_embedded_tools_generated = __esm(() => {
71089
71089
  "tools": [
71090
71090
  {
71091
71091
  "name": "superdoc_get_content",
71092
- "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
71092
+ "description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \\"blocks\\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \\"blocks\\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \\"text\\", \\"markdown\\", and \\"html\\" return compact strings. Actions \\"markdown_projection\\" and \\"html_projection\\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \\"info\\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \\"blocks\\" action supports pagination via \\"offset\\" and \\"limit\\", filtering via \\"nodeTypes\\", and numbering projection via \\"reviewMode\\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"blocks\\"}\\n 2. {\\"action\\":\\"blocks\\",\\"includeText\\":true,\\"offset\\":0,\\"limit\\":20,\\"reviewMode\\":\\"final\\"}\\n 3. {\\"action\\":\\"blocks\\",\\"offset\\":0,\\"limit\\":20,\\"nodeTypes\\":[\\"heading\\",\\"paragraph\\"]}\\n 4. {\\"action\\":\\"text\\"}\\n 5. {\\"action\\":\\"info\\"}\\n 6. {\\"action\\":\\"html_projection\\",\\"reviewMode\\":\\"redline\\",\\"includeSourceMap\\":true}\\n 7. {\\"action\\":\\"markdown_projection\\",\\"reviewMode\\":\\"original\\",\\"scope\\":{\\"kind\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"paragraph-id\\"},\\"includeSourceMap\\":true}",
71093
71093
  "parameters": {
71094
71094
  "type": "object",
71095
71095
  "properties": {
@@ -77115,7 +77115,7 @@ var init_embedded_tools_generated = __esm(() => {
77115
77115
  },
77116
77116
  {
77117
77117
  "name": "superdoc_mutations",
77118
- "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
77118
+ "description": "All steps succeed or all fail; no partial application. Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. Each step has an id, an op, a \\"where\\" clause for targeting ({by:\\"select\\", select:{...}, require:\\"first\\"|\\"exactlyOne\\"|\\"all\\"} or {by:\\"ref\\", ref:\\"...\\"} or {by:\\"block\\", nodeType:\\"paragraph\\", nodeId:\\"...\\"}), and \\"args\\" with operation-specific parameters. Use {by:\\"block\\", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action \\"blocks\\" without relying on text matching. For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:\\"blocks\\" and includeText:true, then rewrite the matching block by nodeId. For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:\\"select\\" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. Use {by:\\"select\\"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. For create steps, \\"where\\" targets an existing anchor block and args.position (\\"before\\" or \\"after\\") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. For format.apply with require \\"all\\", use a node selector to format every heading or paragraph at once: {by:\\"select\\", select:{type:\\"node\\", nodeType:\\"heading\\"}, require:\\"all\\"}. Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. Action \\"preview\\" dry-runs the plan. Action \\"apply\\" executes it. If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.\\n\\nEXAMPLES:\\n 1. {\\"action\\":\\"apply\\",\\"atomic\\":true,\\"changeMode\\":\\"direct\\",\\"steps\\":[{\\"id\\":\\"s1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"old term\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"new term\\"}}},{\\"id\\":\\"s2\\",\\"op\\":\\"text.delete\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\" (deprecated)\\"},\\"require\\":\\"all\\"},\\"args\\":{}}]}\\n 2. {\\"action\\":\\"apply\\",\\"steps\\":[{\\"id\\":\\"r1\\",\\"op\\":\\"text.rewrite\\",\\"where\\":{\\"by\\":\\"block\\",\\"nodeType\\":\\"paragraph\\",\\"nodeId\\":\\"<nodeId>\\"},\\"args\\":{\\"replacement\\":{\\"text\\":\\"Updated clause text.\\"}}},{\\"id\\":\\"f1\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"node\\",\\"nodeType\\":\\"heading\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"color\\":\\"#FF0000\\"}}},{\\"id\\":\\"f2\\",\\"op\\":\\"format.apply\\",\\"where\\":{\\"by\\":\\"select\\",\\"select\\":{\\"type\\":\\"text\\",\\"pattern\\":\\"Confidential Information\\"},\\"require\\":\\"all\\"},\\"args\\":{\\"inline\\":{\\"bold\\":true}}}]}",
77119
77119
  "parameters": {
77120
77120
  "type": "object",
77121
77121
  "properties": {
@@ -80918,13 +80918,13 @@ var init_embedded_tools_generated = __esm(() => {
80918
80918
 
80919
80919
  Every editing tool needs a **target** telling the API *where* to apply the change. There are three ways to get one:
80920
80920
 
80921
- - **From blocks data**: Each block has a \`ref\` (pass directly to superdoc_edit or superdoc_format), a \`nodeId\` (for building \`at\` positions with superdoc_create or \`where: {by: "block", ...}\` in superdoc_mutations), and optional full \`text\` when you call \`superdoc_get_content({action: "blocks", includeText: true})\`.
80921
+ - **From blocks data**: Each block has a \`ref\` (pass directly to superdoc_edit or superdoc_format), a \`nodeId\` (for building \`at\` positions with superdoc_create or \`where: {by: "block", ...}\` in superdoc_mutations), and optional full \`text\` when you call \`superdoc_get_content({action: "blocks", includeText: true})\`. Paragraph-class blocks have \`tabCount\` for the complete text; a compact \`textPreview\` can trim or truncate tabs. If \`tabCount > 0\`, read with \`includeText: true\` before editing.
80922
80922
  - **From superdoc_search**: Returns \`handle.ref\` covering the matched text. Use search when you need to find text patterns, not when you already know which block to target.
80923
80923
  - **From superdoc_create**: Returns \`nodeId\` and \`ref\`. The ref is valid for one immediate format call. For subsequent operations, re-fetch blocks to get fresh refs.
80924
80924
 
80925
80925
  **Refs expire after any mutation** between separate tool calls. Within a superdoc_mutations batch, selectors resolve automatically — no manual re-searching between steps.
80926
80926
 
80927
- **Critical targeting rule:** when rewriting an entire paragraph, clause, or other known block, first read \`superdoc_get_content({action: "blocks", includeText: true})\`, identify the block's \`nodeId\`, then use \`where: {by: "block", nodeType, nodeId}\` in \`superdoc_mutations\`. Do NOT use a shortened text selector to rewrite a whole clause.
80927
+ **Critical targeting rule:** when rewriting an entire paragraph, clause, or other known block, first read \`superdoc_get_content({action: "blocks", includeText: true})\`, identify the block's \`nodeId\`, then use \`where: {by: "block", nodeType, nodeId}\` in \`superdoc_mutations\`. Do NOT use a shortened text selector to rewrite a whole clause. Conversely, to change only a name or placeholder, select that exact text with \`superdoc_search\` and call \`superdoc_edit({action: "replace", ref: "<handle.ref>", text: "new name"})\`, or use a \`text.rewrite\` step with \`where: {by: "select", select: {type: "text", pattern: "old name"}, require: "exactlyOne"}\`. A whole-block plain-text rewrite that omits tabs deletes them; do not use it for a placeholder edit. Preserving tabs does not guarantee a visually aligned column if longer text crosses tab stops.
80928
80928
 
80929
80929
  ## Citation-grade output reads
80930
80930
 
@@ -81403,13 +81403,13 @@ One format.apply step per block. Combine \`inline\`, \`alignment\`, and \`scope:
81403
81403
 
81404
81404
  Every editing tool needs a **target** telling the API *where* to apply the change. There are three ways to get one:
81405
81405
 
81406
- - **From blocks data**: Each block has a \`ref\` (pass directly to superdoc_edit or superdoc_format), a \`nodeId\` (for building \`at\` positions with superdoc_create or \`where: {by: "block", ...}\` in superdoc_mutations), and optional full \`text\` when you call \`superdoc_get_content({action: "blocks", includeText: true})\`.
81406
+ - **From blocks data**: Each block has a \`ref\` (pass directly to superdoc_edit or superdoc_format), a \`nodeId\` (for building \`at\` positions with superdoc_create or \`where: {by: "block", ...}\` in superdoc_mutations), and optional full \`text\` when you call \`superdoc_get_content({action: "blocks", includeText: true})\`. Paragraph-class blocks have \`tabCount\` for the complete text; a compact \`textPreview\` can trim or truncate tabs. If \`tabCount > 0\`, read with \`includeText: true\` before editing.
81407
81407
  - **From superdoc_search**: Returns \`handle.ref\` covering the matched text. Use search when you need to find text patterns, not when you already know which block to target.
81408
81408
  - **From superdoc_create**: Returns \`nodeId\` and \`ref\`. The ref is valid for one immediate format call. For subsequent operations, re-fetch blocks to get fresh refs.
81409
81409
 
81410
81410
  **Refs expire after any mutation** between separate tool calls. Within a superdoc_mutations batch, selectors resolve automatically — no manual re-searching between steps.
81411
81411
 
81412
- **Critical targeting rule:** when rewriting an entire paragraph, clause, or other known block, first read \`superdoc_get_content({action: "blocks", includeText: true})\`, identify the block's \`nodeId\`, then use \`where: {by: "block", nodeType, nodeId}\` in \`superdoc_mutations\`. Do NOT use a shortened text selector to rewrite a whole clause.
81412
+ **Critical targeting rule:** when rewriting an entire paragraph, clause, or other known block, first read \`superdoc_get_content({action: "blocks", includeText: true})\`, identify the block's \`nodeId\`, then use \`where: {by: "block", nodeType, nodeId}\` in \`superdoc_mutations\`. Do NOT use a shortened text selector to rewrite a whole clause. Conversely, to change only a name or placeholder, select that exact text with \`superdoc_search\` and call \`superdoc_edit({action: "replace", ref: "<handle.ref>", text: "new name"})\`, or use a \`text.rewrite\` step with \`where: {by: "select", select: {type: "text", pattern: "old name"}, require: "exactlyOne"}\`. A whole-block plain-text rewrite that omits tabs deletes them; do not use it for a placeholder edit. Preserving tabs does not guarantee a visually aligned column if longer text crosses tab stops.
81413
81413
 
81414
81414
  ## Citation-grade output reads
81415
81415
 
@@ -82195,6 +82195,7 @@ function normalizeSnapshotBlock(value, fallbackOrdinal, blockTextLimit) {
82195
82195
  nodeType: asString(rec.nodeType, "paragraph"),
82196
82196
  text,
82197
82197
  textPreview,
82198
+ ...typeof rec.tabCount === "number" && Number.isInteger(rec.tabCount) && rec.tabCount >= 0 ? { tabCount: rec.tabCount } : {},
82198
82199
  styleId: typeof rec.styleId === "string" ? rec.styleId : null,
82199
82200
  headingLevel: typeof rec.headingLevel === "number" ? rec.headingLevel : undefined,
82200
82201
  ...asRecord(rec.numbering) ? {
@@ -92894,7 +92895,7 @@ var init_actions = __esm(() => {
92894
92895
  operations: ["comments.create"]
92895
92896
  },
92896
92897
  rewrite_block: {
92897
- hint: "selector, text, changeMode? — REPLACES the whole block text using the document API's formatting preservation. For appending a NEW paragraph/clause use insert_paragraphs, and for small wording edits prefer replace_text with a minimal find span",
92898
+ hint: "selector, text, changeMode? — REPLACES the whole block text. Omitted tab controls are deleted: for a tab-aligned paragraph, use replace_text with a minimal find span to change a name/placeholder instead. For appending a NEW paragraph/clause use insert_paragraphs",
92898
92899
  group: "Text/structure actions",
92899
92900
  groupOrder: 7,
92900
92901
  args: ["text", "selector", "changeMode", "evidence"],
@@ -96324,7 +96325,7 @@ var init_operation_definitions = __esm(() => {
96324
96325
  },
96325
96326
  get_content: {
96326
96327
  toolName: "superdoc_get_content",
96327
- description: "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. " + 'Action "blocks" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. ' + 'When you need to evaluate or rewrite existing paragraphs or clauses, prefer action "blocks" with includeText:true so you can identify the correct block and then target it by nodeId. ' + 'Actions "text", "markdown", and "html" return compact strings. Actions "markdown_projection" and "html_projection" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. ' + "Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. " + 'Action "info" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. ' + 'The "blocks" action supports pagination via "offset" and "limit", filtering via "nodeTypes", and numbering projection via "reviewMode". Other actions ignore pagination and filtering parameters. ' + "This tool never modifies the document. " + "Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.",
96328
+ description: "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. " + 'Action "blocks" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. ' + 'When you need to evaluate or rewrite existing paragraphs or clauses, prefer action "blocks" with includeText:true so you can identify the correct block and then target it by nodeId. ' + 'Actions "text", "markdown", and "html" return compact strings. Actions "markdown_projection" and "html_projection" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. ' + "Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. " + 'Action "info" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. ' + 'The "blocks" action supports pagination via "offset" and "limit", filtering via "nodeTypes", and numbering projection via "reviewMode". Other actions ignore pagination and filtering parameters. ' + "This tool never modifies the document. " + "Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.",
96328
96329
  inputExamples: [
96329
96330
  { action: "blocks" },
96330
96331
  { action: "blocks", includeText: true, offset: 0, limit: 20, reviewMode: "final" },
@@ -96616,7 +96617,7 @@ Complete new body.`,
96616
96617
  section: { toolName: "superdoc_section", description: "Page layout, margins, columns" },
96617
96618
  mutations: {
96618
96619
  toolName: "superdoc_mutations",
96619
- description: "All steps succeed or all fail; no partial application. " + "Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. " + "Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. " + 'Each step has an id, an op, a "where" clause for targeting ({by:"select", select:{...}, require:"first"|"exactlyOne"|"all"} or {by:"ref", ref:"..."} or {by:"block", nodeType:"paragraph", nodeId:"..."}), and "args" with operation-specific parameters. ' + 'Use {by:"block", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action "blocks" without relying on text matching. ' + 'For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:"blocks" and includeText:true, then rewrite the matching block by nodeId. ' + 'Use {by:"select"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. ' + 'For create steps, "where" targets an existing anchor block and args.position ("before" or "after") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. ' + 'For format.apply with require "all", use a node selector to format every heading or paragraph at once: {by:"select", select:{type:"node", nodeType:"heading"}, require:"all"}. ' + "Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. " + 'Action "preview" dry-runs the plan. Action "apply" executes it. ' + "If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. " + "Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.",
96620
+ description: "All steps succeed or all fail; no partial application. " + "Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. " + "Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. " + 'Each step has an id, an op, a "where" clause for targeting ({by:"select", select:{...}, require:"first"|"exactlyOne"|"all"} or {by:"ref", ref:"..."} or {by:"block", nodeType:"paragraph", nodeId:"..."}), and "args" with operation-specific parameters. ' + 'Use {by:"block", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action "blocks" without relying on text matching. ' + 'For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:"blocks" and includeText:true, then rewrite the matching block by nodeId. ' + 'For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:"select" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. ' + 'Use {by:"select"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. ' + 'For create steps, "where" targets an existing anchor block and args.position ("before" or "after") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. ' + 'For format.apply with require "all", use a node selector to format every heading or paragraph at once: {by:"select", select:{type:"node", nodeType:"heading"}, require:"all"}. ' + "Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. " + 'Action "preview" dry-runs the plan. Action "apply" executes it. ' + "If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. " + "Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.",
96620
96621
  inputExamples: [
96621
96622
  {
96622
96623
  action: "apply",
@@ -109129,6 +109130,11 @@ var init_schemas4 = __esm(() => {
109129
109130
  oneOf: [{ type: "string" }, { type: "null" }],
109130
109131
  description: "Full flattened block text when requested with includeText."
109131
109132
  },
109133
+ tabCount: {
109134
+ type: "integer",
109135
+ minimum: 0,
109136
+ description: "Tabs in complete paragraph text, even beyond the preview."
109137
+ },
109132
109138
  isEmpty: { type: "boolean" },
109133
109139
  styleId: { oneOf: [{ type: "string" }, { type: "null" }], description: "Named paragraph style." },
109134
109140
  fontFamily: { type: "string", description: "Font family from first text run." },
@@ -124582,6 +124588,13 @@ function parseItem(source, item, ctx) {
124582
124588
  return [];
124583
124589
  case "r":
124584
124590
  return parseRun(source, item, ctx);
124591
+ case "br":
124592
+ if (!isWordprocessingElement(item, ctx.namespaceBindings)) {
124593
+ return [buildDescendingContainer(source, item, ctx, "unknown", "fail-closed")];
124594
+ }
124595
+ return [makeContainerPiece(item, ctx, "unknown", "fail-closed", [
124596
+ buildControlPiece(item, ctx, null, item.byteStart, item.byteEnd, item.charStart, item.charEnd, "", "")
124597
+ ])];
124585
124598
  case "ins":
124586
124599
  case "del":
124587
124600
  case "moveFrom":
@@ -125588,6 +125601,9 @@ function projectElement(xml, elementStart, element, deleted, instruction, namesp
125588
125601
  if (element.selfClosing) {
125589
125602
  if (localName === "r")
125590
125603
  projectRun2(xml, elementStart, element, deleted, instruction, namespaceScopes, collector);
125604
+ if (localName === "br" && isWordprocessingElement2(xml, elementStart, element, namespaceScopes, collector.inferredWordPrefix))
125605
+ appendControl(collector, `
125606
+ `, deleted);
125591
125607
  return;
125592
125608
  }
125593
125609
  switch (localName) {
@@ -125599,6 +125615,16 @@ function projectElement(xml, elementStart, element, deleted, instruction, namesp
125599
125615
  case "r":
125600
125616
  projectRun2(xml, elementStart, element, deleted, instruction, namespaceScopes, collector);
125601
125617
  return;
125618
+ case "br":
125619
+ if (isWordprocessingElement2(xml, elementStart, element, namespaceScopes, collector.inferredWordPrefix)) {
125620
+ appendControl(collector, `
125621
+ `, deleted);
125622
+ return;
125623
+ }
125624
+ withNamespaceScope(namespaceScopes, elementStart, element.openEnd, () => {
125625
+ projectChildSequence(xml, element.openEnd, element.closeStart, deleted, instruction, namespaceScopes, collector);
125626
+ });
125627
+ return;
125602
125628
  case "del":
125603
125629
  case "moveFrom":
125604
125630
  withNamespaceScope(namespaceScopes, elementStart, element.openEnd, () => {
@@ -142029,7 +142055,7 @@ var init_story_slice = __esm(() => {
142029
142055
  init_source_coverage_chunks();
142030
142056
  DEFAULT_MAX_XML_BYTES = 64 * 1024;
142031
142057
  TEXT_DECODER = new TextDecoder("utf-8", { fatal: false });
142032
- NODE_BUFFER = typeof globalThis !== "undefined" && typeof globalThis.Buffer?.byteLength === "function" ? globalThis.Buffer : null;
142058
+ NODE_BUFFER = typeof globalThis !== "undefined" && typeof globalThis.process?.versions?.node === "string" && typeof globalThis.Buffer?.byteLength === "function" ? globalThis.Buffer : null;
142033
142059
  CHUNK_SPAN_CACHE = new WeakMap;
142034
142060
  });
142035
142061
 
@@ -178552,6 +178578,37 @@ function canonicalizeDependencyValue(value) {
178552
178578
  }
178553
178579
  return value;
178554
178580
  }
178581
+ function locateSingleResidentBodyChild(state, storyId, partUri, chunk, paragraphByteStart, paragraphByteEnd, containingBodyChildOrdinal) {
178582
+ const story = state.stories.get(storyId)?.descriptor;
178583
+ const part = state.parts.get(partUri)?.descriptor;
178584
+ if (storyId !== state.mainStoryId || story?.storyId !== storyId || story.storyKind !== "main" || story.ownerPartId !== partUri || story.ownerPartUri !== partUri || part?.partId !== partUri || part.partUri !== partUri || chunk.storyId !== storyId || chunk.partUri !== partUri || chunk.storyRevision !== story.revision || !state.packageBytes.has(partUri))
178585
+ return null;
178586
+ const residentByteLength = state.packageBytes.byteLength(partUri);
178587
+ const { byteStart, byteEnd, bodyChildStartOrdinal, bodyChildEndOrdinal, contentBlockStartOrdinal, contentBlockEndOrdinal, firstChildKind, lastChildKind, bodyChildCount, contentBlockCount, markerChildCount, opaqueAnchorCount, containsTrivia, triviaByteSpans } = chunk;
178588
+ if (residentByteLength == null || !Number.isSafeInteger(residentByteLength) || !Number.isSafeInteger(byteStart) || !Number.isSafeInteger(byteEnd) || byteStart < 0 || byteEnd <= byteStart || byteEnd > residentByteLength || !Number.isSafeInteger(paragraphByteStart) || !Number.isSafeInteger(paragraphByteEnd) || paragraphByteStart < byteStart || paragraphByteEnd <= paragraphByteStart || paragraphByteEnd > byteEnd || !Number.isSafeInteger(containingBodyChildOrdinal) || containingBodyChildOrdinal < 0 || bodyChildCount !== 1 || bodyChildStartOrdinal !== containingBodyChildOrdinal || bodyChildEndOrdinal !== containingBodyChildOrdinal || contentBlockCount !== 1 || contentBlockStartOrdinal == null || !Number.isSafeInteger(contentBlockStartOrdinal) || contentBlockStartOrdinal < 0 || contentBlockEndOrdinal !== contentBlockStartOrdinal || markerChildCount !== 0 || opaqueAnchorCount !== 0 || firstChildKind !== lastChildKind || firstChildKind !== "p" && firstChildKind !== "tbl" && firstChildKind !== "sdt")
178589
+ return null;
178590
+ let ownerByteStart = byteStart;
178591
+ if (triviaByteSpans.length === 0) {
178592
+ if (containsTrivia)
178593
+ return null;
178594
+ } else {
178595
+ if (!containsTrivia || triviaByteSpans.length !== 1)
178596
+ return null;
178597
+ const [triviaStart, triviaEnd] = triviaByteSpans[0];
178598
+ if (triviaStart !== byteStart || !Number.isSafeInteger(triviaEnd) || triviaEnd <= triviaStart || triviaEnd >= byteEnd)
178599
+ return null;
178600
+ ownerByteStart = triviaEnd;
178601
+ }
178602
+ if (paragraphByteStart < ownerByteStart)
178603
+ return null;
178604
+ return {
178605
+ status: "ok",
178606
+ bodyChildOrdinal: bodyChildStartOrdinal,
178607
+ localName: firstChildKind,
178608
+ byteStart: ownerByteStart,
178609
+ byteEnd
178610
+ };
178611
+ }
178555
178612
  function locateExactResidentBodyChild(state, storyId, partUri, byteStart, byteEnd, cache) {
178556
178613
  const chunks = findChunksContainingRange(state.sourceCoverage.get(storyId)?.chunks ?? [], partUri, byteStart, byteEnd);
178557
178614
  if (chunks.length === 0)
@@ -178610,14 +178667,20 @@ function locateContainingResidentBodyChild(state, storyId, partUri, paragraphByt
178610
178667
  const chunks = findChunksContainingRange(state.sourceCoverage.get(storyId)?.chunks ?? [], partUri, paragraphByteStart, paragraphByteEnd);
178611
178668
  if (chunks.length === 0)
178612
178669
  return { status: "failed", reason: "body-child-not-found" };
178613
- const bytes = state.packageBytes.get(partUri);
178614
- if (!bytes)
178615
- return { status: "failed", reason: "body-child-not-found" };
178670
+ let bytes;
178616
178671
  const matches = [];
178617
178672
  for (const chunk of chunks) {
178618
178673
  const relativeOrdinal = containingBodyChildOrdinal - chunk.bodyChildStartOrdinal;
178619
178674
  if (relativeOrdinal < 0 || containingBodyChildOrdinal > chunk.bodyChildEndOrdinal)
178620
178675
  continue;
178676
+ const singleChild = locateSingleResidentBodyChild(state, storyId, partUri, chunk, paragraphByteStart, paragraphByteEnd, containingBodyChildOrdinal);
178677
+ if (singleChild) {
178678
+ matches.push(singleChild);
178679
+ continue;
178680
+ }
178681
+ bytes ?? (bytes = state.packageBytes.get(partUri));
178682
+ if (!bytes)
178683
+ return { status: "failed", reason: "body-child-not-found" };
178621
178684
  const chunkXml = TD24.decode(bytes.subarray(chunk.byteStart, chunk.byteEnd));
178622
178685
  const spans = listTopLevelElementSpans2(chunkXml);
178623
178686
  const span = spans[relativeOrdinal];
@@ -251516,7 +251579,7 @@ var init_operation_definitions2 = __esm(() => {
251516
251579
  },
251517
251580
  get_content: {
251518
251581
  toolName: "superdoc_get_content",
251519
- description: "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. " + 'Action "blocks" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. ' + 'When you need to evaluate or rewrite existing paragraphs or clauses, prefer action "blocks" with includeText:true so you can identify the correct block and then target it by nodeId. ' + 'Actions "text", "markdown", and "html" return compact strings. Actions "markdown_projection" and "html_projection" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. ' + "Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. " + 'Action "info" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. ' + 'The "blocks" action supports pagination via "offset" and "limit", filtering via "nodeTypes", and numbering projection via "reviewMode". Other actions ignore pagination and filtering parameters. ' + "This tool never modifies the document. " + "Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.",
251582
+ description: "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. " + 'Action "blocks" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Paragraph-class blocks include tabCount, the number of U+0009 tabs in the complete text even if the 80-character preview trims or truncates them. If tabCount is positive, read includeText:true before editing; do not treat a preview space as proof that there is no tab. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. ' + 'When you need to evaluate or rewrite existing paragraphs or clauses, prefer action "blocks" with includeText:true so you can identify the correct block and then target it by nodeId. ' + 'Actions "text", "markdown", and "html" return compact strings. Actions "markdown_projection" and "html_projection" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. ' + "Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. " + 'Action "info" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. ' + 'The "blocks" action supports pagination via "offset" and "limit", filtering via "nodeTypes", and numbering projection via "reviewMode". Other actions ignore pagination and filtering parameters. ' + "This tool never modifies the document. " + "Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.",
251520
251583
  inputExamples: [
251521
251584
  { action: "blocks" },
251522
251585
  { action: "blocks", includeText: true, offset: 0, limit: 20, reviewMode: "final" },
@@ -251808,7 +251871,7 @@ Complete new body.`,
251808
251871
  section: { toolName: "superdoc_section", description: "Page layout, margins, columns" },
251809
251872
  mutations: {
251810
251873
  toolName: "superdoc_mutations",
251811
- description: "All steps succeed or all fail; no partial application. " + "Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. " + "Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. " + 'Each step has an id, an op, a "where" clause for targeting ({by:"select", select:{...}, require:"first"|"exactlyOne"|"all"} or {by:"ref", ref:"..."} or {by:"block", nodeType:"paragraph", nodeId:"..."}), and "args" with operation-specific parameters. ' + 'Use {by:"block", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action "blocks" without relying on text matching. ' + 'For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:"blocks" and includeText:true, then rewrite the matching block by nodeId. ' + 'Use {by:"select"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. ' + 'For create steps, "where" targets an existing anchor block and args.position ("before" or "after") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. ' + 'For format.apply with require "all", use a node selector to format every heading or paragraph at once: {by:"select", select:{type:"node", nodeType:"heading"}, require:"all"}. ' + "Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. " + 'Action "preview" dry-runs the plan. Action "apply" executes it. ' + "If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. " + "Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.",
251874
+ description: "All steps succeed or all fail; no partial application. " + "Execute multiple operations atomically in one batch. Use this for any workflow needing 2+ changes. " + "Supported step types: text (text.rewrite, text.insert, text.delete), format (format.apply), create (create.heading, create.paragraph, create.table), assert. " + 'Each step has an id, an op, a "where" clause for targeting ({by:"select", select:{...}, require:"first"|"exactlyOne"|"all"} or {by:"ref", ref:"..."} or {by:"block", nodeType:"paragraph", nodeId:"..."}), and "args" with operation-specific parameters. ' + 'Use {by:"block", nodeType, nodeId} when you want to rewrite, delete, format, or anchor against a whole known block from superdoc_get_content action "blocks" without relying on text matching. ' + 'For full-paragraph or full-clause rewrites, first call superdoc_get_content with action:"blocks" and includeText:true, then rewrite the matching block by nodeId. ' + 'For a placeholder or name within a tab-separated paragraph, use a text.rewrite where.by:"select" targeting only the exact placeholder; a whole-block plain-text rewrite omitting tabs deletes those controls. ' + 'Use {by:"select"} only for substring edits, discovery, or insertion relative to a sentence fragment; do NOT use a shortened text selector to replace an entire known block. ' + 'For create steps, "where" targets an existing anchor block and args.position ("before" or "after") controls placement. Sequential creates targeting the same anchor maintain correct order via internal position mapping. ' + 'For format.apply with require "all", use a node selector to format every heading or paragraph at once: {by:"select", select:{type:"node", nodeType:"heading"}, require:"all"}. ' + "Selectors resolve at compile time (before execution). This means format.apply steps CANNOT target content created by earlier create steps in the same batch. Split creates and formatting into separate batches: first a mutations call with creates, then a mutations call with format.apply. " + 'Action "preview" dry-runs the plan. Action "apply" executes it. ' + "If a selector matches nothing, the failure reports the step id plus selector details so you can retry with a shorter or more distinctive anchor. " + "Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step.",
251812
251875
  inputExamples: [
251813
251876
  {
251814
251877
  action: "apply",
@@ -262232,6 +262295,11 @@ var init_schemas5 = __esm(() => {
262232
262295
  oneOf: [{ type: "string" }, { type: "null" }],
262233
262296
  description: "Full flattened block text when requested with includeText."
262234
262297
  },
262298
+ tabCount: {
262299
+ type: "integer",
262300
+ minimum: 0,
262301
+ description: "Tabs in complete paragraph text, even beyond the preview."
262302
+ },
262235
262303
  isEmpty: { type: "boolean" },
262236
262304
  styleId: { oneOf: [{ type: "string" }, { type: "null" }], description: "Named paragraph style." },
262237
262305
  fontFamily: { type: "string", description: "Font family from first text run." },
@@ -280645,12 +280713,12 @@ function wrapRangeWithMarkupInParagraphXml(input) {
280645
280713
  const middleText = run.text.slice(sliceStart, sliceEnd);
280646
280714
  const afterText = run.text.slice(sliceEnd);
280647
280715
  if (beforeText.length > 0)
280648
- beforeSegment.push(renderRun(run.kind, run.prefix, beforeText, run.rPr, run.leafXml));
280716
+ beforeSegment.push(renderRun(run.kind, run.prefix, beforeText, run.rPr, run.leafXml, run.open));
280649
280717
  if (middleText.length > 0) {
280650
- wrappedRuns.push(renderRun(run.kind, run.prefix, middleText, run.rPr, run.leafXml));
280718
+ wrappedRuns.push(renderRun(run.kind, run.prefix, middleText, run.rPr, run.leafXml, run.open));
280651
280719
  }
280652
280720
  if (afterText.length > 0)
280653
- afterSegment.push(renderRun(run.kind, run.prefix, afterText, run.rPr, run.leafXml));
280721
+ afterSegment.push(renderRun(run.kind, run.prefix, afterText, run.rPr, run.leafXml, run.open));
280654
280722
  segmentCursor = run.xmlEnd;
280655
280723
  }
280656
280724
  if (wrappedRuns.length === 0) {
@@ -280680,6 +280748,8 @@ function replaceRangeInParagraphXml(input) {
280680
280748
  const gapXml = input.paragraphXml.slice(segmentCursor, run.xmlStart);
280681
280749
  if (index === span.value.firstRunIdx)
280682
280750
  beforeSegment.push(gapXml);
280751
+ else if (gapXml.trim())
280752
+ return { ok: false, reason: "unsupported-context" };
280683
280753
  }
280684
280754
  const sliceStart = index === span.value.firstRunIdx ? span.value.startInFirstRun : 0;
280685
280755
  const sliceEnd = index === span.value.lastRunIdx ? span.value.endInLastRun : run.text.length;
@@ -281150,6 +281220,7 @@ function parsePlainRun2(runXml, textStart, xmlStart, xmlEnd) {
281150
281220
  xmlStart,
281151
281221
  xmlEnd,
281152
281222
  xml: runXml,
281223
+ open: run.open,
281153
281224
  prefix: run.prefix,
281154
281225
  textStart,
281155
281226
  textEnd: textStart + text.length,
@@ -281486,15 +281557,15 @@ function buildRPrChange(prefix, stamp, previousChildren) {
281486
281557
  const previous = `<${prefix}:rPr>${serializeTopLevelChildren(previousChildren)}</${prefix}:rPr>`;
281487
281558
  return `<${prefix}:rPrChange w:id="${stamp.revisionId}" w:author="${escapeXmlAttribute3(stamp.author.name)}"${initials} w:date="${escapeXmlAttribute3(stamp.date)}">${previous}</${prefix}:rPrChange>`;
281488
281559
  }
281489
- function renderRun(kind, prefix, text, rPrXml, leafXml) {
281560
+ function renderRun(kind, prefix, text, rPrXml, leafXml, runOpen = `<${prefix}:r>`) {
281490
281561
  if (kind !== "text") {
281491
281562
  if (text.length === 0)
281492
281563
  return "";
281493
281564
  const fallbackLeaf = kind === "tab" ? `<${prefix}:tab/>` : `<${prefix}:${kind}/>`;
281494
- return `<${prefix}:r>${rPrXml}${leafXml ?? fallbackLeaf}</${prefix}:r>`;
281565
+ return `${runOpen}${rPrXml}${leafXml ?? fallbackLeaf}</${prefix}:r>`;
281495
281566
  }
281496
281567
  const preserve = /^\s|\s$/.test(text) ? ' xml:space="preserve"' : "";
281497
- return `<${prefix}:r>${rPrXml}<${prefix}:t${preserve}>${escapeXmlText3(text)}</${prefix}:t></${prefix}:r>`;
281568
+ return `${runOpen}${rPrXml}<${prefix}:t${preserve}>${escapeXmlText3(text)}</${prefix}:t></${prefix}:r>`;
281498
281569
  }
281499
281570
  function ensureHyperlinkRunStyle2(rPrXml, fallbackPrefix, styleId = "Hyperlink") {
281500
281571
  const escapedStyleId = escapeXmlAttribute3(styleId);
@@ -302717,11 +302788,16 @@ function projectTableListEntry(ordinal, nodeId, text, includeText) {
302717
302788
  }
302718
302789
  function projectParagraphListEntry(input) {
302719
302790
  const trimmed = input.text.trim();
302791
+ let tabCount = 0;
302792
+ for (let position = input.text.indexOf("\t");position !== -1; position = input.text.indexOf("\t", position + 1)) {
302793
+ tabCount++;
302794
+ }
302720
302795
  const item = {
302721
302796
  ordinal: input.ordinal,
302722
302797
  nodeId: input.nodeId,
302723
302798
  nodeType: input.nodeType,
302724
302799
  textPreview: trimmed.length > 80 ? `${trimmed.slice(0, 77)}…` : trimmed,
302800
+ tabCount,
302725
302801
  isEmpty: trimmed.length === 0
302726
302802
  };
302727
302803
  if (input.styleId)
@@ -331227,7 +331303,7 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
331227
331303
  }
331228
331304
  };
331229
331305
  }
331230
- if (kind === "inline" && !hasReplacementContent && selectedTextRunCount(para.xml, target.start.offset, target.end.offset) > 1) {
331306
+ if (kind === "inline" && !hasReplacementContent) {
331231
331307
  const template = splitSdtTemplateAroundContent(sdtXml);
331232
331308
  if (!template) {
331233
331309
  return {
@@ -331248,6 +331324,18 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
331248
331324
  if (wrappedRuns.ok) {
331249
331325
  return { ok: true, xml: replaceRange2(documentXml, para.start, para.end, wrappedRuns.xml) };
331250
331326
  }
331327
+ return { ok: false, failure: { code: "CAPABILITY_UNAVAILABLE", message: "Content-control selection spans unsupported inline structures." } };
331328
+ }
331329
+ if (kind === "inline" && hasReplacementContent) {
331330
+ const replaced = replaceRangeInParagraphXml({
331331
+ paragraphXml: para.xml,
331332
+ rangeStart: target.start.offset,
331333
+ rangeEnd: target.end.offset,
331334
+ replacementXml: replaceSdtContentInTemplate(sdtXml, buildReplacementContentXml2(replacementContent))
331335
+ });
331336
+ if (replaced.ok) {
331337
+ return { ok: true, xml: replaceRange2(documentXml, para.start, para.end, replaced.xml) };
331338
+ }
331251
331339
  return {
331252
331340
  ok: false,
331253
331341
  failure: {
@@ -331264,15 +331352,6 @@ function wrapSelectionInXml(context, documentXml, target, sdtXml, kind, replacem
331264
331352
  return { ok: false, failure: { code: "CAPABILITY_UNAVAILABLE", message: "Content-control selection spans unsupported inline structures." } };
331265
331353
  return { ok: true, xml: replaceRange2(documentXml, para.start, para.end, wrapped) };
331266
331354
  }
331267
- function selectedTextRunCount(paragraphXml, start, end) {
331268
- const runs = new Set;
331269
- for (const piece of parseParagraphInlineMap(paragraphXml).leaves()) {
331270
- if (piece.kind === "text" && piece.textRole === "visible" && piece.visibleStart < end && piece.visibleEnd > start) {
331271
- runs.add(piece.runCharStart);
331272
- }
331273
- }
331274
- return runs.size;
331275
- }
331276
331355
  function splitSdtTemplateAroundContent(sdtXml) {
331277
331356
  const sdtRange = findFirstSdtElementRange(sdtXml);
331278
331357
  if (!sdtRange)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc/mcp",
3
- "version": "1.2.0-next.7",
3
+ "version": "1.2.0-next.9",
4
4
  "description": "Model Context Protocol server for SuperDoc, giving an AI agent tools to read and edit .docx files.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0",
@@ -24,13 +24,13 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "@modelcontextprotocol/sdk": "^1.26.0",
27
- "@superdoc/sdk": "2.15.0-next.7",
27
+ "@superdoc/sdk": "2.15.0-next.9",
28
28
  "debug": "^4.4.3",
29
29
  "zod": "^4.3.6"
30
30
  },
31
31
  "devDependencies": {
32
- "superdoc": "2.18.0-next.7",
33
- "@superdoc/docx-engine": "0.17.0-next.8",
32
+ "superdoc": "2.18.0-next.9",
33
+ "@superdoc/docx-engine": "0.17.0-next.10",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",