<!-- Generated by SpecStory, Markdown v2.1.0 -->

# 2026-03-10 16:23:09Z

<!-- cursoride Session 7ac38efd-6dd0-42da-9a01-f7d5062046e9 (2026-03-10 16:23:09Z) -->

_**User**_

Update the DLM_OT_migrator_remove_original class in T:\Dynamic-Link-Manager\ui\operators.py to delete the collection containing the original character instead of just deleting the armature object.

Current implementation:
```python
def execute(self, context):
    orig, rep = _get_migrator_pair(context)
    if not orig:
        self.report({"WARNING"}, "No original character selected")
        return {"CANCELLED"}
    if orig == rep:
        self.report({"ERROR"}, "Original and replacement cannot be the same object")
        return {"CANCELLED"}

    name = orig.name
    try:
        # Remove from scene
        bpy.data.objects.remove(orig, do_unlink=True)
        # Clear the property
        context.scene.dynamic_link_manager.original_character = None
        self.report({"INFO"}, f"Removed original character: {name}")
    except Exception as e:
        self.report({"ERROR"}, f"Failed to remove original: {e}")
        return {"CANCELLED"}
    return {"FINISHED"}
```

Change it to:
1. Import and use `collection_containing_armature` from `..utils` to find the collection
2. Delete the collection (which removes all objects in it)
3. Clear the original_character property
4. Report which collection was deleted

If no collection is found, fall back to just deleting the armature object.

---

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
The user wants me to update a class in a file. Let me first read the file to see the current implementation and understand the context.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: cat "T:\Dynamic-Link-Manager\ui\operators.py"</summary>

```bash
cat "T:\Dynamic-Link-Manager\ui\operators.py"
```

