@rse/ase 1.0.7 → 2.0.0

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 (279) hide show
  1. package/dst/ase-agent-definition-api.d.ts +184 -0
  2. package/dst/ase-agent-definition-api.js +6 -0
  3. package/dst/ase-agent-definition-builtin/condenser.js +42 -0
  4. package/dst/ase-agent-definition-builtin/editor.js +45 -0
  5. package/dst/ase-agent-definition-builtin/estimator.js +98 -0
  6. package/dst/ase-agent-definition-builtin/implementer.js +121 -0
  7. package/dst/ase-agent-definition-builtin/integrator.js +56 -0
  8. package/dst/ase-agent-definition-builtin/qualifier.js +61 -0
  9. package/dst/ase-agent-definition-builtin/rebooter.js +41 -0
  10. package/dst/ase-agent-definition-builtin/researcher.js +77 -0
  11. package/dst/ase-agent-definition-core.js +827 -0
  12. package/dst/ase-agent-fleet.js +772 -0
  13. package/dst/ase-agent-process.js +232 -0
  14. package/dst/ase-agent-relay-client.js +509 -0
  15. package/dst/ase-agent-relay-core.js +213 -0
  16. package/dst/ase-agent-relay-server-bind.js +242 -0
  17. package/dst/ase-agent-relay-server-cli.js +50 -0
  18. package/dst/ase-agent-runtime-claim.js +189 -0
  19. package/dst/ase-agent-runtime-engine.js +1100 -0
  20. package/dst/ase-agent-runtime-exec.js +275 -0
  21. package/dst/ase-agent-runtime-phase.js +581 -0
  22. package/dst/ase-agent-runtime-request.js +272 -0
  23. package/dst/ase-agent-runtime-tool.js +207 -0
  24. package/dst/ase-agent-runtime.js +1316 -0
  25. package/dst/ase-agent.js +65 -0
  26. package/dst/ase-artifact.js +6 -5
  27. package/dst/ase-config-core.js +465 -0
  28. package/dst/ase-config-schema.js +351 -0
  29. package/dst/ase-config-scope.js +172 -0
  30. package/dst/ase-config.js +25 -585
  31. package/dst/ase-hook.js +228 -111
  32. package/dst/ase-lib-daemon-cli.js +130 -0
  33. package/dst/ase-lib-hash.js +20 -0
  34. package/dst/{ase-log.js → ase-lib-log.js} +40 -7
  35. package/dst/ase-lib-server-bind.js +115 -0
  36. package/dst/ase-lib-server-cli.js +474 -0
  37. package/dst/{ase-table.js → ase-lib-table.js} +1 -1
  38. package/dst/{ase-version.js → ase-lib-version.js} +3 -0
  39. package/dst/ase-man.js +96 -0
  40. package/dst/ase-mcp.js +166 -13
  41. package/dst/{ase-getopt.js → ase-service-getopt.js} +82 -80
  42. package/dst/{ase-markdown.js → ase-service-markdown.js} +18 -11
  43. package/dst/ase-service-otel.js +1246 -0
  44. package/dst/{ase-skills.js → ase-service-skills.js} +29 -64
  45. package/dst/ase-service-state.js +101 -0
  46. package/dst/ase-service.js +251 -76
  47. package/dst/ase-setup-common.js +141 -0
  48. package/dst/ase-setup-mcp.js +359 -0
  49. package/dst/ase-setup-settings.js +837 -0
  50. package/dst/ase-setup.js +113 -869
  51. package/dst/ase-spec.js +31 -19
  52. package/dst/ase-statusline.js +108 -43
  53. package/dst/ase-task-board-core.js +739 -0
  54. package/dst/ase-task-board-filter.js +127 -0
  55. package/dst/ase-task-board-flow.js +237 -0
  56. package/dst/ase-task-board-graph.js +497 -0
  57. package/dst/ase-task-board-stats.js +263 -0
  58. package/dst/ase-task-board-tui-control.js +775 -0
  59. package/dst/ase-task-board-tui-model.js +1008 -0
  60. package/dst/ase-task-board-tui-popup.js +626 -0
  61. package/dst/ase-task-board-tui-style.js +106 -0
  62. package/dst/ase-task-board-tui-view.js +847 -0
  63. package/dst/ase-task-board-tui.js +189 -0
  64. package/dst/ase-task-board-web-client.css +1 -0
  65. package/dst/ase-task-board-web-client.html +20 -0
  66. package/dst/ase-task-board-web-client.js +81 -0
  67. package/dst/ase-task-board-web-server.js +823 -0
  68. package/dst/ase-task-board.js +134 -0
  69. package/dst/ase-task-format.js +757 -0
  70. package/dst/ase-task-request.js +208 -0
  71. package/dst/ase-task-store-client.js +495 -0
  72. package/dst/ase-task-store-core.js +804 -0
  73. package/dst/ase-task-store-issues.js +237 -0
  74. package/dst/ase-task-store-plugin-api.js +6 -0
  75. package/dst/ase-task-store-plugin-ase.js +484 -0
  76. package/dst/ase-task-store-plugin-delegate.js +137 -0
  77. package/dst/ase-task-store-plugin-gitea.js +666 -0
  78. package/dst/ase-task-store-plugin-github.js +696 -0
  79. package/dst/ase-task-store-plugin-gitlab.js +668 -0
  80. package/dst/ase-task-store-server-bind.js +538 -0
  81. package/dst/ase-task-store-server-cli.js +154 -0
  82. package/dst/ase-task.js +1335 -357
  83. package/dst/{ase-compat.js → ase-util-compat.js} +2 -2
  84. package/dst/{ase-diagram.js → ase-util-diagram.js} +107 -32
  85. package/dst/{ase-meta.js → ase-util-meta.js} +2 -2
  86. package/dst/{ase-metric.js → ase-util-metric.js} +2 -2
  87. package/dst/{ase-mint.js → ase-util-mint.js} +19 -12
  88. package/dst/{ase-worktree.js → ase-util-worktree.js} +30 -19
  89. package/dst/ase-util.js +20 -0
  90. package/dst/ase.js +108 -32
  91. package/dst/man/ase-agent-adhoc.1 +515 -0
  92. package/dst/man/ase-agent-condenser.1 +193 -0
  93. package/dst/man/ase-agent-editor.1 +212 -0
  94. package/dst/man/ase-agent-estimator.1 +214 -0
  95. package/dst/man/ase-agent-fleet.1 +185 -0
  96. package/dst/man/ase-agent-implementer.1 +233 -0
  97. package/dst/man/ase-agent-integrator.1 +213 -0
  98. package/dst/man/ase-agent-qualifier.1 +214 -0
  99. package/dst/man/ase-agent-rebooter.1 +193 -0
  100. package/dst/man/ase-agent-relay.1 +128 -0
  101. package/dst/man/ase-agent-researcher.1 +217 -0
  102. package/dst/man/ase-agent.1 +264 -0
  103. package/dst/man/ase-artifact-list.1 +38 -0
  104. package/dst/man/ase-artifact-name.1 +39 -0
  105. package/dst/man/ase-artifact.1 +56 -0
  106. package/dst/man/ase-config-delete.1 +45 -0
  107. package/dst/man/ase-config-edit.1 +48 -0
  108. package/dst/man/ase-config-get.1 +46 -0
  109. package/dst/man/ase-config-init.1 +60 -0
  110. package/dst/man/ase-config-list.1 +42 -0
  111. package/dst/man/ase-config-set.1 +52 -0
  112. package/dst/man/ase-config.1 +225 -0
  113. package/dst/man/ase-hook-permission-request.1 +36 -0
  114. package/dst/man/ase-hook-pre-tool-use.1 +59 -0
  115. package/dst/man/ase-hook-session-end.1 +47 -0
  116. package/dst/man/ase-hook-session-persona.1 +37 -0
  117. package/dst/man/ase-hook-session-start.1 +81 -0
  118. package/dst/man/ase-hook-stop.1 +34 -0
  119. package/dst/man/ase-hook-user-prompt-submit.1 +34 -0
  120. package/dst/man/ase-hook.1 +51 -0
  121. package/dst/man/ase-man.1 +67 -0
  122. package/dst/man/ase-mcp.1 +61 -0
  123. package/dst/man/ase-service-log.1 +43 -0
  124. package/dst/man/ase-service-send.1 +47 -0
  125. package/dst/man/ase-service-start.1 +54 -0
  126. package/dst/man/ase-service-status.1 +46 -0
  127. package/dst/man/ase-service-stop.1 +37 -0
  128. package/dst/man/ase-service.1 +85 -0
  129. package/dst/man/ase-setup-disable.1 +44 -0
  130. package/dst/man/ase-setup-enable.1 +45 -0
  131. package/dst/man/ase-setup-install.1 +73 -0
  132. package/dst/man/ase-setup-mcp.1 +124 -0
  133. package/dst/man/ase-setup-status.1 +60 -0
  134. package/dst/man/ase-setup-statusline.1 +92 -0
  135. package/dst/man/ase-setup-telemetry.1 +92 -0
  136. package/dst/man/ase-setup-uninstall.1 +59 -0
  137. package/dst/man/ase-setup-update.1 +64 -0
  138. package/dst/man/ase-setup.1 +93 -0
  139. package/dst/man/ase-spec-export.1 +62 -0
  140. package/dst/man/ase-spec-lint.1 +40 -0
  141. package/dst/man/ase-spec-preview.1 +40 -0
  142. package/dst/man/ase-spec.1 +46 -0
  143. package/dst/man/ase-statusline.1 +189 -0
  144. package/dst/man/ase-task-assign.1 +71 -0
  145. package/dst/man/ase-task-board.1 +384 -0
  146. package/dst/man/ase-task-delete.1 +35 -0
  147. package/dst/man/ase-task-edit.1 +46 -0
  148. package/dst/man/ase-task-idscheme.1 +65 -0
  149. package/dst/man/ase-task-lifecycle.1 +57 -0
  150. package/dst/man/ase-task-list.1 +47 -0
  151. package/dst/man/ase-task-load.1 +36 -0
  152. package/dst/man/ase-task-newid.1 +61 -0
  153. package/dst/man/ase-task-purge.1 +37 -0
  154. package/dst/man/ase-task-rename.1 +44 -0
  155. package/dst/man/ase-task-request.1 +61 -0
  156. package/dst/man/ase-task-save.1 +48 -0
  157. package/dst/man/ase-task-status.1 +55 -0
  158. package/dst/man/ase-task-store.1 +194 -0
  159. package/dst/man/ase-task-view.1 +40 -0
  160. package/dst/man/ase-task.1 +160 -0
  161. package/dst/man/ase-util-compat.1 +25 -0
  162. package/dst/man/ase-util-diagram.1 +76 -0
  163. package/dst/man/ase-util-meta.1 +45 -0
  164. package/dst/man/ase-util-metric.1 +54 -0
  165. package/dst/man/ase-util-mint.1 +59 -0
  166. package/dst/man/ase-util-worktree.1 +72 -0
  167. package/dst/man/ase-util.1 +50 -0
  168. package/dst/man/ase.1 +124 -0
  169. package/package.json +79 -21
  170. package/plugin/.claude-plugin/plugin.json +1 -1
  171. package/plugin/.codex-plugin/plugin.json +1 -1
  172. package/plugin/.github/plugin/plugin.json +1 -1
  173. package/plugin/agents/ase-meta-diagram.md +12 -8
  174. package/plugin/agents/ase-repo-review.md +322 -0
  175. package/plugin/hooks/hooks-codex.json +5 -0
  176. package/plugin/hooks/hooks-copilot.json +5 -0
  177. package/plugin/hooks/hooks.json +8 -0
  178. package/plugin/meta/ase-common-approach.md +117 -0
  179. package/plugin/meta/ase-common-changeset.md +256 -0
  180. package/plugin/meta/ase-common-code.md +10 -173
  181. package/plugin/meta/ase-common-grill.md +317 -0
  182. package/plugin/meta/ase-common-resolve.md +305 -0
  183. package/plugin/meta/ase-common-task.md +83 -4
  184. package/plugin/meta/ase-constitution.md +0 -2
  185. package/plugin/meta/ase-format-specbook.md +208 -25
  186. package/plugin/meta/ase-format-specbook.yaml +242 -851
  187. package/plugin/meta/ase-format-task.md +669 -125
  188. package/plugin/meta/ase-persona.md +3 -4
  189. package/plugin/meta/ase-skill.md +9 -0
  190. package/plugin/mods/ase-mods.ts +409 -0
  191. package/plugin/mods/claude-code.d.ts +13417 -0
  192. package/plugin/skills/ase-arch-analyze/SKILL.md +1 -1
  193. package/plugin/skills/ase-arch-analyze/help.md +2 -2
  194. package/plugin/skills/ase-code-analyze/SKILL.md +59 -8
  195. package/plugin/skills/ase-code-analyze/help.md +29 -4
  196. package/plugin/skills/ase-code-edit/SKILL.md +107 -181
  197. package/plugin/skills/ase-code-edit/help.md +118 -31
  198. package/plugin/skills/ase-code-lint/SKILL.md +64 -13
  199. package/plugin/skills/ase-code-lint/help.md +32 -2
  200. package/plugin/skills/ase-docs-proofread/SKILL.md +4 -4
  201. package/plugin/skills/ase-docs-proofread/help.md +1 -1
  202. package/plugin/skills/ase-docs-refine/SKILL.md +4 -4
  203. package/plugin/skills/ase-docs-shorten/SKILL.md +4 -4
  204. package/plugin/skills/ase-help-intent/data.md +2164 -1087
  205. package/plugin/skills/ase-help-intent/help.md +1 -1
  206. package/plugin/skills/ase-help-skill/catalog.md +12 -9
  207. package/plugin/skills/ase-meta-brainstorm/SKILL.md +1 -1
  208. package/plugin/skills/ase-meta-config/SKILL.md +3 -4
  209. package/plugin/skills/ase-meta-config/help.md +31 -10
  210. package/plugin/skills/ase-meta-mint/SKILL.md +5 -5
  211. package/plugin/skills/ase-meta-mint/help.md +10 -5
  212. package/plugin/skills/ase-meta-why/help.md +1 -1
  213. package/plugin/skills/ase-meta-workflow/SKILL.md +7 -7
  214. package/plugin/skills/ase-meta-workflow/help.md +4 -4
  215. package/plugin/skills/ase-meta-workflow/sample.md +3 -3
  216. package/plugin/skills/ase-meta-workflow/workflow.txt +22 -18
  217. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/SKILL.md +4 -3
  218. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/help.md +5 -5
  219. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/SKILL.md +6 -6
  220. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/help.md +5 -5
  221. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/SKILL.md +6 -6
  222. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/help.md +8 -8
  223. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/SKILL.md +19 -19
  224. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/help.md +10 -12
  225. package/plugin/skills/ase-repo-merge/SKILL.md +346 -0
  226. package/plugin/skills/ase-repo-merge/help.md +107 -0
  227. package/plugin/skills/ase-repo-resolve/SKILL.md +158 -0
  228. package/plugin/skills/ase-repo-resolve/help.md +102 -0
  229. package/plugin/skills/ase-repo-review/SKILL.md +406 -0
  230. package/plugin/skills/ase-repo-review/help.md +181 -0
  231. package/plugin/skills/ase-spec-edit/SKILL.md +117 -183
  232. package/plugin/skills/ase-spec-edit/help.md +107 -26
  233. package/plugin/skills/ase-sync-reconcile/help.md +1 -1
  234. package/plugin/skills/ase-task-assign/SKILL.md +111 -0
  235. package/plugin/skills/ase-task-assign/help.md +119 -0
  236. package/plugin/skills/ase-task-condense/SKILL.md +21 -21
  237. package/plugin/skills/ase-task-condense/help.md +12 -10
  238. package/plugin/skills/ase-task-delete/SKILL.md +1 -1
  239. package/plugin/skills/ase-task-dissect/SKILL.md +71 -48
  240. package/plugin/skills/ase-task-dissect/help.md +10 -9
  241. package/plugin/skills/ase-task-edit/SKILL.md +379 -94
  242. package/plugin/skills/ase-task-edit/help.md +95 -22
  243. package/plugin/skills/ase-task-estimate/SKILL.md +492 -0
  244. package/plugin/skills/ase-task-estimate/help.md +158 -0
  245. package/plugin/skills/ase-task-grill/SKILL.md +246 -138
  246. package/plugin/skills/ase-task-grill/help.md +129 -26
  247. package/plugin/skills/ase-task-id/SKILL.md +8 -1
  248. package/plugin/skills/ase-task-id/help.md +6 -3
  249. package/plugin/skills/ase-task-implement/SKILL.md +535 -145
  250. package/plugin/skills/ase-task-implement/help.md +138 -47
  251. package/plugin/skills/ase-task-integrate/SKILL.md +549 -0
  252. package/plugin/skills/ase-task-integrate/help.md +187 -0
  253. package/plugin/skills/ase-task-list/SKILL.md +55 -23
  254. package/plugin/skills/ase-task-list/help.md +45 -21
  255. package/plugin/skills/ase-task-reboot/SKILL.md +84 -43
  256. package/plugin/skills/ase-task-reboot/help.md +28 -8
  257. package/plugin/skills/ase-task-rename/SKILL.md +10 -2
  258. package/plugin/skills/ase-task-research/SKILL.md +386 -0
  259. package/plugin/skills/ase-task-research/help.md +102 -0
  260. package/plugin/skills/ase-task-status/SKILL.md +137 -0
  261. package/plugin/skills/ase-task-status/help.md +80 -0
  262. package/plugin/skills/ase-task-view/SKILL.md +49 -24
  263. package/plugin/skills/ase-task-view/help.md +19 -9
  264. package/plugin/agents/ase-meta-review.md +0 -187
  265. package/plugin/skills/ase-code-craft/SKILL.md +0 -264
  266. package/plugin/skills/ase-code-craft/help.md +0 -122
  267. package/plugin/skills/ase-code-refactor/SKILL.md +0 -232
  268. package/plugin/skills/ase-code-refactor/help.md +0 -109
  269. package/plugin/skills/ase-code-resolve/SKILL.md +0 -289
  270. package/plugin/skills/ase-code-resolve/help.md +0 -116
  271. package/plugin/skills/ase-meta-review/SKILL.md +0 -210
  272. package/plugin/skills/ase-meta-review/help.md +0 -96
  273. package/plugin/skills/ase-task-preflight/SKILL.md +0 -166
  274. package/plugin/skills/ase-task-preflight/help.md +0 -82
  275. /package/dst/{ase-ignore.js → ase-lib-ignore.js} +0 -0
  276. /package/dst/{ase-stdio.js → ase-lib-stdio.js} +0 -0
  277. /package/dst/{ase-kv.js → ase-service-kv.js} +0 -0
  278. /package/dst/{ase-sleep.js → ase-service-sleep.js} +0 -0
  279. /package/dst/{ase-timestamp.js → ase-service-timestamp.js} +0 -0
@@ -4,6 +4,15 @@ Grill Skill Common Steps
4
4
 
5
5
  <define name="grill-understanding">
6
6
 
7
+ Set <grill-perspective><arg2/></grill-perspective> (with any leading
8
+ and trailing whitespace stripped), set <grill-ground><arg3/></grill-ground>,
9
+ and set <grill-facts></grill-facts> (empty). Set <grill-label/> to
10
+ ` (<grill-perspective/>, grounded)` if <grill-perspective/> is not empty
11
+ and <grill-ground/> is `true`, to ` (<grill-perspective/>)` if only
12
+ <grill-perspective/> is not empty, to ` (grounded)` if only
13
+ <grill-ground/> is `true`, or to empty otherwise. Do not output
14
+ anything.
15
+
7
16
  - GOAL:
8
17
 
9
18
  Interactively interviewing the user *relentlessly* about every
@@ -15,6 +24,24 @@ Grill Skill Common Steps
15
24
  during a subsequent implementation, no essential freedom of choice
16
25
  exists any longer.
17
26
 
27
+ - PERSPECTIVE:
28
+
29
+ <if condition="<grill-perspective/> is not empty">
30
+ Grill *exclusively* from the logical perspective <grill-perspective/>
31
+ -- a keyword or short hint like `domain`, `performance`, or
32
+ `security`. The perspective is an *exclusive lens* over <arg1/>:
33
+ raise *only* open points which are relevant when <arg1/> is viewed
34
+ from this perspective, and *drop* all open points which are not,
35
+ even if they are open otherwise. The perspective does *not* replace
36
+ the *Focus Areas* below: every question still carries its focus
37
+ area, severity, and impact -- e.g. a perspective `domain` still
38
+ yields questions of focus area `ARCHITECTURE`, as long as they are
39
+ relevant from the domain perspective.
40
+ </if>
41
+ <else>
42
+ Grill *holistically*, i.e. from no particular perspective.
43
+ </else>
44
+
18
45
  - FOCUS:
19
46
 
20
47
  Focusing on the following outside-in *Focus Areas*, in order of
@@ -41,6 +68,16 @@ Grill Skill Common Steps
41
68
  is realized in the code base. These aspects *CAN* be
42
69
  clarified, as they shape technical inner details only.
43
70
 
71
+ 5. *REGRESSION*: Aspects affecting the regression checks of
72
+ <arg1/>, i.e. decisions on what must *not* break. These
73
+ aspects *SHOULD* be clarified, as they decide when the
74
+ solution counts as safe.
75
+
76
+ 6. *CONFIRMATION*: Aspects affecting the confirmation checks of
77
+ <arg1/>, i.e. decisions on what proves the specified
78
+ behavior. These aspects *SHOULD* be clarified, as they
79
+ decide when the solution counts as complete and correct.
80
+
44
81
  - SEVERITY:
45
82
 
46
83
  The *Focus Area* indicate the severity of the aspect:
@@ -49,6 +86,23 @@ Grill Skill Common Steps
49
86
  - severity *MUST* for *INTERFACE* focus area
50
87
  - severity *SHOULD* for *ARCHITECTURE* focus area
51
88
  - severity *MAY* for *IMPLEMENTATION* focus area
89
+ - severity *SHOULD* for *REGRESSION* focus area
90
+ - severity *SHOULD* for *CONFIRMATION* focus area
91
+
92
+ - IMPACT:
93
+
94
+ Independent of its *Focus Area*, every open point carries an
95
+ individual *impact* rating, describing how noticeably its decision
96
+ shapes the solution:
97
+
98
+ - impact *HIGH*: the decision shapes the solution fundamentally
99
+ - impact *MEDIUM*: the decision shapes the solution noticeably
100
+ - impact *LOW*: the decision shapes the solution marginally
101
+
102
+ The impact decides *which* open points are raised as questions --
103
+ points of higher impact first, so points of lowest impact are the
104
+ first ones to be dropped -- and in which *order* they are raised
105
+ *within* a focus area.
52
106
 
53
107
  - INDICATORS:
54
108
 
@@ -87,3 +141,266 @@ Grill Skill Common Steps
87
141
 
88
142
  </define>
89
143
 
144
+ <define name="grill-ground">
145
+
146
+ Ground the grilling *once*, before its first round, where <arg1/> is
147
+ the grilled subject and <arg2/> is the directory of the working copy
148
+ the local artifacts are read from (or empty for the project working
149
+ copy). It sets <grill-facts/> to the grounding facts, which -- unlike
150
+ all other information gathered by a round -- are *exempt* from the
151
+ forgetting at the start of every round and hence serve *all* rounds.
152
+ Do not output anything, except for the warning below.
153
+
154
+ <if condition="<grill-ground/> is equal `true`">
155
+
156
+ 1. LOCAL GROUNDING:
157
+
158
+ Resolve the artifact kinds `spec`, `code`, `docs`, `infr`, and
159
+ `othr` to their project-relative file lists:
160
+
161
+ <if condition="<arg2/> is not empty">
162
+ Run the command `ase artifact list` *once* with <arg2/> as its
163
+ working directory and parse its `# <kind/>:` and `- <file/>` output
164
+ lines into the file lists -- the `ase_artifact_list` tool always
165
+ resolves against the *project* working copy and hence *MUST* *NOT*
166
+ be used here.
167
+ </if>
168
+ <else>
169
+ Call the `ase_artifact_list(kind: [ "spec", "code", "docs", "infr",
170
+ "othr" ])` tool of the `ase` MCP server *once* and read the returned
171
+ `artifacts` array of `{ kind, files }` objects into the file lists.
172
+ </else>
173
+
174
+ From these file lists, determine the files (or their parts) which
175
+ are relevant for <arg1/>
176
+ <if condition="<grill-perspective/> is not empty">
177
+ when viewed from the perspective <grill-perspective/>
178
+ </if>
179
+ -- across *all* artifact kinds, not only the grilled subject itself
180
+ -- and *read* them. Condense their relevant *project facts* --
181
+ existing decisions, conventions, constraints, and terminology --
182
+ each with its project-relative file path, into <grill-facts/>.
183
+
184
+ 2. WEB GROUNDING:
185
+
186
+ Use the `ase-meta-search` skill in a sub-agent to gather *world
187
+ facts* -- established practices, standards, patterns, and pitfalls
188
+ -- with the following tool call, where <topic/> is a concise,
189
+ self-contained summary of <arg1/>
190
+ <if condition="<grill-perspective/> is not empty">
191
+ from the perspective <grill-perspective/>
192
+ </if>
193
+ which mentions *no* confidential project internals:
194
+
195
+ `Agent(
196
+ description: "Query Web Search Service",
197
+ subagent_type: "ase:ase-meta-search",
198
+ prompt: "Search the Internet/Web and gather established maxims, principles, tenets, practices, standards, definitions, patterns, and pitfalls about the following topic: <topic/>",
199
+ run_in_background: false
200
+ )`
201
+
202
+ Condense the returned relevant facts, each with its source, and
203
+ append them to <grill-facts/>.
204
+
205
+ 3. <if condition="<grill-facts/> contains no usable facts">
206
+
207
+ Set <grill-facts></grill-facts> (empty), so the grilling falls back
208
+ to model knowledge, and output the following <template/>:
209
+
210
+ <template>
211
+ <ase-tpl-bullet-secondary/> **WARNING**: grounding found no usable facts -- falling back to model knowledge.
212
+ </template>
213
+
214
+ </if>
215
+
216
+ </if>
217
+
218
+ </define>
219
+
220
+ <define name="grill-stop">
221
+
222
+ The requested number of grilling rounds is a *maximum* only: the
223
+ grilling *stops early* once all open points of severity <arg1/> or
224
+ higher are clear. For this, the freshly determined questions of the
225
+ current round are the *still open points*, ranked by their
226
+ <context-N-severity/> in the descending order `MUST`, `SHOULD`, `MAY`.
227
+
228
+ <if condition="no question has a <context-N-severity/> of <arg1/> or higher">
229
+ Set <grill-stop>true</grill-stop> and only output the following <template/>:
230
+
231
+ <template>
232
+ ⧉ **ASE**: <arg2/>, ▶ status: **grilling finished early -- all points of severity <arg1/> or higher are clear**
233
+ </template>
234
+ </if>
235
+ <else>
236
+ Set <grill-stop>false</grill-stop>. Do not output anything.
237
+ </else>
238
+
239
+ </define>
240
+
241
+ <define name="grill-questions">
242
+
243
+ Determine, sort, answer, and show the questions of the current grilling
244
+ *round* <round-id/>, where <arg1/> is the severity of the `grill-stop`
245
+ decision, <arg2/> is the skill chrome of its status line, <arg3/> is the
246
+ list of *literal aspects*, <arg4/> is the source of the grounded answer
247
+ alternatives, <arg5/> is an optional *final* sort criterion, and
248
+ <content/> are optional additional instructions for determining the
249
+ questions:
250
+
251
+ 1. DETERMINE QUESTIONS:
252
+
253
+ Determine the questions, comprised of a round-local id
254
+ <question-N-id/> of `<N/>` -- where <N/> restarts at `1`
255
+ in *every* round, independent of the numbering of previous
256
+ rounds --, and a very brief but precise question text
257
+ <question-N-text/>. Each question is chosen to
258
+ resolve the open points related to the above understanding
259
+ of grilling, by focusing on the mentioned *Focus Areas*
260
+ <if condition="<grill-perspective/> is not empty">
261
+ and seen *exclusively* through the mentioned *Perspective*
262
+ <grill-perspective/>
263
+ </if>.
264
+
265
+ <if condition="<grill-facts/> is not empty">
266
+ Derive the open points primarily from the grounding facts in
267
+ <grill-facts/> instead of from your world knowledge alone: raise
268
+ the decisions these facts reveal as open -- like a project
269
+ convention the subject deviates from, or an established practice
270
+ or pitfall the subject does not address yet.
271
+ </if>
272
+
273
+ <content/>
274
+
275
+ For <question-N-text/> use the format `Shall...?` for
276
+ questions of focus area `DOMAIN`, `INTERFACE`, `REGRESSION`,
277
+ and `CONFIRMATION`, the format `Should...?` for questions of
278
+ focus area `ARCHITECTURE`, and the format `May...?` for
279
+ questions of focus area `IMPLEMENTATION`.
280
+
281
+ In every <question-N-text/>, encode all *literal aspects*
282
+ -- <arg3/> -- with backticks.
283
+
284
+ Keep every <question-N-text/> at most *200 characters* long
285
+ -- compact the text until it fits --, as a longer question
286
+ overflows its table cell and silently degrades the entire
287
+ table into a plain text rendering.
288
+
289
+ 2. DETERMINE CONTEXT:
290
+
291
+ For each question, determine its focus area
292
+ <context-N-focus/> from the mentioned *Focus Areas*, a 1-3
293
+ word hint <context-N-topic/>, describing what the question
294
+ is about, a <context-N-severity/>, describing how
295
+ important this question is, and a <context-N-impact/> of
296
+ `HIGH`, `MEDIUM`, or `LOW`, rating the individual impact
297
+ of the question.
298
+
299
+ Set <context-N-id/> to `DOM` for <context-N-focus/> of
300
+ `DOMAIN`, `IFC` for <context-N-focus/> of `INTERFACE`, `ARC`
301
+ for <context-N-focus/> of `ARCHITECTURE`, `IMP` for
302
+ <context-N-focus/> of `IMPLEMENTATION`, `REG` for
303
+ <context-N-focus/> of `REGRESSION`, and `CON` for
304
+ <context-N-focus/> of `CONFIRMATION`.
305
+
306
+ Finally, decide whether the grilling stops early:
307
+
308
+ <expand name="grill-stop" arg1="<arg1/>" arg2="<arg2/>"></expand>
309
+
310
+ If <grill-stop/> is `true`, skip all remaining items of this
311
+ expansion.
312
+
313
+ 3. SORT QUESTIONS:
314
+
315
+ Finally, *sort* the questions by descending focus area
316
+ order -- first all `DOMAIN`, then all `INTERFACE`, then all
317
+ `ARCHITECTURE`, then all `IMPLEMENTATION`, then all
318
+ `REGRESSION`, and then all `CONFIRMATION` ones -- and,
319
+ within each focus area, by descending
320
+ <context-N-impact/><arg5/>. If more than 10 questions exist,
321
+ drop the questions of lowest <context-N-impact/> -- within
322
+ equal impact the ones of lowest focus area order first --
323
+ until a maximum of 10 questions remains. Then renumber
324
+ <N/> according to the sort order, starting at `1`, and set
325
+ <n/> to the number of remaining questions. Do not output
326
+ anything.
327
+
328
+ Finally, assemble the <question-N/> out of
329
+ `**<question-N-id/>** ▶ **<context-N-id/>** ▷
330
+ **<context-N-topic/>**: <question-N-text/>`.
331
+
332
+ 4. DETERMINE ANSWERS:
333
+
334
+ For all remaining <question-N/>, check <arg4/> and
335
+ <if condition="<grill-facts/> is not empty">
336
+ the grounding facts in <grill-facts/> -- preferring them over
337
+ your world knowledge, which only fills their gaps --
338
+ </if>
339
+ <else>
340
+ your world knowledge
341
+ </else>
342
+ to find *two to three* grounded answer
343
+ alternatives <answer-N-K/> with a question-local id
344
+ <answer-N-K-id/> of the <K/>-th upper-case letter (`A`, `B`,
345
+ `C`) -- where <K/> restarts at `1` for *every* question,
346
+ independent of the numbering of other questions --, a 1-3
347
+ word label <answer-N-K-label/>, and
348
+ an ultra brief description <answer-N-K-description/> of
349
+ at most *10 words*. For the answer which reflects the
350
+ current decision state of the grilled subject, append
351
+ ` ⚑` to its <answer-N-K-label/>.
352
+
353
+ Assemble an <answer-N/> out of `**<answer-N-1-id/>**
354
+ ▶ **<answer-N-1-label/>**: <answer-N-1-description/>,
355
+ **<answer-N-2-id/>** ▶ **<answer-N-2-label/>**:
356
+ <answer-N-2-description/>[, ...]`.
357
+
358
+ Keep every assembled <answer-N/> at most *240 characters*
359
+ long -- drop the least relevant alternative and compact the
360
+ descriptions until it fits -- as a longer answer overflows
361
+ its table cell and silently degrades the entire table into a
362
+ plain text rendering.
363
+
364
+ 5. SHOW QUESTIONS:
365
+
366
+ Output only the following <template/> -- it lists *all*
367
+ questions of the round up-front, one table row per
368
+ aspect, so the subsequent dialog only has to ask for the
369
+ combined answer. Align all column edges of the table.
370
+
371
+ In every table cell you *MUST* escape each literal pipe
372
+ character outside a code span as `\|` and you *MUST*
373
+ open *and* close every backtick code span within the
374
+ *same* cell -- an unescaped pipe or an unbalanced
375
+ backtick run splits the cell and silently degrades the
376
+ entire table into a plain text rendering:
377
+
378
+ <template>
379
+ ⧉ **ASE**: <round-id/><grill-label/>: *Relentless Interviewing Until Clarity*
380
+
381
+ | QUESTION | ANSWERS |
382
+ | ------------- | ----------- |
383
+ | <question-1/> | <answer-1/> |
384
+ | <question-2/> | <answer-2/> |
385
+ | [...] | [...] |
386
+
387
+ Legend: **DOM**: Domain (MUST) **IFC**: Interface (MUST) **n**: round-local question number
388
+ **ARC**: Architecture (SHOULD) **IMP**: Implementation (MAY) **X**: question-local answer letter
389
+ **REG**: Regression (SHOULD) **CON**: Confirmation (SHOULD) ⚑: current decision state
390
+ </template>
391
+
392
+ </define>
393
+
394
+ <define name="grill-short-responses">
395
+
396
+ Within the combined reply, recognize every token matching
397
+ the regexp `\d+[a-zA-Z]` (like `1A`, separated by whitespace
398
+ or commas, and freely mixed with keyword text) as a *short
399
+ response*, which cherry-picks for the question with
400
+ <question-N-id/> equal to its number the answer with
401
+ <answer-N-K-id/> equal to its letter (case-insensitive). A
402
+ token referencing a non-existing question or answer is
403
+ treated as plain free text.
404
+
405
+ </define>
406
+
@@ -0,0 +1,305 @@
1
+
2
+ Resolve Skill Common Steps
3
+ ==========================
4
+
5
+ <define name="resolve-conflicts">
6
+
7
+ *Resolve* the conflicts inside the Git working directory <arg2/> on
8
+ behalf of the skill <arg1/>, where <arg3/> (`true` or `false`) enables
9
+ the *interactive* resolution of otherwise unresolvable hunks, <arg4/>
10
+ (`true` or `false`) enables the *safe* mode which never touches
11
+ non-content conflicts, and <arg5/> is an optional whitespace-separated
12
+ list of paths restricting the files to resolve. This sets
13
+ <resolve-verdict/> to `NONE`, `RESOLVED`, `PARTIAL`, or `FAILED`,
14
+ <resolve-operation/> to the in-progress Git operation,
15
+ <resolve-escalations/> to the list of escalated conflicts, and
16
+ <resolve-backup-dir/> to the backup directory.
17
+
18
+ The overarching rule is: you *MUST* *NEVER* lose any change of any
19
+ side. When in doubt, a conflict stays *exactly as it is* and is
20
+ escalated -- an unresolved conflict is always acceptable, a silently
21
+ dropped change *never* is.
22
+
23
+ 1. DETERMINE STATE:
24
+
25
+ 1. Set <resolve-verdict>FAILED</resolve-verdict>,
26
+ <resolve-escalations></resolve-escalations> (empty), and
27
+ <resolve-backup-dir></resolve-backup-dir> (empty).
28
+
29
+ 2. Determine the *repository root* and the *Git directory* by
30
+ running the commands `git -C "<arg2/>" rev-parse --show-toplevel`
31
+ and `git -C "<arg2/>" rev-parse --absolute-git-dir` and capturing
32
+ their outputs into <repo-root/> and <git-dir/>. If a command
33
+ fails, skip all remaining items of this expansion, as
34
+ <arg2/> is no Git working directory.
35
+
36
+ 3. Determine the *in-progress operation* by running the command
37
+ `git -C "<repo-root/>" rev-parse --verify --quiet "<ref/>"` for
38
+ <ref/> being `MERGE_HEAD`, `REBASE_HEAD`, `CHERRY_PICK_HEAD`,
39
+ and `REVERT_HEAD` (in this order) and set
40
+ <resolve-operation/> to `merge`, `rebase`, `cherry-pick`, or
41
+ `revert` for the *first* existing one, and to `none` (e.g.,
42
+ after `git stash apply`, `git apply --3way`, or `patch --merge`)
43
+ if none exists. Set <theirs-ref/> to that existing ref (or to
44
+ empty for `none`).
45
+
46
+ 4. Determine the *intents* of both sides: *ours* is `HEAD` and
47
+ *theirs* is <theirs-ref/>. Inspect them by running the commands
48
+ `git -C "<repo-root/>" log --oneline -n 10 HEAD` and, if
49
+ <theirs-ref/> is not empty,
50
+ `git -C "<repo-root/>" log --oneline -n 10 "<theirs-ref/>"` and
51
+ `git -C "<repo-root/>" show --stat "<theirs-ref/>"`. Keep in
52
+ mind that under `rebase` *ours* is the upstream the commits are
53
+ replayed onto and *theirs* is the replayed commit of the user's
54
+ branch, and that under `revert` *theirs* is the *inverse* of
55
+ the reverted commit. Without <theirs-ref/>, derive the sides
56
+ from the labels of the conflict markers only.
57
+
58
+ 2. DETERMINE CONFLICTS:
59
+
60
+ 1. Determine the *unmerged files* by running the command
61
+ `git -C "<repo-root/>" -c core.quotepath=off status --porcelain=v1`
62
+ and taking all entries with the status codes `UU` (both
63
+ modified), `AA` (both added), `UD`/`DU` (modified/deleted),
64
+ `AU`/`UA` (added by one side, usually a rename), and `DD` (both
65
+ deleted). For each of them, additionally capture the output of
66
+ `git -C "<repo-root/>" ls-files -u -- "<file/>"`, which lists
67
+ the object ids of the stages `1` (base), `2` (ours), and `3`
68
+ (theirs) -- these stay retrievable via
69
+ `git -C "<repo-root/>" cat-file -p <object-id/>` even after the
70
+ index entry got resolved.
71
+
72
+ 2. Determine the *marker files* -- files carrying conflict markers
73
+ *without* an unmerged index entry (e.g., after `patch --merge`)
74
+ -- by running the command
75
+ `git -C "<repo-root/>" -c core.quotepath=off grep -l -I --untracked -E "^<{7}( |$)"`
76
+ and keeping every listed file which is *not* an unmerged file,
77
+ *not* below the `.ase/` directory, and additionally contains a
78
+ matching `^={7}$` and `^>{7}( |$)` line (so that, e.g., a
79
+ Markdown heading underline alone never qualifies). Additionally
80
+ determine the *reject files* of `patch` by running the command
81
+ `git -C "<repo-root/>" -c core.quotepath=off ls-files --others --exclude-standard -- "*.rej"`:
82
+ they carry hunks which were *not* applied at all, so every one
83
+ of them is escalated as a whole and *never* touched or removed.
84
+
85
+ 3. If <arg5/> is not empty, keep only those unmerged, marker, and
86
+ reject files which equal or are located below one of the paths
87
+ in <arg5/> (resolved relative to <arg2/>).
88
+
89
+ 4. If no unmerged, marker, or reject files remain, set
90
+ <resolve-verdict>NONE</resolve-verdict> and skip all remaining
91
+ items of this expansion.
92
+
93
+ 5. Classify every unmerged and marker file into its *conflict
94
+ kind*: `content` for a text file with conflict markers (`UU`,
95
+ `AA`, or a marker file), `binary` for a `UU` or `AA` file Git
96
+ treats as binary (no conflict markers written), `submodule` for
97
+ a gitlink entry (mode `160000`), `modify/delete` for `UD` and
98
+ `DU`, `rename` for `AU` and `UA`, and `delete/delete` for `DD`.
99
+
100
+ 3. BACK UP FILES:
101
+
102
+ Set <resolve-backup-dir><git-dir/>/ase-resolve</resolve-backup-dir>.
103
+ For every unmerged and marker file which exists in the working
104
+ directory, back it up *before* touching it by running the commands
105
+ `mkdir -p "<resolve-backup-dir/>/<file-dir/>"` and
106
+ `cp -p "<repo-root/>/<file/>" "<resolve-backup-dir/>/<file/>"`,
107
+ where <file-dir/> is the directory part of <file/>. If a backup of
108
+ this file *already exists* (from an earlier, partial run), you
109
+ *MUST* *NOT* overwrite it, as it holds the *more original* state.
110
+ If a backup fails, you *MUST* *NOT* touch this file at all and
111
+ escalate it with the reason `backup failed`. The backups are
112
+ especially essential for marker files, whose sides exist *nowhere*
113
+ else than inside the file itself.
114
+
115
+ 4. RESOLVE CONFLICTS:
116
+
117
+ Resolve every file which is *not* a reject file, one after another,
118
+ according to its conflict kind:
119
+
120
+ 1. `content`:
121
+
122
+ 1. Read the file and split it into its *conflict hunks*, each
123
+ consisting of the *ours* section (after `<<<<<<<`), the
124
+ optional *base* section (after `|||||||`, written under the
125
+ `diff3` or `zdiff3` conflict style), and the *theirs*
126
+ section (after `=======`, up to `>>>>>>>`). If no base
127
+ section exists and the file is unmerged with a stage `1`,
128
+ read the *base* version *read-only* by running the command
129
+ `git -C "<repo-root/>" show ":1:<file/>"`. You *MUST* *NEVER*
130
+ regenerate the markers via `git checkout --conflict=...` or
131
+ `git checkout -m`, as this would destroy all manual edits
132
+ already present in the file.
133
+
134
+ 2. For every hunk, understand *what* each side changed relative
135
+ to the base and *why* (with the help of the intents of
136
+ item 1.4, the surrounding code, and -- if necessary -- the
137
+ other places of the code base the hunk depends on), and
138
+ classify it:
139
+
140
+ - *trivial*: both sides are identical, differ in
141
+ whitespace only, or one side equals the base -- take
142
+ the side carrying the change.
143
+ - *independent*: both sides changed *different* aspects
144
+ (e.g., adjacent additions, unrelated edits of the same
145
+ region) -- combine *both* changes, ordering additions
146
+ in a sensible way.
147
+ - *compatible*: both sides changed the *same* aspect, but
148
+ in a way that can be *combined* (e.g., one side renamed
149
+ an identifier, the other side added a use of it) -- merge
150
+ both, so *both* intents are honored.
151
+ - *unresolvable*: both intents *contradict* each other
152
+ (e.g., the same value changed to two different values),
153
+ or you are *not confident* about a resolution.
154
+
155
+ Replace every *trivial*, *independent*, and *compatible*
156
+ hunk by its resolution, including the removal of its
157
+ conflict markers, while keeping every *unresolvable* hunk
158
+ *verbatim* including its conflict markers. Change *nothing*
159
+ outside of the conflict hunks, except for a consequence of
160
+ a *compatible* resolution which is *strictly* needed inside
161
+ the *same* file (e.g., the renamed identifier in code one
162
+ side added outside of the hunks).
163
+
164
+ 2. `binary` and `submodule`:
165
+
166
+ If <arg4/> is `true`, escalate the file untouched. Otherwise
167
+ compare the object ids of the stages: if the stage `2` or `3`
168
+ equals the stage `1` (one side left it unchanged), take the
169
+ other, changed side by running the command
170
+ `git -C "<repo-root/>" checkout --ours -- "<file/>"` (stage `2`)
171
+ or `git -C "<repo-root/>" checkout --theirs -- "<file/>"`
172
+ (stage `3`), which is independent of the swapped side
173
+ semantics under `rebase`. Otherwise, escalate the file, as two
174
+ different binary contents or submodule commits cannot be
175
+ combined.
176
+
177
+ 3. `modify/delete`, `rename`, and `delete/delete`:
178
+
179
+ If <arg4/> is `true`, escalate the file untouched. Otherwise
180
+ resolve it only if the intent is *unambiguous* and *no* change
181
+ gets lost:
182
+
183
+ - `delete/delete`: both sides agree, so remove the file from
184
+ the index by running the command
185
+ `git -C "<repo-root/>" rm --quiet -- "<file/>"`.
186
+ - `modify/delete` and `rename`: if the deleting side *moved*
187
+ the content (e.g., renamed or split the file), *port* the
188
+ modification of the other side *completely* into the new
189
+ location (then treated like a *compatible* content
190
+ resolution, including the change preservation check) and
191
+ remove the old file via `git -C "<repo-root/>" rm --quiet -- "<file/>"`.
192
+ If the deletion *intentionally* removed a feature, but the
193
+ other side modified it, the intents contradict each other,
194
+ so escalate the file. When uncertain, escalate, as keeping
195
+ the conflict is always safe.
196
+
197
+ 4. <if condition="<arg3/> is `true` and <ase-headless/> is not `true`">
198
+
199
+ Before a hunk or file is finally escalated, let the user decide
200
+ on it interactively. For this, first show the hunk (its *ours*,
201
+ *base*, and *theirs* sections, or the stage summary for a
202
+ non-content conflict), the determined intents of both sides,
203
+ and the reason why it is unresolvable. Then, in the following,
204
+ you *MUST* *NOT* use your built-in <user-dialog-tool/> tool!
205
+ Instead, you *MUST* just show a custom dialog according to the
206
+ expanded `custom-dialog` definition. You *MUST* closely follow
207
+ this definition:
208
+
209
+ <expand name="custom-dialog" arg1="--other">
210
+ Conflict: How shall the conflict be resolved? (free-text: describe the manual resolution)
211
+ OURS: take the ours side only
212
+ THEIRS: take the theirs side only
213
+ BOTH: take both sides, ours first, then theirs
214
+ KEEP: keep the conflict as it is and escalate it
215
+ </expand>
216
+
217
+ Apply `OURS`, `THEIRS`, or `BOTH` literally, which is an
218
+ *explicit* user decision and hence exempt from the change
219
+ preservation check below. For an `OTHER: ` result, strip this
220
+ prefix and apply the described manual resolution. For `KEEP` or
221
+ `CANCEL`, escalate the hunk or file as usual.
222
+
223
+ </if>
224
+
225
+ Record every escalated hunk or file in <resolve-escalations/> with
226
+ its file, its line range (or the whole file), its conflict kind, a
227
+ one-line intent of each side, and a one-line reason.
228
+
229
+ 5. CHECK CHANGE PRESERVATION:
230
+
231
+ For every *resolved* hunk (except explicit user decisions), verify
232
+ that *no* change got lost: every line which *ours* added, removed,
233
+ or modified relative to the *base*, and every line which *theirs*
234
+ added, removed, or modified relative to the *base*, *MUST* be
235
+ reflected in the resolution, unless the deviation is *justified* by
236
+ the intent of the other side (e.g., a combined line which carries
237
+ both modifications). Without a base, every line of both sides
238
+ *MUST* be reflected. Additionally, compare the resolved file against
239
+ its backup by running the command
240
+ `git -C "<repo-root/>" diff --no-index -- "<resolve-backup-dir/>/<file/>" "<repo-root/>/<file/>"`
241
+ (which intentionally exits non-zero when the files differ) and
242
+ verify that it changed *nothing* outside of the conflict hunks
243
+ except for the strictly needed consequences of item 4.1.2.
244
+
245
+ If any check fails for a hunk, restore this hunk *verbatim* from the
246
+ backup, including its conflict markers, and escalate it with the
247
+ reason `change preservation check failed`. If the check cannot be
248
+ decided at all for a file, restore the entire file from the backup
249
+ by running the command
250
+ `cp -p "<resolve-backup-dir/>/<file/>" "<repo-root/>/<file/>"`
251
+ and escalate all its hunks.
252
+
253
+ 6. STAGE RESOLVED FILES:
254
+
255
+ 1. Determine the *fully resolved* files: all unmerged and marker
256
+ files without any escalated hunk. Check them for leftover
257
+ conflict markers by running the command
258
+ `git -C "<repo-root/>" grep -n -I --untracked -E "^(<{7}|\|{7}|>{7})( |$)" -- <files/>`
259
+ (with <files/> being the quoted fully resolved files). If it
260
+ reports lines of a file, treat the reported hunks as escalated
261
+ with the reason `leftover conflict markers`.
262
+
263
+ 2. Stage every fully resolved *unmerged* file by running the
264
+ command `git -C "<repo-root/>" add -- "<file/>"` (except for
265
+ files already removed from the index via `git rm` or taken via
266
+ `git checkout --ours`/`--theirs`, which additionally need this
267
+ `git add`). You *MUST* *NOT* stage *marker* files, as they were
268
+ not staged before either, and you *MUST* *NOT* stage *partially*
269
+ resolved files, which hence stay *unmerged* (resp. carry their
270
+ remaining conflict markers).
271
+
272
+ 7. DETERMINE VERDICT:
273
+
274
+ If <resolve-escalations/> is empty, set
275
+ <resolve-verdict>RESOLVED</resolve-verdict> and remove the backups
276
+ by running the command `rm -rf "<resolve-backup-dir/>"`. Otherwise,
277
+ set <resolve-verdict>PARTIAL</resolve-verdict> and *keep* the
278
+ backups, as they hold the original conflict state of the escalated
279
+ files.
280
+
281
+ </define>
282
+
283
+ <define name="resolve-report">
284
+
285
+ <if condition="<resolve-escalations/> is not empty">
286
+ Set <backups/> to the text `⊚ backups:`, followed by a blank and
287
+ <resolve-backup-dir/> rendered as a code span, if <resolve-backup-dir/>
288
+ is not empty, or to empty otherwise. Then only output the following <template/>, with one entry
289
+ per escalation in <resolve-escalations/>:
290
+
291
+ <template>
292
+ <ase-tpl-head title="ESCALATIONS" subtitle="<arg1/>"/>
293
+
294
+ <ase-tpl-bullet-signal/> `<file/>:<lines/>` (<kind/>): <reason/>
295
+ ◦ ours: <ours-intent/>
296
+ ◦ theirs: <theirs-intent/>
297
+ [...]
298
+
299
+ <backups/>
300
+
301
+ <ase-tpl-foot title="ESCALATIONS" subtitle="<arg1/>"/>
302
+ </template>
303
+ </if>
304
+
305
+ </define>