Work with the editor feature
Use the editor feature when you need to validate frontmatter, surface lint diagnostics, provide autocomplete suggestions, locate references, or rename aliases, tags, and template paths across a corpus.
Prerequisites
- A configured
corpusobject that implementsCorpusProtocol - Python access to the
attune_rag.editorpackage
Validate and lint a template
Use these steps to check a template's frontmatter and surface any diagnostics before saving.
-
Parse and validate the frontmatter. Call
parse_frontmatter(yaml_text)with the raw YAML block from the top of your template. The function returns a(dict, list[FrontmatterIssue])tuple. If the YAML is malformed, it raisesSchemaError.from attune_rag.editor import parse_frontmatter, SchemaError try: data, issues = parse_frontmatter(yaml_text) except SchemaError as e: print(f"Malformed YAML: {e}") -
Inspect schema violations. Iterate
issues. EachFrontmatterIssuehas acode,message, andpathtuple pointing to the offending key.for issue in issues: print(issue.code, issue.path, issue.message) -
Run the full lint pass. Call
lint_template(text, rel_path, corpus)with the full template text, its corpus-relative path, and your corpus. Each returnedDiagnosticcarries aseverity,code,message, and 1-indexedline/col/end_line/end_colrange.from attune_rag.editor import lint_template diagnostics = lint_template(text, "templates/my_template.md", corpus) for d in diagnostics: print(d.severity, d.code, d.line, d.message)
Success criterion: parse_frontmatter returns an empty issues list and lint_template returns an empty diagnostics list for a valid template.
Provide autocomplete suggestions
Use these steps to populate tag or alias suggestions in an editor UI as the user types.
-
Suggest tags. Call
autocomplete_tags(corpus, prefix, limit=50)with the current prefix string. The function returns up tolimitmatching tag strings.from attune_rag.editor import autocomplete_tags suggestions = autocomplete_tags(corpus, prefix="data-") -
Suggest aliases. Call
autocomplete_aliases(corpus, prefix, limit=50)to get up tolimitAliasInfoobjects whose names start withprefix.from attune_rag.editor import autocomplete_aliases suggestions = autocomplete_aliases(corpus, prefix="my_")
Success criterion: Both calls return a non-empty list when matching entries exist in the corpus, and an empty list when none match.
Find references across a corpus
Use this step to locate every occurrence of an alias, tag, or template path before making a structural change.
-
Call
find_references. Pass your corpus, the name to look up, and the appropriateReferenceKindvalue.from attune_rag.editor import find_references, ReferenceKind refs = find_references(corpus, "my_alias", ReferenceKind.ALIAS) for ref in refs: print(ref.template_path, ref.line, ref.col, ref.context)find_referencesraisesValueErrorif you pass an unsupportedReferenceKind.
Success criterion: The returned list contains a Reference entry for each file and line in the corpus that uses the specified name.
Rename an alias, tag, or template path
Use these steps to rename a name across every file in the corpus atomically.
-
Build the rename plan. Call
plan_rename(corpus, old, new, kind)to compute aRenamePlan. The plan containsFileEditobjects (with per-fileHunkdiffs) and anyFileMoveobjects for path renames. No files are modified at this step.from attune_rag.editor import plan_rename, ReferenceKind plan = plan_rename(corpus, "old_alias", "new_alias", ReferenceKind.ALIAS)plan_renameraisesValueErrorfor an unsupportedReferenceKind. -
Review the plan. Inspect
plan.editsandplan.movesbefore applying. EachFileEditexposesold_text,new_text, and a list ofHunkobjects you can display as a unified diff.for edit in plan.edits: print(edit.path) for hunk in edit.hunks: print(hunk.header) print("".join(hunk.lines)) -
Apply the plan. Call
apply_rename(corpus, plan)to write all edits and file moves to disk and refresh the corpus. The function returns a list of paths that were modified.from attune_rag.editor import apply_rename modified = apply_rename(corpus, plan) print("Modified files:", modified)apply_renameraisesRenameCollisionErrorif the proposed new name already exists, andRenameErrorfor other failures such as a missing corpus root, a moved file that has drifted from the plan, or a missing source file.
Success criterion: apply_rename returns a list of modified paths with no exceptions, and calling find_references(corpus, "old_alias", ReferenceKind.ALIAS) afterwards returns an empty list.
Key files
| File | Responsibility |
|---|---|
src/attune_rag/editor/__init__.py |
Public API surface |
src/attune_rag/editor/schema.py |
Frontmatter schema, parse_frontmatter, validate_frontmatter, load_schema |
src/attune_rag/editor/lint.py |
lint_template and Diagnostic |
src/attune_rag/editor/autocomplete.py |
autocomplete_tags, autocomplete_aliases |
src/attune_rag/editor/references.py |
find_references and Reference |
src/attune_rag/editor/rename.py |
plan_rename, apply_rename, RenamePlan, FileEdit, FileMove, Hunk |