@rse/ase 0.9.50 → 0.9.52

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 (75) hide show
  1. package/dst/ase-hook.js +9 -13
  2. package/dst/ase-statusline.js +30 -4
  3. package/dst/ase-task.js +7 -2
  4. package/package.json +7 -7
  5. package/plugin/.claude-plugin/plugin.json +1 -1
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/.github/plugin/plugin.json +1 -1
  8. package/plugin/agents/ase-code-lint.md +21 -1
  9. package/plugin/agents/ase-meta-proximity.md +133 -0
  10. package/plugin/etc/stx.conf +2 -2
  11. package/plugin/meta/ase-common-dissect.md +110 -0
  12. package/plugin/meta/ase-common-task.md +5 -3
  13. package/plugin/meta/ase-control.md +53 -0
  14. package/plugin/meta/ase-format-task.md +6 -0
  15. package/plugin/meta/ase-skill.md +8 -8
  16. package/plugin/package.json +2 -2
  17. package/plugin/skills/ase-arch-analyze/SKILL.md +23 -12
  18. package/plugin/skills/ase-arch-analyze/help.md +16 -0
  19. package/plugin/skills/ase-arch-discover/SKILL.md +2 -2
  20. package/plugin/skills/ase-code-analyze/SKILL.md +33 -16
  21. package/plugin/skills/ase-code-analyze/help.md +19 -2
  22. package/plugin/skills/ase-code-craft/SKILL.md +2 -2
  23. package/plugin/skills/ase-code-dissect/SKILL.md +380 -0
  24. package/plugin/skills/ase-code-dissect/help.md +121 -0
  25. package/plugin/skills/ase-code-explain/SKILL.md +2 -2
  26. package/plugin/skills/ase-code-insight/SKILL.md +2 -2
  27. package/plugin/skills/ase-code-lint/SKILL.md +43 -12
  28. package/plugin/skills/ase-code-lint/help.md +43 -1
  29. package/plugin/skills/ase-code-refactor/SKILL.md +2 -2
  30. package/plugin/skills/ase-code-resolve/SKILL.md +2 -2
  31. package/plugin/skills/ase-docs-distill/SKILL.md +2 -2
  32. package/plugin/skills/ase-docs-proofread/SKILL.md +2 -2
  33. package/plugin/skills/ase-help-intent/SKILL.md +2 -2
  34. package/plugin/skills/ase-help-skill/SKILL.md +2 -2
  35. package/plugin/skills/ase-help-skill/catalog.md +4 -0
  36. package/plugin/skills/ase-meta-brainstorm/SKILL.md +2 -2
  37. package/plugin/skills/ase-meta-changelog/SKILL.md +2 -2
  38. package/plugin/skills/ase-meta-chat/SKILL.md +2 -2
  39. package/plugin/skills/ase-meta-commit/SKILL.md +2 -2
  40. package/plugin/skills/ase-meta-config/SKILL.md +2 -2
  41. package/plugin/skills/ase-meta-diaboli/SKILL.md +2 -2
  42. package/plugin/skills/ase-meta-diff/SKILL.md +2 -2
  43. package/plugin/skills/ase-meta-eli5/SKILL.md +2 -2
  44. package/plugin/skills/ase-meta-eli5/help.md +1 -1
  45. package/plugin/skills/ase-meta-evaluate/SKILL.md +2 -2
  46. package/plugin/skills/ase-meta-proximity/SKILL.md +51 -92
  47. package/plugin/skills/ase-meta-proximity/help.md +11 -10
  48. package/plugin/skills/ase-meta-quorum/SKILL.md +2 -2
  49. package/plugin/skills/ase-meta-quotes/SKILL.md +214 -0
  50. package/plugin/skills/ase-meta-quotes/help.md +109 -0
  51. package/plugin/skills/ase-meta-review/SKILL.md +2 -2
  52. package/plugin/skills/ase-meta-review/help.md +4 -3
  53. package/plugin/skills/ase-meta-search/SKILL.md +2 -2
  54. package/plugin/skills/ase-meta-steelman/SKILL.md +2 -2
  55. package/plugin/skills/ase-meta-why/SKILL.md +2 -2
  56. package/plugin/skills/ase-meta-workflow/SKILL.md +378 -0
  57. package/plugin/skills/ase-meta-workflow/help.md +117 -0
  58. package/plugin/skills/ase-meta-workflow/sample.md +70 -0
  59. package/plugin/skills/ase-meta-workflow/workflow.txt +97 -0
  60. package/plugin/skills/ase-sync-export/SKILL.md +2 -2
  61. package/plugin/skills/ase-sync-import/SKILL.md +2 -2
  62. package/plugin/skills/ase-sync-reconcile/SKILL.md +2 -2
  63. package/plugin/skills/ase-task-condense/SKILL.md +26 -6
  64. package/plugin/skills/ase-task-delete/SKILL.md +2 -2
  65. package/plugin/skills/ase-task-dissect/SKILL.md +299 -0
  66. package/plugin/skills/ase-task-dissect/help.md +114 -0
  67. package/plugin/skills/ase-task-edit/SKILL.md +6 -4
  68. package/plugin/skills/ase-task-grill/SKILL.md +6 -4
  69. package/plugin/skills/ase-task-id/SKILL.md +2 -2
  70. package/plugin/skills/ase-task-implement/SKILL.md +2 -2
  71. package/plugin/skills/ase-task-list/SKILL.md +2 -2
  72. package/plugin/skills/ase-task-preflight/SKILL.md +2 -2
  73. package/plugin/skills/ase-task-reboot/SKILL.md +12 -6
  74. package/plugin/skills/ase-task-rename/SKILL.md +2 -2
  75. package/plugin/skills/ase-task-view/SKILL.md +2 -2
