@rse/ase 0.9.12 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dst/ase-compat.js +1 -1
  2. package/dst/ase-diagram.js +5 -2
  3. package/dst/ase-getopt.js +2 -1
  4. package/dst/ase-kv.js +30 -11
  5. package/dst/ase-mcp.js +2 -0
  6. package/dst/ase-persona.js +4 -1
  7. package/dst/ase-skills.js +13 -3
  8. package/dst/ase-statusline.js +2 -2
  9. package/dst/ase.js +1 -1
  10. package/package.json +1 -1
  11. package/plugin/.claude-plugin/plugin.json +1 -1
  12. package/plugin/.codex-plugin/plugin.json +1 -1
  13. package/plugin/.github/plugin/plugin.json +1 -1
  14. package/plugin/agents/ase-meta-chat.md +3 -3
  15. package/plugin/meta/ase-dialog.md +1 -1
  16. package/plugin/meta/ase-format-arch.md +26 -9
  17. package/plugin/meta/ase-format-meta.md +7 -3
  18. package/plugin/meta/ase-format-spec.md +11 -6
  19. package/plugin/meta/ase-getopt.md +8 -3
  20. package/plugin/meta/ase-skill.md +49 -21
  21. package/plugin/package.json +1 -1
  22. package/plugin/skills/ase-arch-analyze/SKILL.md +26 -13
  23. package/plugin/skills/ase-arch-discover/SKILL.md +25 -14
  24. package/plugin/skills/ase-code-analyze/SKILL.md +10 -5
  25. package/plugin/skills/ase-code-craft/SKILL.md +16 -4
  26. package/plugin/skills/ase-code-explain/SKILL.md +0 -1
  27. package/plugin/skills/ase-code-insight/SKILL.md +1 -1
  28. package/plugin/skills/ase-code-lint/SKILL.md +56 -18
  29. package/plugin/skills/ase-code-refactor/SKILL.md +16 -4
  30. package/plugin/skills/ase-code-resolve/SKILL.md +17 -4
  31. package/plugin/skills/ase-docs-proofread/SKILL.md +48 -17
  32. package/plugin/skills/ase-meta-brainstorm/SKILL.md +5 -2
  33. package/plugin/skills/ase-meta-compat/SKILL.md +2 -12
  34. package/plugin/skills/ase-meta-diff/SKILL.md +3 -3
  35. package/plugin/skills/ase-meta-evaluate/SKILL.md +32 -24
  36. package/plugin/skills/ase-meta-quorum/SKILL.md +3 -3
  37. package/plugin/skills/ase-task-condense/SKILL.md +6 -9
  38. package/plugin/skills/ase-task-edit/SKILL.md +6 -2
  39. package/plugin/skills/ase-task-grill/SKILL.md +9 -15
  40. package/plugin/skills/ase-task-id/SKILL.md +7 -4
  41. package/plugin/skills/ase-task-implement/SKILL.md +6 -11
  42. package/plugin/skills/ase-task-preflight/SKILL.md +5 -10
  43. package/plugin/skills/ase-task-reboot/SKILL.md +21 -13
  44. package/plugin/skills/ase-task-rename/SKILL.md +9 -0
@@ -115,8 +115,16 @@ for the technology stack to *provide* the *needed functionality*
115
115
  <keyword-L/> (L=1-M), which allow you to search for suitable
116
116
  components.
117
117
 
118
- 3. In the to be discovered result set of components <component-K/>
119
- (K=1-N), remember the component name as <name-K/>, the
118
+ 3. Determine the *candidate pool size* <pool/> as twice the
119
+ <getopt-option-limit/> (i.e. <pool/> = 2 &times;
120
+ <getopt-option-limit/>). Each discovery source below may fetch up
121
+ to <pool/> candidates so that the later ranking and trimming
122
+ (which alone is governed by <getopt-option-limit/>) has a
123
+ meaningful set to choose from.
124
+
125
+ In the to be discovered candidate set of components <component-K/>
126
+ (K=1-C, where C is the merged and deduplicated candidate count),
127
+ remember the component name as <name-K/>, the
120
128
  official package name as <package-K/>, the latest version as
121
129
  <version-K/>, the stars as <stars-K/>, the created date as
122
130
  <created-K/>, the last updated date as <updated-K/>, the total
@@ -126,13 +134,13 @@ for the technology stack to *provide* the *needed functionality*
126
134
 
127
135
  1. Based on the essential keywords <keyword-L/> (L=1-M),
128
136
  use the `ase-meta-search` skill in a subagent to *generally*
