@superdoc-dev/sdk 1.3.0-next.42 → 1.3.0-next.44

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.
@@ -3,7 +3,7 @@
3
3
  "tools": [
4
4
  {
5
5
  "name": "superdoc_get_content",
6
- "description": "Read document content. Use action \"info\" for structure and styles, \"blocks\" for all block IDs and types, \"text\" or \"markdown\" for content. Call info or blocks before editing.",
6
+ "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, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Action \"text\" and \"markdown\" return the full document as plain text or Markdown. Action \"html\" returns HTML. 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\", and filtering via \"nodeTypes\". Other actions ignore these 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.",
7
7
  "input_schema": {
8
8
  "type": "object",
9
9
  "properties": {
@@ -52,11 +52,31 @@
52
52
  "action"
53
53
  ],
54
54
  "additionalProperties": false
55
- }
55
+ },
56
+ "input_examples": [
57
+ {
58
+ "action": "blocks"
59
+ },
60
+ {
61
+ "action": "blocks",
62
+ "offset": 0,
63
+ "limit": 20,
64
+ "nodeTypes": [
65
+ "heading",
66
+ "paragraph"
67
+ ]
68
+ },
69
+ {
70
+ "action": "text"
71
+ },
72
+ {
73
+ "action": "info"
74
+ }
75
+ ]
56
76
  },
57
77
  {
58
78
  "name": "superdoc_edit",
59
- "description": "Insert, replace, delete text, or undo/redo",
79
+ "description": "Refs expire after any mutation; always re-search before the next edit. Modify document text: insert new content, replace existing text, delete a range, or undo/redo. Use this for single text modifications. For 2+ edits that must succeed or fail atomically, use superdoc_mutations instead. For replace and delete, pass a \"ref\" from superdoc_search or superdoc_get_content blocks. A search ref covers only the matched substring; a block ref covers the entire block text, so use block refs when rewriting or shortening whole paragraphs. Insert supports plain text (default), markdown, or html via the \"type\" parameter. Use \"placement\" (before, after, insideStart, insideEnd) to control position relative to the target. Supports \"dryRun\" to preview changes and \"changeMode: tracked\" to record edits as tracked changes. Do NOT build \"target\" objects manually when a ref is available; prefer \"ref\" for simpler, more reliable targeting.",
60
80
  "input_schema": {
61
81
  "type": "object",
62
82
  "properties": {
@@ -278,7 +298,7 @@
278
298
  ]
279
299
  }
280
300
  ],
281
- "description": "Target address object. Use 'ref' instead if you have a search handle. Format: {kind:'text', blockId, range:{start,end}} or {kind:'block', nodeType, nodeId}."
301
+ "description": "Target address. For inline/set_style: prefer 'ref' from superdoc_search, or use {kind:'selection', start:{kind:'text', blockId, offset}, end:{kind:'text', blockId, offset}}. For paragraph actions (set_alignment, set_indentation, set_spacing, set_direction, set_flow_options): use {kind:'block', nodeType:'paragraph'|'heading'|'listItem', nodeId:'<nodeId from blocks list>'}."
282
302
  },
283
303
  "value": {
284
304
  "type": "string",
@@ -295,7 +315,7 @@
295
315
  },
296
316
  "ref": {
297
317
  "type": "string",
298
- "description": "Handle ref string returned by a prior search/query result."
318
+ "description": "Handle ref from superdoc_search result (pass handle.ref value directly). Preferred over building a target object."
299
319
  },
300
320
  "content": {
301
321
  "oneOf": [
@@ -335,22 +355,6 @@
335
355
  },
336
356
  "description": "Controls nesting behavior. tables: 'allow' permits inserting tables inside other tables. Only for actions 'insert', 'replace'. Omit for other actions."
337
357
  },
338
- "blockId": {
339
- "type": "string",
340
- "description": "Block ID of the target paragraph."
341
- },
342
- "start": {
343
- "type": "number",
344
- "description": "Start offset within the block (character index)."
345
- },
346
- "end": {
347
- "type": "number",
348
- "description": "End offset within the block (character index)."
349
- },
350
- "offset": {
351
- "type": "number",
352
- "description": "Character offset for insertion (alias for --start/--end with same value). Only for action 'insert'. Omit for other actions."
353
- },
354
358
  "text": {
355
359
  "type": "string",
356
360
  "description": "Replacement text content. Only for action 'replace'. Omit for other actions."
@@ -368,11 +372,36 @@
368
372
  "action"
369
373
  ],
