cape.agent.skills.fileedit: LLM-driven editing of allow-listed files

This module defines the built-in agent skill "file-editor", which teaches the CAPE agent how to edit a restricted set of files in the repo in which the agent is launched.

The skill provides three tools:

  • list_editable_files(): list the active allow-list patterns and the existing files that match them

  • read_file(): read a file with line numbers (any repo file smaller than about 2 MB; provided by cape.agent.skills.fileread)

  • edit_file(): apply an exact-match search-and-replace edit to an allow-listed file, returning a unified diff of the change

The allow-list restricts which files may be edited; it does not apply to reading, which is limited only by the repo root folder and the file-size limit of the file-reader skill (see cape.agent.skills.fileread).

The set of editable files (the allow-list) comes from three sources:

  • the top-level EditAllowList option of the cape-agent.json file: a list of glob patterns relative to the repo root (see cape.agent.options)

  • cape.cfdx.cntl.Cntl.get_edit_allowlist(), which allows the agent to edit the CAPE control JSON file itself

  • cape.agent.agentcntl.EDIT_FILE_ALLOW_LIST, a registry of file names that other skills (e.g. fix-json) append to at run time; this is the only route for files that cannot be read into a Cntl instance, such as a JSON file with a syntax error

Note that fnmatch.fnmatch() is used for matching, so "*" matches folder separators as well; a pattern such as "tools/*.py" matches tools/a/b.py as well as tools/a.py.

Every tool resolves any symlinks in the target file’s path and rejects files outside the repo root folder, regardless of the allow-list.

cape.agent.skills.fileedit.edit_file(fname: str, old: str, new: str) → dict

Replace one occurrence of old with new in an allow-listed file

The text old must occur exactly once in the file; otherwise no edit is made. On success the result includes a unified diff of the change, truncated to MAX_DIFF_CHARS characters.

Call:
>>> result = edit_file(fname, old, new)
Inputs:
fname: str

Name of file to edit; must match the edit allow-list

old: str

Exact text to search for; must occur exactly once

new: str

Replacement text; may be "" to delete the match

Outputs:
result: dict

Keys include success, file, and diff

cape.agent.skills.fileedit.list_editable_files() → dict

List the edit allow-list and the existing files that match it

The allow-list combines the EditAllowList glob patterns from the cape-agent.json file, the files returned by cape.cfdx.cntl.Cntl.get_edit_allowlist() for the current CAPE control instance (if any), and files registered by other skills via cape.agent.agentcntl.EDIT_FILE_ALLOW_LIST.

Call:
>>> result = list_editable_files()
Outputs:
result: dict

Keys include success, patterns, cntl_files, skill_files, and files (existing files matching the patterns)

cape.agent.skills.fileedit.register_editable_file(fname: str) → dict

Add a file to the session edit allow-list, for use by skills

This is how other skills, e.g. fix-json, grant the agent edit access to a specific file that is not covered by the static EditAllowList patterns or by the Cntl-provided allow-list (for example a JSON file that cannot be read due to a syntax error). The file must be inside the repo root folder.

Call:
>>> result = register_editable_file(fname)
Inputs:
fname: str

Name of file to register, absolute or relative to the current folder

Outputs:
result: dict

Keys include success, path (resolved absolute path), file (name relative to the root folder), and added (False if already registered)