129
- discover an initial set of a maximum of <getopt-option-limit/> *NPM packages*
137
+ discover an initial set of a maximum of <pool/> *NPM packages*
130
138
  <component-K/> and at least their real name <name-K/> and
131
139
  their unique package names <package-K/>.
132
140
 
133
- 2. Use the shell command `npm search --json --searchlimit <getopt-option-limit/>
141
+ 2. Use the shell command `npm search --json --searchlimit <pool/>
134
142
  "<keyword-1/>" [...] "<keyword-M/>"` to *specifically*
135
- discover an additional set of a maximum of <getopt-option-limit/> *NPM packages*
143
+ discover an additional set of a maximum of <pool/> *NPM packages*
136
144
  <component-K/> and at least their unique package names
137
145
  <package-K/>, based on the essential keywords <keyword-L/>
138
146
  (L=1-M). Merge the results into the already existing result
@@ -142,14 +150,14 @@ for the technology stack to *provide* the *needed functionality*
142
150
 
143
151
  1. Based on the essential keywords <keyword-L/> (L=1-M),
144
152
  use the `ase-meta-search` skill in a subagent to *generally*
145
- discover an initial set of a maximum of <getopt-option-limit/> *Maven packages*
153
+ discover an initial set of a maximum of <pool/> *Maven packages*
146
154
  <component-K/> and at least their real name <name-K/> and
147
155
  their unique Maven coordinates <package-K/> of the form
148
156
  `groupId:artifactId`.
149
157
 
150
- 2. Use the shell command `curl -s 'https://search.maven.org/solrsearch/select?q=<keyword-1/>+[...]+<keyword-M/>&rows=<getopt-option-limit/>&wt=json'`
158
+ 2. Use the shell command `curl -s 'https://search.maven.org/solrsearch/select?q=<keyword-1/>+[...]+<keyword-M/>&rows=<pool/>&wt=json'`
151
159
  to *specifically* discover an additional set of a maximum
152
- of <getopt-option-limit/> *Maven packages* <component-K/> and at least their
160
+ of <pool/> *Maven packages* <component-K/> and at least their
153
161
  unique Maven coordinates <package-K/> (i.e. `<g/>:<a/>` from
154
162
  each result document's `g` and `a` fields), based on the
155
163
  essential keywords <keyword-L/> (L=1-M). Merge the results
@@ -157,22 +165,25 @@ for the technology stack to *provide* the *needed functionality*
157
165
  entries by Maven coordinate.
158
166
 
159
167
  6. Call the `ase_component_info(stack: "<stack/>", components:
160
- [ "<package-1/>", ..., "<package-N/>" ])` tool of the `ase` MCP
161
- server *once* for the entire set of discovered packages.
168
+ [ "<package-1/>", ..., "<package-C/>" ])` tool of the `ase` MCP
169
+ server *once* for the entire candidate set of discovered packages.
162
170
  The tool dispatches internally on <stack/> and fetches all
163
171
  metadata in maximum parallel and returns an array of objects `{
164
172
  name, version, created, updated, repository, stars, downloads,
165
173
  rank }`. For each
166
- component <component-K/> (K=1-N) read from its corresponding
174
+ component <component-K/> (K=1-C) read from its corresponding
167
175
  entry: <version-K/> from `version`, <updated-K/> from `updated`,
168
176
  <created-K/> from `created`, <repository-K/> from `repository`,
169
177
  <stars-K/> from `stars` (numeric or `N.A.`), <downloads-K/>
170
178
  from `downloads` (numeric or `N.A.`) and <rank-K/> from `rank`
171
179
  (numeric).
172
180
 
173
- 7. Sort, in descending order, the discovered components
174
- <component-K/> (K=1-N) by their `rank` field and trim the result
175
- list to just a maximum of <getopt-option-limit/> total components.
181
+ 7. Sort, in descending order, the discovered candidate components
182
+ <component-K/> (K=1-C) by their `rank` field and trim the result
183
+ list to just a maximum of <getopt-option-limit/> total components,
184
+ which establishes the final retained set <component-K/> (K=1-N,
185
+ where N is at most <getopt-option-limit/>). All subsequent steps
186
+ operate solely on this retained set.
176
187
 
177
188
  8. For each component <component-K/> (K=1-N), research and then