370
374
  "additionalProperties": false
371
- }
375
+ },
376
+ "input_examples": [
377
+ {
378
+ "action": "replace",
379
+ "ref": "<handle.ref>",
380
+ "text": "new text here"
381
+ },
382
+ {
383
+ "action": "insert",
384
+ "value": "Appended paragraph.",
385
+ "placement": "insideEnd"
386
+ },
387
+ {
388
+ "action": "insert",
389
+ "ref": "<block.ref>",
390
+ "value": "Inserted before.",
391
+ "placement": "before"
392
+ },
393
+ {
394
+ "action": "delete",
395
+ "ref": "<handle.ref>"
396
+ },
397
+ {
398
+ "action": "undo"
399
+ }
400
+ ]
372
401
  },
373
402
  {
374
403
  "name": "superdoc_format",
375
- "description": "Change text and paragraph formatting. Use action \"inline\" with a search ref for bold/italic/etc. Use action \"set_style\" with a styleId from superdoc_get_content info to apply a named paragraph style.",
404
+ "description": "Change text and paragraph formatting. Use this after superdoc_create to style new content, or with a search ref to restyle existing text. Action \"inline\" applies character formatting (bold, italic, underline, color, fontSize, fontFamily, highlight, strike, vertAlign) to a text range via \"ref\". Action \"set_style\" applies a named paragraph style by styleId (get available styles from superdoc_get_content info). Actions \"set_alignment\", \"set_indentation\", \"set_spacing\", \"set_direction\", and \"set_flow_options\" change paragraph-level properties and require a block target: {kind:\"block\", nodeType:\"paragraph\", nodeId:\"<nodeId>\"}, NOT a ref. Use \"set_flow_options\" with pageBreakBefore:true to start a paragraph on a new page. Supports \"dryRun\" and \"changeMode: tracked\" for inline formatting. Paragraph-level actions do NOT support tracked changes. Do NOT use a search ref for paragraph-level actions; they require a block target with nodeId. Do NOT use {kind:\"block\", start:{kind:\"nodeEdge\",...}} or selection-like structures for paragraph actions. ONLY {kind:\"block\", nodeType, nodeId} is accepted. Do NOT issue multiple superdoc_format calls in parallel; each call invalidates refs for subsequent calls. Format one block at a time. Do NOT hardcode formatting values; always read them from superdoc_get_content blocks and replicate.",
376
405
  "input_schema": {
377
406
  "type": "object",
378
407
  "properties": {
@@ -382,11 +411,12 @@
382
411
  "inline",
383
412
  "set_alignment",
384
413
  "set_direction",
414
+ "set_flow_options",
385
415
  "set_indentation",
386
416
  "set_spacing",
387
417
  "set_style"
388
418
  ],
389
- "description": "The action to perform. One of: inline, set_alignment, set_direction, set_indentation, set_spacing, set_style."
419
+ "description": "The action to perform. One of: inline, set_alignment, set_direction, set_flow_options, set_indentation, set_spacing, set_style."
390
420
  },
391
421
  "force": {
392
422
  "type": "boolean",
@@ -561,7 +591,7 @@
561
591
  "start",
562
592
  "end"
563
593
  ],
564
- "description": "Selection target: {kind:'selection', start:{kind:'text', blockId, offset}, end:{kind:'text', blockId, offset}}. Use 'ref' instead when you have a search result handle. Required for actions 'set_style', 'set_alignment', 'set_indentation', 'set_spacing', 'set_direction'."
594
+ "description": "Selection target: {kind:'selection', start:{kind:'text', blockId, offset}, end:{kind:'text', blockId, offset}}. Use 'ref' instead when you have a search result handle. Required for actions 'set_style', 'set_alignment', 'set_indentation', 'set_spacing', 'set_flow_options', 'set_direction'."
565
595
  },
566
596
  "inline": {
567
597
  "type": "object",
@@ -879,6 +909,18 @@
879
909
  "atLeast"
880
910
  ]
881
911
  },