```
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

import bpy
import os
from bpy.types import Operator
from bpy.props import StringProperty, BoolProperty
from bpy.props import StringProperty, IntProperty

ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__


def _prefs(context):
    return context.preferences.addons.get(ADDON_NAME)


class DLM_OT_replace_linked_asset(Operator):
    bl_idname = "dlm.replace_linked_asset"
    bl_label = "Replace Linked Asset"
    bl_description = "Open file browser to replace the linked asset with another file"
    bl_options = {"REGISTER", "UNDO"}
    filepath: StringProperty(name="File Path", description="Path to the new asset file", subtype="FILE_PATH")

    def execute(self, context):
        obj = context.active_object
        if not obj:
            self.report({"ERROR"}, "No object selected")
            return {"CANCELLED"}
        if getattr(obj, "library", None):
            self.report({"INFO"}, f"Object '{obj.name}' is linked from: {obj.library.filepath}")
            return {"FINISHED"}
        if obj.data and getattr(obj.data, "library", None) and obj.data.library:
            self.report({"INFO"}, f"Object '{obj.name}' has linked data from: {obj.data.library.filepath}")
            return {"FINISHED"}
        if obj.type == "ARMATURE" and obj.data and obj.data.name in bpy.data.armatures:
            ad = bpy.data.armatures[obj.data.name]
            if getattr(ad, "library", None) and ad.library:
                self.report({"INFO"}, f"Armature '{obj.name}' data is linked from: {ad.library.filepath}")
                return {"FINISHED"}
        self.report({"ERROR"}, "Selected object is not a linked asset")
        return {"CANCELLED"}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {"RUNNING_MODAL"}


class DLM_OT_scan_linked_assets(Operator):
    bl_idname = "dlm.scan_linked_assets"
    bl_label = "Scan Linked Libraries"
    bl_description = "Scan the current file for linked libraries and list their status"
    bl_options = {"REGISTER"}

    def execute(self, context):
        from ..ops import library

        return library.scan_linked_assets(context, self.report)


class DLM_OT_find_libraries_in_folders(Operator):
    bl_idname = "dlm.find_libraries_in_folders"
    bl_label = "Find Libraries in Folders"
    bl_description = "Search addon search paths for missing library blend files"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        from ..ops import library

        return library.find_libraries_in_folders(context, self.report, ADDON_NAME)


class DLM_OT_open_linked_file(Operator):
    bl_idname = "dlm.open_linked_file"
    bl_label = "Open Linked File"
    bl_description = "Open the selected linked blend file in a new Blender instance"
    bl_options = {"REGISTER"}
    filepath: StringProperty(name="File Path", default="")

    def execute(self, context):
        if not self.filepath:
            self.report({"ERROR"}, "No file path specified")
            return {"CANCELLED"}
        try:
            bpy.ops.wm.path_open(filepath=self.filepath)
            self.report({"INFO"}, f"Opening linked file: {self.filepath}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to open linked file: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}


class DLM_OT_add_search_path(Operator):
    bl_idname = "dlm.add_search_path"
    bl_label = "Add Search Path"
    bl_description = "Add a new folder to the list of search paths for finding libraries"
    bl_options = {"REGISTER"}

    def execute(self, context):
        prefs = _prefs(context)
        if prefs:
            p = prefs.preferences.search_paths.add()
            p.path = "//"
            self.report({"INFO"}, f"Added search path: {p.path}")
        return {"FINISHED"}


class DLM_OT_remove_search_path(Operator):
    bl_idname = "dlm.remove_search_path"
    bl_label = "Remove Search Path"
    bl_description = "Remove the selected search path from the list"
    bl_options = {"REGISTER"}
    index: IntProperty(name="Index", default=0)

    def execute(self, context):
        prefs = _prefs(context)
        if prefs and prefs.preferences.search_paths and 0 &lt;= self.index &lt; len(prefs.preferences.search_paths):
            prefs.preferences.search_paths.remove(self.index)
            self.report({"INFO"}, f"Removed search path at index {self.index}")
        return {"FINISHED"}


class DLM_OT_attempt_relink(Operator):
    bl_idname = "dlm.attempt_relink"
    bl_label = "Attempt Relink"
    bl_description = "Try to relink missing libraries using the configured search paths"
    bl_options = {"REGISTER"}

    def execute(self, context):
        from ..ops import library

        return library.attempt_relink(context, self.report, ADDON_NAME)


class DLM_OT_browse_search_path(Operator):
    bl_idname = "dlm.browse_search_path"
    bl_label = "Browse Search Path"
    bl_description = "Browse to set the folder for the selected search path"
    bl_options = {"REGISTER"}
    index: IntProperty(name="Index", default=0)
    filepath: StringProperty(name="Search Path", subtype="DIR_PATH")

    def execute(self, context):
        prefs = _prefs(context)
        if prefs and prefs.preferences.search_paths and 0 &lt;= self.index &lt; len(prefs.preferences.search_paths):
            prefs.preferences.search_paths[self.index].path = self.filepath
            self.report({"INFO"}, f"Updated search path {self.index + 1}: {self.filepath}")
        return {"FINISHED"}

    def invoke(self, context, event):
        prefs = _prefs(context)
        if prefs and prefs.preferences.search_paths and 0 &lt;= self.index &lt; len(prefs.preferences.search_paths):
            self.filepath = prefs.preferences.search_paths[self.index].path
        context.window_manager.fileselect_add(self)
        return {"RUNNING_MODAL"}


class DLM_OT_reload_libraries(Operator):
    bl_idname = "dlm.reload_libraries"
    bl_label = "Reload Libraries"
    bl_description = "Reload all linked libraries (or fallback manual reload)"
    bl_options = {"REGISTER"}

    def execute(self, context):
        try:
            bpy.ops.outliner.lib_operation(type="RELOAD")
            self.report({"INFO"}, "Library reload operation completed")
        except Exception:
            try:
                for lib in bpy.data.libraries:
                    if lib.filepath and os.path.exists(bpy.path.abspath(lib.filepath)):
                        lib.reload()
                self.report({"INFO"}, "Libraries reloaded manually")
            except Exception as e:
                self.report({"ERROR"}, f"Failed to reload libraries: {e}")
                return {"CANCELLED"}
        return {"FINISHED"}


class DLM_OT_make_paths_relative(Operator):
    bl_idname = "dlm.make_paths_relative"
    bl_label = "Make Paths Relative"
    bl_description = "Convert all internal file paths to relative"
    bl_options = {"REGISTER"}

    def execute(self, context):
        try:
            bpy.ops.file.make_paths_relative()
            self.report({"INFO"}, "All file paths made relative")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to make paths relative: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}


class DLM_OT_make_paths_absolute(Operator):
    bl_idname = "dlm.make_paths_absolute"
    bl_label = "Make Paths Absolute"
    bl_description = "Convert all internal file paths to absolute"
    bl_options = {"REGISTER"}

    def execute(self, context):
        try:
            bpy.ops.file.make_paths_absolute()
            self.report({"INFO"}, "All file paths made absolute")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to make paths absolute: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}


class DLM_OT_relocate_single_library(Operator):
    bl_idname = "dlm.relocate_single_library"
    bl_label = "Relocate Library"
    bl_description = "Point the selected library to a new blend file and reload"
    bl_options = {"REGISTER", "UNDO"}
    target_filepath: StringProperty(name="Current Library Path", default="")
    filepath: StringProperty(name="New Library File", subtype="FILE_PATH", default="")

    def execute(self, context):
        if not self.target_filepath or not self.filepath:
            self.report({"ERROR"}, "No target or new file specified")
            return {"CANCELLED"}
        abs_match = bpy.path.abspath(self.target_filepath) if self.target_filepath else ""
        library = None
        for lib in bpy.data.libraries:
            try:
                if lib.filepath and bpy.path.abspath(lib.filepath) == abs_match:
                    library = lib
                    break
            except Exception:
                if lib.filepath == self.target_filepath:
                    library = lib
                    break
        if not library:
            self.report({"ERROR"}, "Could not resolve the selected library")
            return {"CANCELLED"}
        try:
            library.filepath = self.filepath
            library.reload()
            self.report({"INFO"}, f"Relocated to: {self.filepath}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to relocate: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}

    def invoke(self, context, event):
        if self.target_filepath:
            try:
                self.filepath = bpy.path.abspath(self.target_filepath)
            except Exception:
                self.filepath = self.target_filepath
        context.window_manager.fileselect_add(self)
        return {"RUNNING_MODAL"}


def _get_migrator_pair(context):
    """Return (orig, rep) from scene props (manual or automatic). (None, None) if invalid."""
    from ..ops.migrator import get_pair_manual, get_pair_automatic

    props = getattr(context.scene, "dynamic_link_manager", None)
    if not props:
        return None, None
    use_auto = getattr(props, "migrator_mode", False)
    orig, rep = get_pair_automatic(context) if use_auto else get_pair_manual(context)
    return orig, rep


class DLM_OT_migrator_copy_attributes(Operator):
    bl_idname = "dlm.migrator_copy_attributes"
    bl_label = "CopyAttr"
    bl_description = "Copy object and armature attributes from original to replacement character"
    bl_icon = "COPY_ID"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair (set Original/Replacement or enable Automatic).")
            return {"CANCELLED"}
        try:
            from ..ops.migrator import run_copy_attr
            run_copy_attr(orig, rep)
            self.report({"INFO"}, "Copy attributes done.")
            return {"FINISHED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_migrate_nla(Operator):
    bl_idname = "dlm.migrator_migrate_nla"
    bl_label = "MigNLA"
    bl_description = "Migrate NLA tracks and strips from original to replacement character"
    bl_icon = "NLA"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.migrator import run_mig_nla
            run_mig_nla(orig, rep, report=self.report)
            return {"FINISHED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_custom_properties(Operator):
    bl_idname = "dlm.migrator_custom_properties"
    bl_label = "MigCustProps"
    bl_description = "Copy custom properties from original to replacement character"
    bl_icon = "PROPERTIES"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.migrator import run_mig_cust_props
            run_mig_cust_props(orig, rep)
            self.report({"INFO"}, "Custom properties done.")
            return {"FINISHED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_bone_constraints(Operator):
    bl_idname = "dlm.migrator_bone_constraints"
    bl_label = "MigBoneConst"
    bl_description = "Migrate bone constraints from original to replacement armature"
    bl_icon = "CONSTRAINT_BONE"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.migrator import run_mig_bone_const
            orig_to_rep = {orig: rep}
            run_mig_bone_const(orig, rep, orig_to_rep)
            self.report({"INFO"}, "Bone constraints done.")
            return {"FINISHED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_retarget_relations(Operator):
    bl_idname = "dlm.migrator_retarget_relations"
    bl_label = "RetargRelatives"
    bl_description = "Retarget parent/child and other relations to the replacement character"
    bl_icon = "ORIENTATION_PARENT"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.migrator import run_retarg_relatives
            from ..utils import descendants
            rep_descendants = descendants(rep)
            orig_to_rep = {orig: rep}
            run_retarg_relatives(orig, rep, rep_descendants, orig_to_rep)
            self.report({"INFO"}, "Retarget relations done.")
            return {"FINISHED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_basebody_shapekeys(Operator):
    bl_idname = "dlm.migrator_basebody_shapekeys"
    bl_label = "MigBBodyShapeKeys"
    bl_description = "Migrate base body mesh shape key values from original to replacement"
    bl_icon = "SHAPEKEY_DATA"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.migrator import run_mig_bbody_shapekeys
            from ..utils import descendants
            rep_descendants = descendants(rep)
            run_mig_bbody_shapekeys(orig, rep, rep_descendants, context)
            self.report({"INFO"}, "Migrate BaseBody shapekeys done.")
            return {"FINISHED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_fk_rotations(Operator):
    bl_idname = "dlm.migrator_fk_rotations"
    bl_label = "MigFKRot"
    bl_description = "Copy FK arm and finger rotations from original to replacement (uses constraints)"
    bl_icon = "BONE_DATA"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.fk_rotations import copy_fk_rotations
            ok, msg = copy_fk_rotations(context, orig, rep)
            if ok:
                self.report({"INFO"}, msg)
                return {"FINISHED"}
            else:
                self.report({"ERROR"}, msg)
                return {"CANCELLED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_fk_rotations_bake(Operator):
    bl_idname = "dlm.migrator_fk_rotations_bake"
    bl_label = "Bake MigFKRot"
    bl_description = "Bake FK rotations to keyframes using nla.bake (similar to tweak tools)"
    bl_icon = "KEYFRAME"
    bl_options = {"REGISTER", "UNDO"}

    track_name: StringProperty(name="NLA Track", description="Optional NLA track name for frame range", default="")
    post_clean: BoolProperty(name="Post-clean", description="Clean curves after bake", default=False)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.fk_rotations import bake_fk_rotations
            ok, msg = bake_fk_rotations(context, orig, rep, track_name=self.track_name or None, post_clean=self.post_clean)
            if ok:
                self.report({"INFO"}, msg)
                return {"FINISHED"}
            else:
                self.report({"ERROR"}, msg)
                return {"CANCELLED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}


class DLM_OT_migrator_fk_rotations_remove(Operator):
    bl_idname = "dlm.migrator_fk_rotations_remove"
    bl_label = "Remove MigFKRot"
    bl_description = "Remove FK rotation COPY_TRANSFORMS constraints (similar to tweak_remove_arm)"
    bl_icon = "X"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig or not rep or orig == rep:
            self.report({"ERROR"}, "No valid character pair.")
            return {"CANCELLED"}
        try:
            from ..ops.fk_rotations import remove_fk_rotations
            ok, msg = remove_fk_rotations(context, rep)
            if ok:
                self.report({"INFO"}, msg)
                return {"FINISHED"}
            else:
                self.report({"ERROR"}, msg)
                return {"CANCELLED"}
        except Exception as e:
            self.report({"ERROR"}, str(e))
            return {"CANCELLED"}




class DLM_OT_migrator_remove_original(Operator):
    bl_idname = "dlm.migrator_remove_original"
    bl_label = "Remove Original"
    bl_description = "Delete the original character armature and its data from the scene"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}



class DLM_OT_picker_original_character(Operator):
    bl_idname = "dlm.picker_original_character"
    bl_label = "Pick Original"
    bl_description = "Set the original character armature from the active object"
    bl_options = {"REGISTER"}

    def execute(self, context):
        obj = context.active_object
        if not obj or obj.type != "ARMATURE":
            self.report({"WARNING"}, "Select an armature")
            return {"CANCELLED"}
        context.scene.dynamic_link_manager.original_character = obj
        self.report({"INFO"}, f"Original: {obj.name}")
        return {"FINISHED"}


class DLM_OT_picker_replacement_character(Operator):
    bl_idname = "dlm.picker_replacement_character"
    bl_label = "Pick Replacement"
    bl_description = "Set the replacement character armature from the active object"
    bl_options = {"REGISTER"}

    def execute(self, context):
        obj = context.active_object
        if not obj or obj.type != "ARMATURE":
            self.report({"WARNING"}, "Select an armature")
            return {"CANCELLED"}
        context.scene.dynamic_link_manager.replacement_character = obj
        self.report({"INFO"}, f"Replacement: {obj.name}")
        return {"FINISHED"}


def _tweak_poll(context):
    orig, rep = _get_migrator_pair(context)
    return orig is not None and rep is not None


class DLM_OT_tweak_add_arm(Operator):
    bl_idname = "dlm.tweak_add_arm"
    bl_label = "Add Arm Tweaks"
    bl_description = "Add tweak bone constraints to arm bones on the replacement character"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        from ..ops import tweak_tools
        tweak_tools.add_tweak_constraints(orig, rep, "arm")
        self.report({"INFO"}, "Arm tweak constraints added.")
        return {"FINISHED"}


class DLM_OT_tweak_remove_arm(Operator):
    bl_idname = "dlm.tweak_remove_arm"
    bl_label = "Remove Arm Tweaks"
    bl_description = "Remove arm tweak constraints from the replacement character"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        from ..ops import tweak_tools
        n = tweak_tools.remove_tweak_constraints(orig, rep, "arm")
        self.report({"INFO"}, f"Removed {n} arm tweak constraints.")
        return {"FINISHED"}


class DLM_OT_tweak_bake_arm(Operator):
    bl_idname = "dlm.tweak_bake_arm"
    bl_label = "Bake Arm Tweaks"
    bl_description = "Bake arm tweak constraints to keyframes and optionally remove constraints"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        props = context.scene.dynamic_link_manager
        from ..ops import tweak_tools
        ok, msg = tweak_tools.bake_tweak_constraints(
            context, orig, rep, "arm",
            getattr(props, "tweak_nla_track_name", "") or "",
            getattr(props, "tweak_bake_post_clean", False),
        )
        if ok:
            self.report({"INFO"}, msg)
            return {"FINISHED"}
        self.report({"ERROR"}, msg)
        return {"CANCELLED"}


class DLM_OT_tweak_add_leg(Operator):
    bl_idname = "dlm.tweak_add_leg"
    bl_label = "Add Leg Tweaks"
    bl_description = "Add tweak bone constraints to leg bones on the replacement character"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        from ..ops import tweak_tools
        tweak_tools.add_tweak_constraints(orig, rep, "leg")
        self.report({"INFO"}, "Leg tweak constraints added.")
        return {"FINISHED"}


class DLM_OT_tweak_remove_leg(Operator):
    bl_idname = "dlm.tweak_remove_leg"
    bl_label = "Remove Leg Tweaks"
    bl_description = "Remove leg tweak constraints from the replacement character"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        from ..ops import tweak_tools
        n = tweak_tools.remove_tweak_constraints(orig, rep, "leg")
        self.report({"INFO"}, f"Removed {n} leg tweak constraints.")
        return {"FINISHED"}


class DLM_OT_tweak_bake_leg(Operator):
    bl_idname = "dlm.tweak_bake_leg"
    bl_label = "Bake Leg Tweaks"
    bl_description = "Bake leg tweak constraints to keyframes and optionally remove constraints"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        props = context.scene.dynamic_link_manager
        from ..ops import tweak_tools
        ok, msg = tweak_tools.bake_tweak_constraints(
            context, orig, rep, "leg",
            getattr(props, "tweak_nla_track_name", "") or "",
            getattr(props, "tweak_bake_post_clean", False),
        )
        if ok:
            self.report({"INFO"}, msg)
            return {"FINISHED"}
        self.report({"ERROR"}, msg)
        return {"CANCELLED"}


class DLM_OT_tweak_add_both(Operator):
    bl_idname = "dlm.tweak_add_both"
    bl_label = "Add Arm &amp; Leg Tweaks"
    bl_description = "Add tweak bone constraints to both arm and leg bones"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        from ..ops import tweak_tools
        tweak_tools.add_tweak_constraints(orig, rep, "both")
        self.report({"INFO"}, "Arm &amp; leg tweak constraints added.")
        return {"FINISHED"}


class DLM_OT_tweak_remove_both(Operator):
    bl_idname = "dlm.tweak_remove_both"
    bl_label = "Remove Arm &amp; Leg Tweaks"
    bl_description = "Remove all arm and leg tweak constraints from the replacement character"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        from ..ops import tweak_tools
        n = tweak_tools.remove_tweak_constraints(orig, rep, "both")
        self.report({"INFO"}, f"Removed {n} tweak constraints.")
        return {"FINISHED"}


class DLM_OT_tweak_bake_both(Operator):
    bl_idname = "dlm.tweak_bake_both"
    bl_label = "Bake Arm &amp; Leg Tweaks"
    bl_description = "Bake all arm and leg tweak constraints to keyframes and optionally remove constraints"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return _tweak_poll(context)

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        props = context.scene.dynamic_link_manager
        from ..ops import tweak_tools
        ok, msg = tweak_tools.bake_tweak_constraints(
            context, orig, rep, "both",
            getattr(props, "tweak_nla_track_name", "") or "",
            getattr(props, "tweak_bake_post_clean", False),
        )
        if ok:
            self.report({"INFO"}, msg)
            return {"FINISHED"}
        self.report({"ERROR"}, msg)
        return {"CANCELLED"}


OPERATOR_CLASSES = [
    DLM_OT_replace_linked_asset,
    DLM_OT_scan_linked_assets,
    DLM_OT_find_libraries_in_folders,
    DLM_OT_open_linked_file,
    DLM_OT_add_search_path,
    DLM_OT_remove_search_path,
    DLM_OT_browse_search_path,
    DLM_OT_attempt_relink,
    DLM_OT_reload_libraries,
    DLM_OT_make_paths_relative,
    DLM_OT_make_paths_absolute,
    DLM_OT_relocate_single_library,
    DLM_OT_migrator_remove_original,
    DLM_OT_picker_original_character,
    DLM_OT_picker_replacement_character,
    DLM_OT_migrator_copy_attributes,
    DLM_OT_migrator_migrate_nla,
    DLM_OT_migrator_custom_properties,
    DLM_OT_migrator_bone_constraints,
    DLM_OT_migrator_retarget_relations,
    DLM_OT_migrator_basebody_shapekeys,
    DLM_OT_tweak_add_arm,
    DLM_OT_tweak_remove_arm,
    DLM_OT_tweak_bake_arm,
    DLM_OT_tweak_add_leg,
    DLM_OT_tweak_remove_leg,
    DLM_OT_tweak_bake_leg,
    DLM_OT_tweak_add_both,
    DLM_OT_tweak_remove_both,
    DLM_OT_tweak_bake_both,
    DLM_OT_migrator_fk_rotations,
    DLM_OT_migrator_fk_rotations_bake,
    DLM_OT_migrator_fk_rotations_remove,
]

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: cat "T:\Dynamic-Link-Manager\utils\__init__.py"</summary>

```bash
cat "T:\Dynamic-Link-Manager\utils\__init__.py"
```

```
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