178
189
  decide which *one* of *USP* (Unique Selling Point -- what makes
@@ -151,8 +151,11 @@ problems in *performance* and *efficiency*, or problems in *security*.
151
151
 
152
152
  Then renumber the surviving problems contiguously as `P<n/>` with
153
153
  <n/> = 1, 2, ... in the original ordering. If *all* problems are
154
- dropped, skip the per-problem report but still emit the final hint
155
- <template/> below.
154
+ dropped, skip the per-problem report but still purge any stale
155
+ persisted problems with a *single* `ase_kv_batch` call to the `ase`
156
+ MCP server with `transactional` set to `true` and a `commands`
157
+ parameter array holding exactly one `{ command: "clear" }` entry,
158
+ and still emit the final hint <template/> below.
156
159
 
157
160
  In this STEP 3, for *EVERY* surviving problem, immediately report
158
161
  it with the following output <template/>, based on concise bullet
@@ -234,9 +237,11 @@ problems in *performance* and *efficiency*, or problems in *security*.
234
237
  - *Additionally*, persist all reported problems in a *single*
235
238
  `ase_kv_batch` call to the `ase` MCP server with `transactional`
236
239
  set to `true`. The `commands` parameter array of this call
237
- starts with one `{ command: "clear" }` entry, followed by one
238
- `{ command: "set", key: "ase-issue-P<n/>", val: "<title/>:
239
- <description/>" }` entry per reported problem.
240
+ starts with one `{ command: "clear", prefix: "ase-issue-" }`
241
+ entry (which removes only the previously persisted `ase-issue-*`
242
+ keys, leaving any unrelated keys in the shared store intact),
243
+ followed by one `{ command: "set", key: "ase-issue-P<n/>", val:
244
+ "<title/>: <description/>" }` entry per reported problem.
240
245
 
241
246
  Finally, output the following <template/> to give a final hint:
242
247
 
@@ -319,7 +319,19 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
319
319
  as <head/> (or `none` if the list is `none`/empty).
320
320
  Set <args>--int-reuse-task</args>.
321
321
 
322
- 1. <if condition="<head/> is equal `IMPLEMENT`">
322
+ 1. <if condition="<head/> is equal `DONE`">
323
+ Consume the head: set <getopt-option-next/> to the remaining
324
+ tokens (joined back with `,`, or `none` if empty). `DONE`
325
+ means the freshly composed plan is finalized as-is, so do
326
+ *not* hand off to `ase-task-edit`. Only output the following
327
+ <template/> and then *STOP*. Do *not* implement the plan.
328
+
329
+ <template>
330
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan finalized -- done**
331
+ </template>
332
+ </if>
333
+
334
+ 2. <elseif condition="<head/> is equal `IMPLEMENT`">
323
335
  Consume the head: set <getopt-option-next/> to the remaining
324
336
  tokens (joined back with `,`, or `none` if empty).
325
337
  <if condition="<getopt-option-next/> is not equal `none`">
@@ -327,9 +339,9 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
327
339
  </if>
328
340
  Call the tool `Skill(skill: "ase:ase-task-implement", args: "<args/>")`
329
341
  to *implement* the freshly composed plan, bypassing `ase-task-edit`.
330
- </if>
342
+ </elseif>
331
343
 
332
- 2. <elseif condition="<head/> is equal `PREFLIGHT`">
344
+ 3. <elseif condition="<head/> is equal `PREFLIGHT`">
333
345
  Consume the head: set <getopt-option-next/> to the remaining
334
346
  tokens (joined back with `,`, or `none` if empty).
335
347
  <if condition="<getopt-option-next/> is not equal `none`">
@@ -339,7 +351,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
339
351
  to *preflight* the freshly composed plan, bypassing `ase-task-edit`.
340
352
  </elseif>
341
353
 
342
- 3. <else>
354
+ 4. <else>
343
355
  Hand off to `ase-task-edit`.
344
356
  <if condition="<head/> is equal `EDIT`">
345
357
  Consume the head: set <getopt-option-next/> to the remaining
@@ -8,7 +8,6 @@ user-invocable: true
8
8
  disable-model-invocation: false
9
9
  effort: high
10
10
  allowed-tools:
11
- - "Skill"
12
11
  - "Agent"
13
12
  ---
14
13
 
@@ -12,7 +12,7 @@ allowed-tools:
12
12
  - "Bash(sort *)"
13
13
  - "Bash(uniq *)"
14
14
  - "Bash(head *)"
15
- - "Skill"
15
+ - "Bash(git log * | grep * | sort * | uniq * | sort * | head *)"
16
16
  - "Agent"
17
17
  ---
18
18
 
@@ -107,6 +107,16 @@ related to a set of code quality aspects.
107
107
  "ase-code-lint", scope: "session:<ase-session-id/>")` tool
108
108
  from the `ase` MCP server. Do not output anything in this substep.
109
109
 
110
+ *Critical safety invariant*: the marker set here grants `Edit`
111
+ auto-approval and *MUST* be cleared again (substep 3 below)
112
+ *before* this skill yields control, *regardless* of how the
113
+ iteration in substep 2 ends - whether it completes normally,
114
+ is aborted early (e.g. an `Edit` failure, an unparseable value,
115
+ or any other unexpected condition), or is otherwise interrupted.
116
+ If you ever stop or bail out of substep 2 early, you *MUST*
117
+ still perform substep 3 first. Never leave this marker active
118
+ for a later, unrelated `Edit`.
119
+
110
120
  2. Iterate over all problems:
111
121
 
112
122
  <for items="<problems/>">
@@ -143,34 +153,62 @@ related to a set of code quality aspects.
143
153
  Set <new-text/> to the `new_text` field of <item/>.
144
154
  Set <context-after/> to the `context_after` field of <item/>.
145
155
 
146
- 2. If <context/> is not empty, set
156
+ 2. Determine the hunk *body* as an ordered list of lines,
157
+ each carrying a one-character prefix (` ` for context,
158
+ `-` for old-side, `+` for new-side). Build it by
159
+ concatenating, in order and *skipping any part that is
160
+ empty*:
161
+
162
+ - one ` `-prefixed line for *each* line of
163
+ <context-before/> (if non-empty),
164
+ - one `-`-prefixed line for *each* line of <old-text/>
165
+ (if non-empty; split <old-text/> on newlines),
166
+ - one `+`-prefixed line for *each* line of <new-text/>
167
+ (if non-empty; split <new-text/> on newlines),
168
+ - one ` `-prefixed line for *each* line of
169
+ <context-after/> (if non-empty).
170
+
171
+ Set <hunk-body/> to those prefixed lines joined by
172
+ newlines.
173
+
174
+ Set <old-count/> to the number of old-side hunk lines,
175
+ i.e., the combined line count of <context-before/>,
176
+ <old-text/>, and <context-after/> (each empty part
177
+ counts as `0`).
178
+ Set <new-count/> to the number of new-side hunk lines,
179
+ i.e., the combined line count of <context-before/>,
180
+ <new-text/>, and <context-after/> (each empty part
181
+ counts as `0`).
182
+
183
+ Set <old-start/> to the 1-based line number of the
184
+ *first* old-side hunk line: if <context-before/> is
185
+ non-empty, that is its line (one before <line/>);
186
+ otherwise it is <line/> itself (the first line of
187
+ <old-text/>). For a hunk that *only inserts* new lines
188
+ (empty <old-text/> *and* empty context), set it to the
189
+ line *before* which the insertion happens, clamped to a
190
+ minimum of `0`, so a top-of-file insertion yields
191
+ `@@ -0,0 ... @@`.
192
+ Set <new-start/> to the same value as <old-start/>, but
193
+ clamped to a minimum of `1` whenever <new-count/> is
194
+ greater than `0` (the corrected side then has a real
195
+ first line).
196
+
197
+ 3. If <context/> is not empty, set
147
198
  <context><context/>,</context> (append a comma).
148
199
  Then append the following <template/> to <context/>:
149
200
 
150
201
  <template>`<file/>`:<line/></template>
151
202
 
152
- 3. Append the following <template/> to <diff-file/>:
203
+ 4. Append the following <template/> to <diff-file/>,
204
+ emitting <hunk-body/> verbatim (one already-prefixed
205
+ line per line, with no extra blank or space-only lines):
153
206
 
154
207
  <template>
155
208
  @@ -<old-start/>,<old-count/> +<new-start/>,<new-count/> @@
156
- <context-before/>
157
- -<old-text/>
158
- +<new-text/>
159
- <context-after/>
209
+ <hunk-body/>
160
210
  </template>
161
211
 
162
- Hints:
163
- - The <old-start/> is the line of the first hunk line, i.e.,
164
- the line of <context-before/> (one before <line/>).
165
- - The <new-start/> is the same as <old-start/> (the unchanged
166
- <context-before/> line shares the same start in both files).
167
- - The <old-count/> is the total number of old-side hunk lines, i.e.,
168
- the number of lines in <context-before/>, <old-text/>, and
169
- <context-after/> combined.
170
- - The <new-count/> is the total number of new-side hunk lines, i.e.,
171
- the number of lines in <context-before/>, <new-text/>, and
172
- <context-after/> combined.
173
-
174
212
  </for>
175
213
 
176
214
  3. Append <diff-file/> to <diff/>.
@@ -308,7 +308,19 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
308
308
  as <head/> (or `none` if the list is `none`/empty).
309
309
  Set <args>--int-reuse-task</args>.
310
310
 
311
- 1. <if condition="<head/> is equal `IMPLEMENT`">
311
+ 1. <if condition="<head/> is equal `DONE`">
312
+ Consume the head: set <getopt-option-next/> to the remaining
313
+ tokens (joined back with `,`, or `none` if empty). `DONE`
314
+ means the freshly composed plan is finalized as-is, so do
315
+ *not* hand off to `ase-task-edit`. Only output the following
316
+ <template/> and then *STOP*. Do *not* implement the plan.
317
+
318
+ <template>
319
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan finalized -- done**
320
+ </template>
321
+ </if>
322
+
323
+ 2. <elseif condition="<head/> is equal `IMPLEMENT`">
312
324
  Consume the head: set <getopt-option-next/> to the remaining
313
325
  tokens (joined back with `,`, or `none` if empty).
314
326
  <if condition="<getopt-option-next/> is not equal `none`">
@@ -316,9 +328,9 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
316
328
  </if>
317
329
  Call the tool `Skill(skill: "ase:ase-task-implement", args: "<args/>")`
318
330
  to *implement* the freshly composed plan, bypassing `ase-task-edit`.
319
- </if>
331
+ </elseif>
320
332
 
321
- 2. <elseif condition="<head/> is equal `PREFLIGHT`">
333
+ 3. <elseif condition="<head/> is equal `PREFLIGHT`">
322
334
  Consume the head: set <getopt-option-next/> to the remaining
323
335
  tokens (joined back with `,`, or `none` if empty).
324
336
  <if condition="<getopt-option-next/> is not equal `none`">
@@ -328,7 +340,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
328
340
  to *preflight* the freshly composed plan, bypassing `ase-task-edit`.
329
341
  </elseif>
330
342
 
331
- 3. <else>
343
+ 4. <else>
332
344
  Hand off to `ase-task-edit`.
333
345
  <if condition="<head/> is equal `EDIT`">
334
346
  Consume the head: set <getopt-option-next/> to the remaining
@@ -71,6 +71,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
71
71
  <problem-id/> and stop processing.
72
72
 
73
73
  2. <if condition="
74
+ <problem-id/> is not set AND
74
75
  <problem/> matches the regexp `^[a-zA-Z][a-zA-Z0-9_-]*$`
75
76
  ">
76
77
  Set <ase-task-id><problem/></ase-task-id> (set task id to problem)
@@ -366,7 +367,19 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
366
367
  as <head/> (or `none` if the list is `none`/empty).
367
368
  Set <args>--int-reuse-task</args>.
368
369
 
369
- 1. <if condition="<head/> is equal `IMPLEMENT`">
370
+ 1. <if condition="<head/> is equal `DONE`">
371
+ Consume the head: set <getopt-option-next/> to the remaining
372
+ tokens (joined back with `,`, or `none` if empty). `DONE`
373
+ means the freshly composed plan is finalized as-is, so do
374
+ *not* hand off to `ase-task-edit`. Only output the following
375
+ <template/> and then *STOP*. Do *not* implement the plan.
376
+
377
+ <template>
378
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan finalized -- done**
379
+ </template>
380
+ </if>
381
+
382
+ 2. <elseif condition="<head/> is equal `IMPLEMENT`">
370
383
  Consume the head: set <getopt-option-next/> to the remaining
371
384
  tokens (joined back with `,`, or `none` if empty).
372
385
  <if condition="<getopt-option-next/> is not equal `none`">
@@ -374,9 +387,9 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
374
387
  </if>
375
388
  Call the tool `Skill(skill: "ase:ase-task-implement", args: "<args/>")`
376
389
  to *implement* the freshly composed plan, bypassing `ase-task-edit`.
377
- </if>
390
+ </elseif>
378
391
 
379
- 2. <elseif condition="<head/> is equal `PREFLIGHT`">
392
+ 3. <elseif condition="<head/> is equal `PREFLIGHT`">
380
393
  Consume the head: set <getopt-option-next/> to the remaining
381
394
  tokens (joined back with `,`, or `none` if empty).
382
395
  <if condition="<getopt-option-next/> is not equal `none`">
@@ -386,7 +399,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
386
399
  to *preflight* the freshly composed plan, bypassing `ase-task-edit`.
387
400
  </elseif>
388
401
 
389
- 3. <else>
402
+ 4. <else>
390
403
  Hand off to `ase-task-edit`.
391
404
  <if condition="<head/> is equal `EDIT`">
392
405
  Consume the head: set <getopt-option-next/> to the remaining
@@ -96,6 +96,16 @@ Analyze documents for spelling, punctuation, or grammar errors
96
96
  "ase-docs-proofread", scope: "session:<ase-session-id/>")` tool
