@rse/ase 2.0.7 → 2.0.8

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 (33) hide show
  1. package/dst/ase-agent-relay-client.js +3 -4
  2. package/dst/ase-config-schema.js +4 -1
  3. package/dst/ase-lib-fetch.js +12 -0
  4. package/dst/ase-lib-server-cli.js +8 -5
  5. package/dst/ase-task-board-diff.js +120 -0
  6. package/dst/ase-task-board-tui-control.js +8 -5
  7. package/dst/ase-task-board-tui-model.js +54 -14
  8. package/dst/ase-task-board-tui-popup.js +41 -8
  9. package/dst/ase-task-board-tui.js +42 -27
  10. package/dst/ase-task-board-web-client.css +1 -1
  11. package/dst/ase-task-board-web-client.html +16 -0
  12. package/dst/ase-task-board-web-client.js +33 -33
  13. package/dst/ase-task-board-web-server.js +44 -9
  14. package/dst/ase-task-board.js +12 -4
  15. package/dst/ase-task-store-client.js +4 -5
  16. package/dst/man/ase-config-init.md +2 -1
  17. package/dst/man/ase-config.md +5 -0
  18. package/dst/man/ase-task-board.md +44 -2
  19. package/package.json +7 -6
  20. package/plugin/.claude-plugin/plugin.json +1 -1
  21. package/plugin/.codex-plugin/plugin.json +1 -1
  22. package/plugin/.github/plugin/plugin.json +1 -1
  23. package/plugin/meta/ase-common-task.md +24 -0
  24. package/plugin/mods/ase-mods-common.ts +73 -42
  25. package/plugin/mods/ase-mods-task-edit.ts +427 -0
  26. package/plugin/mods/ase-mods.ts +45 -14
  27. package/plugin/skills/ase-help-intent/data.md +78 -8
  28. package/plugin/skills/ase-task-edit/SKILL.md +114 -9
  29. package/plugin/skills/ase-task-edit/help.md +60 -0
  30. package/plugin/skills/ase-task-grill/SKILL.md +35 -20
  31. package/plugin/skills/ase-task-grill/help.md +18 -8
  32. /package/plugin/mods/{ase-mods-evaluate.ts → ase-mods-meta-evaluate.ts} +0 -0
  33. /package/plugin/mods/{ase-mods-grill.ts → ase-mods-task-grill.ts} +0 -0
@@ -6,24 +6,26 @@
6
6
 
7
7
  /* Claude Code function hooks module ("mod", EARLY ACCESS):
8
8
  Hooking infrastructure, registering the function hooks and dispatching
9
- them into the grill table ("ase-mods-grill.ts"), the decision matrix
10
- ("ase-mods-evaluate.ts"), the intent help ("ase-mods-help-find.ts"),
9
+ them into the grill table ("ase-mods-task-grill.ts"), the decision matrix
10
+ ("ase-mods-meta-evaluate.ts"), the intent help ("ase-mods-help-find.ts"),
11
11
  the synopsis form ("ase-mods-help-compose.ts"),
12
12
  the manual band ("ase-mods-help-show.ts"), the manpage browser
13
- ("ase-mods-help-browse.ts"), and the hint band ("ase-mods-help-hint.ts").
13
+ ("ase-mods-help-browse.ts"), the hint band ("ase-mods-help-hint.ts"),
14
+ and the task band ("ase-mods-task-edit.ts").
14
15
  As the engine loads only a module spelling "on", "$", and "next" literally,
15
16
  this is the only module touching the engine, and it binds the engine
16
17
  services needed by the other modules as plain functions. */
17
18
 
18
19
  import type { Register, PromptBox, Timer } from "claude-code"
19
20
  import { type Band, TRIGGER } from "./ase-mods-common.ts"
20
- import { modGrill } from "./ase-mods-grill.ts"
21
- import { modEvaluate } from "./ase-mods-evaluate.ts"
21
+ import { modGrill } from "./ase-mods-task-grill.ts"
22
+ import { modEvaluate } from "./ase-mods-meta-evaluate.ts"
22
23
  import { modHelpFind } from "./ase-mods-help-find.ts"
23
24
  import { modHelpCompose } from "./ase-mods-help-compose.ts"
24
25
  import { modHelpShow } from "./ase-mods-help-show.ts"
25
26
  import { modHelpBrowse } from "./ase-mods-help-browse.ts"
26
27
  import { modHelpHint } from "./ase-mods-help-hint.ts"
