ase-code-lint

SkillDev tools

Lint source code for potential code quality problems. Use when the user wants to "lint" or "check" source code.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the ase-code-lint skill

What this skill tells your AI

The instructions your AI receives, as published by rse/ase in plugin/skills/ase-code-lint/SKILL.md and read by ahel’s review.

@${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

$ARGUMENTS

  1. The project source artifacts are classified as a black box, so the user does not want them inspected or their problems surfaced. Skip the entire investigation and reporting: do not invoke any Glob or Agent tool and do not read any source, only output the following and then SKIP the remaining steps STEP 2 and STEP 3:

    First, determine the effective aspect set , i.e., the code quality aspects which are checked at all. For this, parse and as comma-separated token lists, silently dropping the none sentinel and any empty token. If a token is not one of the aspect ids A01...A21, only output the following and then STOP the entire flow (do not perform any further steps):

    Otherwise set to all twenty-one aspect ids A01...A21 if both lists are empty, to the include list if only it is non-empty, to all twenty-one minus the exclude list if only it is non-empty, and to the include list minus the exclude list if both are non-empty. If the resulting is empty, only output the following and then STOP the entire flow (do not perform any further steps):

    Then, use the following to give a hint on this step:

    Dispatch the investigation to sub-agents via the Agent tool so that no investigation details leak into the user-visible transcript. The sub-agents perform the silent reading and checking; only their final structured return values are consumed here.

    For this, first silently resolve <getopt-arguments/> to the list of individual source code files, expanding any directory or wildcard references with the Glob tool. Then partition , preserving order, into at most eight batches of roughly equal size (a single file yields a single batch), and invoke the following tool once per batch, emitting all invocations in one single message so they run in parallel:

        Agent(
            description:       "Lint Investigation (<batch-index/>/<batch-count/>)",
            subagent_type:     "ase:ase-code-lint",
            prompt:            "<aspects/> <batch/>",
            run_in_background: false
        )
    

    Here is the comma-separated list of the effective aspect ids (without any spaces), is the space-separated list of the source code file paths of the corresponding batch, is the 1-based index of that batch, and is the total number of batches, so that each parallel invocation is distinguishable in the progress display.

    Parse the result message of each Agent tool invocation as a JSON array and concatenate all those arrays. Then deduplicate the combined list: when two problems share the same file, line, and aspect, silently drop all but the first one (sub-agents may have read overlapping related files for comprehension). Finally sort the list by file and then numerically by line, and set to that list.

    Then determine the effective severity floor : define the ordinal rank LOW=1, MEDIUM=2, HIGH=3, start from (default LOW), and - if is equal grey - raise to MEDIUM whenever its current rank is below rank(MEDIUM) (grey boxing surfaces only material findings of severity MEDIUM and above).

    Then apply the effective severity floor : Keep a problem in if and only if its severity field is ACCEPTED or rank(severity) is greater than or equal to rank(<floor/>); silently drop all other problems. With the default floor LOW, all problems are kept. ACCEPTED problems are never dropped.

    Finally, sort the surviving problems in by their severity field from highest to lowest in the fixed order HIGH, MEDIUM, LOW, ACCEPTED, so the subsequent reporting starts with the most severe problem. Within the same severity, keep the file/line order established above.

    You MUST NOT output anything else in this STEP 1.

  2. Use the following to output a summary of the detected problems in (if any were found), in the original aspect ordering A01 - XXX...A21 - XXX.

    AX - XXX: N issues AX - XXX: N issues [...]

    Else, if no problems were found, use the following to output the summary instead:

    (no problems detected)

    You MUST NOT output anything else in this STEP 2.

    1. Mark this skill as the active edit-capable skill so that the ASE pre-tool-use hook auto-approves the subsequent Edit invocations on any invocation path (slash command or Skill tool). Call the ase_config_set(key: "agent.skill", val: "ase-code-lint", scope: "session:<ase-session-id/>") tool from the ase MCP server. Do not output anything in this substep.

      Critical safety invariant: the marker set here grants Edit auto-approval and MUST be cleared again (substep 3 below) before this skill yields control, regardless of how the iteration in substep 2 ends - whether it completes normally, is aborted early (e.g. an Edit failure, an unparseable value, or any other unexpected condition), or is otherwise interrupted. If you ever stop or bail out of substep 2 early, you MUST still perform substep 3 first. Never leave this marker active for a later, unrelated Edit.

    2. Set to the number of problems in and to 0. Then iterate over all problems:

      1. Increment by one (the 1-based position of the current within ). Set to the aspect field of . Set to the severity field of . Set to the description field of . Set to the change-set field of .

      2. Set (set to empty). Set (set to empty). Set (set to empty).

      3. Iterate over the change set:

        1. Set to the file field of . Set to the change-hunks field of .

          Unless is equal grey (where the full unified diff is suppressed and no context lines are rendered at all), silently read the current content of with the Read tool - reusing the content read for the same earlier in this iteration, unless an Edit was applied to it in between - and set to its lines, stripped of the line-number prefixes the tool adds. Set to empty if the file cannot be read.

          This content is the authoritative source of the context lines of substep 2 below, so the rendered diff shows real context even when a sub-agent supplied none.

          Unless is equal grey (where the full unified diff is suppressed and this per-file header is unused), set to the following :

        2. Iterate over the change hunks.

          1. Set to the line field of . Set to the context_before field of . Set to the old_text field of . Set to the new_text field of . Set to the context_after field of .

            Then normalize the hunk to its minimal form, so that the proposed diff shows exactly the lines the later Edit will actually change: while the first line of is identical to the first line of , move that line from both to the end of and increment by one; likewise, while the last line of is identical to the last line of , move that line from both to the front of . Finally, trim to its last two lines and to its first two lines.

            Then, whenever is non-empty, re-derive both context parts from it, overriding the sub-agent supplied values: set to the up to two lines of directly before line (empty if is 1) and to the up to two lines of starting at line ( + ), where is the number of lines in (empty if that line is beyond the end of the file). Keep the sub-agent supplied values only when is empty.

          2. Skip this substep entirely when is equal grey - the full unified diff is suppressed there, so none of the , , , , or values below are consumed (substep 4 builds only the condensed one-liner instead).

            Otherwise, determine the hunk body as an ordered list of lines, each carrying a one-character prefix ( for context, - for old-side, + for new-side). Build it by concatenating, in order and skipping any part that is empty:

            • one -prefixed line for each line of (if non-empty),
            • one --prefixed line for each line of (if non-empty; split on newlines),
            • one +-prefixed line for each line of (if non-empty; split on newlines),
            • one -prefixed line for each line of (if non-empty).

            Set to those prefixed lines joined by newlines.

            Set to the number of old-side hunk lines, i.e., the combined line count of , , and (each empty part counts as 0). Set to the number of new-side hunk lines, i.e., the combined line count of , , and (each empty part counts as 0).

            Set to the 1-based line number of the first old-side hunk line: if is non-empty, that is the line of its first context line, i.e. minus the number of lines in ; otherwise it is itself (the first line of ). For a hunk that only inserts new lines (empty and empty context), set it to the line before which the insertion happens, clamped to a minimum of 0, so a top-of-file insertion yields @@ -0,0 ... @@. Set to the same value as , but clamped to a minimum of 1 whenever is greater than 0 (the corrected side then has a real first line).

          3. If is not empty, set , (append a comma). Then append the following to :

            <file/>:

          4. The full unified diff is suppressed under grey boxing (see substep 5 below), so skip the full-diff append and instead build only a condensed one-line representation of this hunk: determine as the single-line collapse of (join its lines with , or when is empty for a pure insertion) and as the same collapse of (or when empty for a pure deletion). Then append the following to as a new line:

            Append the following to , emitting verbatim (one already-prefixed line per line, with no extra blank or space-only lines):

        3. Unless is equal grey (where is unused), append to .

      4. Report the problem with the following :

      5. The project source artifacts are classified as a grey box, so the user does not want the full artifact internals surfaced: suppress the full unified diff and instead show only the condensed one-line-per-hunk representation. Report the solution with the following :

        Report the solution with the following :

        <diff/>
        

        Report the solution with the following :

        (corresponding change automatically applied)

      6. In the following, you MUST NOT use your built-in tool! Instead, you MUST just show a custom dialog according to the expanded custom-dialog definition. You MUST closely follow this definition:

        Set ACCEPT. You MUST NOT output anything else in this sub-step 6.

      7. Check and dispatch accordingly:

        • Skip this without any Edit call and continue with the next .

    3. Clear the active edit-capable skill marker now that all Edit invocations are done, so a later unrelated Edit is not auto-approved. Call the ase_config_delete(key: "agent.skill", scope: "session:<ase-session-id/>") tool from the ase MCP server. Do not output anything in this substep.

    4. You MUST NOT output any further additional explanations or summaries at the end of this skill processing, except for the following final :

    5. Finally, give the closing hints by expanding the following (which, depending on the configured , may each expand into nothing and hence emit no output at all):

Signals

GitHub stars
52
Forks
5
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
ase-code-lint
Source
github.com/rse/ase