97
97
  from the `ase` MCP server. Do not output anything in this substep.
98
98
 
99
+ *Critical safety invariant*: the marker set here grants `Edit`
100
+ auto-approval and *MUST* be cleared again (substep 3 below)
101
+ *before* this skill yields control, *regardless* of how the
102
+ iteration in substep 2 ends - whether it completes normally,
103
+ is aborted early (e.g. an `Edit` failure, an unparseable value,
104
+ or any other unexpected condition), or is otherwise interrupted.
105
+ If you ever stop or bail out of substep 2 early, you *MUST*
106
+ still perform substep 3 first. Never leave this marker active
107
+ for a later, unrelated `Edit`.
108
+
99
109
  2. Iterate over all problems:
100
110
 
101
111
  <for items="<problems/>">
@@ -119,8 +129,44 @@ Analyze documents for spelling, punctuation, or grammar errors
119
129
 
120
130
  3. <if condition="<getopt-option-auto/> is not 'true'">
121
131
 
132
+ Determine the hunk *body* as an ordered list of lines, each
133
+ carrying a one-character prefix (` ` for context, `-` for
134
+ old-side, `+` for new-side). Build it by concatenating, in
135
+ order and *skipping any part that is empty*:
136
+
137
+ - one ` `-prefixed line for *each* line of <context-before/>
138
+ (if non-empty),
139
+ - one `-`-prefixed line for *each* line of <old-text/>
140
+ (if non-empty; split <old-text/> on newlines),
141
+ - one `+`-prefixed line for *each* line of <new-text/>
142
+ (if non-empty; split <new-text/> on newlines),
143
+ - one ` `-prefixed line for *each* line of <context-after/>
144
+ (if non-empty).
145
+
146
+ Set <hunk-body/> to those prefixed lines joined by newlines.
147
+
148
+ Set <old-count/> to the number of old-side hunk lines, i.e.,
149
+ the combined line count of <context-before/>, <old-text/>, and
150
+ <context-after/> (each empty part counts as `0`).
151
+ Set <new-count/> to the number of new-side hunk lines, i.e.,
152
+ the combined line count of <context-before/>, <new-text/>, and
153
+ <context-after/> (each empty part counts as `0`).
154
+
155
+ Set <old-start/> to the 1-based line number of the *first*
156
+ old-side hunk line: if <context-before/> is non-empty, that is
157
+ its line (one before <line/>); otherwise it is <line/> itself
158
+ (the first line of <old-text/>). For a hunk that *only inserts*
159
+ new lines (empty <old-text/> *and* empty context), set it to the
160
+ line *before* which the insertion happens, clamped to a minimum
161
+ of `0`, so a top-of-file insertion yields `@@ -0,0 ... @@`.
162
+ Set <new-start/> to the same value as <old-start/>, but clamped
163
+ to a minimum of `1` whenever <new-count/> is greater than `0`
164
+ (the corrected side then has a real first line).
165
+
122
166
  Render the proposed correction as a *unified diff* with *up to