"""Shared helpers for Dynamic Link Manager."""

import bpy


def descendants(armature):
    """Return a set of objects whose parent chain leads to the given armature."""
    out = set()
    for ob in bpy.data.objects:
        p = ob.parent
        while p:
            if p == armature:
                out.add(ob)
                break
            p = p.parent
    return out


def collection_containing_armature(armature):
    """
    Return a collection that contains the armature (for linked character context).
    Prefers a collection whose name matches the character base (e.g. "Steve" for Steve_Rigify).
    """
    if not armature or armature.name not in bpy.data.objects:
        return None
    colls = getattr(armature, "users_collection", []) or []
    if not colls:
        return None
    name = armature.name
    base = name.replace("_Rigify", "").replace(".001", "").rstrip("0123456789.")
    for c in colls:
        if c.name == base or base in c.name or c.name in name:
            return c
    return colls[0]

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
I found the `collection_containing_armature` function in the utils module. Now I need to find the exact line numbers for the `DLM_OT_migrator_remove_original` class so I can update it properly.

Looking at the file output, I can see the class is around line 340-360 or so. Let me get more precise line numbers by looking at the relevant section more carefully.

From the output, I can see the class starts with:
```python
class DLM_OT_migrator_remove_original(Operator):
    bl_idname = "dlm.migrator_remove_original"
    bl_label = "Remove Original"
    bl_description = "Delete the original character armature and its data from the scene"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}
```

