|
1950 | 1950 | "patch": { |
1951 | 1951 | "operationId": "editFileContent", |
1952 | 1952 | "summary": "Edit File Content", |
1953 | | - "description": "Change part of a text file in place, leaving the rest untouched. `PUT` on this path replaces the whole file; this is the partial counterpart, so one line can be corrected without regenerating everything around it. `replace_string` requires `oldString` to match **exactly once** — several matches answer `400` naming the lines they sit on, because replacing an arbitrary one of them would be a silent write to a line the caller never chose. `insert_lines` inserts after a 1-based line, with `0` meaning the top; a line past the end of the file answers `400` rather than appending. Line numbers are the ones `GET /api/v2/files/{fileId}/text` and file search report. Only files whose stored bytes are UTF-8 text can be edited: editing works on the bytes, never on parsed text, so a PDF or DOCX answers `400`. A concurrent write answers `409`, and retrying means re-reading first.", |
| 1953 | + "description": "Change part of a text file in place, leaving the rest untouched. `PUT` on this path replaces the whole file; this is the partial counterpart. `search_replace` matches exact text and requires one match unless `replaceAll` is true. `replace_between`, `insert_after`, and `delete_between` match complete lines after trimming surrounding whitespace, so edits remain stable when unrelated changes move the target to another line. Anchored replacement preserves both boundary lines; insertion preserves its anchor; deletion removes the start anchor and preserves the end anchor. Use `occurrence` when an anchor line repeats. Only files whose stored bytes are UTF-8 text can be edited: a PDF or DOCX answers `400`. A concurrent write answers `409`, and retrying means re-reading first.", |
1954 | 1954 | "tags": ["Files"], |
1955 | 1955 | "parameters": [ |
1956 | 1956 | { |
|
4600 | 4600 | "properties": { |
4601 | 4601 | "mode": { |
4602 | 4602 | "type": "string", |
4603 | | - "const": "replace_string", |
4604 | | - "description": "Replace one exact piece of text with another." |
| 4603 | + "const": "search_replace", |
| 4604 | + "description": "Replace exact text." |
4605 | 4605 | }, |
4606 | | - "oldString": { |
| 4606 | + "search": { |
4607 | 4607 | "type": "string", |
4608 | 4608 | "minLength": 1, |
4609 | | - "description": "Exact text to replace, matched verbatim. It must appear exactly once: several matches are refused with `400` naming the lines they sit on, so include enough surrounding text to be unique." |
| 4609 | + "description": "Exact text to replace, matched verbatim. It must appear once unless replaceAll is true." |
4610 | 4610 | }, |
4611 | | - "newString": { |
| 4611 | + "content": { |
4612 | 4612 | "type": "string", |
4613 | 4613 | "description": "Text to put in its place. An empty string deletes the matched text." |
| 4614 | + }, |
| 4615 | + "replaceAll": { |
| 4616 | + "description": "Replace every non-overlapping match. Defaults to false.", |
| 4617 | + "type": "boolean" |
4614 | 4618 | } |
4615 | 4619 | }, |
4616 | | - "required": ["mode", "oldString", "newString"], |
| 4620 | + "required": ["mode", "search", "content"], |
4617 | 4621 | "additionalProperties": false |
4618 | 4622 | }, |
4619 | 4623 | { |
4620 | 4624 | "type": "object", |
4621 | 4625 | "properties": { |
4622 | 4626 | "mode": { |
4623 | 4627 | "type": "string", |
4624 | | - "const": "insert_lines", |
4625 | | - "description": "Insert new lines at a given line." |
| 4628 | + "const": "replace_between", |
| 4629 | + "description": "Replace content between two complete-line anchors." |
| 4630 | + }, |
| 4631 | + "beforeAnchor": { |
| 4632 | + "type": "string", |
| 4633 | + "minLength": 1, |
| 4634 | + "description": "Boundary line before the replaced content. This line remains." |
| 4635 | + }, |
| 4636 | + "afterAnchor": { |
| 4637 | + "type": "string", |
| 4638 | + "minLength": 1, |
| 4639 | + "description": "Boundary line after the replaced content. This line remains." |
| 4640 | + }, |
| 4641 | + "content": { |
| 4642 | + "type": "string", |
| 4643 | + "description": "Replacement text. An empty string clears the interior." |
4626 | 4644 | }, |
4627 | | - "afterLine": { |
| 4645 | + "occurrence": { |
| 4646 | + "description": "Matching anchor occurrence, starting at 1. Defaults to 1.", |
4628 | 4647 | "type": "integer", |
4629 | | - "minimum": 0, |
4630 | | - "maximum": 9007199254740991, |
4631 | | - "description": "The 1-based line to insert after; 0 inserts at the top. A line past the end is refused rather than appended." |
| 4648 | + "minimum": 1, |
| 4649 | + "maximum": 9007199254740991 |
| 4650 | + } |
| 4651 | + }, |
| 4652 | + "required": ["mode", "beforeAnchor", "afterAnchor", "content"], |
| 4653 | + "additionalProperties": false |
| 4654 | + }, |
| 4655 | + { |
| 4656 | + "type": "object", |
| 4657 | + "properties": { |
| 4658 | + "mode": { |
| 4659 | + "type": "string", |
| 4660 | + "const": "insert_after", |
| 4661 | + "description": "Insert content after a complete-line anchor." |
| 4662 | + }, |
| 4663 | + "anchor": { |
| 4664 | + "type": "string", |
| 4665 | + "minLength": 1, |
| 4666 | + "description": "Complete line after which content is inserted." |
4632 | 4667 | }, |
4633 | 4668 | "content": { |
4634 | 4669 | "type": "string", |
4635 | | - "description": "Text to insert. Multiple lines insert as multiple lines." |
| 4670 | + "minLength": 1, |
| 4671 | + "description": "Text to insert." |
| 4672 | + }, |
| 4673 | + "occurrence": { |
| 4674 | + "description": "Matching anchor occurrence, starting at 1. Defaults to 1.", |
| 4675 | + "type": "integer", |
| 4676 | + "minimum": 1, |
| 4677 | + "maximum": 9007199254740991 |
| 4678 | + } |
| 4679 | + }, |
| 4680 | + "required": ["mode", "anchor", "content"], |
| 4681 | + "additionalProperties": false |
| 4682 | + }, |
| 4683 | + { |
| 4684 | + "type": "object", |
| 4685 | + "properties": { |
| 4686 | + "mode": { |
| 4687 | + "type": "string", |
| 4688 | + "const": "delete_between", |
| 4689 | + "description": "Delete from one complete-line anchor to another." |
| 4690 | + }, |
| 4691 | + "startAnchor": { |
| 4692 | + "type": "string", |
| 4693 | + "minLength": 1, |
| 4694 | + "description": "First line to delete. This start anchor is removed." |
| 4695 | + }, |
| 4696 | + "endAnchor": { |
| 4697 | + "type": "string", |
| 4698 | + "minLength": 1, |
| 4699 | + "description": "Ending boundary line. This end anchor remains." |
| 4700 | + }, |
| 4701 | + "occurrence": { |
| 4702 | + "description": "Matching anchor occurrence, starting at 1. Defaults to 1.", |
| 4703 | + "type": "integer", |
| 4704 | + "minimum": 1, |
| 4705 | + "maximum": 9007199254740991 |
4636 | 4706 | } |
4637 | 4707 | }, |
4638 | | - "required": ["mode", "afterLine", "content"], |
| 4708 | + "required": ["mode", "startAnchor", "endAnchor"], |
4639 | 4709 | "additionalProperties": false |
4640 | 4710 | } |
4641 | 4711 | ], |
4642 | | - "description": "The change to apply." |
| 4712 | + "description": "One exact or anchor-based edit: search_replace, replace_between, insert_after, or delete_between." |
4643 | 4713 | } |
4644 | 4714 | }, |
4645 | 4715 | "required": ["workspaceId", "edit"], |
|
4650 | 4720 | { |
4651 | 4721 | "workspaceId": "a91c4b2e-6d3f-4e8a-b5c7-0d9e2f1a8c64", |
4652 | 4722 | "edit": { |
4653 | | - "mode": "replace_string", |
4654 | | - "oldString": "- based in NYC", |
4655 | | - "newString": "- based in SF" |
| 4723 | + "mode": "search_replace", |
| 4724 | + "search": "- based in NYC", |
| 4725 | + "content": "- based in SF" |
4656 | 4726 | } |
4657 | 4727 | }, |
4658 | 4728 | { |
4659 | 4729 | "workspaceId": "a91c4b2e-6d3f-4e8a-b5c7-0d9e2f1a8c64", |
4660 | 4730 | "edit": { |
4661 | | - "mode": "insert_lines", |
4662 | | - "afterLine": 4, |
| 4731 | + "mode": "insert_after", |
| 4732 | + "anchor": "## Preferences", |
4663 | 4733 | "content": "- prefers async updates" |
4664 | 4734 | } |
4665 | 4735 | } |
|
0 commit comments