123
- two* lines of context in a fenced block based on the following <template/>:
167
+ two* lines of context in a fenced block based on the following
168
+ <template/>, emitting <hunk-body/> verbatim (one already-prefixed
169
+ line per line, with no extra blank or space-only lines):
124
170
 
125
171
  <template>
126
172
 
@@ -130,26 +176,11 @@ Analyze documents for spelling, punctuation, or grammar errors
130
176
  --- <file/> (original)
131
177
  +++ <file/> (corrected)
132
178
  @@ -<old-start/>,<old-count/> +<new-start/>,<new-count/> @@
133
- <context-before/>
134
- -<old-text/>
135
- +<new-text/>
136
- <context-after/>
179
+ <hunk-body/>
137
180
  ```
138
181
 
139
182
  </template>
140
183
 
141
- Hints:
142
- - The <old-start/> is the line of the first hunk line, i.e.,
143
- the line of <context-before/> (one before <line/>).
144
- - The <new-start/> is the same as <old-start/> (the unchanged
145
- <context-before/> line shares the same start in both files).
146
- - The <old-count/> is the total number of old-side hunk lines, i.e.,
147
- the number of lines in <context-before/>, <old-text/>, and
148
- <context-after/> combined.
149
- - The <new-count/> is the total number of new-side hunk lines, i.e.,
150
- the number of lines in <context-before/>, <new-text/>, and
151
- <context-after/> combined.
152
-
153
184
  </if>
154
185
 
155
186
  4. <if condition="<getopt-option-auto/> is not 'true'">
@@ -137,8 +137,11 @@ Honor the following tenets throughout the brainstorming:
137
137
  4. Dispatch on the dialog <result/>:
138
138
 
139
139
  - If <result/> is `CANCEL`:
140
- Skip the remaining sub-steps of this iteration cycle and
141
- continue directly with sub-step 2 below (cancellation handling).
140
+ Skip the remaining sub-steps of this iteration cycle, break
141
+ out of the iteration cycle entirely, and continue directly
142
+ with the outer item `2.` (cancellation handling) that
143
+ immediately follows this iteration cycle `1.` within this
144
+ STEP 2.
142
145
 
143
146
  - If <result/> starts with `ERROR:`:
144
147
  Ask the user interactively, without a special tool, the
@@ -71,7 +71,7 @@ Procedure
71
71
  `width="<w/>"` and read the attribute `width` back.
72
72
  Record actual result for `xml-placeholders/nested-attr`.
73
73
 
74
- 6. *entity*: Evaluate the XML entity `&#x25CB;` and get the rendered
74
+ 6. *entity*: Evaluate the XML entity `&#x29BF;` and get the rendered
75
75
  Unicode character.