I need to:
1. Import `collection_containing_armature` from `..utils`
2. Find the collection containing the original armature
3. Delete the collection (which removes all objects in it)
4. Clear the original_character property
5. Report which collection was deleted
6. Fall back to just deleting the armature if no collection found
 
I'll use grep to precisely locate the exact line numbers for the class definition. This will help me make precise edits to the code with minimal risk of breaking the existing structure.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

Let me find the exact line numbers for the class.

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: rg -n "class DLM_OT_migrator_remove_original" "T:\Dynamic-Link-Manager\ui\operators.py"</summary>

```bash
rg -n "class DLM_OT_migrator_remove_original" "T:\Dynamic-Link-Manager\ui\operators.py"
```

```
rg: C:\Users\Nathan\AppData\Local\Temp\ps-script-abaef4c0-ea67-44c8-9ae3-693d849bd9a8.ps1:113
Line |
 113 |  rg -n "class DLM_OT_migrator_remove_original" "T:\Dynamic-Link-Manage .
     |  ~~
     | The term 'rg' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the
     | spelling of the name, or if a path was included, verify that the path is correct and try again.

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
Let me try with Select-String instead.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: Select-String -Path "T:\Dynamic-Link-Manager\ui\operators.py" -Pattern "class DLM_OT_migrator_remove_original" | ForEach-Object { $_.LineNumber }</summary>

```bash
Select-String -Path "T:\Dynamic-Link-Manager\ui\operators.py" -Pattern "class DLM_OT_migrator_remove_original" | ForEach-Object { $_.LineNumber }
```

```
490

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
The class starts at line 490. Now let me read around that area to see the full method.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: (Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[488..520] -join "`n"</summary>

```bash
(Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[488..520] -join "`n"
```

```

class DLM_OT_migrator_remove_original(Operator):
    bl_idname = "dlm.migrator_remove_original"
    bl_label = "Remove Original"
    bl_description = "Delete the original character armature and its data from the scene"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}