@@ -102,11 +102,13 @@ allowed-tools:
102
102
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
103
103
  @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
104
104
 
105
- <skill name="ase-arch-analyze">
105
+ <purpose name="ase-arch-analyze">
106
106
  Review Software Architecture
107
- </skill>
107
+ </purpose>
108
108
 
109
- <expand name="getopt" arg1="ase-arch-analyze">
109
+ <expand name="getopt"
110
+ arg1="ase-arch-analyze"
111
+ arg2="--prefix|-P=">
110
112
  $ARGUMENTS
111
113
  </expand>
112
114
 
@@ -343,6 +345,14 @@ interface quality, quality attributes, and architecture governance.
343
345
  </step>
344
346
 
345
347
  3. <step id="STEP 3: Reconcile and Show Results">
348
+ Before reporting, determine the *finding id prefix* <id-prefix/>:
349
+ set <id-prefix><getopt-option-prefix/>-</id-prefix> if
350
+ <getopt-option-prefix/> is *not* empty, and set <id-prefix></id-prefix>
351
+ (set to empty) otherwise. Every reported `PROBLEM` and `TRADEOFF` id
352
+ and every persisted key below carries this <id-prefix/>, so that
353
+ analyses run under *distinct* prefixes occupy *distinct* id
354
+ namespaces and hence do not overwrite each other.
355
+
346
356
  Before reporting, classify every finding into one of three
347
357
  categories:
348
358
 
@@ -378,7 +388,7 @@ interface quality, quality attributes, and architecture governance.
378
388
  Report each unpaired finding with the following <template/>:
379
389
 
380
390
  <template>
381
- <ase-tpl-bullet-signal/> **PROBLEM** P<n/> (Severity: <severity/>, Aspect: <aspect-id/>): **<title/>**
391
+ <ase-tpl-bullet-signal/> **PROBLEM** <id-prefix/>P<n/> (Severity: <severity/>, Aspect: <aspect-id/>): **<title/>**
382
392
 
383
393
  <description/>
384
394
  </template>
@@ -386,7 +396,7 @@ interface quality, quality attributes, and architecture governance.
386
396
  Report each paired or clustered finding with the following <template/>:
387
397
 
388
398
  <template>
389
- <ase-tpl-bullet-normal/> **TRADEOFF** T<n/> (Severity: <severity/>): **<title/>**
399
+ <ase-tpl-bullet-normal/> **TRADEOFF** <id-prefix/>T<n/> (Severity: <severity/>): **<title/>**
390
400
 
391
401
  - *Focal aspect*: <focal-aspect/> - <focal-state/>
392
402
  - *In tension with*: <partner-list/>
@@ -458,12 +468,13 @@ interface quality, quality attributes, and architecture governance.
458
468
  - *Additionally*, persist all reported findings in a *single*
459
469
  `ase_kv_batch` call to the `ase` MCP server with `transactional`
460
470
  set to `true`. The `commands` parameter array of this call