76
76
  Record actual result for `xml-placeholders/entity`.
77
77
 
@@ -152,8 +152,6 @@ Procedure
152
152
 
153
153
  Set <re-total/> to the number of regex probes above.
154
154
 
155
- </step>
156
-
157
155
  5. STEP 5: Probe Arithmetic
158
156
 
159
157
  Execute *all* of the following arithmetic probes (in the given
@@ -181,8 +179,6 @@ Procedure
181
179
 
182
180
  Set <arith-total/> to the number of arithmetic probes above.
183
181
 
184
- </step>
185
-
186
182
  6. STEP 6: Fetch Expected Values and Score
187
183
 
188
184
  Call the `ase_compat()` tool of the `ase` MCP server with an
@@ -209,8 +205,6 @@ Procedure
209
205
  - Set <re-pass/> to the number of `regex/*` probes that passed.
210
206
  - Set <arith-pass/> to the number of `arithmetic/*` probes that passed.
211
207
 
212
- </step>
213
-
214
208
  7. STEP 7: Compute and Report Compatibility
215
209
 
216
210
  Compute each category's *pass-rate* (a value in 0.0…1.0) by dividing
@@ -269,9 +263,7 @@ Procedure
269
263
  4. If <failures/> is not empty:
270
264
  Append to <verdict/> the suffix ` (failed: <failures/>)`.
271
265
 
272
- Output the final compatibility report with the following <template/>:
273
-
274
- <template>
266
+ Finally, output the compatibility report:
275
267
 
276
268
  **RESULTS**:
277
269
 
@@ -284,5 +276,3 @@ Procedure
284
276
  | **OVERALL** | | | **<overall-pct/>%** |
285
277
 
286
278
  **VERDICT**: <verdict/>
287
-
288
- </template>
@@ -274,9 +274,9 @@ explicitly requested by this procedure via outputs based on a <template/>!
274
274
 
275
275
  <ase-tpl-bullet-signal/> **CHANGE RISK REPORT**: Overall: **<band/>** (<aggregate/>/5)
276
276
 
277
- | Axis | Score | Findings |
278
- | ----------- | ---------- | ----------------------------------------------------------- |
279
- | **<axis/>** | <score/>/5 | ● **EVIDENCE**: <evidence/> ● **MITIGATION**: <mitigation/> |
277
+ | Axis | Score | Findings |
278
+ | ----------- | ---------- | ----------------------------------------------------------------------------------------------------- |
279
+ | **<axis/>** | <score/>/5 | ● **EVIDENCE**: <evidence/><if condition="axis score is `>= 4`"> ● **MITIGATION**: <mitigation/></if> |
280
280
  </template>
281
281
  </step>
282
282
 
@@ -81,15 +81,17 @@ multi-*criteria* decision matrix.
81
81
  - For each alternative <alternative-K/> (K=1-N), decide whether
82
82
  it is a genuine member of <class-of-alternatives/>. If any
83
83
  <alternative-K/> is *not* a member (i.e. the alternatives are not
84
- mutually comparable within a single class), let <alternative-J/>
85
- (J=1-P, P<=N) be the subset of non-member alternatives, output the
86
- following <template/> and *stop the entire flow* immediately without
87
- executing any further steps:
84
+ mutually comparable within a single class), collect the subset
85
+ of non-member alternatives into the space-separated list
86
+ <non-members/> (the <alternative-K/> for which the membership
87
+ decision was negative), output the following <template/> and
88
+ *stop the entire flow* immediately without executing any further
89
+ steps:
88
90
 