28
+ import { modTaskEdit, TOOL } from "./ase-mods-task-edit.ts"
27
29
 
28
30
  /* function hook registration entry point */
29
31
  export const register: Register = (on, options) => {
@@ -32,7 +34,7 @@ export const register: Register = (on, options) => {
32
34
  return
33
35
 
34
36
  /* the grill table, the decision matrix, the intent help, the synopsis form,
35
- the manual band, the manpage browser, and the hint band */
37
+ the manual band, the manpage browser, the hint band, and the task band */
36
38
  const grill = modGrill()
37
39
  const evaluate = modEvaluate()
38
40
  const intent = modHelpFind()
@@ -40,6 +42,27 @@ export const register: Register = (on, options) => {
40
42
  const manual = modHelpShow()
41
43
  const browse = modHelpBrowse()
42
44
  const hint = modHelpHint()
45
+ const task = modTaskEdit()
46
+
47
+ /* provide the tool of the task band where a person sees the band only, so
48
+ its absence tells "ase-task-edit --interactive" that no band exists */
49
+ on("session.start", async ($, e, next) => {
50
+ if (e.isInteractive && e.surface === "terminal")
51
+ await $.tool.register(TOOL)
52
+ return next(e)
53
+ })
54
+
55
+ /* serve the tool of the task band, which needs no permission, as it just
56
+ shows a task, and whose loading of the task is as harmless */
57
+ on("tool.check", { tool: "mcp__ase__ase_task_band" }, () => ({ decision: "allow" }))
58
+ on("tool.call", { tool: "mcp__ase__ase_task_band" }, async ($, e) => ({
59
+ result: await task.open(String(e.id), String(e.sections ?? ""), {
60
+ invalidate: () => $.ui.invalidate("ui.render"),
61
+ every: (ms, fn) => $.clock.every(ms, fn),
62
+ load: async (id) => (await $.tool.call({ tool: "mcp__plugin_ase_ase__ase_task_load",
63
+ id, variant: "source", tag: true })).text ?? ""
64
+ })
65
+ }))
43
66
 
44
67
  /* the bands above the prompt (the synopsis form, the intent band, and the
45
68
  manpage browser, opened in this order), the shown one (as at most one is
@@ -65,7 +88,8 @@ export const register: Register = (on, options) => {
65
88
  (toggling the manual band for a skill command with "//", resp. showing the
66
89
  synopsis form for a skill command with a manual page with "!!", else arming
67
90
  the matching of the prompt as an intent with "!!", resp. showing the manpage
68
- browser for any other prompt with "//"), close the manual band once the
91
+ browser for any other prompt with "//", resp. dropping the diff of the task
92
+ band with "##"), close the manual band once the
69
93
  prompt left its skill command or another band opened, track the skill
70
94
  command of the hint band, and track the picks of the grill table inside
71
95
  the edited prompt while no band is shown */
@@ -95,6 +119,11 @@ export const register: Register = (on, options) => {
95
119
  }
96
120
  else {
97
121
  box = await next(e)
122
+ const stripped = task.edit(box, e.inputText)
123
+ if (stripped !== box) {
124
+ box = stripped
125
+ $.ui.invalidate("ui.render")
126
+ }
98
127
  if (/[!/]$/.test(e.inputText) && box.cursor === box.text.length && TRIGGER.test(box.text))
99
128
  box = await open(box)
100
129
  }
@@ -130,10 +159,10 @@ export const register: Register = (on, options) => {
130
159
  })
131
160
 
132
161
  /* operate the synopsis form resp. the intent band, else scroll the manual
133
- page in the band, by the wheel, and never let the engine move the window
134
- over our (overflowing) band, even while it takes no scrolling */
162
+ page, else the task, in the band, by the wheel, and never let the engine
163
+ move the window over our (overflowing) band, even while it takes no scrolling */
135
164
  on("ui.scroll", { component: "AbovePrompt" }, ($, e, next) => {
136
- if (!bands.some((band) => band.scroll(e)) && !manual.scroll(e))
165
+ if (!bands.some((band) => band.scroll(e)) && !manual.scroll(e) && !task.scroll(e))
137
166
  return shown() === undefined && !manual.active() ? next(e) : {}
138
167
  $.ui.invalidate("ui.render")
139
168
  return {}
@@ -194,6 +223,7 @@ export const register: Register = (on, options) => {
194
223
  reset()
195
224
  manual.reset()
196
225
  hint.reset()
226
+ task.submit(e.text)
197
227
  $.ui.invalidate("ui.render")
198
228
  return next(e)
199
229
  }).catch(($, e, next) =>
@@ -216,19 +246,20 @@ export const register: Register = (on, options) => {
216
246
  }) ?? evaluate.render(e, ui, { invalidate }) ?? drawn
217
247
  })
218
248
 
219
- /* draw the intent band resp. the synopsis form, else the manual page,
220
- else the argument hint, into the band above the prompt (terminal only) */
249
+ /* draw the intent band resp. the synopsis form, else the manual page, else
250
+ the task, else the argument hint, into the band above the prompt (terminal only) */
221
251
  on("ui.render", { component: "AbovePrompt", surface: "terminal" }, async ($, e, next) => {
222
252
  const drawn = await next(e)
223
253
  const ui = $.ui.resolve(e)
224
- return shown()?.render(e, ui) ?? manual.render(e, ui) ?? hint.render(e, ui) ?? drawn
254
+ return shown()?.render(e, ui) ?? manual.render(e, ui) ?? task.render(e, ui) ?? hint.render(e, ui) ?? drawn
225
255
  }).catch(($, e, next) => {
226
256
  /* close a failed intent band resp. synopsis form, restore the prompt
227
257
  resp. the command as typed (instead of the held prompt), resp. close
228
- a failed manual band and hint band, and keep the drawing beneath */
258
+ a failed manual band, task band, and hint band, and keep the drawing beneath */
229
259
  const text = cancel()
230
260
  if (text === undefined) {
231
261
  manual.reset()
262
+ task.reset()
232
263
  hint.reset()
233
264
  }
234
265
  if (text !== undefined)
@@ -4595,6 +4595,9 @@ Dissect a specific task plan with a hint:
4595
4595
  [`--mode`|`-m` `auto`|`craft`|`refactor`|`resolve`|`specify`]
4596
4596
  [`--approach`|`-a`]
4597
4597
  [`--unverified`|`-u`]
4598
+ [`--focus`|`-f` *section*[,...]]
4599
+ [`--quiet`|`-q`]
4600
+ [`--interactive`|`-i`]
4598
4601
  [`--next`|`-n` *option*[,...]]
4599
4602
  [*id* | *id*: *instruction* | *instruction* | *issue-id*]
4600
4603
 
@@ -4679,6 +4682,51 @@ stale draft.
4679
4682
  build, tests, linter, type-checker, or program execution) once
4680
4683
  the source files have been modified.
4681
4684
 
4685
+ - `--focus`|`-f` *section*[,...]:
4686
+ Edit and show only the given plan *section*(s). Each *section* is
4687
+ one of `SPECIFICATION` (also `SPEC` or `WHAT`), `DESIGN` (also `DES`
4688
+ or `HOW`), or `VERIFICATION` (also `VERIFY`, `VER`, or `WHEN`),
4689
+ matched case-sensitively, or the sentinel `all` (default). The shown
4690
+ plan consists only of these sections, including their headings, but
4691
+ without the frontmatter and the title.
4692
+
4693
+ The rest of the plan stays the context, and an *instruction* requiring a
4694
+ change outside of the focus is applied nevertheless and reported by
4695
+ a warning. A new plan gets all section headings, but only the focused
4696
+ sections are populated, and `OVERWRITE` re-generates only them. An
4697
+ unknown, empty, or duplicate *section* token aborts the skill. It is
4698
+ forwarded on a hand-off to `ase-task-grill`, but not on a hand-off
4699
+ to another skill.
4700
+
4701
+ - `--quiet`|`-q`:
4702
+ Do not print the resulting plan at the end of a planning round. The
4703
+ status lines, the dialogs, and the warning on a stale implementation
4704
+ draft stay. It is forwarded on a hand-off to `ase-task-grill`, but
4705
+ not on a hand-off to another skill.
4706
+
4707
+ - `--interactive`|`-i`:
4708
+ Show the plan in a band above the prompt (*Anthropic Claude Code CLI* with
4709
+ active ASE function hooks in an interactive terminal only, else the skill
4710
+ aborts), instead of printing it, and ask for the next step without any
4711
+ dialog. The band takes 75% of the terminal height, in the fullscreen mode
4712
+ all the rows the terminal UI leaves it. Under `--focus`, it shows only the
4713
+ focused sections.
4714
+
4715
+ The band follows every change of the plan, also by others, and keeps its
4716
+ scroll position. Its line numbers are those of the plan text in `ase task
4717
+ edit`. It shows the last change as a unified diff with colored backgrounds and
4718
+ line numbers, red for removed and blue for added lines. In the fullscreen
4719
+ mode, scroll it with the mouse wheel, or with *CTRL+x* *TAB* and then
4720
+ *PageUp*/*PageDown*.
4721
+
4722
+ At the prompt, type either a refinement instruction, or one of `DONE`,
4723
+ `GRILL`, `DRAFT`, `IMPLEMENT`, or `CANCEL` (in any case), which closes the
4724
+ band. After a hand-off to `ase-task-grill`, a hand-off back reopens it.
4725
+
4726
+ Type `##` at the end of the prompt (which removes it again) to remove the
4727
+ unified diff and show just the latest state of the plan, until its next
4728
+ change. The band stays open and the input does not reach the agent.
4729
+
4682
4730
  - `--next`|`-n` *option*[,...]:
4683
4731
  Automatically answer the user dialog for the next step (at the end
4684
4732
  of this skill). *option* is a single token or a *comma-separated
@@ -4750,6 +4798,18 @@ Plan a refactoring under the id `cleanup`:
4750
4798
  ❯ /ase-task-edit -m refactor cleanup: extract HTTP client into its own class
4751
4799
  ```
4752
4800
 
4801
+ Refine and show only the `DESIGN` section of the task under id `hello`:
4802
+
4803
+ ```text
4804
+ ❯ /ase-task-edit --focus HOW hello: print the text via a dedicated logger.
4805
+ ```
4806
+
4807
+ Refine the task under id `hello` with its plan shown in a band above the prompt:
4808
+
4809
+ ```text
4810
+ ❯ /ase-task-edit --interactive hello
4811
+ ```
4812
+
4753
4813
  </purpose>
4754
4814
  <purpose name="ase-task-estimate">
4755
4815
 
@@ -4923,6 +4983,7 @@ Calibrate the estimation and store the fitted rates:
4923
4983
  [`--ground`|`-G`]
4924
4984
  [`--focus`|`-f` *section*[,...]]
4925
4985
  [`--force`|`-F`]
4986
+ [`--quiet`|`-q`]
4926
4987
  [`--next`|`-n` *option*[,...]]
4927
4988
  [*id*]
4928
4989
 
@@ -4971,7 +5032,7 @@ persisted, its `Tags:` frontmatter key records each grilled section as
4971
5032
  its own tag `grilled:`*section* (lower-case, kept alongside the tags of
4972
5033
  previously grilled sections, e.g. `grilled:specification,
4973
5034
  grilled:design`), and a `PLAN CHANGES` box shows the bullet-points
4974
- changed by the round. Finally, the user is offered a complete
5035
+ changed by the round (unless `--quiet` is given). Finally, the user is offered a complete
4975
5036
  re-grilling (with the same grilling options), or a hand-off to editing,
4976
5037
  implementation, or draft.
4977
5038
 
@@ -5033,19 +5094,28 @@ in state `[-]` (cancelled) or `[>]` (deferred) are never questioned.
5033
5094
 
5034
5095
  - `--focus`|`-f` *section*[,...]:
5035
5096
  Grill only the given plan *section*(s), in the given order. Each
5036
- *section* is one of `SPECIFICATION` (abbreviated `SPEC`), `DESIGN`
5037
- (abbreviated `DES`), or `VERIFICATION` (abbreviated `VER`), matched
5038
- case-insensitively, or the sentinel `all` (default), which expands
5039
- to `SPECIFICATION,DESIGN,VERIFICATION`. The questions are derived
5040
- from the themes of the focused sections only, while the entire plan
5041
- stays the context, and the answers may still update any section.
5042
- An unknown, empty, or duplicate *section* token aborts the skill.
5097
+ *section* is one of `SPECIFICATION` (also `SPEC` or `WHAT`), `DESIGN`
5098
+ (also `DES` or `HOW`), or `VERIFICATION` (also `VERIFY`, `VER`, or
5099
+ `WHEN`), matched case-sensitively, or the sentinel `all` (default),
5100
+ which expands to `SPECIFICATION,DESIGN,VERIFICATION`. The questions
5101
+ are derived from the themes of the focused sections only, while the
5102
+ entire plan stays the context, and an answer requiring a change
5103
+ outside of the focus is applied nevertheless and reported by a
5104
+ warning. An unknown, empty, or duplicate *section* token aborts the
5105
+ skill. It is forwarded on a re-grilling and on a hand-off to
5106
+ `ase-task-edit`, but not on a hand-off to another skill.
5043
5107
 
5044
5108
  - `--force`|`-F`:
5045
5109
  Re-grill already grilled sections completely, i.e., ignore their
5046
5110
  `grilled:`*section* tags instead of skipping them resp. re-asking
5047
5111
  only their `[?]` bullet-points.
5048
5112
 
5113
+ - `--quiet`|`-q`:
5114
+ Do not print the `PLAN CHANGES` box of the bullet-points changed by
5115
+ a round. The status lines and the dialogs stay. It is forwarded on a
5116
+ re-grilling and on a hand-off to `ase-task-edit`, but not on a
5117
+ hand-off to another skill.
5118
+
5049
5119
  - `--next`|`-n` *option*[,...]:
5050
5120
  Automatically answer the user dialog for the next step (at the end
5051
5121
  of this skill). *option* is a single token or a *comma-separated
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ase-task-edit
3
- argument-hint: "[--help|-h] [--plan|-p <option>] [--mode|-m auto|craft|refactor|resolve|specify] [--approach|-a] [--unverified|-u] [--next|-n <option>[,...]] [<id> | <id>: <instruction> | <instruction> | <issue-id>]"
3
+ argument-hint: "[--help|-h] [--plan|-p <option>] [--mode|-m auto|craft|refactor|resolve|specify] [--approach|-a] [--unverified|-u] [--focus|-f <section>[,...]] [--quiet|-q] [--interactive|-i] [--next|-n <option>[,...]] [<id> | <id>: <instruction> | <instruction> | <issue-id>]"
4
4
  description: >
5
5
  Iteratively edit and refine a named plan for a task through a
6
6
  conversational loop. A new plan is optionally composed along the
@@ -27,7 +27,7 @@ Iteratively Edit a Task Plan
27
27
 
28
28
  <expand name="getopt"
29
29
  arg1="ase-task-edit"
30
- arg2="--plan|-p=(none|OVERWRITE|REFINE|PRESERVE) --mode|-m=(auto|craft|refactor|resolve|specify) --approach|-a --unverified|-u --next|-n=(none|DONE|GRILL|DRAFT|IMPLEMENT)... --int-reuse-task --int-source-dir=">
30
+ arg2="--plan|-p=(none|OVERWRITE|REFINE|PRESERVE) --mode|-m=(auto|craft|refactor|resolve|specify) --approach|-a --unverified|-u --focus|-f=(all|SPECIFICATION|SPEC|WHAT|DESIGN|DES|HOW|VERIFICATION|VERIFY|VER|WHEN)... --quiet|-q --interactive|-i --next|-n=(none|DONE|GRILL|DRAFT|IMPLEMENT)... --int-reuse-task --int-source-dir=">
31
31
  $ARGUMENTS
32
32
  </expand>
33
33
 
@@ -81,6 +81,19 @@ When refining the plan this way, preserve the overall structure of the
81
81
  plan and only modify what the user actually requested. Do *not* rewrite
82
82
  unrelated sections of the plan.
83
83
 
84
+ <if condition="<getopt-option-focus/> is not equal `all`">
85
+ Restrict the refinement to the sections in <sections/>: all other
86
+ sections and the "backmatter" stay *unchanged* and serve as read-only
87
+ context. Only if the <instruction/> inevitably requires a *foreign
88
+ change* outside of these sections, apply it nevertheless, set <foreign/>
89
+ to the comma-separated names of the changed sections (resp.
90
+ `backmatter`), and only output the following <template/>:
91
+
92
+ <template>
93
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ WARNING: changed sections outside of focus: **<foreign/>**
94
+ </template>
95
+ </if>
96
+
84
97
  <if condition="<getopt-option-int-source-dir/> is not empty">
85
98
  The *code basis* of the task is the separate working copy
86
99
  <getopt-option-int-source-dir/> (e.g. a checkout of the branch of its
@@ -212,6 +225,17 @@ then immediately *STOP* processing the entire current skill:
212
225
  Set <chosen-approach></chosen-approach> (empty). Do not output anything.
213
226
  </else>
214
227
 
228
+ <if condition="<getopt-option-focus/> is not equal `all` and <task-content/> is not empty">
229
+ This is the `OVERWRITE` of an existing plan under a focus, so re-generate
230
+ *only* the sections in <sections/> of <task-content/> in-place, by
231
+ closely following the defined plan format <format/> and injecting into
232
+ them all the information from the <instruction/>, the <chosen-approach/>
233
+ (if not empty), all decisions you derived from the <instruction/> and the
234
+ <chosen-approach/>, and the grounding in the project. All other sections,
235
+ the "backmatter", and all other frontmatter keys stay *unchanged*. Set the
236
+ `Kind:` frontmatter key to <task-kind/>.
237
+ </if>
238
+ <else>
215
239
  Create a new plan from scratch and store the result as
216
240
  <task-content/> by closely following the defined plan format
217
241
  <format/> and injecting into it all the information from
@@ -220,6 +244,14 @@ decisions you derived from the <instruction/> and the <chosen-approach/>, and
220
244
  the grounding in the project. Set the `Kind:` frontmatter key to
221
245
  <task-kind/>.
222
246
 
247
+ <if condition="<getopt-option-focus/> is not equal `all`">
248
+ Populate *only* the sections in <sections/> and keep all other sections
249
+ *empty*, i.e., as bare `##` headings without any bullet-points, until a
250
+ later round focuses them. Hence, the `CHANGELOG.md` bullet-point of the
251
+ grounding above is due only if `DESIGN` is in <sections/>.
252
+ </if>
253
+ </else>
254
+
223
255
  <if condition="<task-kind/> is equal `RESOLVING`">
224
256
  The plan *MUST* carry code references, a precise description of the
225
257
  problem, the resolution approach, a preview of the *unified
@@ -238,7 +270,8 @@ Call the `ase_timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
238
270
  `ase` MCP server and use the `text` field of its response
239
271
  for fresh <timestamp-created/> and <timestamp-modified/>
240
272
  information. Then insert the current <ase-task-id/>,
241
- <timestamp-created/>, and <timestamp-modified/> information.
273
+ <timestamp-created/>, and <timestamp-modified/> information -- except
274
+ for the `OVERWRITE` under a focus above, which keeps the `Created:` key.
242
275
  Set <task-content-dirty>true</task-content-dirty>.
243
276
  </define>
244
277
 
@@ -262,6 +295,23 @@ Set <args></args> (set args to empty).
262
295
  Inherit the always existing <ase-session-id/> from the current context.
263
296
  Do not output anything.
264
297
 
298
+ <expand name="task-focus" arg1="ase-task-edit"></expand>
299
+
300
+ Set <band-open>false</band-open>.
301
+ <if condition="<getopt-option-interactive/> is `true`">
302
+ The band of `--interactive` is drawn by the function hooks module
303
+ of the plugin, which provides the `mcp__ase__ase_task_band` tool
304
+ in an interactive terminal only. Load the schema of this tool (if
305
+ deferred, via `ToolSearch` with the query
306
+ `select:mcp__ase__ase_task_band`). If this tool does not exist,
307
+ only output the following <template/> and then immediately *STOP*
308
+ processing the entire current skill:
309
+
310
+ <template>
311
+ ⧉ **ASE**: ☻ skill: **ase-task-edit**, ▶ ERROR: `--interactive` requires the active ASE function hooks in an interactive terminal
312
+ </template>
313
+ </if>
314
+
265
315
  2. Resolve a potential analyzer issue:
266
316
 
267
317
  <if condition="
@@ -647,6 +697,7 @@ Set <args></args> (set args to empty).
647
697
  silently *skip* this entire step 3.3 (no MCP tool call and no
648
698
  output at all) and continue with step 3.4.
649
699
 
700
+ <if condition="<getopt-option-quiet/> is not equal `true` and <getopt-option-interactive/> is not equal `true`">
650
701
  <if condition="<task-render/> is empty">
651
702
  Call the `ase_markdown_prepare(text: "<task-content/>")` tool of
652
703
  the `ase` MCP server and set <task-render/> to the `text` output
@@ -684,22 +735,34 @@ Set <args></args> (set args to empty).
684
735
  ⇥ **Target:** <task-target/>
685
736
  </format>
686
737
 
738
+ Set <focus-label></focus-label> (empty).
739
+ <if condition="<getopt-option-focus/> is not equal `all`">
740
+ For the *rendering only*, overriding the above, additionally drop
741
+ the glyph lines, the `# TASK: <title/>` heading, every `##`
742
+ section whose name is *not* in <sections/>, and the entire
743
+ "backmatter", keeping the remaining sections, including their
744
+ `##` headings, in their plan order, and set <focus-label/> to
745
+ ` (<names/>)`, with <names/> being the comma-separated names of
746
+ these remaining sections.
747
+ </if>
748
+
687
749
  Only output the following <template/>, so the user
688
750
  can read the plan and react to it. Do *not* truncate,
689
- summarize, or partially show the plan. Use the
690
- following <template/>:
751
+ summarize, or partially show the plan, beyond the focus
752
+ above. Use the following <template/>:
691
753
 
692
754
  <template>
693
- <ase-tpl-head title="TASK" subtitle="<task-id/>"/>
755
+ <ase-tpl-head title="TASK" subtitle="<task-id/><focus-label/>"/>
694
756
  <task-render/>
695
- <ase-tpl-foot title="TASK" subtitle="<task-id/>"/>
757
+ <ase-tpl-foot title="TASK" subtitle="<task-id/><focus-label/>"/>
696
758
  </template>
759
+ </if>
697
760
 
698
761
  <if condition="the backmatter of <task-content/> contains an attachment
699
762
  block with the `Type` key value `text/x-diff; charset=utf-8; kind="draft"`
700
763
  which is *stale* according to the plan <format/> (its `Modified` key
701
764
  is absent or older than the `Modified` key of the frontmatter)">
702
- Directly *after* this <template/>, only output the following
765
+ Directly *after* any rendering, only output the following
703
766
  <template/> and then give the corrective hint by expanding the
704
767
  subsequent construct (which, depending on the configured
705
768
  <ase-guidance-level/>, may expand into nothing and hence emit
@@ -742,7 +805,40 @@ Set <args></args> (set args to empty).
742
805
  ⧉ **ASE**: ☻ skill: **ase-task-edit**, ▶ ERROR: invalid `--next` token: **<head/>**
743
806
  </template>
744
807
 
745
- - If <getopt-option-next/> is equal to `none`:
808
+ - If <getopt-option-next/> is equal to `none` and <getopt-option-interactive/> is `true`:
809
+
810
+ <if condition="<band-open/> is `false`">
811
+ Call the `mcp__ase__ase_task_band(id: "<ase-task-id/>")` tool --
812
+ if <getopt-option-focus/> is not equal `all`, additionally with
813
+ the argument `sections: "<sections/>"` -- to show the plan in the
814
+ band above the prompt, which from now on follows every change of
815
+ the plan on its own, and set <band-open>true</band-open>. If its
816
+ `text` output field starts with `ERROR: <info/>`, only output the
817
+ following <template/> and then immediately *STOP* processing the
818
+ entire current skill:
819
+
820
+ <template>
821
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: **<info/>**
822
+ </template>
823
+ </if>
824
+
825
+ Do *not* show any dialog. Only output the following <template/>,
826
+ end the current turn, wait for the user input, and store the
827
+ user input in <result/>:
828
+
829
+ <template>
830
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **awaiting instruction**
831
+ </template>
832
+
833
+ If <result/>, with any leading and trailing whitespace stripped,
834
+ case-insensitively equals `DONE`, `GRILL`, `DRAFT`, `IMPLEMENT`,
835
+ or `CANCEL` -- exactly the inputs on which the band closes on its
836
+ own -- set <result/> to this upper-case token. Otherwise, set
837
+ <result>OTHER: <result/></result>, also for an input which merely
838
+ indicates that the user does not want to proceed, as the band
839
+ stays open on it.
840
+
841
+ - If <getopt-option-next/> is equal to `none` and <getopt-option-interactive/> is not `true`:
746
842
 
747
843
  In the following, you *MUST* *NOT* use your built-in
748
844
  <user-dialog-tool/> tool! Instead, you *MUST* just show a
@@ -772,6 +868,15 @@ Set <args></args> (set args to empty).
772
868
 
773
869
  *Break* out of the *loop*.
774
870
  <expand name="handoff-args"/>
871
+ <if condition="<getopt-option-quiet/> is `true`">
872
+ Set <args><args/> --quiet</args>.
873
+ </if>
874
+ <if condition="<getopt-option-interactive/> is `true`">
875
+ Set <args><args/> --int-interactive</args>.
876
+ </if>
877
+ <if condition="<getopt-option-focus/> is not equal `all`">
878
+ Set <args><args/> --focus <getopt-option-focus/></args>.
879
+ </if>
775
880
  Only output the following <template/> and then call the
776
881
  `Skill(skill: "ase:ase-task-grill", args: "<args/>")` tool
777
882
  to *grill* the finalized plan.
@@ -11,6 +11,9 @@
11
11
  [`--mode`|`-m` `auto`|`craft`|`refactor`|`resolve`|`specify`]
12
12
  [`--approach`|`-a`]
13
13
  [`--unverified`|`-u`]
14
+ [`--focus`|`-f` *section*[,...]]
15
+ [`--quiet`|`-q`]
16
+ [`--interactive`|`-i`]
14
17
  [`--next`|`-n` *option*[,...]]
15
18
  [*id* | *id*: *instruction* | *instruction* | *issue-id*]
16
19
 
@@ -95,6 +98,51 @@ stale draft.
95
98
  build, tests, linter, type-checker, or program execution) once
96
99
  the source files have been modified.
97
100
 
101
+ - `--focus`|`-f` *section*[,...]:
102
+ Edit and show only the given plan *section*(s). Each *section* is
103
+ one of `SPECIFICATION` (also `SPEC` or `WHAT`), `DESIGN` (also `DES`
104
+ or `HOW`), or `VERIFICATION` (also `VERIFY`, `VER`, or `WHEN`),
105
+ matched case-sensitively, or the sentinel `all` (default). The shown
106
+ plan consists only of these sections, including their headings, but
107
+ without the frontmatter and the title.
108
+
109
+ The rest of the plan stays the context, and an *instruction* requiring a
110
+ change outside of the focus is applied nevertheless and reported by
111
+ a warning. A new plan gets all section headings, but only the focused
112
+ sections are populated, and `OVERWRITE` re-generates only them. An
113
+ unknown, empty, or duplicate *section* token aborts the skill. It is
114
+ forwarded on a hand-off to `ase-task-grill`, but not on a hand-off
115
+ to another skill.
116
+
117
+ - `--quiet`|`-q`:
118
+ Do not print the resulting plan at the end of a planning round. The
119
+ status lines, the dialogs, and the warning on a stale implementation
120
+ draft stay. It is forwarded on a hand-off to `ase-task-grill`, but
121
+ not on a hand-off to another skill.
122
+
123
+ - `--interactive`|`-i`:
124
+ Show the plan in a band above the prompt (*Anthropic Claude Code CLI* with
125
+ active ASE function hooks in an interactive terminal only, else the skill
126
+ aborts), instead of printing it, and ask for the next step without any
127
+ dialog. The band takes 75% of the terminal height, in the fullscreen mode
128
+ all the rows the terminal UI leaves it. Under `--focus`, it shows only the
129
+ focused sections.
130
+
131
+ The band follows every change of the plan, also by others, and keeps its
132
+ scroll position. Its line numbers are those of the plan text in `ase task
133
+ edit`. It shows the last change as a unified diff with colored backgrounds and
134
+ line numbers, red for removed and blue for added lines. In the fullscreen
135
+ mode, scroll it with the mouse wheel, or with *CTRL+x* *TAB* and then
136
+ *PageUp*/*PageDown*.
137
+
138
+ At the prompt, type either a refinement instruction, or one of `DONE`,
139
+ `GRILL`, `DRAFT`, `IMPLEMENT`, or `CANCEL` (in any case), which closes the
140
+ band. After a hand-off to `ase-task-grill`, a hand-off back reopens it.
141
+
142
+ Type `##` at the end of the prompt (which removes it again) to remove the
143
+ unified diff and show just the latest state of the plan, until its next
144
+ change. The band stays open and the input does not reach the agent.
145
+
98
146
  - `--next`|`-n` *option*[,...]:
99
147
  Automatically answer the user dialog for the next step (at the end
100
148
  of this skill). *option* is a single token or a *comma-separated
@@ -166,6 +214,18 @@ Plan a refactoring under the id `cleanup`:
166
214
  ❯ /ase-task-edit -m refactor cleanup: extract HTTP client into its own class
167
215
  ```
168
216
 
217
+ Refine and show only the `DESIGN` section of the task under id `hello`:
218
+
219
+ ```text
220
+ ❯ /ase-task-edit --focus HOW hello: print the text via a dedicated logger.
221
+ ```
222
+
223
+ Refine the task under id `hello` with its plan shown in a band above the prompt:
224
+
225
+ ```text
226
+ ❯ /ase-task-edit --interactive hello
227
+ ```
228
+
169
229
  ## SEE ALSO
170
230
 
171
231
  [`ase-code-edit`](../ase-code-edit/help.md), [`ase-spec-edit`](../ase-spec-edit/help.md), [`ase-task-grill`](../ase-task-grill/help.md),