461
- starts with one `{ command: "clear", prefix: "ase-issue-" }`
462
- entry (which removes only the previously persisted `ase-issue-*`
463
- keys, leaving any unrelated keys in the shared store intact),
464
- followed by one `{ command: "set", key: "ase-issue-P<n/>", val:
465
- "<title/>: <description/>" }` entry per reported PROBLEM and one
466
- `{ command: "set", key: "ase-issue-T<n/>", val: "<title/>:
471
+ starts with one `{ command: "clear", prefix: "ase-issue-<id-prefix/>" }`
472
+ entry (which removes only the previously persisted
473
+ `ase-issue-<id-prefix/>*` keys, leaving any unrelated keys in the
474
+ shared store intact),
475
+ followed by one `{ command: "set", key: "ase-issue-<id-prefix/>P<n/>",
476
+ val: "<title/>: <description/>" }` entry per reported PROBLEM and one
477
+ `{ command: "set", key: "ase-issue-<id-prefix/>T<n/>", val: "<title/>:
467
478
  <description/>" }` entry per reported TRADEOFF.
468
479
 
469
480
  Finally, give a final hint by expanding the following (which,
@@ -471,7 +482,7 @@ interface quality, quality attributes, and architecture governance.
471
482
  nothing and hence emit no output at all):
472
483
 
473
484
  <ase-tpl-hint level="minimal">
474
- For deeper analysis, suggestions on solution approaches and then final source code changes, use `/ase-code-resolve P{n}` or `/ase-code-resolve T{n}` in the same or even a different session.
485
+ For deeper analysis, suggestions on solution approaches and then final source code changes, use `/ase-code-resolve <id-prefix/>P{n}` or `/ase-code-resolve <id-prefix/>T{n}` in the same or even a different session.
475
486
  </ase-tpl-hint>
476
487
 
477
488
  </step>
@@ -7,6 +7,7 @@
7
7
 
8
8
  `ase-arch-analyze`
9
9
  [`--help`|`-h`]
10
+ [`--prefix`|`-P` *prefix*]
10
11
  *source-reference*
11
12
 
12
13
  ## DESCRIPTION
@@ -24,6 +25,15 @@ governance, and package cohesion), renders a high-level architecture
24
25
  diagram, and reports findings as either `PROBLEM` or `TRADEOFF` entries
25
26
  based on a built-in tension matrix.
26
27
 
28
+ The `--prefix`|`-P` *prefix* option prefixes every reported finding id
29
+ with *prefix* and a hyphen, so `P1` becomes `<prefix>-P1` and `T1`
30
+ becomes `<prefix>-T1`, with the persisted keys becoming
31
+ `ase-issue-<prefix>-P1` and `ase-issue-<prefix>-T1` accordingly. The
32
+ purge of stale results is narrowed to the same namespace, so analyses
33
+ run under *distinct* prefixes coexist instead of overwriting each other.
34
+ Without the option (the default), ids stay unprefixed and the purge
35
+ covers the *entire* `ase-issue-*` space, including any prefixed results.
36
+
27
37
  ## ARGUMENTS
28
38
 
29
39
  *source-reference*:
@@ -44,6 +54,12 @@ Analyze a specific module:
44
54
  ❯ /ase-arch-analyze src/core
45
55
  ```
46
56
 
57
+ Analyze a module under an own id namespace, yielding `core-P1`, `core-T1`, ...:
58
+
59
+ ```text
60
+ ❯ /ase-arch-analyze --prefix core src/core
61
+ ```
62
+
47
63
  ## SEE ALSO
48
64
 
49
65
  [`ase-arch-discover`](../ase-arch-discover/help.md), [`ase-code-analyze`](../ase-code-analyze/help.md), [`ase-code-resolve`](../ase-code-resolve/help.md),
@@ -19,9 +19,9 @@ allowed-tools:
19
19
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
20
20
  @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
21
21
 
22
- <skill name="ase-arch-discover">
22
+ <purpose name="ase-arch-discover">
23
23
  Discover Components
24
- </skill>
24
+ </purpose>
25
25
 
26
26
  <expand name="getopt"
27
27
  arg1="ase-arch-discover"
@@ -17,13 +17,13 @@ allowed-tools:
17
17
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
18
18
  @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
19
19
 
20
- <skill name="ase-code-analyze">
20
+ <purpose name="ase-code-analyze">
21
21
  Analyze Source Code
22
- </skill>
22
+ </purpose>
23
23
 
24
24
  <expand name="getopt"
25
25
  arg1="ase-code-analyze"
26
- arg2="--performance|-p --security|-s --severity|-S=(LOW|MEDIUM|HIGH)">
26
+ arg2="--performance|-p --security|-s --severity|-S=(LOW|MEDIUM|HIGH) --prefix|-P=">
27
27
  $ARGUMENTS
28
28
  </expand>
29
29
 
@@ -123,6 +123,14 @@ problems in *performance* and *efficiency*, or problems in *security*.
123
123
 
124
124
  3. <step id="STEP 3: Show Results">
125
125
 
126
+ Before reporting, determine the *problem id prefix* <id-prefix/>:
127
+ set <id-prefix><getopt-option-prefix/>-</id-prefix> if
128
+ <getopt-option-prefix/> is *not* empty, and set <id-prefix></id-prefix>
129
+ (set to empty) otherwise. Every reported problem id and every
130
+ persisted key below carries this <id-prefix/>, so that analyses run
131
+ under *distinct* prefixes occupy *distinct* id namespaces and hence
132
+ do not overwrite each other.
133
+
126
134
  Before reporting, determine the *effective severity floor* <floor/>:
127
135
  define the ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
128
136
  <floor><getopt-option-severity/></floor> (default `LOW`), and - if
@@ -137,13 +145,21 @@ problems in *performance* and *efficiency*, or problems in *security*.
137
145
  persisted). With the default floor `LOW`, all problems are kept.
138
146
  `ACCEPTED` problems are *never* dropped.
139
147
 
140
- Then renumber the surviving problems contiguously as `P<n/>` with
141
- <n/> = 1, 2, ... in the original ordering. If *all* problems are
142
- dropped, skip the per-problem report but still purge any stale
148
+ Then sort the surviving problems in <problems/> by their `severity`
149
+ field from highest to lowest in the fixed order `HIGH`, `MEDIUM`,
150
+ `LOW`, `ACCEPTED`, so the reporting starts with the most severe
151
+ problem. Within the same severity, keep the `file`/`line` order
152
+ established in STEP 2.
153
+
154
+ Then renumber the surviving problems contiguously as `<id-prefix/>P<n/>`
155
+ with <n/> = 1, 2, ... in that sorted ordering, so `<id-prefix/>P1` is
156
+ the most severe problem and the persisted `ase-issue-<id-prefix/>P<n/>`
157
+ keys follow the reported sequence. If *all* problems are dropped, skip
158
+ the per-problem report but still purge any stale
143
159
  persisted problems with a *single* `ase_kv_batch` call to the `ase`
144
160
  MCP server with `transactional` set to `true` and a `commands`
145
161
  parameter array holding exactly one `{ command: "clear", prefix:
146
- "ase-issue-" }` entry,
162
+ "ase-issue-<id-prefix/>" }` entry,
147
163
  and still emit the final hint <template/> below.