class DLM_OT_picker_original_character(Operator):
    bl_idname = "dlm.picker_original_character"
    bl_label = "Pick Original"

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
Now I can see the full execute method is from line 497 to line 515. I'll create a Python script to update this file with the new implementation. The new code should:

1. Import `collection_containing_armature` from `..utils`
2. Find the collection containing the original armature
3. Delete the collection (which removes all objects in it)
4. Clear the original_character property
5. Report which collection was deleted
6. Fall back to just deleting the armature if no collection found

Let me also check if there's already an import from `..utils` at the top of the file.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: (Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[0..20] -join "`n"</summary>

```bash
(Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[0..20] -join "`n"
```

```
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

import bpy
import os
from bpy.types import Operator
from bpy.props import StringProperty, BoolProperty
from bpy.props import StringProperty, IntProperty

ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__


def _prefs(context):
    return context.preferences.addons.get(ADDON_NAME)


class DLM_OT_replace_linked_asset(Operator):
    bl_idname = "dlm.replace_linked_asset"
    bl_label = "Replace Linked Asset"

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
I can see there's no import from `..utils` currently. I'll need to add one and then update the `execute` method. Let me create the update script.

The changes needed:
1. Add import for `collection_containing_armature` from `..utils` (probably around line 12)
2. Update the execute method (lines 497-515)

