@${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
Ground Rule
This skill removes text, so unlike ase-docs-refine it MAY lose
content. It still MUST NOT corrupt whatever survives: every fact,
number, technical term, qualifier, and negation which survives into
the shortened text stays exactly as it was, no content is invented,
the order of the surviving argument is kept, and fenced code blocks,
inline code spans, link targets, Markdown frontmatter, and the heading
structure are never touched.
The skill also MUST NOT shorten beyond the target: it stops at the first change which reaches the target, so a document is never cut more than the user asked for.
Determine the target length from the two mutually exclusive options. Set to and to , treating a non-numeric or negative value as
0. Then dispatch:Only output the following and then IMMEDIATELY STOP all further skill processing:
Only output the following and then IMMEDIATELY STOP all further skill processing:
Do not output anything else in this substep.
Silently resolve
<getopt-arguments/>to the list of individual document files, expanding any directory or wildcard reference with theGlobtool. Then dispatch:Only output the following and then IMMEDIATELY STOP all further skill processing:
A target length applies to one document, so a reference which expands to several documents is ambiguous: it is unclear whether the target bounds each document or their sum. Set to the number of documents, then only output the following and IMMEDIATELY STOP all further skill processing:
Set to the single document of .
Do not output anything else in this STEP 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
Agenttool and do not read any document, only output the following and then SKIP the remaining steps STEP 3, STEP 4, and STEP 5:First, use the following to give a hint on this step:
Dispatch the investigation to a sub-agent via the
Agenttool so that no investigation details leak into the user-visible transcript. The sub-agent performs the silent reading, measuring, and shortening; only its final structured return value is consumed here. As a target length applies to exactly one document, exactly one sub-agent is invoked, which keeps the length budget coherent:Agent( description: "Shorten Investigation", subagent_type: "ase:ase-docs-shorten", prompt: "UNIT: <unit/>\nTARGET: <target/>\nFILE: <file/>", run_in_background: false )Parse the result message of the
Agenttool invocation as a JSON object. Set to itslength_beforefield, to itslength_projectedfield, and to itsblocksarray, ordered by ascendingline.You MUST NOT output anything at all in this STEP 2 beyond the above hint template and the
Agenttool invocation.The document already meets the target, so nothing is shortened. Only output the following and then SKIP the remaining steps STEP 4 and STEP 5:
Use the following to give a summary of the proposed shortenings in :
Shortening Stage Shortening Result TIGHTEN: blocks proposed DROP: blocks proposed COMPRESS: blocks proposed Hints:
- is the number of blocks with
stageequal toTIGHTENin - is the number of blocks with
stageequal toDROPin - is the number of blocks with
stageequal toCOMPRESSin
- is the number of blocks with
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-docs-shorten", 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 to the number of blocks in and to
0. Then iterate over all blocks:Increment by one (the 1-based position of the current within ). Set to the
stagefield of . Set to thelinefield of . Set to thedescriptionfield of . Set to theold_textfield of . Set to thenew_textfield of . Set to thelength_beforefield of . Set to thelength_afterfield of .Then verify the Ground Rule for this : compare against and drop the entirely -- continuing with the next without any output -- whenever a fact, number, technical term, qualifier, or negation which survives into was altered, whenever states something did not, or whenever a fenced code block, an inline code span, a link target, or a heading was touched.
Then set to ( - ) and to that difference expressed as a rounded percentage of , so the reviewer sees what the block actually saves.
Then set and to empty and normalize the change to its minimal form, so that the proposed diff shows exactly the lines the later
Editwill 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, 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 theReadtool - reusing the content read earlier in this iteration, unless anEditwas applied 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.Whenever is non-empty, re-derive both context parts from it, so the rendered diff shows real context: 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 document).Report the proposed block with the following :
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 two-line hunk. Unlike a proofreading correction or a refinement, a shortening block spans whole paragraphs, so both sides MUST be normalized and elided onto one line each -- an unelided side-by-side collapse exceeds the terminal width and wraps into an unreadable run.
Determine from by replacing every run of whitespace (line breaks included) with a single space and trimming the result, then -- only if it is longer than
100characters -- keeping just its first60and last30characters, joined by[…]. Determine the same way from , or set it to∅when is empty for a pure removal. Then report the shortening with the following , emitting both snippet lines verbatim (no wrapping, no extra blank lines):SHORTENING ( → , -%):
- <old-snippet/> + <new-snippet/>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 as0).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 ). Set to the same value as , but clamped to a minimum of
1whenever is greater than0(the shortened side then has a real first line).Render the proposed shortening as a unified diff with up to two lines of context in a fenced block based on the following , emitting verbatim (one already-prefixed line per line, with no extra blank or space-only lines):
SHORTENING ( → , -%):
--- <file/> (original) +++ <file/> (shortened) @@ -<old-start/>,<old-count/> +<new-start/>,<new-count/> @@ <hunk-body/>- one
In the following, you MUST NOT use your built-in tool! Instead, you MUST just show a custom dialog according to the expanded
custom-dialogdefinition. You MUST closely follow this definition:Set ACCEPT.
Check and dispatch accordingly:
Invoke the
Edittool to apply the change by replacing with at :. The operation will be auto-approved by the ASEpre-tool-usehook (which tracks the active skill), so no interactive permission prompt will appear. Then continue with the next .Generate a new proposal for the same , incorporating the user's free-text hint from after the "OTHER:" prefix. Reassign , , , , and to reflect this refined proposal ( stays anchored to the existing text at :; and carry the new shortening) so the subsequent rendering and any
Edituse the new proposal rather than the original. Then re-apply the minimal-form normalization and the context re-derivation of substep 1 to the refined and (so the re-rendered diff again shows exactly the changed lines) and go back to substep 2 of thisfor-iteration. There is no cap on refinement rounds - keep refining until the user picksACCEPTorREJECT.-
Skip this without any
Editcall and continue with the next .
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.
Silently call the
ase_text_metric(file: "<file/>")tool of theaseMCP server and set to the field of its result, so the report states the measured, achieved length rather than the projected one -- rejected blocks otherwise falsify the numbers. Then set to ( - ) and to that reduction expressed as a rounded percentage of . Do not output anything in this substep.Report the achieved length with the following :
Length Metric Length Value BEFORE: AFTER: TARGET: REDUCTION: (%) Set to ( - ).
You MUST NOT output any further additional explanations or summaries at the end of this skill processing, except for the following final :
Finally, give the closing hint by expanding the following (which, depending on the configured , may expand into nothing and hence emit no output at all):