89
91
  <template>
90
92
  <ase-tpl-bullet-signal/> **ERROR: INCOMPARABLE ALTERNATIVES**: *<class-of-alternatives/>*
91
93
 
92
- <for items="<alternative-J/> [...]">
94
+ <for items="<non-members/>">
93
95
  ⚑ **<item/>** (*member of a different class*)
94
96
  </for>
95
97
  </template>
@@ -199,12 +201,18 @@ multi-*criteria* decision matrix.
199
201
  - Determine rating distance percentage <percentage/> between
200
202
  <alternative-K/> and <alternative-X/> from their *raw,
201
203
  unrounded* ratings as follows. If <rating-K/> is exactly zero,
202
- skip the division entirely and treat <percentage/> as if it
203
- were equal to <distance/> (so a true zero tie with <distance/>
204
- = 0 falls into the *MULTIPLE BEST* branch below, while a non-zero
205
- gap with zero best is routed by the magnitude of <distance/>
206
- through the same thresholds as <percentage/> otherwise). Do not
207
- output anything.
204
+ skip the division entirely (it is undefined against a zero
205
+ anchor) and classify directly by <distance/> instead of routing a
206
+ raw rating magnitude through the ratio thresholds below: if
207
+ <distance/> is also exactly zero, both best and second best rate
208
+ zero, which is a genuine tie, so set <percentage/> = 0 to fall
209
+ into the *MULTIPLE BEST* branch below; otherwise <distance/> > 0
210
+ means the second best rates strictly negative (since <rating-K/>
211
+ is the maximum), so there is a clear positive gap to a worse
212
+ runner-up and <alternative-K/> is an unambiguous winner, hence set
213
+ <percentage/> = 1 (a sentinel exceeding all small-distance
214
+ thresholds) to fall through to the plain *BEST ALTERNATIVE* branch.
215
+ Do not output anything.
208
216
 