Let me do this using a Python script that modifies the file.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

Now I'll create a script to update the file with the new implementation.

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: python -c "
import re

# Read the file
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f:
    content = f.read()

# Add import for collection_containing_armature
old_import = '''from bpy.props import StringProperty, IntProperty'''
new_import = '''from bpy.props import StringProperty, IntProperty

from ..utils import collection_containing_armature'''
content = content.replace(old_import, new_import)

# Update the execute method
old_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({\"WARNING\"}, \"No original character selected\")
            return {\"CANCELLED\"}
        if orig == rep:
            self.report({\"ERROR\"}, \"Original and replacement cannot be the same object\")
            return {\"CANCELLED\"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({\"INFO\"}, f\"Removed original character: {name}\")
        except Exception as e:
            self.report({\"ERROR\"}, f\"Failed to remove original: {e}\")
            return {\"CANCELLED\"}
        return {\"FINISHED\"}'''

new_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({\"WARNING\"}, \"No original character selected\")
            return {\"CANCELLED\"}
        if orig == rep:
            self.report({\"ERROR\"}, \"Original and replacement cannot be the same object\")
            return {\"CANCELLED\"}

        name = orig.name
        try:
            # Try to find and delete the collection containing the original character
            coll = collection_containing_armature(orig)
            if coll:
                bpy.data.collections.remove(coll)
                context.scene.dynamic_link_manager.original_character = None
                self.report({\"INFO\"}, f\"Removed collection: {coll.name}\")
            else:
                # Fallback: just delete the armature object
                bpy.data.objects.remove(orig, do_unlink=True)
                context.scene.dynamic_link_manager.original_character = None
                self.report({\"INFO\"}, f\"Removed original character: {name}\")
        except Exception as e:
            self.report({\"ERROR\"}, f\"Failed to remove original: {e}\")
            return {\"CANCELLED\"}
        return {\"FINISHED\"}'''

content = content.replace(old_execute, new_execute)

# Write back
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'w') as f:
    f.write(content)

print('File updated successfully')
"</summary>

```bash
python -c "
import re

# Read the file
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f:
    content = f.read()

# Add import for collection_containing_armature
old_import = '''from bpy.props import StringProperty, IntProperty'''
new_import = '''from bpy.props import StringProperty, IntProperty

from ..utils import collection_containing_armature'''
content = content.replace(old_import, new_import)

# Update the execute method
old_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({\"WARNING\"}, \"No original character selected\")
            return {\"CANCELLED\"}
        if orig == rep:
            self.report({\"ERROR\"}, \"Original and replacement cannot be the same object\")
            return {\"CANCELLED\"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({\"INFO\"}, f\"Removed original character: {name}\")
        except Exception as e:
            self.report({\"ERROR\"}, f\"Failed to remove original: {e}\")
            return {\"CANCELLED\"}
        return {\"FINISHED\"}'''

new_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({\"WARNING\"}, \"No original character selected\")
            return {\"CANCELLED\"}
        if orig == rep:
            self.report({\"ERROR\"}, \"Original and replacement cannot be the same object\")
            return {\"CANCELLED\"}

        name = orig.name
        try:
            # Try to find and delete the collection containing the original character
            coll = collection_containing_armature(orig)
            if coll:
                bpy.data.collections.remove(coll)
                context.scene.dynamic_link_manager.original_character = None
                self.report({\"INFO\"}, f\"Removed collection: {coll.name}\")
            else:
                # Fallback: just delete the armature object
                bpy.data.objects.remove(orig, do_unlink=True)
                context.scene.dynamic_link_manager.original_character = None
                self.report({\"INFO\"}, f\"Removed original character: {name}\")
        except Exception as e:
            self.report({\"ERROR\"}, f\"Failed to remove original: {e}\")
            return {\"CANCELLED\"}
        return {\"FINISHED\"}'''

content = content.replace(old_execute, new_execute)

# Write back
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'w') as f:
    f.write(content)

print('File updated successfully')
"
```

```
python.exe: C:\Users\Nathan\AppData\Local\Temp\ps-script-d9765fd0-3e27-48bc-a39a-ee946e3a5470.ps1:113
Line |
 113 |  python -c "
     |  ~~~~~~~~~~~
     | ScriptBlock should only be specified as a value of the Command parameter.

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
The PowerShell syntax is causing issues. Let me write the Python script to a file and then execute it.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: Set-Content -Path "T:\Dynamic-Link-Manager\update_script.py" -Value @'
import re

# Read the file
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f:
    content = f.read()

# Add import for collection_containing_armature
old_import = '''from bpy.props import StringProperty, IntProperty'''
new_import = '''from bpy.props import StringProperty, IntProperty

from ..utils import collection_containing_armature'''
content = content.replace(old_import, new_import)

# Update the execute method
old_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}'''

new_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Try to find and delete the collection containing the original character
            coll = collection_containing_armature(orig)
            if coll:
                bpy.data.collections.remove(coll)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed collection: {coll.name}")
            else:
                # Fallback: just delete the armature object
                bpy.data.objects.remove(orig, do_unlink=True)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}'''

content = content.replace(old_execute, new_execute)

# Write back
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'w') as f:
    f.write(content)

print('File updated successfully')
'@</summary>

```bash
Set-Content -Path "T:\Dynamic-Link-Manager\update_script.py" -Value @'
import re

# Read the file
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'r') as f:
    content = f.read()

# Add import for collection_containing_armature
old_import = '''from bpy.props import StringProperty, IntProperty'''
new_import = '''from bpy.props import StringProperty, IntProperty

from ..utils import collection_containing_armature'''
content = content.replace(old_import, new_import)

# Update the execute method
old_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Remove from scene
            bpy.data.objects.remove(orig, do_unlink=True)
            # Clear the property
            context.scene.dynamic_link_manager.original_character = None
            self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}'''

new_execute = '''    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Try to find and delete the collection containing the original character
            coll = collection_containing_armature(orig)
            if coll:
                bpy.data.collections.remove(coll)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed collection: {coll.name}")
            else:
                # Fallback: just delete the armature object
                bpy.data.objects.remove(orig, do_unlink=True)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}'''

content = content.replace(old_execute, new_execute)

# Write back
with open(r'T:\Dynamic-Link-Manager\ui\operators.py', 'w') as f:
    f.write(content)

print('File updated successfully')
'@
```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
Good, now let me run the script.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: python "T:\Dynamic-Link-Manager\update_script.py"</summary>

```bash
python "T:\Dynamic-Link-Manager\update_script.py"
```

```
File updated successfully

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
The file was updated. Let me verify the changes by reading the relevant parts of the file.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

Let me verify the changes.

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: (Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[9..15] -join "`n"</summary>

```bash
(Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[9..15] -join "`n"
```

```
from bpy.props import StringProperty, IntProperty

from ..utils import collection_containing_armature

ADDON_NAME = __package__.rsplit(".", 1)[0] if "." in __package__ else __package__



```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: (Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[490..530] -join "`n"</summary>

```bash
(Get-Content "T:\Dynamic-Link-Manager\ui\operators.py")[490..530] -join "`n"
```

```

class DLM_OT_migrator_remove_original(Operator):
    bl_idname = "dlm.migrator_remove_original"
    bl_label = "Remove Original"
    bl_description = "Delete the original character armature and its data from the scene"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Try to find and delete the collection containing the original character
            coll = collection_containing_armature(orig)
            if coll:
                bpy.data.collections.remove(coll)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed collection: {coll.name}")
            else:
                # Fallback: just delete the armature object
                bpy.data.objects.remove(orig, do_unlink=True)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}



class DLM_OT_picker_original_character(Operator):
    bl_idname = "dlm.picker_original_character"
    bl_label = "Pick Original"
    bl_description = "Set the original character armature from the active object"
    bl_options = {"REGISTER"}

```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
The changes were applied correctly. Let me clean up the update script file and verify the final result.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2">
<details><summary>Tool use: **run_terminal_command_v2** • Run command: Remove-Item "T:\Dynamic-Link-Manager\update_script.py"</summary>

```bash
Remove-Item "T:\Dynamic-Link-Manager\update_script.py"
```
</details>
</tool-use>

<tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"><details>
<summary>Tool use: **run_terminal_command_v2**</summary>

</details></tool-use>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

<think><details><summary>Thought Process</summary>
The file has been successfully updated. Let me summarize what was done.</details></think>

_**Agent (accounts/fireworks/models/kimi-k2p5)**_

The `DLM_OT_migrator_remove_original` class has been updated successfully. Here's a summary of the changes:

**1. Added import** (line 12):
```python
from ..utils import collection_containing_armature
```

**2. Updated `execute` method** to:
- Use `collection_containing_armature(orig)` to find the collection containing the original character
- If a collection is found, delete it with `bpy.data.collections.remove(coll)` (which removes all objects in the collection)
- Clear the `original_character` property
- Report which collection was deleted
- Fall back to just deleting the armature object if no collection is found

The updated implementation at `T:\Dynamic-Link-Manager\ui\operators.py`:

```497:525:T:\Dynamic-Link-Manager\ui\operators.py
    def execute(self, context):
        orig, rep = _get_migrator_pair(context)
        if not orig:
            self.report({"WARNING"}, "No original character selected")
            return {"CANCELLED"}
        if orig == rep:
            self.report({"ERROR"}, "Original and replacement cannot be the same object")
            return {"CANCELLED"}

        name = orig.name
        try:
            # Try to find and delete the collection containing the original character
            coll = collection_containing_armature(orig)
            if coll:
                bpy.data.collections.remove(coll)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed collection: {coll.name}")
            else:
                # Fallback: just delete the armature object
                bpy.data.objects.remove(orig, do_unlink=True)
                context.scene.dynamic_link_manager.original_character = None
                self.report({"INFO"}, f"Removed original character: {name}")
        except Exception as e:
            self.report({"ERROR"}, f"Failed to remove original: {e}")
            return {"CANCELLED"}
        return {"FINISHED"}
```
