Ase code lint
Lint source code for potential code quality problems. Use when the user wants to "lint" or "check" source code.From its SKILL.md
npx -y skills add rse/ase --skill ase-code-lintAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
20.2 KB, ~4.9k tokens by cl100k_base, as published. Nobody here has run it
@${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
<purpose name="ase-code-lint"> Lint Source Code </purpose><expand name="getopt" arg1="ase-code-lint" arg2="--auto|-a --severity|-S=(LOW|MEDIUM|HIGH) --include|-i=(none|A01|A02|A03|A04|A05|A06|A07|A08|A09|A10|A11|A12|A13|A14|A15|A16|A17|A18|A19|A20)... --exclude|-e=(none|A01|A02|A03|A04|A05|A06|A07|A08|A09|A10|A11|A12|A13|A14|A15|A16|A17|A18|A19|A20)..."> $ARGUMENTS </expand>
<objective> *Analyze* the code of `<getopt-arguments/>` for *potential problems* related to a set of code quality aspects. </objective> <flow>-
<step id="STEP 1: Investigation">
<if condition="<ase-project-boxing/> is equal `black`">
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
<template> <ase-tpl-bullet-normal/> **LINT**: *suppressed* (`project.boxing` is `black`) </template> </if>GloborAgenttool and do not read any source, only output the following <template/> and then SKIP the remaining steps STEP 2 and STEP 3:First, determine the effective aspect set <aspects/>, i.e., the code quality aspects which are checked at all. For this, parse <getopt-option-include/> and <getopt-option-exclude/> as comma-separated token lists, silently dropping the
<template> ⧉ **ASE**: ✪ skill: **ase-code-lint**, ▶ ERROR: invalid aspect id: **<token/>** </template>nonesentinel and any empty token. If a token <token/> is not one of the aspect idsA01...A20, only output the following <template/> and then STOP the entire flow (do not perform any further steps):Otherwise set <aspects/> to all twenty aspect ids
<template> ⧉ **ASE**: ✪ skill: **ase-code-lint**, ▶ ERROR: options `--include` and `--exclude` cancel out to an empty aspect set </template>A01...A20if both lists are empty, to the include list if only it is non-empty, to all twenty 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 <aspects/> is empty, only output the following <template/> and then STOP the entire flow (do not perform any further steps):Then, use the following <template/> to give a hint on this step:
<template> <ase-tpl-bullet-secondary/> **LINT INVESTIGATION** </template>Dispatch the investigation to sub-agents via the
Agenttool 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 <sources/> of individual source code files, expanding any directory or wildcard references with theGlobtool. Then partition <sources/>, 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 <aspects/> is the comma-separated list of the effective aspect ids (without any spaces), <batch/> is the space-separated list of the source code file paths of the corresponding batch, <batch-index/> is the 1-based index of that batch, and <batch-count/> is the total number of batches, so that each parallel invocation is distinguishable in the progress display.
Parse the result message of each
Agenttool invocation as a JSON array and concatenate all those arrays. Then deduplicate the combined list: when two problems share the samefile,line, andaspect, silently drop all but the first one (sub-agents may have read overlapping related files for comprehension). Finally sort the list byfileand then numerically byline, and set <problems/> to that list.Then determine the effective severity floor <floor/>: define the ordinal rank
LOW=1,MEDIUM=2,HIGH=3, start from <floor><getopt-option-severity/></floor> (defaultLOW), and - if <ase-project-boxing/> is equalgrey- raise <floor/> toMEDIUMwhenever its current rank is belowrank(MEDIUM)(grey boxing surfaces only material findings of severityMEDIUMand above).Then apply the effective severity floor <floor/>: Keep a problem in <problems/> if and only if its
severityfield isACCEPTEDorrank(severity)is greater than or equal torank(<floor/>); silently drop all other problems. With the default floorLOW, all problems are kept.ACCEPTEDproblems are never dropped.Finally, sort the surviving problems in <problems/> by their
severityfield from highest to lowest in the fixed orderHIGH,MEDIUM,LOW,ACCEPTED, so the subsequent reporting starts with the most severe problem. Within the same severity, keep thefile/lineorder established above.You MUST NOT output anything else in this STEP 1.
</step> -
<step id="STEP 2: Summary">
Use the following <template/> to output a summary of the detected problems in <problems/> (if any were found), in the original aspect ordering
<template> <ase-tpl-bullet-secondary/> **LINT SUMMARY**:A01 - XXX...A20 - XXX.<ase-tpl-bullet-signal/> AX - XXX: N issues <ase-tpl-bullet-signal/> AX - XXX: N issues [...] </template>
Else, if no problems were found, use the following <template/> to output the summary instead:
<template> <ase-tpl-bullet-secondary/> **LINT SUMMARY**:(no problems detected) </template>
You MUST NOT output anything else in this STEP 2.
</step> -
<step id="STEP 3: Correction">
-
Mark this skill as the active edit-capable skill so that the ASE
pre-tool-usehook auto-approves the subsequentEditinvocations on any invocation path (slash command orSkilltool). Call thease_config_set(key: "agent.skill", val: "ase-code-lint", scope: "session:<ase-session-id/>")tool from theaseMCP server. Do not output anything in this substep.Critical safety invariant: the marker set here grants
Editauto-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. anEditfailure, 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, unrelatedEdit. -
Set <total/> to the number of problems in <problems/> and <index/> to
<for items="<problems/>">0. Then iterate over all problems:-
Increment <index/> by one (the 1-based position of the current <item/> within <problems/>). Set <aspect/> to the
aspectfield of <item/>. Set <severity/> to theseverityfield of <item/>. Set <description/> to thedescriptionfield of <item/>. Set <change-set/> to thechange-setfield of <item/>. -
Set <context></context> (set to empty). Set <diff></diff> (set to empty). Set <diff-condensed></diff-condensed> (set to empty).
-
Iterate over the change set:
<for items="<change-set/>">-
Set <file/> to the
filefield of <item/>. Set <change-hunks/> to thechange-hunksfield of <item/>.Unless <ase-project-boxing/> is equal
<template> --- <file/> (original) +++ <file/> (corrected) </template>grey(where the full unified diff is suppressed and this per-file header is unused), set <diff-file/> to the following <template/>: -
Iterate over the change hunks.
<for items="<change-hunks/>">-
Set <line/> to the
linefield of <item/>. Set <context-before/> to thecontext_beforefield of <item/>. Set <old-text/> to theold_textfield of <item/>. Set <new-text/> to thenew_textfield of <item/>. Set <context-after/> to thecontext_afterfield of <item/>.Then normalize the hunk to its minimal form, so that the proposed diff shows exactly the lines the later
Editwill actually change: while the first line of <old-text/> is identical to the first line of <new-text/>, move that line from both to the end of <context-before/> and increment <line/> by one; likewise, while the last line of <old-text/> is identical to the last line of <new-text/>, move that line from both to the front of <context-after/>. Finally, trim <context-before/> to its last two lines and <context-after/> to its first two lines. -
Skip this substep entirely when <ase-project-boxing/> is equal
grey- the full unified diff is suppressed there, so none of the <hunk-body/>, <old-count/>, <new-count/>, <old-start/>, or <new-start/> 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 <context-before/> (if non-empty), - one
--prefixed line for each line of <old-text/> (if non-empty; split <old-text/> on newlines), - one
+-prefixed line for each line of <new-text/> (if non-empty; split <new-text/> on newlines), - one
-prefixed line for each line of <context-after/> (if non-empty).
Set <hunk-body/> to those prefixed lines joined by newlines.
Set <old-count/> to the number of old-side hunk lines, i.e., the combined line count of <context-before/>, <old-text/>, and <context-after/> (each empty part counts as
0). Set <new-count/> to the number of new-side hunk lines, i.e., the combined line count of <context-before/>, <new-text/>, and <context-after/> (each empty part counts as0).Set <old-start/> to the 1-based line number of the first old-side hunk line: if <context-before/> is non-empty, that is its line (one before <line/>); otherwise it is <line/> itself (the first line of <old-text/>). For a hunk that only inserts new lines (empty <old-text/> 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 <new-start/> to the same value as <old-start/>, but clamped to a minimum of1whenever <new-count/> is greater than0(the corrected side then has a real first line). - one
-
If <context/> is not empty, set <context><context/>,</context> (append a comma). Then append the following <template/> to <context/>:
<template>
<file/>:<line/></template> -
<if condition="<ase-project-boxing/> is equal `grey`">
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 <old-snippet/> as the single-line collapse of <old-text/> (join its lines with
<template> <ase-tpl-bullet-signal/> `<file/>`:<line/>: `<old-snippet/>` → `<new-snippet/>` </template> </if> <else>⏎, or∅when <old-text/> is empty for a pure insertion) and <new-snippet/> as the same collapse of <new-text/> (or∅when empty for a pure deletion). Then append the following <template/> to <diff-condensed/> as a new line:Append the following <template/> to <diff-file/>, emitting <hunk-body/> verbatim (one already-prefixed line per line, with no extra blank or space-only lines):
<template> @@ -<old-start/>,<old-count/> +<new-start/>,<new-count/> @@ <hunk-body/> </template> </else>
-
-
Unless <ase-project-boxing/> is equal
grey(where <diff-file/> is unused), append <diff-file/> to <diff/>.
-
-
Report the problem with the following <template/>:
<template> <ase-tpl-bullet-signal/> [<index/>/<total/>]: **<aspect/> PROBLEM** (`<severity/>`): <context/> <description/> </template> -
<if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
<if condition="<ase-project-boxing/> is equal `grey`">
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 <template/>:
<template> <ase-tpl-bullet-normal/> **<aspect/> SOLUTION**: <diff-condensed/> </template> </if> <else>Report the solution with the following <template/>:
<template> <ase-tpl-bullet-normal/> **<aspect/> SOLUTION**:
</template> </else> </if> <else><diff/>Report the solution with the following <template/>:
<template> <ase-tpl-bullet-normal/> **<aspect/> SOLUTION**:(corresponding change automatically applied)
</template> </else> -
<if condition="<getopt-option-auto/> is not equal `true`">
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
<expand name="custom-dialog" arg1="--other"> CORRECTION: How would you like to proceed with this proposed correction? ACCEPT: Apply this proposed correction. REJECT: Skip this proposed correction. </expand> </if> <else>custom-dialogdefinition. You MUST closely follow this definition:Set <result>ACCEPT</result>. You MUST NOT output anything else in this sub-step 6.
</else> -
Check <result/> and dispatch accordingly:
- <if condition="<result/> is 'ACCEPT'"> Invoke the `Edit` tool to apply the changes exactly as given by the hunks of the current <change-set/> (rendered as <diff/>, unless suppressed under grey boxing). The operation will be auto-approved by the ASE `pre-tool-use` hook (which tracks the active skill), so *no* interactive permission prompt will appear. After applying the changes, just continue with the next <item/>. </if>
- <if condition="<result/> starts with 'OTHER'"> Generate a *new* proposal for the *same* <item/> (incorporating the user's free-text hint from <result/> if provided via the "OTHER" prefix). *Reassign* <description/> and <change-set/> to reflect this refined proposal (each change-hunk's `old_text` stays anchored to the existing text at its `file`:`line`; `new_text` carries the refinement) so that the substep 2/3 rebuild renders the new <diff/> and any `Edit` applies the new proposal rather than the original. Then loop back to substep 2 of this iteration. There is *no* cap on refinement rounds - keep refining until the user picks `ACCEPT` or `REJECT`. </if>
-
<if condition=" <result/> is 'REJECT' or <result/> is 'CANCEL' or <result/> starts with 'ERROR' "> Skip this <item/> without any
Editcall and continue with the next <item/>. </if>
-
-
Clear the active edit-capable skill marker now that all
Editinvocations are done, so a later unrelatedEditis not auto-approved. Call thease_config_delete(key: "agent.skill", scope: "session:<ase-session-id/>")tool from theaseMCP server. Do not output anything in this substep. -
You MUST NOT output any further additional explanations or summaries at the end of this skill processing, except for the following final <template/>:
<template> <ase-tpl-bullet-secondary/> **LINT FINISHED** </template> -
Finally, give the closing hints by expanding the following (which, depending on the configured <ase-guidance-level/>, may each expand into nothing and hence emit no output at all):
<if condition="at least one problem in <problems/> was left uncorrected"> <ase-tpl-hint level="normal"> For problems whose correction demands more than a local edit, use `/ase-code-resolve` to derive and apply a full solution approach. </ase-tpl-hint> </if> <if condition="<getopt-option-auto/> is not equal `true`"> <ase-tpl-hint level="verbose"> Use `/ase-code-lint --auto` to apply all corrections unattended, `--severity` to raise the reporting floor, and `--include`/`--exclude` to narrow the checked aspects. </ase-tpl-hint> </if>
-
What ships with it: 1 file
3.5 KB alongside SKILL.md
- help.md3.5 KB