| 83 | |
| 84 | |
| 85 | def _apply_edit_with_report(skill: str, edit: EditType | dict) -> tuple[str, dict]: |
| 86 | op, content, target = _edit_fields(edit) |
| 87 | report = { |
| 88 | "op": op, |
| 89 | "target": target[:200], |
| 90 | "content_preview": content[:200], |
| 91 | "status": "unknown", |
| 92 | } |
| 93 | |
| 94 | if target and _is_in_protected_region(skill, target): |
| 95 | report["status"] = "skipped_protected_region" |
| 96 | return skill, report |
| 97 | |
| 98 | if op == "append": |
| 99 | prot_start = _earliest_protected_start(skill) |
| 100 | if prot_start != -1: |
| 101 | before = skill[:prot_start].rstrip() |
| 102 | after = skill[prot_start:] |
| 103 | report["status"] = "applied_append_before_protected_region" |
| 104 | return before + "\n\n" + content + "\n\n" + after, report |
| 105 | report["status"] = "applied_append" |
| 106 | return skill.rstrip() + "\n\n" + content + "\n", report |
| 107 | |
| 108 | if op == "insert_after": |
| 109 | if not target or target not in skill: |
| 110 | prot_start = _earliest_protected_start(skill) |
| 111 | if prot_start != -1: |
| 112 | before = skill[:prot_start].rstrip() |
| 113 | after = skill[prot_start:] |
| 114 | report["status"] = "applied_insert_after_fallback_before_protected_region" |
| 115 | return before + "\n\n" + content + "\n\n" + after, report |
| 116 | report["status"] = "applied_insert_after_fallback_append" |
| 117 | return skill.rstrip() + "\n\n" + content + "\n", report |
| 118 | idx = skill.index(target) + len(target) |
| 119 | newline = skill.find("\n", idx) |
| 120 | insert_at = newline + 1 if newline != -1 else len(skill) |
| 121 | report["status"] = "applied_insert_after" |
| 122 | return skill[:insert_at] + "\n" + content + "\n" + skill[insert_at:], report |
| 123 | |
| 124 | if op == "replace": |
| 125 | if not target: |
| 126 | report["status"] = "skipped_replace_missing_target" |
| 127 | return skill, report |
| 128 | if target not in skill: |
| 129 | report["status"] = "skipped_replace_target_not_found" |
| 130 | return skill, report |
| 131 | report["status"] = "applied_replace" |
| 132 | return skill.replace(target, content, 1), report |
| 133 | |
| 134 | if op == "delete": |
| 135 | if not target: |
| 136 | report["status"] = "skipped_delete_missing_target" |
| 137 | return skill, report |
| 138 | if target not in skill: |
| 139 | report["status"] = "skipped_delete_target_not_found" |
| 140 | return skill, report |
| 141 | report["status"] = "applied_delete" |
| 142 | return skill.replace(target, "", 1), report |