148
164
 
149
165
  In this STEP 3, for *EVERY* surviving problem in <problems/>, set
@@ -157,7 +173,7 @@ problems in *performance* and *efficiency*, or problems in *security*.
157
173
 
158
174
  <template>
159
175
 
160
- <ase-tpl-bullet-signal/> **PROBLEM** (Severity: **<severity/>**): **P<n/>**: **<title/>**
176
+ <ase-tpl-bullet-signal/> **PROBLEM** (Severity: **<severity/>**): **<id-prefix/>P<n/>**: **<title/>**
161
177
 
162
178
  <description/>
163
179
 
@@ -172,7 +188,7 @@ problems in *performance* and *efficiency*, or problems in *security*.
172
188
 
173
189
  <template>
174
190
 
175
- <ase-tpl-bullet-signal/> **PROBLEM** (Severity: **<severity/>**): **P<n/>**: **<title/>**
191
+ <ase-tpl-bullet-signal/> **PROBLEM** (Severity: **<severity/>**): **<id-prefix/>P<n/>**: **<title/>**
176
192
 
177
193
  <description/>
178
194
 
@@ -185,23 +201,24 @@ problems in *performance* and *efficiency*, or problems in *security*.
185
201
  - For the final results, do *not* output anything else, especially do
186
202
  *not* give any further explanations or information.
187
203
 
188
- - Uniquely identify the problems with `P<n/>` where <n/> is 1, 2, ...
204
+ - Uniquely identify the problems with `<id-prefix/>P<n/>` where <n/> is 1, 2, ...
189
205
 
190
206
  - *Additionally*, persist all reported problems in a *single*
191
207
  `ase_kv_batch` call to the `ase` MCP server with `transactional`
192
208
  set to `true`. The `commands` parameter array of this call
193
- starts with one `{ command: "clear", prefix: "ase-issue-" }`
194
- entry (which removes only the previously persisted `ase-issue-*`
195
- keys, leaving any unrelated keys in the shared store intact),
196
- followed by one `{ command: "set", key: "ase-issue-P<n/>", val:
197
- "<title/>: <description/>" }` entry per reported problem.
209
+ starts with one `{ command: "clear", prefix: "ase-issue-<id-prefix/>" }`
210
+ entry (which removes only the previously persisted
211
+ `ase-issue-<id-prefix/>*` keys, leaving any unrelated keys in the
212
+ shared store intact),
213
+ followed by one `{ command: "set", key: "ase-issue-<id-prefix/>P<n/>",
214
+ val: "<title/>: <description/>" }` entry per reported problem.
198
215
 
199
216
  Finally, give a final hint by expanding the following (which,
200
217
  depending on the configured <ase-guidance-level/>, may expand into
201
218
  nothing and hence emit no output at all):
202
219
 
203
220
  <ase-tpl-hint level="minimal">
204
- For deeper analysis, suggestions on solution approaches and then final problem resolution, use `/ase-code-resolve P{n}` in the same or even a different session.
221
+ For deeper analysis, suggestions on solution approaches and then final problem resolution, use `/ase-code-resolve <id-prefix/>P{n}` in the same or even a different session.
205
222
  </ase-tpl-hint>
206
223
 
207
224
  You *MUST* not output anything else in this STEP 3,
@@ -10,6 +10,7 @@
10
10
  [`--performance`|`-p`]
11
11
  [`--security`|`-s`]
12
12
  [`--severity`|`-S`=(`LOW`|`MEDIUM`|`HIGH`)]
13
+ [`--prefix`|`-P` *prefix*]
13
14
  *source-reference*
14
15
 
15
16
  ## DESCRIPTION
@@ -33,8 +34,18 @@ The `--severity`|`-S`=(`LOW`|`MEDIUM`|`HIGH`) option sets a *severity
33
34
  floor* (default `LOW`): problems below the chosen threshold are silently
34
35
  suppressed (neither reported nor persisted), ordered `LOW` < `MEDIUM` <
35
36
  `HIGH`. The default `LOW` keeps all problems; `ACCEPTED` problems are
36
- never suppressed. Surviving problems are renumbered contiguously as
37
- `P<n>`.
37
+ never suppressed. Surviving problems are reported in *descending
38
+ severity* order `HIGH`, `MEDIUM`, `LOW`, `ACCEPTED` - keeping the
39
+ `file`/`line` order within the same severity - and are renumbered
40
+ contiguously as `P<n>`, so `P1` is the most severe problem.
41
+
42
+ The `--prefix`|`-P` *prefix* option prefixes every reported problem id
43
+ with *prefix* and a hyphen, so `P1` becomes `<prefix>-P1` and its
44
+ persisted key becomes `ase-issue-<prefix>-P1`. The purge of stale
45
+ results is narrowed to the same namespace accordingly, so analyses run
46
+ under *distinct* prefixes coexist instead of overwriting each other.
47
+ Without the option (the default), ids stay unprefixed and the purge
48
+ covers the *entire* `ase-issue-*` space, including any prefixed results.
38
49
 
39
50
  The skill investigates the code base silently, reports each detected
40
51
  problem as a `PROBLEM` entry with severity (`LOW`, `MEDIUM`, `HIGH`) and
@@ -81,6 +92,12 @@ Analyze a directory, reporting only `MEDIUM` and `HIGH` problems:
81
92
  ❯ /ase-code-analyze -S MEDIUM src/handlers/
82
93
  ```
83
94
 
95
+ Analyze a directory under an own id namespace, yielding `auth-P1`, `auth-P2`, ...:
96
+
97
+ ```text
98
+ ❯ /ase-code-analyze --prefix auth src/auth/
99
+ ```
100
+
84
101
  ## SEE ALSO
85
102
 
86
103
  [`ase-code-resolve`](../ase-code-resolve/help.md), [`ase-code-refactor`](../ase-code-refactor/help.md), [`ase-code-lint`](../ase-code-lint/help.md),
@@ -17,9 +17,9 @@ allowed-tools:
17
17
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
18
18
  @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
19
19
 
20
- <skill name="ase-code-craft">
20
+ <purpose name="ase-code-craft">
21
21
  Craft Source Code
22
- </skill>
22
+ </purpose>
23
23
 
24
24
  <expand name="getopt"
25
25
  arg1="ase-code-craft"
@@ -0,0 +1,380 @@
1
+ ---
2
+ name: ase-code-dissect
3
+ argument-hint: "[--help|-h] [--max-parts|-m <count>] [--staged|-s] [--dry|-d] [--force|-f] [<dissect-hint>]"
4
+ description: >
5
+ Dissect the current Git change set, treated as an epic, domain-wise
6
+ and logically into cohesive parts and materialize each part in its
7
+ own dedicated Git WorkTree. Use when the user calls to "dissect",
8
+ "split", "break up", or "decompose" a large change set into atomic,
9
+ separately committable parts.
10
+ user-invocable: true
11
+ disable-model-invocation: false
12
+ effort: xhigh
13
+ allowed-tools:
14
+ - "Bash(git *)"
15
+ - "Bash(rm -f *)"
16
+ - "Write"
17
+ - "Read"
18
+ - "Edit"
19
+ ---
20
+
21
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
22
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
23
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
24
+
25
+ <purpose name="ase-code-dissect">
26
+ Dissect a Change Set
27
+ </purpose>
28
+
29
+ <expand name="getopt"
30
+ arg1="ase-code-dissect"
31
+ arg2="--max-parts|-m=8 --staged|-s --dry|-d --force|-f">
32
+ $ARGUMENTS
33
+ </expand>
34
+
35
+ <objective>
36
+ *Dissect* the current Git change set, treated as an *epic*, domain-wise
37
+ and logically into *cohesive parts*, and materialize every part in its
38
+ own dedicated *Git WorkTree*, so each part can be reviewed and
39
+ committed *atomically* and *independently*.
40
+ </objective>
41
+
42
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-common-dissect.md
43
+
44
+ Procedure
45
+ ---------
46
+
47
+ <flow>
48
+
49
+ 1. <step id="STEP 1: Determine Change Set and Hint">
50
+
51
+ 1. Determine the *dissection hint*: set
52
+ <dissect-hint><getopt-arguments/></dissect-hint>, with any
53
+ leading and trailing whitespace stripped. Additionally, inherit
54
+ the always existing <ase-project-id/> from the current context,
55
+ as it names the worktrees and branches of all derived parts.
56
+
57
+ <if condition="<dissect-hint/> is not empty">
58
+ Only output the following <template/>:
59
+
60
+ <template>
61
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ⇌ hint: **<dissect-hint/>**
62
+ </template>
63
+ </if>
64
+ <else>
65
+ No dissection hint was given, so the parts are derived from the
66
+ change set alone. Do not output anything.
67
+ </else>
68
+
69
+ 2. Determine the *repository root* by running the corresponding
70
+ command (taken exactly as given) and capturing its output into
71
+ <repo-root/>:
72
+
73
+ `git rev-parse --show-toplevel`
74
+
75
+ 3. Determine the *diff details* and the *diff statistics* by
76
+ running the corresponding commands (taken exactly as given) and
77
+ capturing their full outputs into <diff/> and <stat/>:
78
+
79
+ <if condition="<getopt-option-staged/> is equal `true`">
80
+ `git diff --cached HEAD`
81
+
82
+ `git diff --cached --numstat HEAD`
83
+ </if>
84
+ <else>
85
+ `git diff`
86
+
87
+ `git diff --numstat`
88
+ </else>
89
+
90
+ 4. <if condition="<getopt-option-staged/> is not equal `true`">
91
+ Additionally, *fold in the untracked files* -- they are part of
92
+ the working copy change set, but carry no diff of their own.
93
+ Determine them *read-only* by running the corresponding command
94
+ (taken exactly as given):
95
+
96
+ `git -C "<repo-root/>" ls-files --others --exclude-standard`
97
+
98
+ *Skip* every listed entry below the `.ase/` directory -- it
99
+ carries *ASE*'s own state and the worktrees created by this very
100
+ skill, and hence is never part of the user's change set.
101
+
102
+ Then, for *every* remaining listed file, capture its creation
103
+ diff by running the corresponding command (taken exactly as
104
+ given) and *append* its output to <diff/>:
105
+
106
+ `git -C "<repo-root/>" diff --no-index --binary /dev/null "<file/>"`
107
+
108
+ This command intentionally exits with a non-zero status,
109
+ because the two compared paths differ; treat this exit status
110
+ as *success*, not as an error. Judge the *outcome* by the
111
+ *output* instead: a run which emits *no* diff on standard output
112
+ but an `error:` or `fatal:` message (e.g. the entry is a *nested*
113
+ Git repository, which `git ls-files` reports as a directory) is a
114
+ *real* failure -- append nothing for that entry and only output
115
+ the following <template/>, then continue with the next file:
116
+
117
+ <template>
118
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ⊘ untracked: `<file/>`, ▶ status: **not foldable into the change set**
119
+ </template>
120
+ </if>
121
+ <else>
122
+ Untracked files are *not* folded in under `--staged`/`-s`,
123
+ because they are by definition *not* part of the Git index. Do
124
+ not output anything.
125
+ </else>
126
+
127
+ 5. <if condition="<diff/> is empty">
128
+ Only output the following <template/> and then *STOP* immediately:
129
+
130
+ <template>
131
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ▶ status: **no changes to dissect**
132
+ </template>
133
+ </if>
134
+
135
+ </step>
136
+
137
+ 2. <step id="STEP 2: Dissect Change Set">
138
+
139
+ 1. *Derive the parts* of the epic:
140
+
141
+ <expand
142
+ name="dissect-derive"
143
+ arg1="ase-code-dissect"
144
+ arg2="<dissect-hint/>"
145
+ arg3="<ase-project-id/>"
146
+ >
147
+ the individual hunks of the captured <diff/>, weighted by the
148
+ line counts of <stat/> and -- for the folded-in untracked files,
149
+ which carry no <stat/> entry -- by their own diff line counts
150
+ </expand>
151
+
152
+ Additionally, try to keep *all* hunks of *one* file in the
153
+ *same* part, and split a file's hunks across parts *only* when
154
+ they are genuinely unrelated -- this keeps the per-part patches
155
+ applicable.
156
+
157
+ A *single* hunk is *atomic* here, so rule 3's splitting
158
+ permission does *not* apply to it: you *MUST NOT* break a hunk
159
+ into sub-hunks, because this would require re-computing its `@@`
160
+ header and hence destroy the byte-exactness the per-part
161
+ <patch/> depends on.
162
+
163
+ 2. *Report the parts*:
164
+
165
+ <expand name="dissect-report" arg1="<ase-project-id/>"></expand>
166
+
167
+ </step>
168
+
169
+ 3. <step id="STEP 3: Detect Target Collisions"
170
+ condition="<getopt-option-dry/> is not equal `true`">
171
+
172
+ 1. Determine the *existing worktrees* and *existing branches* by
173
+ running the corresponding commands (taken exactly as given) and
174
+ capturing their outputs:
175
+
176
+ `git worktree list --porcelain`
177
+
178
+ `git branch --list`
179
+
180
+ 2. Set <collisions/> to all <part-id/> of <parts/> for which either
181
+ a worktree directory `<repo-root/>/.ase/worktree/<part-id/>` or
182
+ a branch `<part-id/>` already exists.
183
+
184
+ 3. <if condition="<collisions/> is not empty AND <getopt-option-force/> is not equal `true`">
185
+ Only output the following <template/> -- with <collisions/>
186
+ rendered as a comma-separated list of code spans -- and then
187
+ immediately *STOP* processing the entire current skill, leaving
188
+ *all* existing worktrees and branches untouched:
189
+
190
+ <template>
191
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ⊘ collisions: <collisions/>
192
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ✪ dissection: **<n/>** parts, ▶ status: **targets exist**
193
+ </template>
194
+
195
+ Directly *after* this <template/>, and *before* stopping, give
196
+ the corrective hint by expanding the following (which, depending
197
+ on the configured <ase-guidance-level/>, may expand into nothing
198
+ and hence emit no output at all):
199
+
200
+ <ase-tpl-hint level="minimal">
201
+ Re-run `/ase-code-dissect --force` to remove and re-create the colliding worktrees and branches.
202
+ </ase-tpl-hint>
203
+ </if>
204
+
205
+ 4. <if condition="<collisions/> is not empty AND <getopt-option-force/> is equal `true`">
206
+ *Remove* every colliding target by running the corresponding
207
+ commands (taken exactly as given) per colliding <part-id/>, and
208
+ silently ignore the failure of an individual command when the
209
+ corresponding worktree or branch does not exist:
210
+
211
+ `git worktree remove --force "<repo-root/>/.ase/worktree/<part-id/>"`
212
+
213
+ `git worktree prune`
214
+
215
+ `git branch -D <part-id/>`
216
+ </if>
217
+
218
+ </step>
219
+
220
+ 4. <step id="STEP 4: Materialize WorkTrees"
221
+ condition="<getopt-option-dry/> is not equal `true`">
222
+
223
+ You *MUST* *NEVER* mutate the *original* working copy in this step:
224
+ do *not* modify, stage, stash, revert, or commit anything outside of
225
+ the freshly created worktrees.
226
+
227
+ 1. Set <tmp-dir/> to the value of the `TMPDIR` environment variable
228
+ if it is known in the current session context, and to `/tmp`
229
+ otherwise. Do not output anything.
230
+
231
+ 2. For *every* part in <parts/>, in their derived order:
232
+
233
+ 1. Assemble <patch/> from the *verbatim* subset of <diff/>
234
+ assigned to this part: keep the complete `diff --git` file
235
+ headers and the complete `@@` hunk headers of the assigned
236
+ hunks, and change *nothing* inside them.
237
+
238
+ The captured <diff/> is *byte-exact* input and <patch/> stays
239
+ *byte-exact*, too, because `git apply` rejects even the
240
+ smallest deviation. You *MUST* therefore *NEVER* re-wrap a
241
+ line, re-indent a line, normalize or strip trailing
242
+ whitespace, drop the leading context/`+`/`-` marker column,
243
+ re-encode a character, or omit the trailing newline -- and
244
+ you *MUST* *NEVER* re-render any part of the diff as
245
+ Markdown, so no bullet marker and no inline code span is ever
246
+ introduced into <patch/>.
247
+
248
+ 2. Use the `Write` tool to write <patch/> to the patch file
249
+ `<tmp-dir/>/ase-dissect-<part-id/>.patch`.
250
+
251
+ 3. Create the worktree by running the corresponding command
252
+ (taken exactly as given), which creates the directory
253
+ *and* -- named after its last path component -- the branch
254
+ <part-id/> from `HEAD`. The `.ase` directory is usually
255
+ git-ignored, so the worktree itself never shows up as a
256
+ change:
257
+
258
+ `git worktree add "<repo-root/>/.ase/worktree/<part-id/>"`
259
+
260
+ <if condition="this command fails">
261
+ Only output the following <template/>, then *continue* with
262
+ the *next* part -- a single failing part *never* aborts the
263
+ remaining ones:
264
+
265
+ <template>
266
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ◉ part: **<part-id/>**, ▶ status: **worktree failed to create**
267
+ </template>
268
+ </if>
269
+
270
+ 4. Apply the patch *inside* the freshly created worktree by
271
+ running the corresponding command (taken exactly as given):
272
+
273
+ `git -C "<repo-root/>/.ase/worktree/<part-id/>" apply --whitespace=nowarn "<tmp-dir/>/ase-dissect-<part-id/>.patch"`
274
+
275
+ <if condition="this command fails">
276
+ Only output the following <template/>, then *continue* with
277
+ the *next* part -- a single failing part *never* aborts the
278
+ remaining ones:
279
+
280
+ <template>
281
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ◉ part: **<part-id/>**, ▶ status: **patch failed to apply**
282
+ </template>
283
+ </if>
284
+
285
+ 5. <if condition="a `CHANGELOG.md` file exists in the created worktree">
286
+ Add *one* new entry to the *first* (most recent) section of
287
+ that `CHANGELOG.md` *inside the worktree*, summarizing
288
+ *this part's* change set only, and strictly aligned with the
289
+ established style and conventions of the project (usually
290
+ `- <change-type/> [<artifact-kind/>]: <summary/>`).
291
+
292
+ The *existing* `CHANGELOG.md` is *changed*, never replaced:
293
+ you *MUST* use the `Read` tool to read it and the `Edit` tool
294
+ to insert the single new entry *in place*, and you *MUST*
295
+ *NEVER* use the `Write` tool on it, as this would drop the
296
+ entire remaining change history.
297
+
298
+ <if condition="the patch of this part already added an entry to that `CHANGELOG.md`">
299
+ The part's own change set already carries its `CHANGELOG.md`
300
+ entry, so you *MUST* *NOT* add a second one. Keep the entry
301
+ which came with the patch and, if it mentions changes which
302
+ landed in *other* parts, reduce it to *this* part's change
303
+ set only.
304
+ </if>
305
+ </if>
306
+ <else>
307
+ The project keeps no `CHANGELOG.md`, so nothing is added and
308
+ no `CHANGELOG.md` is created. Do not output anything.
309
+ </else>
310
+
311
+ 6. Leave the worktree *uncommitted*: do *not* run `git add` and
312
+ do *not* run `git commit`, so the user keeps full control
313
+ over the final commit of every part.
314
+
315
+ 7. Only output the following <template/>:
316
+
317
+ <template>
318
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ◉ part: **<part-id/>**, ▶ status: **worktree created**
319
+ </template>
320
+
321
+ 3. *Clean up* the temporary patch files by running the
322
+ corresponding command (taken exactly as given) once per
323
+ <part-id/> of the *successfully* materialized <parts/>, and
324
+ silently ignore the failure of an individual command when the
325
+ corresponding patch file does not exist:
326
+
327
+ `rm -f "<tmp-dir/>/ase-dissect-<part-id/>.patch"`
328
+
329
+ The patch file of a *successful* part is a pure *intermediate*:
330
+ it was already consumed by `git apply` and its content is fully
331
+ preserved in the worktree, so it is removed. The patch file of a
332
+ part whose worktree or patch *failed* is *kept* instead, because
333
+ it is that part's only materialization and would otherwise be
334
+ lost. Do not output anything.
335
+
336
+ </step>
337
+
338
+ 5. <step id="STEP 5: Report Result">
339
+
340
+ 1. <if condition="<getopt-option-dry/> is equal `true`">
341
+ Only output the following <template/>:
342
+
343
+ <template>
344
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ✪ dissection: **<n/>** parts, ▶ status: **dry-run -- no worktrees created**
345
+ </template>
346
+ </if>
347
+ <else>
348
+ Only output the following <template/>:
349
+
350
+ <template>
351
+ ⧉ **ASE**: ✪ skill: **ase-code-dissect**, ✪ dissection: **<n/>** parts, ▶ status: **change set dissected**
352
+ </template>
353
+ </else>
354
+
355
+ 2. Finally, give the closing hints by expanding the following
356
+ (which, depending on the configured <ase-guidance-level/>, may
357
+ each expand into nothing and hence emit no output at all):
358
+
359
+ <if condition="<getopt-option-dry/> is not equal `true`">
360
+ <ase-tpl-hint level="minimal">
361
+ The parts are uncommitted in `.ase/worktree/<id>` -- review and commit each of them separately, then remove them via `git worktree remove`.
362
+ </ase-tpl-hint>
363
+ </if>
364
+ <else>
365
+ <ase-tpl-hint level="minimal">
366
+ Re-run `/ase-code-dissect` without `--dry` to actually create the reported worktrees, optionally with a `<dissect-hint>` argument if the reported split is not the intended one.
367
+ </ase-tpl-hint>
368
+ </else>
369
+
370
+ <ase-tpl-hint level="normal">
371
+ Use `/ase-meta-diff` and `/ase-meta-review` inside a part's worktree to summarize and review it before committing.
372
+ </ase-tpl-hint>
373
+
374
+ <ase-tpl-hint level="verbose">
375
+ Use `/ase-code-dissect --staged` to dissect the staged changes only, `--max-parts <count>` to bound the number of parts, `--force` to re-create already existing worktrees, and a `<dissect-hint>` argument to steer the split.
376
+ </ase-tpl-hint>
377
+
378
+ </step>
379
+
380
+ </flow>