209
217
  - Otherwise (<rating-K/> is non-zero), calculate: <percentage/> =
210
218
  <distance/> / abs(<rating-K/>). Do not output anything.
@@ -217,29 +225,29 @@ multi-*criteria* decision matrix.
217
225
  appear large; the all-negative regime is surfaced as a dedicated
218
226
  warning branch below. Do not output anything.
219
227
 
220
- - If <percentage/> is less than 0.01 (i.e. <distance/> is
221
- effectively zero relative to abs(<rating-K/>)), stop the flow after
222
- you output just the following <template/> and do not output anything
223
- else:
224
-
225
- <template>
226
- <ase-tpl-bullet-signal/> **ERROR**: ✘ *MULTIPLE BEST ALTERNATIVES FOUND*,
227
- ⚠ *Please give some hints on the criteria to ensure a single best alternative!*
228
- </template>
229
-
230
- - Otherwise, if <rating-K/> is less than zero (i.e. all alternatives
228
+ - If <rating-K/> is less than zero (i.e. all alternatives
231
229
  rate negatively and the "best" is merely the least-bad), stop the
232
230
  flow after you output just the following <template/> and do not
233
231
  output anything else. This all-negative check is evaluated *before*
234
- the small-distance check below, so that an all-negative alternative
232
+ the small-distance checks below, so that an all-negative alternative
235
233
  set with a small winning gap surfaces the all-negative warning rather
236
- than being masked by the small-distance branch:
234
+ than being masked by the multiple-best or small-distance branches:
237
235
 
238
236
  <template>
239
237
  <ase-tpl-bullet-signal/> **BEST ALTERNATIVE**: ⚑ **<alternative-K/>**
240
238
  ⚠ *ATTENTION: all alternatives rate negatively; this is the least-bad choice, not a strong winner!*
241
239
  </template>
242
240
 
241
+ - Otherwise, if <percentage/> is less than 0.01 (i.e. <distance/> is
242
+ effectively zero relative to abs(<rating-K/>)), stop the flow after
243
+ you output just the following <template/> and do not output anything
244
+ else:
245
+
246
+ <template>
247
+ <ase-tpl-bullet-signal/> **ERROR**: ✘ *MULTIPLE BEST ALTERNATIVES FOUND*,
248
+ ⚠ *Please give some hints on the criteria to ensure a single best alternative!*
249
+ </template>
250
+
243
251
  - Otherwise, if <percentage/> is less than 0.10, stop the flow after
244
252
  you output just the following <template/> and do not output anything
245
253
  else: