---
name: ase-code-refactor
argument-hint: "[--help|-h] [--auto|-a] [--dry|-d] [--quick|-Q] [--next|-n <option>[,...]] [<task-id>:] <request>"
description: >
    Refactor Code:
    Use when user wants to "refactor", or "change" the code base.
user-invocable: true
disable-model-invocation: false
effort: xhigh
allowed-tools:
    - "Skill"
    - "Agent"
---

@${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md

<skill name="ase-code-refactor">
Refactor Artifacts
</skill>

<expand name="getopt"
    arg1="ase-code-refactor"
    arg2="--auto|-a --dry|-d --quick|-Q --next|-n=(none|DONE|EDIT|PREFLIGHT|IMPLEMENT)...">
    $ARGUMENTS
</expand>

<if condition="<getopt-option-quick/> is equal `true`">
The `--quick`/`-Q` flag is a *shorthand alias*: set <getopt-option-auto/>
to `true`, <getopt-option-dry/> to `true`, and <getopt-option-next/> to
`IMPLEMENT,DELETE`. Do not output anything.
</if>

<objective>
*Refactor* existing artifacts the following way:
<request><getopt-arguments/></request>
</objective>

@${CLAUDE_SKILL_DIR}/../../meta/ase-format-task.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-tenets.md

Procedure
---------

You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
filesystem-modifying tool during this entire skill. The *only*
permitted way to persist artifacts is via `ase_task_save(...)`.

<flow>

1.  <step id="STEP 1: Reason About Refactoring">

    1.  <if condition="
            <request/> matches the regexp `^[a-zA-Z][a-zA-Z0-9_-]*$`
        ">
        Set <ase-task-id><request/></ase-task-id> (set task id to request)
        and <request></request> (set request empty), call the
        `ase_task_id(id: "<ase-task-id/>", session: "<ase-session-id/>")` tool
        from the `ase` MCP server to switch the task, and then only
        output the following <template/>:

        <template>
        ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **task given**
        </template>
        </if>

    2.  <if condition="
            <request/> has the format `<id/>: <text/>` AND
            <id/> matches the regexp `^[a-zA-Z][a-zA-Z0-9_-]*$`
        ">
        Set <request><text/></request> and
        <ase-task-id><id/></ase-task-id> and call the `ase_task_id(id:
        "<ase-task-id/>", session: "<ase-session-id/>")` tool from the
        `ase` MCP server to implicitly switch the task. Do not output
        anything.
        </if>

    3.  <if condition="<request/> is empty">
        Ask the user interactively, without a special tool, for the
        initial request with a single question:

        `**No refactoring details known yet. What is the refactoring you want to request?**`

        Then set <request/> to the response of the user.
        </if>

    4.  <if condition="
            <ase-task-id/> is equal `default` and
            <request/> is not empty
        ">
        Set <ase-task-id/> to a unique task id, derived from <request/>,
        which consists of two lower-case words concatenated with a
        `-` character. Then call the `ase_task_id(id: "<ase-task-id/>",
        session: "<ase-session-id/>")` tool from the `ase` MCP server to
        implicitly switch the task. Do not output anything.
        </if>

    5.  Report the task and request with the following <template/>:

        <template>
        ⧉ **ASE**: ◉ task: **<ase-task-id/>**
        ⧉ **ASE**: ⇌ request: **<request/>**
        </template>

    6.  Figure out what the artifact refactoring <request/> is about.

    7.  Ask the user for clarification if the goal of this refactoring is
        too unclear.

    8.  Do not output anything in this step, unless you asked the user.

    </step>

2.  <step id="STEP 2: Investigate Code Base">

    1.  Check the existing source files for all code which is related to the
        refactoring <request/>.

    2.  Check the architecture of the existing code base to understand the
        overall structures and dynamics.

    3.  Do not output anything in this STEP 2.

    </step>

3.  <step id="STEP 3: Internalize Refactoring Tenets">

    1.  You *MUST* internalize and strictly honor the **GENERIC TENETS**,
        and the **REFACTORING TENETS** of the **ASE Tenets** when updating
        in the following. Do not output anything.

    2.  Do not output anything in this STEP 3.

    </step>

4.  <step id="STEP 4: Choose Refactoring Approaches">

    You *MUST* perform the following sub-steps *internally* and *without
    any output* until and including the recommendation decision. Only
    sub-steps 4-6 below are allowed to produce output, and only if
    <getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
    is *not* equal `black`.

    If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
    equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
    no output at all) to speed up processing.

    1.  *Propose* corresponding *refactoring approach*, including
        optionally, some *alternative* refactoring approaches. Do *not*
        output anything in this sub-step.

    2.  *Reflect* on and *critique* the proposed approaches by deriving,
        per approach, a small set of concrete *pros* and *cons*. Do
        *not* output anything in this sub-step.

    3.  Based on the reflection, *decide* which approach to recommend
        and annotate it with an <annotation/> of
        ` ⚝ **RECOMMENDATION** ⚝`. All other approaches receive an
        empty <annotation/>. Do *not* output anything in this sub-step.

    4.  Indicate start of reporting by showing the following <template/>:

        <template>
        <ase-tpl-head title="APPROACHES"/>
        </template>

    5.  Now report each approach with the following <template/>,
        inlining its pros/cons derived in sub-step 2, and do not output
        anything else in this step:

        <template>
        ●   **APPROACH A<n/>**<annotation/>: **<summary/>**
        ○   [...]
        ⊕   *PRO*: [...]
        ⊖   *CON*: [...]
        </template>

        Hints:

        -   Give a short one-sentence <summary/> of the refactoring
            approach plus *precise* and *ultra brief and concise*
            refactoring information. Try to keep the number of bullet
            points (`○ [...]`) in the range of 1-4.

    6.  Indicate end of reporting by showing the following <template/>:

        <template>
        <ase-tpl-foot title="APPROACHES"/>
        </template>

    7.  <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">

        In the following, you *MUST* *NOT* use your built-in
        <user-dialog-tool/> tool! Instead, you *MUST* just show a
        custom dialog according to the expanded `custom-dialog`
        definition. You *MUST* closely follow this definition.

        Let the user choose the preferred approach A<n/> by raising
        a question with the following custom dialog, where per
        approach A<n/>, you determine an ultra brief summary
        <short-summary/> and then use the answer option `A<n/>:
        ⚝ **RECOMMENDATION** ⚝ - <short-summary/>` for your
        recommended approach plus zero or more answer options `A<n/>:
        <short-summary/>` for all other approaches:

        <expand name="custom-dialog" arg1="--no-other">
            Select Approach: Select your preferred refactoring approach to follow?
            A<n/>: <short-summary/>
            [...]
        </expand>

        </if>
        <else>

        Set <n/> to the number of the refactoring approach A<n/> you recommend.
        Output a hint with the following <template/>:

        <template>
        ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **auto-chosen approach A<n/>**
        </template>

        </else>

    </step>

5.  <step id="STEP 5: Compose Refactoring Plan">

    1.  *Compose a refactoring plan* for the chosen refactoring A<n/> by
        closely aligning to the existing architecture and the existing
        code base. Use the <format/> defined for a task plan and inject
        the information from refactoring A<n/> and all derived realization
        decisions into it. Store the resulting task plan in <content/>.

        If a `CHANGELOG.md` file exists in the project (or in any
        affected sub-package), the plan *MUST* include, as part of its
        `## ※ CHANGES` section, an explicit bullet point describing
        the addition of a corresponding new entry to that `CHANGELOG.md`
        file, aligned with its existing style and conventions.

        <if condition="<getopt-option-dry/> is equal `true`">
        You *MUST* completely omit the `##  VERIFICATION` section
        (including its heading and all of its bullet points) from
        <content/>.
        </if>

        You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
        filesystem-modifying tool during this step.

    2.  Call the `ase_timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
        `ase` MCP server and use the `text` field of its response for
        <timestamp-created/> and <timestamp-modified/> information. Then
        insert the current <ase-task-id/>, <timestamp-created/>, and
        <timestamp-modified/> information and calculate the number of
        words <words/> of <content/>.

    3.  You then *MUST* *save* the resulting plan content with the
        `ase_task_save(id: "<ase-task-id/>", text: "<content/>")`.

    4.  Output a hint with the following <template/>:

        <template>
        ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan created**
        </template>

    5.  Directly pass-through control to the next skill:

        Treat <getopt-option-next/> as a comma-separated chronological
        list of pre-selected next-step tokens. *Peek* the *first* token
        as <head/> (or `none` if the list is `none`/empty).
        Set <args>--int-reuse-task</args>.

        1.  <if condition="<head/> is equal `DONE`">
            Consume the head: set <getopt-option-next/> to the remaining
            tokens (joined back with `,`, or `none` if empty). `DONE`
            means the freshly composed plan is finalized as-is, so do
            *not* hand off to `ase-task-edit`. Only output the following
            <template/> and then *STOP*. Do *not* implement the plan.

            <template>
            ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan finalized -- done**
            </template>
            </if>

        2.  <elseif condition="<head/> is equal `IMPLEMENT`">
            Consume the head: set <getopt-option-next/> to the remaining
            tokens (joined back with `,`, or `none` if empty).
            <if condition="<getopt-option-next/> is not equal `none`">
                Set <args><args/> --next <getopt-option-next/></args>
            </if>
            Call the tool `Skill(skill: "ase:ase-task-implement", args: "<args/>")`
            to *implement* the freshly composed plan, bypassing `ase-task-edit`.
            </elseif>

        3.  <elseif condition="<head/> is equal `PREFLIGHT`">
            Consume the head: set <getopt-option-next/> to the remaining
            tokens (joined back with `,`, or `none` if empty).
            <if condition="<getopt-option-next/> is not equal `none`">
                Set <args><args/> --next <getopt-option-next/></args>
            </if>
            Call the tool `Skill(skill: "ase:ase-task-preflight", args: "<args/>")`
            to *preflight* the freshly composed plan, bypassing `ase-task-edit`.
            </elseif>

        4.  <else>
            Hand off to `ase-task-edit`.
            <if condition="<head/> is equal `EDIT`">
                Consume the head: set <getopt-option-next/> to the remaining
                tokens (joined back with `,`, or `none` if empty). `EDIT`
                is this skill's own dispatch token, *not* part of
                `ase-task-edit`'s `--next` vocabulary, so it must be
                stripped here rather than forwarded.
            </if>
            All remaining tokens are `ase-task-edit`'s own vocabulary
            and are forwarded verbatim, so `ase-task-edit` consumes its
            own head itself.
            <if condition="<getopt-option-next/> is not equal `none`">
                Set <args><args/> --next <getopt-option-next/></args>
            </if>
            Then call the tool `Skill(skill: "ase:ase-task-edit", args: "<args/>")`.
            </else>

    </step>

</flow>

