Skip to content
Back to skills

Ase Docs Proofread

ASecurity

Analyze the documents for spelling, capitalization, punctuation, word break, or grammar errors. Use when the user wants to "proofread" or "spellcheck" a document.

  • 56 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 1, 2026
ai-agentsgoapi

Works with

  • api
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 22, 2026

npx -y skills add rse/ase --skill ase-docs-proofread --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ase Docs Proofread?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ase Docs Proofread
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rse-ase-docs-proofread/badge)](https://www.skillsdirectory.com/skills/rse-ase-docs-proofread)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ase-docs-proofread
argument-hint: "[--help|-h] [--auto|-a] <docs-reference>"
description: >
    Analyze the documents for spelling, capitalization, punctuation, word break, or grammar errors.
    Use when the user wants to "proofread" or "spellcheck" a document.
user-invocable: true
disable-model-invocation: false
effort: high
---

@${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-docs-proofread">
Analyze documents for spelling, capitalization, punctuation, word break, or grammar errors
</purpose>

<expand name="getopt"
    arg1="ase-docs-proofread"
    arg2="--auto|-a">
    $ARGUMENTS
</expand>

<objective>
*Proofread* the documents of `<getopt-arguments/>` for problems in their
*spelling*, *capitalization*, *punctuation*, *word break*, or *grammar* and propose corrections.
</objective>

<flow>

1.  <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
    `Glob` or `Agent` tool and do *not* read any document, only output
    the following <template/> and then *SKIP* the remaining steps STEP 2
    and STEP 3:

    <template>
    <ase-tpl-bullet-normal/> **PROOFREAD**: *suppressed* (`project.boxing` is `black`)
    </template>

    </if>

    First, use the following <template/> to give a hint on this step:

    <template>
    <ase-tpl-bullet-secondary/> **PROOFREADING INVESTIGATION**
    </template>

    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 <documents/> of individual document files, expanding any
    directory or wildcard references with the `Glob` tool. Then
    partition <documents/>, preserving order, into at most *eight*
    batches of roughly equal size (a single document yields a single
    batch), and invoke the following tool once per batch, emitting
    *all* invocations *in one single message* so they run in
    *parallel*:

    ```text
        Agent(
            description:       "Proofread Investigation (<batch-index/>/<batch-count/>)",
            subagent_type:     "ase:ase-docs-proofread",
            prompt:            <batch/>,
            run_in_background: false
        )
    ```

    Here <batch/> is the space-separated list of the document 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 `Agent` tool invocation as a JSON
    array, concatenate all those arrays, sort the combined list by
    `file` and then numerically by `line`, and set <problems/> to that
    list.

    You *MUST* *NOT* output anything at all in this STEP 1 beyond the
    above hint template and the `Glob` and `Agent` tool invocations.
    </step>

2.  <step id="STEP 2: Summary">

    Use the following <template/> to give a summary of the detected
    problems in <problems/>:

    <template>
    <ase-tpl-bullet-secondary/> **PROOFREADING SUMMARY**:

    | *Proofread Type*    | *Proofread Result*      |
    | ------------------- | ----------------------- |
    | **SPELLING**:       | **<n/>** problems found |
    | **CAPITALIZATION**: | **<c/>** problems found |
    | **PUNCTUATION**:    | **<m/>** problems found |
    | **WORD-BREAK**:     | **<w/>** problems found |
    | **GRAMMAR**:        | **<k/>** problems found |

    </template>

    Hints:

    -   <n/> is the number of problems with `type` equal to `SPELLING`       in <problems/>
    -   <c/> is the number of problems with `type` equal to `CAPITALIZATION` in <problems/>
    -   <m/> is the number of problems with `type` equal to `PUNCTUATION`    in <problems/>
    -   <w/> is the number of problems with `type` equal to `WORD-BREAK`     in <problems/>
    -   <k/> is the number of problems with `type` equal to `GRAMMAR`        in <problems/>

    </step>

3.  <step id="STEP 3: Correction">

    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-docs-proofread", 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 <total/> to the number of problems in <problems/> and
        <index/> to `0`. Then iterate over all problems:

        <for items="<problems/>">

        1.  Increment <index/> by one (the 1-based position of the
            current <item/> within <problems/>).
            Set <type/>           to the `type` field of <item/>.
            Set <file/>           to the `file` field of <item/>.
            Set <line/>           to the `line` field of <item/>.
            Set <description/>    to the `description` field of <item/>.
            Set <context-before/> to the `context_before` field of <item/>.
            Set <old-text/>       to the `old_text` field of <item/>.
            Set <new-text/>       to the `new_text` field of <item/>.
            Set <context-after/>  to the `context_after` field of <item/>.

            Then *normalize* the change to its *minimal* form, so
            that the proposed diff shows exactly the lines the later
            `Edit` will 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.

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

            Whenever <file-lines/> is non-empty, *re-derive* both
            context parts from it, *overriding* the sub-agent supplied
            values, so the rendered diff shows real context even when a
            sub-agent supplied none: set <context-before/> to the *up to
            two* lines of <file-lines/> directly *before* line <line/>
            (empty if <line/> is `1`) and <context-after/> to the *up
            to two* lines of <file-lines/> starting at line (<line/> +
            <n/>), where <n/> is the number of lines in <old-text/>
            (empty if that line is beyond the end of the document).
            Keep the sub-agent supplied values only when <file-lines/>
            is empty.

        2.  Report the problem with the following <template/>:

            <template>
            <ase-tpl-bullet-signal/> [<index/>/<total/>]: **<type/> PROBLEM**: `<file/>`:<line/>:

            <description/>
            </template>

        3.  <if condition="<getopt-option-auto/> is not equal `true` and <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 a
            *condensed* one-line representation. Determine <old-snippet/>
            as the *single-line* collapse of <old-text/> (join its lines
            with ` ⏎ `, 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
            report the correction with the following <template/>:

            <template>

            <ase-tpl-bullet-normal/> **<type/> CORRECTION**: `<old-snippet/>` → `<new-snippet/>`

            </template>

            </if>
            <elseif condition="<getopt-option-auto/> is not equal `true`">

            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 as `0`).

            Set <old-start/> to the 1-based line number of the *first*
            old-side hunk line: if <context-before/> is non-empty, that is
            the line of its *first* context line, i.e., <line/> minus the
            number of lines in <context-before/>; 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 of `1` whenever <new-count/> is greater than `0`
            (the corrected side then has a real first line).

            Render the proposed correction as a *unified diff* with *up to
            two* lines of context in a fenced block based on the following
            <template/>, emitting <hunk-body/> verbatim (one already-prefixed
            line per line, with no extra blank or space-only lines):

            <template>

            <ase-tpl-bullet-normal/> **<type/> CORRECTION**:

            ```diff
            --- <file/> (original)
            +++ <file/> (corrected)
            @@ -<old-start/>,<old-count/> +<new-start/>,<new-count/> @@
            <hunk-body/>
            ```

            </template>

            </elseif>

        4.  <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 `custom-dialog`
            definition. You *MUST* closely follow this definition:

            <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>

            Set <result>ACCEPT</result>.

            </else>

        5.  Check <result/> and dispatch accordingly:

            -   <if condition="<result/> is 'ACCEPT'">

                Invoke the `Edit` tool to apply the change by replacing
                <old-text/> with <new-text/> at <file/>:<line/>. 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. Then 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/>
                after the "OTHER:" prefix. *Reassign* <description/>,
                <old-text/>, and <new-text/> to reflect this refined
                proposal (<old-text/> stays anchored to the existing text
                at <file/>:<line/>; <new-text/> and <description/> carry the
                refinement) so the subsequent rendering and any `Edit` use
                the new proposal rather than the original. Then *re-apply*
                the minimal-form normalization of substep 1 to the refined
                <old-text/> and <new-text/> (so the re-rendered diff again
                shows exactly the changed lines) and *go back* to substep 2
                of this `for`-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 `Edit` call and continue
                with the next <item/>.

                </if>

        </for>

    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 <template/>:

        <template>
        <ase-tpl-bullet-secondary/> **PROOFREAD FINISHED**
        </template>

    5.  Finally, give the closing hint by expanding the following
        (which, depending on the configured <ase-guidance-level/>, may
        expand into nothing and hence emit no output at all):

        <if condition="<getopt-option-auto/> is not equal `true`">
        <ase-tpl-hint level="verbose">
        Use `/ase-docs-proofread --auto` to apply all corrections unattended.
        </ase-tpl-hint>
        </if>

    </step>

</flow>

Files in this skill

  • SKILL.md15.3 KB
  • help.md1.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.