912
+ "contextualSpacing": {
913
+ "type": "boolean",
914
+ "description": "Only for action 'set_flow_options'. Omit for other actions."
915
+ },
916
+ "pageBreakBefore": {
917
+ "type": "boolean",
918
+ "description": "Only for action 'set_flow_options'. Omit for other actions."
919
+ },
920
+ "suppressAutoHyphens": {
921
+ "type": "boolean",
922
+ "description": "Only for action 'set_flow_options'. Omit for other actions."
923
+ },
882
924
  "direction": {
883
925
  "type": "string",
884
926
  "enum": [
@@ -900,11 +942,60 @@
900
942
  "action"
901
943
  ],
902
944
  "additionalProperties": false
903
- }
945
+ },
946
+ "input_examples": [
947
+ {
948
+ "action": "inline",
949
+ "ref": "<handle.ref>",
950
+ "inline": {
951
+ "bold": true
952
+ }
953
+ },
954
+ {
955
+ "action": "inline",
956
+ "ref": "<create.ref>",
957
+ "inline": {
958
+ "fontFamily": "Calibri",
959
+ "fontSize": 11,
960
+ "color": "#000000",
961
+ "bold": false
962
+ }
963
+ },
964
+ {
965
+ "action": "set_alignment",
966
+ "target": {
967
+ "kind": "block",
968
+ "nodeType": "paragraph",
969
+ "nodeId": "<nodeId>"
970
+ },
971
+ "alignment": "center"
972
+ },
973
+ {
974
+ "action": "set_flow_options",
975
+ "target": {
976
+ "kind": "block",
977
+ "nodeType": "paragraph",
978
+ "nodeId": "<nodeId>"
979
+ },
980
+ "pageBreakBefore": true
981
+ },
982
+ {
983
+ "action": "set_spacing",
984
+ "target": {
985
+ "kind": "block",
986
+ "nodeType": "paragraph",
987
+ "nodeId": "<nodeId>"
988
+ },
989
+ "lineSpacing": {
990
+ "rule": "auto",
991
+ "value": 1.5
992
+ }
993
+ }
994
+ ]
904
995
  },
905
996
  {
906
997
  "name": "superdoc_create",
907
- "description": "Create one paragraph or heading per call. After creating, search for it and apply formatting (fontFamily, fontSize) from neighboring blocks. For multiple paragraphs, use superdoc_mutations with text.insert steps instead of calling create repeatedly.",
998
+ "description": "You MUST call superdoc_format after this tool to match document styling. Create a single paragraph, heading, or table in the document. Returns a nodeId for chaining subsequent creates and for use as a block target in superdoc_format. When the user asks for a \"heading\", use action \"heading\" with a level (default 1). Use action \"paragraph\" only when the user asks for regular body text. Before creating, call superdoc_get_content blocks to read formatting from regular body text paragraphs (non-empty, non-title blocks with alignment \"justify\" or \"left\"). After creating, re-fetch blocks with superdoc_get_content to get a fresh ref for the new block, then apply TWO format calls: (1) superdoc_format action \"inline\" for character styling, AND (2) superdoc_format action \"set_alignment\" with the block target for paragraph alignment. Both calls are REQUIRED. For body paragraphs: inline {bold:false, underline:false, fontFamily, fontSize, color from body blocks}, alignment \"justify\". Ignore underline:true from blocks data for body text; it is a style artifact. For headings: inline {bold:true, underline:true, fontSize scaled up, fontFamily, color}, alignment \"center\". Position with \"at\": {kind:\"documentEnd\"} (default), {kind:\"documentStart\"}, or {kind:\"after\"/\"before\", target:{kind:\"block\", nodeType, nodeId}} for relative placement. When creating multiple items in sequence, use the previous response nodeId as the next \"at\" target to maintain correct ordering. Do NOT use newlines in \"text\" to create multiple paragraphs; call this tool separately for each one.",
908
999
  "input_schema": {
909
1000
  "type": "object",
910
1001
  "properties": {
@@ -912,9 +1003,10 @@
912
1003
  "type": "string",
913
1004
  "enum": [
914
1005
  "heading",
915
- "paragraph"
1006
+ "paragraph",
1007
+ "table"
916
1008
  ],
917
- "description": "The action to perform. One of: heading, paragraph."
1009
+ "description": "The action to perform. One of: heading, paragraph, table."
918
1010
  },
919
1011
  "force": {
920
1012
  "type": "boolean",
@@ -1058,17 +1150,67 @@
1058
1150
  "level": {
1059
1151
  "type": "number",
1060
1152
  "description": "Heading level (1-6). Required for action 'heading'."
1153
+ },
1154
+ "rows": {
1155
+ "type": "number",
1156
+ "description": "Required for action 'table'."
1157
+ },
1158
+ "columns": {
1159
+ "type": "number",
1160
+ "description": "Required for action 'table'."
1061
1161
  }
1062
1162
  },
1063
1163
  "required": [
1064
1164
  "action"
1065
1165
  ],
1066
1166
  "additionalProperties": false
1067
- }
1167
+ },
1168
+ "input_examples": [
1169
+ {
1170
+ "action": "paragraph",
1171
+ "text": "New paragraph content.",
1172
+ "at": {
1173
+ "kind": "documentEnd"
1174
+ }
1175
+ },
1176
+ {
1177
+ "action": "heading",
1178
+ "text": "Section Title",
1179
+ "level": 2,
1180
+ "at": {
1181
+ "kind": "after",
1182
+ "target": {
1183
+ "kind": "block",
1184
+ "nodeType": "paragraph",
1185
+ "nodeId": "<nodeId>"
1186
+ }
1187
+ }
1188
+ },
1189
+ {
1190
+ "action": "paragraph",
1191
+ "text": "Chained item.",
1192
+ "at": {
1193
+ "kind": "after",
1194
+ "target": {
1195
+ "kind": "block",
1196
+ "nodeType": "paragraph",
1197
+ "nodeId": "<previousNodeId>"
1198
+ }
1199
+ }
1200
+ },
1201
+ {
1202
+ "action": "table",
1203
+ "rows": 3,
1204
+ "columns": 4,
1205
+ "at": {
1206
+ "kind": "documentEnd"
1207
+ }
1208
+ }
1209
+ ]
1068
1210
  },
1069
1211
  {
1070
1212
  "name": "superdoc_list",
1071
- "description": "Create and manipulate lists",
1213
+ "description": "Create and manipulate bullet and numbered lists. To create a list: first create all paragraphs at the SAME location using superdoc_create (chain each using the previous nodeId as the \"at\" target). Then call action \"create\" with mode:\"fromParagraphs\", a preset (\"disc\" for bullet, \"decimal\" for numbered), and a range target: {from:{kind:\"block\", nodeType:\"paragraph\", nodeId:\"<first>\"}, to:{kind:\"block\", nodeType:\"paragraph\", nodeId:\"<last>\"}}. The range converts ALL paragraphs between from and to into list items. Make sure no other content exists between them. Action \"set_type\" converts between bullet and ordered (target any item in the list, kind:\"ordered\" or \"bullet\"). Action \"insert\" adds a new item before/after a target list item. Actions \"indent\" and \"outdent\" change nesting level; \"set_level\" jumps to a specific level (0-8). Action \"detach\" converts a list item back to a plain paragraph. Do NOT target paragraphs with indent/outdent/set_type; these actions require a listItem target.",
1072
1214
  "input_schema": {
1073
1215
  "type": "object",
1074
1216
  "properties": {
@@ -1318,11 +1460,57 @@
1318
1460
  "action"
1319
1461
  ],
1320
1462
  "additionalProperties": false
1321
- }
1463
+ },
1464
+ "input_examples": [
1465
+ {
1466
+ "action": "create",
1467
+ "mode": "fromParagraphs",
1468
+ "preset": "disc",
1469
+ "target": {
1470
+ "from": {
1471
+ "kind": "block",
1472
+ "nodeType": "paragraph",
1473
+ "nodeId": "<firstId>"
1474
+ },
1475
+ "to": {
1476
+ "kind": "block",
1477
+ "nodeType": "paragraph",
1478
+ "nodeId": "<lastId>"
1479
+ }
1480
+ }
1481
+ },
1482
+ {
1483
+ "action": "set_type",
1484
+ "target": {
1485
+ "kind": "block",
1486
+ "nodeType": "listItem",
1487
+ "nodeId": "<itemId>"
1488
+ },
1489
+ "kind": "ordered"
1490
+ },
1491
+ {
1492
+ "action": "insert",
1493
+ "target": {
1494
+ "kind": "block",
1495
+ "nodeType": "listItem",
1496
+ "nodeId": "<itemId>"
1497
+ },
1498
+ "position": "after",
1499
+ "text": "New list item"
1500
+ },
1501
+ {
1502
+ "action": "indent",
1503
+ "target": {
1504
+ "kind": "block",
1505
+ "nodeType": "listItem",
1506
+ "nodeId": "<itemId>"
1507
+ }
1508
+ }
1509
+ ]
1322
1510
  },
1323
1511
  {
1324
1512
  "name": "superdoc_comment",
1325
- "description": "Comment threads — create, edit, delete",
1513
+ "description": "Manage document comment threads: create, read, update, and delete. To create a comment, first use superdoc_search to find the target text, then pass action \"create\" with the comment text and a target: {kind:\"text\", blockId:\"<blockId>\", range:{start:<N>, end:<N>}} using the blockId and highlightRange from the search result. For threaded replies, pass \"parentId\" with the parent comment ID. Action \"list\" returns all comments with optional pagination (limit, offset) and filtering (includeResolved:true to include resolved). Action \"get\" retrieves a single comment by ID. Action \"update\" changes status to \"resolved\" or marks as internal. Action \"delete\" removes a comment or reply by ID. Do NOT pass \"ref\", \"id\", or \"parentId\" when creating a new top-level comment; only \"action\", \"text\", and \"target\" are needed.",
1326
1514
  "input_schema": {
1327
1515
  "type": "object",
1328
1516
  "properties": {
@@ -1422,11 +1610,39 @@
1422
1610
  "action"
1423
1611
  ],
1424
1612
  "additionalProperties": false
1425
- }
1613
+ },
1614
+ "input_examples": [
1615
+ {
1616
+ "action": "create",
1617
+ "text": "Please review this section.",
1618
+ "target": {
1619
+ "kind": "text",
1620
+ "blockId": "<blockId>",
1621
+ "range": {
1622
+ "start": 5,
1623
+ "end": 25
1624
+ }
1625
+ }
1626
+ },
1627
+ {
1628
+ "action": "list",
1629
+ "limit": 20,
1630
+ "offset": 0
1631
+ },
1632
+ {
1633
+ "action": "update",
1634
+ "id": "<commentId>",
1635
+ "status": "resolved"
1636
+ },
1637
+ {
1638
+ "action": "delete",
1639
+ "id": "<commentId>"
1640
+ }
1641
+ ]
1426
1642
  },
1427
1643
  {
1428
1644
  "name": "superdoc_track_changes",
1429
- "description": "Review and resolve tracked changes",
1645
+ "description": "Review and resolve tracked changes (insertions, deletions, format changes) in the document. Action \"list\" returns all tracked changes with optional filtering by type (insert, delete, format) and pagination (limit, offset). Each change includes an ID, type, author, timestamp, and content preview. Action \"decide\" accepts or rejects changes. Pass decision:\"accept\" to apply the change permanently, or decision:\"reject\" to discard it. Target a single change with {id:\"<changeId>\"} or all changes at once with {scope:\"all\"}. Do NOT use this tool unless the document has tracked changes. Use superdoc_get_content info to check the tracked change count first.",
1430
1646
  "input_schema": {
1431
1647
  "type": "object",
1432
1648
  "properties": {
@@ -1509,11 +1725,35 @@
1509
1725
  "action"
1510
1726
  ],
1511
1727
  "additionalProperties": false
1512
- }
1728
+ },
1729
+ "input_examples": [
1730
+ {
1731
+ "action": "list"
1732
+ },
1733
+ {
1734
+ "action": "list",
1735
+ "type": "insert",
1736
+ "limit": 10
1737
+ },
1738
+ {
1739
+ "action": "decide",
1740
+ "decision": "accept",
1741
+ "target": {
1742
+ "id": "<changeId>"
1743
+ }
1744
+ },
1745
+ {
1746
+ "action": "decide",
1747
+ "decision": "reject",
1748
+ "target": {
1749
+ "scope": "all"
1750
+ }
1751
+ }
1752
+ ]
1513
1753
  },
1514
1754
  {
1515
1755
  "name": "superdoc_search",
1516
- "description": "Find text or nodes in the document",
1756
+ "description": "Refs expire after any mutation; always re-search before the next edit. Find text patterns or nodes in the document and get ref handles for targeting edits and formatting. Use this to locate content before calling superdoc_edit or superdoc_format. Text search returns handle.ref covering only the matched substring. Node search finds blocks by type (paragraph, heading, table, listItem, etc.). The \"require\" parameter controls match cardinality: \"first\" returns one match, \"all\" returns every match, \"exactlyOne\" fails if not exactly one match. Supports scoping via \"within\" to search inside a single block. Do NOT use regex or markdown formatting markers (#, **, etc.) in search patterns; patterns are plain text only. Do NOT use this tool when you already have a ref from superdoc_get_content blocks or superdoc_create; use that ref directly.",
1517
1757
  "input_schema": {
1518
1758
  "type": "object",
1519
1759
  "properties": {
@@ -1664,11 +1904,46 @@
1664
1904
  "select"
1665
1905
  ],
1666
1906
  "additionalProperties": false
1667
- }
1907
+ },
1908
+ "input_examples": [
1909
+ {
1910
+ "select": {
1911
+ "type": "text",
1912
+ "pattern": "Introduction"
1913
+ },
1914
+ "require": "first"
1915
+ },
1916
+ {
1917
+ "select": {
1918
+ "type": "text",
1919
+ "pattern": "total amount"
1920
+ },
1921
+ "require": "all"
1922
+ },
1923
+ {
1924
+ "select": {
1925
+ "type": "node",
1926
+ "nodeType": "heading"
1927
+ },
1928
+ "require": "all"
1929
+ },
1930
+ {
1931
+ "select": {
1932
+ "type": "text",
1933
+ "pattern": "contract"
1934
+ },
1935
+ "within": {
1936
+ "kind": "block",
1937
+ "nodeType": "paragraph",
1938
+ "nodeId": "abc123"
1939
+ },
1940
+ "require": "first"
1941
+ }
1942
+ ]
1668
1943
  },
1669
1944
  {
1670
1945
  "name": "superdoc_mutations",
1671
- "description": "Atomic multi-step batch edits (escape hatch)",
1946
+ "description": "All steps succeed or all fail; no partial application. Execute multiple text edits atomically in a single batch. Use this INSTEAD OF multiple sequential superdoc_edit calls when you need 2+ text changes that should succeed or fail together. Each step has an id (e.g. \"s1\"), an op (text.rewrite, text.insert, text.delete, format.apply, assert), a \"where\" clause for targeting ({by:\"select\", select:{...}, require:\"first\"|\"exactlyOne\"|\"all\"} or {by:\"ref\", ref:\"...\"}), and \"args\" with operation-specific parameters. Action \"preview\" dry-runs the plan without modifying the document. Action \"apply\" executes it. CRITICAL: split mutations by phase. Text mutations (text.rewrite, text.insert, text.delete) go in one call. Formatting (format.apply) goes in a separate call with fresh refs from a new superdoc_search. Do NOT create two steps that target overlapping text in the same block; combine them into a single text.rewrite step. Overlapping steps fail with PLAN_CONFLICT_OVERLAP. Do NOT use this for single edits; use superdoc_edit instead. Do NOT mix text mutations and formatting in the same call.",
1672
1947
  "input_schema": {
1673
1948
  "type": "object",
1674
1949
  "properties": {
@@ -3615,7 +3890,46 @@
3615
3890
  "steps"
3616
3891
  ],
3617
3892
  "additionalProperties": false
3618
- }
3893
+ },
3894
+ "input_examples": [
3895
+ {
3896
+ "action": "apply",
3897
+ "atomic": true,
3898
+ "changeMode": "direct",
3899
+ "steps": [
3900
+ {
3901
+ "id": "s1",
3902
+ "op": "text.rewrite",
3903
+ "where": {
3904
+ "by": "select",
3905
+ "select": {
3906
+ "type": "text",
3907
+ "pattern": "old term"
3908
+ },
3909
+ "require": "all"
3910
+ },
3911
+ "args": {
3912
+ "replacement": {
3913
+ "text": "new term"
3914
+ }
3915
+ }
3916
+ },
3917
+ {
3918
+ "id": "s2",
3919
+ "op": "text.delete",
3920
+ "where": {
3921
+ "by": "select",
3922
+ "select": {
3923
+ "type": "text",
3924
+ "pattern": " (deprecated)"
3925
+ },
3926
+ "require": "all"
3927
+ },
3928
+ "args": {}
3929
+ }
3930
+ ]
3931
+ }
3932
+ ]
3619
3933
  }
3620
3934
  ]
3621
3935
  }