@rse/ase 0.0.32 → 0.0.33

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.
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "ase",
3
+ "owner": {
4
+ "name": "Dr. Ralf S. Engelschall",
5
+ "email": "rse@engelschall.com"
6
+ },
7
+ "metadata": {
8
+ "description": "Agentic Software Engineering (ASE)"
9
+ },
10
+ "plugins": [
11
+ {
12
+ "name": "ase",
13
+ "source": "./plugin/",
14
+ "description": "Agentic Software Engineering (ASE)"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,145 @@
1
+ /*
2
+ ** Agentic Software Engineering (ASE)
3
+ ** Copyright (c) 2025-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+ import { z } from "zod";
7
+ import { Command, Option } from "commander";
8
+ import { parse as shParse, quote as shQuote } from "shell-quote";
9
+ /* MCP registration entry point for the option-parser tool */
10
+ export class GetoptMCP {
11
+ register(mcp) {
12
+ mcp.registerTool("getopt", {
13
+ title: "ASE option parser",
14
+ description: "Parse `args` against the options specification in " +
15
+ "`spec` of the form `--<long>[|-<short>][=<default>] ...` " +
16
+ "and return `{ opts, argv, args, info }` as JSON `text`, where " +
17
+ "`argv` is the array of remaining tokens after option parsing, " +
18
+ "`args` is the verbatim substring of the original input " +
19
+ "containing those remaining tokens (quotes preserved), and " +
20
+ "`info` is a markdown rendering of the parsed options in the " +
21
+ "form `key: **value**, key: **value**, ...` for printing at " +
22
+ "the top of a skill.",
23
+ inputSchema: {
24
+ name: z.string()
25
+ .describe("Name of the caller (e.g. skill name), used in error messages"),
26
+ spec: z.string()
27
+ .describe("Whitespace-separated option spec, e.g. `--foo/-f --bar --baz/-b=BAZ`"),
28
+ args: z.union([z.string(), z.array(z.string())])
29
+ .describe("Arguments to parse (string is split on whitespace)")
30
+ }
31
+ }, async (args) => {
32
+ let helpText = "";
33
+ try {
34
+ /* normalize args */
35
+ const argsRaw = typeof args.args === "string" ? args.args : null;
36
+ const argsVec = typeof args.args === "string" ?
37
+ shParse(args.args).filter((e) => typeof e === "string") :
38
+ args.args;
39
+ /* build a fresh commander program */
40
+ const cmd = new Command(args.name)
41
+ .exitOverride()
42
+ .allowExcessArguments(true)
43
+ .allowUnknownOption(false)
44
+ .passThroughOptions(true)
45
+ .configureOutput({
46
+ writeOut: (str) => { helpText += str; },
47
+ writeErr: () => { }
48
+ });
49
+ /* tokenize spec and add one option per token */
50
+ const tokens = args.spec.split(/\s+/).filter((e) => e.length > 0);
51
+ const re = /^--([A-Za-z][A-Za-z0-9-]*)(?:\|-([A-Za-z]))?(?:=(\((.*)\)|.*))?$/;
52
+ for (const tok of tokens) {
53
+ const m = re.exec(tok);
54
+ if (m === null)
55
+ throw new Error(`invalid spec token "${tok}"`);
56
+ const long = m[1];
57
+ const short = m[2] ?? null;
58
+ const valuePart = m[3] ?? null;
59
+ const choicePart = m[4] ?? null;
60
+ const takesValue = valuePart !== null;
61
+ const choices = choicePart !== null ? choicePart.split("|") : null;
62
+ const dflt = choices !== null ? choices[0] : valuePart;
63
+ const head = short !== null ? `-${short}, --${long}` : `--${long}`;
64
+ const flags = takesValue ? `${head} <value>` : head;
65
+ const opt = new Option(flags);
66
+ if (takesValue) {
67
+ if (choices !== null)
68
+ opt.choices(choices);
69
+ opt.default(dflt);
70
+ }
71
+ else
72
+ opt.default(false);
73
+ cmd.addOption(opt);
74
+ }
75
+ /* parse args */
76
+ cmd.parse(argsVec, { from: "user" });
77
+ /* compute verbatim trailing argument string */
78
+ let argsVerbatim = "";
79
+ if (argsRaw !== null) {
80
+ /* tokenize raw input into [start,end) ranges, preserving quotes */
81
+ const ranges = [];
82
+ let i = 0;
83
+ while (i < argsRaw.length) {
84
+ while (i < argsRaw.length && /\s/.test(argsRaw[i]))
85
+ i++;
86
+ if (i >= argsRaw.length)
87
+ break;
88
+ const start = i;
89
+ while (i < argsRaw.length && !/\s/.test(argsRaw[i])) {
90
+ const ch = argsRaw[i];
91
+ if (ch === "\"" || ch === "'") {
92
+ const quote = ch;
93
+ i++;
94
+ while (i < argsRaw.length && argsRaw[i] !== quote) {
95
+ if (argsRaw[i] === "\\" && i + 1 < argsRaw.length)
96
+ i++;
97
+ i++;
98
+ }
99
+ if (i < argsRaw.length)
100
+ i++;
101
+ }
102
+ else
103
+ i++;
104
+ }
105
+ ranges.push({ start, end: i });
106
+ }
107
+ const tail = cmd.args.length;
108
+ if (tail > 0 && ranges.length >= tail) {
109
+ const first = ranges[ranges.length - tail].start;
110
+ argsVerbatim = argsRaw.slice(first);
111
+ }
112
+ }
113
+ else
114
+ argsVerbatim = cmd.args.join(" ");
115
+ /* build markdown info rendering of parsed options */
116
+ const opts = cmd.opts();
117
+ const info = Object.entries(opts)
118
+ .map(([k, v]) => `${k}: **${shQuote([String(v)])}**`)
119
+ .join(", ");
120
+ /* build result */
121
+ const result = { opts, argv: cmd.args, args: argsVerbatim, info };
122
+ return {
123
+ content: [{ type: "text", text: JSON.stringify(result) }]
124
+ };
125
+ }
126
+ catch (err) {
127
+ /* intercept commander help/version output */
128
+ const code = err?.code ?? "";
129
+ if (code === "commander.helpDisplayed"
130
+ || code === "commander.help"
131
+ || code === "commander.version") {
132
+ return {
133
+ isError: true,
134
+ content: [{ type: "text", text: `ERROR: usage information requested\n\n${helpText.trimEnd()}` }]
135
+ };
136
+ }
137
+ const message = err instanceof Error ? err.message : String(err);
138
+ return {
139
+ isError: true,
140
+ content: [{ type: "text", text: `ERROR: ${message}` }]
141
+ };
142
+ }
143
+ });
144
+ }
145
+ }
@@ -21,6 +21,7 @@ import { TaskMCP } from "./ase-task.js";
21
21
  import { KVMCP } from "./ase-kv.js";
22
22
  import PersonaMCP from "./ase-persona.js";
23
23
  import { TimestampMCP } from "./ase-timestamp.js";
24
+ import { GetoptMCP } from "./ase-getopt.js";
24
25
  import pkg from "../package.json" with { type: "json" };
25
26
  /* shared service host */
26
27
  export const SERVICE_HOST = "127.0.0.1";
@@ -236,6 +237,7 @@ export default class ServiceCommand {
236
237
  new KVMCP().register(mcp);
237
238
  new PersonaMCP(this.log).register(mcp);
238
239
  new TimestampMCP().register(mcp);
240
+ new GetoptMCP().register(mcp);
239
241
  return mcp;
240
242
  };
241
243
  /* listen to HTTP/REST endpoints */
package/dst/ase-setup.js CHANGED
@@ -126,6 +126,28 @@ export default class SetupCommand {
126
126
  }
127
127
  return 0;
128
128
  }
129
+ /* handler for "ase setup enable" (both tools) */
130
+ async doEnable(tool) {
131
+ const spec = toolSpecs[tool];
132
+ await this.ensureTool(spec.cli);
133
+ this.log.write("info", `setup: enable: enabling ASE ${spec.label} plugin`);
134
+ const args = tool === "claude" ?
135
+ ["plugin", "enable", "ase@ase"] :
136
+ ["plugin", "install", "ase@ase"];
137
+ await this.run(spec.cli, args, { retries: tool === "claude" ? 1 : 3 });
138
+ return 0;
139
+ }
140
+ /* handler for "ase setup disable" (both tools) */
141
+ async doDisable(tool) {
142
+ const spec = toolSpecs[tool];
143
+ await this.ensureTool(spec.cli);
144
+ this.log.write("info", `setup: disable: disabling ASE ${spec.label} plugin`);
145
+ const args = tool === "claude" ?
146
+ ["plugin", "disable", "ase@ase"] :
147
+ ["plugin", "uninstall", "ase@ase"];
148
+ await this.run(spec.cli, args, { retries: tool === "claude" ? 1 : 3 });
149
+ return 0;
150
+ }
129
151
  /* handler for "ase setup uninstall" (both tools) */
130
152
  async doUninstall(tool, dev) {
131
153
  const spec = toolSpecs[tool];
@@ -197,5 +219,21 @@ export default class SetupCommand {
197
219
  .action(async (opts) => {
198
220
  process.exit(await this.doUninstall(this.parseTool(opts.tool), opts.dev));
199
221
  });
222
+ /* register CLI sub-command "ase setup enable" */
223
+ setupCmd
224
+ .command("enable")
225
+ .description("enable the ASE plugin for a tool")
226
+ .option("-t, --tool <tool>", "target tool (\"claude\" or \"copilot\")", toolDflt)
227
+ .action(async (opts) => {
228
+ process.exit(await this.doEnable(this.parseTool(opts.tool)));
229
+ });
230
+ /* register CLI sub-command "ase setup disable" */
231
+ setupCmd
232
+ .command("disable")
233
+ .description("disable the ASE plugin for a tool")
234
+ .option("-t, --tool <tool>", "target tool (\"claude\" or \"copilot\")", toolDflt)
235
+ .action(async (opts) => {
236
+ process.exit(await this.doDisable(this.parseTool(opts.tool)));
237
+ });
200
238
  }
201
239
  }
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "homepage": "http://github.com/rse/ase",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "http://github.com/rse/ase/issues" },
9
- "version": "0.0.32",
9
+ "version": "0.0.33",
10
10
  "license": "GPL-3.0-only",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -68,6 +68,7 @@
68
68
  "dst/**/*",
69
69
  "bin/**/*",
70
70
  "plugin/**/*",
71
+ ".claude-plugin/**/*",
71
72
  "README.md"
72
73
  ],
73
74
  "scripts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -0,0 +1,68 @@
1
+
2
+ <define name="getopt">
3
+
4
+ For parsing the command/skill options, perform the following seven steps
5
+ and then continue processing the remaining skill.
6
+
7
+ Do not output anything in the following steps. The entire purpose is to
8
+ set placeholders into the context as a side-effect.
9
+
10
+ 1. **Determine Parameters**:
11
+ Set <getopt-skill><arg1/></getopt-skill>.
12
+ Set <getopt-spec/><arg2/></getopt-spec>.
13
+ Set <getopt-opts/><arg3/>/getopt-opts>.
14
+ Set <getopt-args/><content/></getopt-args>.
15
+
16
+ 2. **Short-Circuit for Quick Processing**:
17
+ If <getopt-opts/> contains `quick` *AND*
18
+ <getopt-args/> does *NOT* match the regexp `^\s*-':
19
+ Set <getopt-arguments><getopt-args/></getopt-arguments> and
20
+ then just silently *SKIP* the following steps 3-7!
21
+
22
+ 3. **MCP Call**:
23
+ Call the `getopt(name: <getopt-skill/>, spec: <getopt-spec/>, args:
24
+ <getopt-args/>)` tool of the `ase` MCP service and set <text/> to the
25
+ `text` output field of this tool call. The `spec` syntax for each
26
+ option token is `--<long>[|-<short>][=<default>|=(<c1>|<c2>|...)]`,
27
+ where `=<default>` declares a value-taking option with a default,
28
+ and `=(<c1>|<c2>|...)` declares a value-taking option restricted to
29
+ the listed fixed choices (the first choice acts as the default).
30
+
31
+ 4. **Short-Circuit for Error**:
32
+ If <text/> starts with `ERROR:`:
33
+ Remove all `ERROR:` or `error:` prefixes from <text/>.
34
+ Then only output the following <template/> and
35
+ then immediately *STOP* processing the entire current skill:
36
+
37
+ <template>
38
+ ⧉ **ASE**: ☻ skill: **<getopt-skill/>**, ▶ ERROR: option parsing failed: **<text/>**
39
+ </template>
40
+
41
+ 5. **Parsing JSON Result**:
42
+ The tool returned a single `text` content payload containing JSON.
43
+ Parse this JSON in <text/> now into <getopt-result/> by recognizing
44
+ the following shape:
45
+
46
+ ```json
47
+ {
48
+ "opts": { "<long1/>": <value1/>, "<long2/>": <value2/>, ... },
49
+ "argv": [ "<arg1/>", "<arg2/>", ... ]
50
+ "args": "..."
51
+ }
52
+ ```
53
+
54
+ 6. **Materializing into Context**:
55
+ For each *key* `<long/>` in <getopt-result/>`.opts`:
56
+ Set <getopt-option-<long/>/> to the corresponding value from
57
+ `<getopt-result/>.opts[<long/>]`.
58
+ Set <getopt-arguments/> to the value of `<getopt-result/>.args`.
59
+ Set <getopt-info/> to `<getopt-result/>`.info`.
60
+
61
+ 7. **Display Results**:
62
+ Just output the following <template/>:
63
+
64
+ <template>
65
+ ⧉ **ASE**: ☻ skill: **<getopt-skill/>**, ▶ options: <getopt-info/>
66
+ </template>
67
+ </define>
68
+
@@ -14,6 +14,7 @@ allowed-tools:
14
14
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
16
16
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
17
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
17
18
 
18
19
  Craft Feature
19
20
  =============
@@ -22,13 +23,19 @@ Craft Feature
22
23
  Craft Source Code
23
24
  </skill>
24
25
 
26
+ <expand name="getopt"
27
+ arg1="ase-code-craft"
28
+ arg2="--auto|-a --next|-n=(none|DONE|EDIT|PREFLIGHT|IMPLEMENT)">
29
+ $ARGUMENTS
30
+ </expand>
31
+
25
32
  <role>
26
33
  Your role is an experienced, *expert-level software developer*.
27
34
  </role>
28
35
 
29
36
  <objective>
30
37
  From scratch *craft* the following feature:
31
- <feature>$ARGUMENTS</feature>
38
+ <feature><getopt-arguments/></feature>
32
39
  </objective>
33
40
 
34
41
  @${CLAUDE_SKILL_DIR}/../../meta/ase-plan.md
@@ -42,6 +49,10 @@ You *MUST* not skip any numbered item during processing!
42
49
  You *MUST* *NOT* output anything in this entire procedure, *except* when
43
50
  explicitly requested by this procedure via outputs based on a <template/>!
44
51
 
52
+ You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
53
+ filesystem-modifying tool during this entire skill. The *only*
54
+ permitted way to persist artifacts is via `task_save(...)`.
55
+
45
56
  1. **Reason About Feature**:
46
57
 
47
58
  1. <if condition="
@@ -156,19 +167,31 @@ explicitly requested by this procedure via outputs based on a <template/>!
156
167
 
157
168
  4. **Choose Feature Crafting Approach**:
158
169
 
159
- 1. Let the *user interactively choose* the preferred feature approach A<n/>
170
+ 1. If <getopt-option-auto/> is equal `true`:
171
+ Let the *user interactively choose* the preferred feature approach A<n/>
160
172
  with the help of the <user-dialog-tool/> tool. Use *single-selection* only
161
173
  and provide small *code change previews*. Mark your recommended
162
174
  feature approach with ` ⚝ **RECOMMENDATION** ⚝` here again.
163
175
 
164
- 5. **Write Feature Crafting Plan**:
176
+ 2. If <getopt-option-auto/> is not equal `true`:
177
+ Set <n/> to the number of the feature approach A<n/> you recommend.
178
+ Output a hint with the following <template/>:
179
+
180
+ <template>
181
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **auto-chosen approach A<n/>**
182
+ </template>
165
183
 
166
- 1. *Write a feature plan* for the chosen feature A<n/> by
184
+ 5. **Compose Feature Crafting Plan**:
185
+
186
+ 1. *Compose a feature plan* for the chosen feature A<n/> by
167
187
  closely aligning to the existing architecture and the existing
168
188
  code base. Use the <format/> defined for a task plan and inject
169
189
  the information from feature A<n/> and all derived realization
170
190
  decisions into it. Store the resulting task plan in <content/>.
171
191
 
192
+ You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
193
+ filesystem-modifying tool during this step.
194
+
172
195
  2. Call the `timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
173
196
  `ase` MCP service and use the `text` field of its response for
174
197
  <timestamp-created/> and <timestamp-modified/> information. Then
@@ -185,16 +208,22 @@ explicitly requested by this procedure via outputs based on a <template/>!
185
208
  ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan created**
186
209
  </template>
187
210
 
188
- 5. *Ask user*: Let the *user interactively choose*
189
- what to do as the next step.
211
+ 5. *Determine next step*:
212
+
213
+ - If <getopt-option-next/> matches the regex `^(DONE|EDIT|PREFLIGHT|IMPLEMENT)$`:
214
+ Honor the pre-selection what to do as the next step.
215
+ Set <result><getopt-option-next/></result>.
216
+
217
+ - If <getopt-option-next/> is equal to `none`:
218
+ Let the *user interactively choose* what to do as the next step.
190
219
 
191
- <expand name="user-dialog>
192
- Next Step: How would you like to proceed with the plan?
193
- DONE: Stop processing.
194
- EDIT: Hand processing off to editing.
195
- PREFLIGHT: Hand processing off to preflighting.
196
- IMPLEMENT: Hand processing off to implementation.
197
- </expand>
220
+ <expand name="user-dialog>
221
+ Next Step: How would you like to proceed with the plan?
222
+ DONE: Stop processing.
223
+ EDIT: Hand processing off to editing.
224
+ PREFLIGHT: Hand processing off to preflighting.
225
+ IMPLEMENT: Hand processing off to implementation.
226
+ </expand>
198
227
 
199
228
  6. Check the tool <result/> and dispatch accordingly:
200
229
 
@@ -14,6 +14,7 @@ allowed-tools:
14
14
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
16
16
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
17
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
17
18
 
18
19
  Refactor Artifacts
19
20
  ==================
@@ -22,13 +23,19 @@ Refactor Artifacts
22
23
  Refactor Artifacts
23
24
  </skill>
24
25
 
26
+ <expand name="getopt"
27
+ arg1="ase-code-refactor"
28
+ arg2="--auto|-a --next|-n=(none|DONE|EDIT|PREFLIGHT|IMPLEMENT)">
29
+ $ARGUMENTS
30
+ </expand>
31
+
25
32
  <role>
26
33
  Your role is an experienced, *expert-level software developer*.
27
34
  </role>
28
35
 
29
36
  <objective>
30
37
  *Refactor* existing artifacts the following way:
31
- <request>$ARGUMENTS</request>
38
+ <request><getopt-arguments/></request>
32
39
  </objective>
33
40
 
34
41
  @${CLAUDE_SKILL_DIR}/../../meta/ase-plan.md
@@ -42,6 +49,10 @@ You *MUST* not skip any numbered item during processing!
42
49
  You *MUST* *NOT* output anything in this entire procedure, *except* when
43
50
  explicitly requested by this procedure via outputs based on a <template/>!
44
51
 
52
+ You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
53
+ filesystem-modifying tool during this entire skill. The *only*
54
+ permitted way to persist artifacts is via `task_save(...)`.
55
+
45
56
  1. **Reason About Refactoring**:
46
57
 
47
58
  1. <if condition="
@@ -160,20 +171,32 @@ explicitly requested by this procedure via outputs based on a <template/>!
160
171
 
161
172
  4. **Choose Refactoring Approach**:
162
173
 
163
- 1. Let the *user interactively choose* the preferred refactoring approach A<n/>
174
+ 1. If <getopt-option-auto/> is equal `true`:
175
+ Let the *user interactively choose* the preferred refactoring approach A<n/>
164
176
  with the help of the <user-dialog-tool/> tool. Use *single-selection* only
165
177
  and provide small *code change previews*. Mark your recommended
166
178
  refactoring approach with ` ⚝ **RECOMMENDATION** ⚝` here again.
167
179
  Except for the interactive selection, do not output anything in this step.
168
180
 
169
- 5. **Write Refactoring Plan**:
181
+ 2. If <getopt-option-auto/> is not equal `true`:
182
+ Set <n/> to the number of the refactoring approach A<n/> you recommend.
183
+ Output a hint with the following <template/>:
184
+
185
+ <template>
186
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **auto-chosen approach A<n/>**
187
+ </template>
170
188
 
171
- 1. *Write a refactoring plan* for the chosen refactoring A<n/> by
189
+ 5. **Compose Refactoring Plan**:
190
+
191
+ 1. *Compose a refactoring plan* for the chosen refactoring A<n/> by
172
192
  closely aligning to the existing architecture and the existing
173
193
  code base. Use the <format/> defined for a task plan and inject
174
194
  the information from refactoring A<n/> and all derived realization
175
195
  decisions into it. Store the resulting task plan in <content/>.
176
196
 
197
+ You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
198
+ filesystem-modifying tool during this step.
199
+
177
200
  2. Call the `timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
178
201
  `ase` MCP service and use the `text` field of its response for
179
202
  <timestamp-created/> and <timestamp-modified/> information. Then
@@ -190,16 +213,22 @@ explicitly requested by this procedure via outputs based on a <template/>!
190
213
  ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan created**
191
214
  </template>
192
215
 
193
- 5. *Ask user*: Let the *user interactively choose*
194
- what to do as the next step.
216
+ 5. *Determine next step*:
217
+
218
+ - If <getopt-option-next/> matches the regex `^(DONE|EDIT|PREFLIGHT|IMPLEMENT)$`:
219
+ Honor the pre-selection what to do as the next step.
220
+ Set <result><getopt-option-next/></result>.
221
+
222
+ - If <getopt-option-next/> is equal to `none`:
223
+ Let the *user interactively choose* what to do as the next step.
195
224
 
196
- <expand name="user-dialog>
197
- Next Step: How would you like to proceed with the plan?
198
- DONE: Stop processing.
199
- EDIT: Hand processing off to editing.
200
- PREFLIGHT: Hand processing off to preflighting.
201
- IMPLEMENT: Hand processing off to implementation.
202
- </expand>
225
+ <expand name="user-dialog>
226
+ Next Step: How would you like to proceed with the plan?
227
+ DONE: Stop processing.
228
+ EDIT: Hand processing off to editing.
229
+ PREFLIGHT: Hand processing off to preflighting.
230
+ IMPLEMENT: Hand processing off to implementation.
231
+ </expand>
203
232
 
204
233
  6. Check the tool <result/> and dispatch accordingly:
205
234
 
@@ -14,6 +14,7 @@ allowed-tools:
14
14
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
16
16
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
17
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
17
18
 
18
19
  Resolve Problem
19
20
  ===============
@@ -22,13 +23,19 @@ Resolve Problem
22
23
  Resolve Problem
23
24
  </skill>
24
25
 
26
+ <expand name="getopt"
27
+ arg1="ase-code-resolve"
28
+ arg2="--auto|-a --next|-n=(none|DONE|EDIT|PREFLIGHT|IMPLEMENT)">
29
+ $ARGUMENTS
30
+ </expand>
31
+
25
32
  <role>
26
33
  Your role is an experienced, *expert-level software developer*.
27
34
  </role>
28
35
 
29
36
  <objective>
30
37
  *Resolve* the following problem:
31
- <problem>$ARGUMENTS</problem>
38
+ <problem><getopt-arguments/></problem>
32
39
  </objective>
33
40
 
34
41
  @${CLAUDE_SKILL_DIR}/../../meta/ase-plan.md
@@ -42,6 +49,10 @@ You *MUST* not skip any numbered item during processing!
42
49
  You *MUST* *NOT* output anything in this entire procedure, *except* when
43
50
  explicitly requested by this procedure via outputs based on a <template/>!
44
51
 
52
+ You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
53
+ filesystem-modifying tool during this entire skill. The *only*
54
+ permitted way to persist artifacts is via `task_save(...)`.
55
+
45
56
  1. **Reason About Problem**:
46
57
 
47
58
  1. If <problem/> matches the regexp `^[PT]\d+$` (i.e. a bare issue
@@ -212,19 +223,31 @@ explicitly requested by this procedure via outputs based on a <template/>!
212
223
 
213
224
  4. **Choose Problem Resolution Approach**:
214
225
 
215
- 1. Let the *user interactively choose* the preferred resolution approach A<n/>
226
+ 1. If <getopt-option-auto/> is equal `true`:
227
+ Let the *user interactively choose* the preferred resolution approach A<n/>
216
228
  with the help of the <user-dialog-tool/> tool. Use *single-selection* only
217
229
  and provide small *code change previews*. Mark your recommended
218
230
  resolution approach with ` ⚝ **RECOMMENDATION** ⚝` here again.
219
231
 
220
- 5. **Write Problem Resolution Plan**:
232
+ 2. If <getopt-option-auto/> is not equal `true`:
233
+ Set <n/> to the number of the resolution approach A<n/> you recommend.
234
+ Output a hint with the following <template/>:
235
+
236
+ <template>
237
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **auto-chosen approach A<n/>**
238
+ </template>
221
239
 
222
- 1. *Write a plan* with code references, a precise description of the
240
+ 5. **Compose Problem Resolution Plan**:
241
+
242
+ 1. *Compose a plan* with code references, a precise description of the
223
243
  problem, the chosen resolution approach, a preview of the *unified
224
244
  diff* of the necessary code changes, and a possible way to verify
225
245
  the success of the resolution, by using the <format/> defined for a
226
246
  task plan. Store the resulting task plan in <content/>.
227
247
 
248
+ You *MUST* *NOT* call `Edit`, `Write`, `NotebookEdit`, or any
249
+ filesystem-modifying tool during this step.
250
+
228
251
  2. Call the `timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
229
252
  `ase` MCP service and use the `text` field of its response for
230
253
  <timestamp-created/> and <timestamp-modified/> information. Then
@@ -248,16 +271,22 @@ explicitly requested by this procedure via outputs based on a <template/>!
248
271
  ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan created**
249
272
  </template>
250
273
 
251
- 6. *Ask user*: Let the *user interactively choose*
252
- what to do as the next step.
274
+ 6. *Determine next step*:
275
+
276
+ - If <getopt-option-next/> matches the regex `^(DONE|EDIT|PREFLIGHT|IMPLEMENT)$`:
277
+ Honor the pre-selection what to do as the next step.
278
+ Set <result><getopt-option-next/></result>.
279
+
280
+ - If <getopt-option-next/> is equal to `none`:
281
+ Let the *user interactively choose* what to do as the next step.
253
282
 
254
- <expand name="user-dialog>
255
- Next Step: How would you like to proceed with the plan?
256
- DONE: Stop processing.
257
- EDIT: Hand processing off to editing.
258
- PREFLIGHT: Hand processing off to preflighting.
259
- IMPLEMENT: Hand processing off to implementation.
260
- </expand>
283
+ <expand name="user-dialog>
284
+ Next Step: How would you like to proceed with the plan?
285
+ DONE: Stop processing.
286
+ EDIT: Hand processing off to editing.
287
+ PREFLIGHT: Hand processing off to preflighting.
288
+ IMPLEMENT: Hand processing off to implementation.
289
+ </expand>
261
290
 
262
291
  7. Check the tool <result/> and dispatch accordingly:
263
292
 
@@ -15,6 +15,7 @@ effort: high
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
16
16
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
17
17
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
18
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
18
19
 
19
20
  Iteratively Edit a Task Plan
20
21
  ============================
@@ -23,6 +24,12 @@ Iteratively Edit a Task Plan
23
24
  Iteratively Edit a Task Plan
24
25
  </skill>
25
26
 
27
+ <expand name="getopt"
28
+ arg1="ase-task-edit"
29
+ arg2="--plan|-p=(none|OVERWRITE|REFINE|PRESERVE) --next|-n=(none|DONE|IMPLEMENT|PREFLIGHT|REFINE)">
30
+ $ARGUMENTS
31
+ </expand>
32
+
26
33
  Your role is an experienced, *expert-level assistant*,
27
34
  specialized in the *planning* of changes
28
35
  through *iterative conversational refinement*.
@@ -45,7 +52,7 @@ explicitly requested by this procedure via outputs based on a <template/>!
45
52
 
46
53
  1. **Determine Task and Instruction:**
47
54
 
48
- 1. Set <instruction>$ARGUMENTS</instruction> initially.
55
+ 1. Set <instruction><getopt-arguments/></instruction> initially.
49
56
  Inherit the always existing <ase-task-id/> from the current context.
50
57
  Do not output anything.
51
58
 
@@ -162,14 +169,21 @@ explicitly requested by this procedure via outputs based on a <template/>!
162
169
  3. <if condition="<content/> is not empty AND
163
170
  <instruction/> is not empty AND
164
171
  <instruction/> is not equal <content/>">
165
- Let the *user interactively choose* what to do as the next step.
172
+ *Determine previous-plan handling*:
173
+
174
+ - If <getopt-option-plan/> matches the regex `^(OVERWRITE|REFINE|PRESERVE)$`:
175
+ Honor the pre-selection what to do with the previous plan.
176
+ Set <result><getopt-option-plan/></result>.
177
+
178
+ - If <getopt-option-plan/> is equal to `none`:
179
+ Let the *user interactively choose* what to do as the next step.
166
180
 
167
- <expand name="user-dialog>
168
- Previous Plan: Should the previous plan content be overwritten, refined, or preserved?
169
- OVERWRITE: Continue operation, overwrite previous plan.
170
- REFINE: Continue operation, refine previous plan.
171
- PRESERVE: Cancel operation, preserve previous plan.
172
- </expand>
181
+ <expand name="user-dialog>
182
+ Previous Plan: Should the previous plan content be overwritten, refined, or preserved?
183
+ OVERWRITE: Continue operation, overwrite previous plan.
184
+ REFINE: Continue operation, refine previous plan.
185
+ PRESERVE: Cancel operation, preserve previous plan.
186
+ </expand>
173
187
 
174
188
  Check the tool <result/> and dispatch accordingly:
175
189
 
@@ -285,9 +299,11 @@ explicitly requested by this procedure via outputs based on a <template/>!
285
299
  </if>
286
300
 
287
301
  3. *Render plan*: Only output the following <template/>, so the user
288
- can read the plan and react to it. Do *not* truncate, summarize,
289
- or partially show the plan -- always show the complete plan
290
- <content/> here:.
302
+ can read the plan and react to it. If <content/> is longer than
303
+ 90 lines and a `※ IMPLEMENTATION DRAFT` section exists, replace
304
+ the entire content of the `※ IMPLEMENTATION DRAFT` section with
305
+ `[...]`. Else, do *not* truncate, summarize, or partially show
306
+ the plan. Use the following <template/>:
291
307
 
292
308
  <template>
293
309
  ⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `TASK-PLAN-BEGIN` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
@@ -295,16 +311,24 @@ explicitly requested by this procedure via outputs based on a <template/>!
295
311
  ⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `TASK-PLAN-END` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
296
312
  </template>
297
313
 
298
- 4. *Ask user*: Let the *user interactively choose* what to do as the
299
- next step.
314
+ 4. *Determine next step*:
315
+
316
+ - If <getopt-option-next/> matches the regex `^(DONE|IMPLEMENT|PREFLIGHT|REFINE)$`:
317
+ Honor the pre-selection what to do as the next step.
318
+ Set <result><getopt-option-next/></result>.
319
+ Then *clear* <getopt-option-next/> by setting <getopt-option-next>none</getopt-option-next>
320
+ so that subsequent loop iterations fall back to the interactive dialog.
321
+
322
+ - If <getopt-option-next/> is equal to `none`:
323
+ Let the *user interactively choose* what to do as the next step.
300
324
 
301
- <expand name="user-dialog>
302
- Next Step: How would you like to proceed with the plan?
303
- DONE: Mark plan finalized, exit planning loop.
304
- IMPLEMENT: Hand off plan to implementation.
305
- PREFLIGHT: Hand off plan to pre-flighting.
306
- REFINE: Further refine plan with instructions.
307
- </expand>
325
+ <expand name="user-dialog>
326
+ Next Step: How would you like to proceed with the plan?
327
+ DONE: Mark plan finalized, exit planning loop.
328
+ IMPLEMENT: Hand off plan to implementation.
329
+ PREFLIGHT: Hand off plan to pre-flighting.
330
+ REFINE: Further refine plan with instructions.
331
+ </expand>
308
332
 
309
333
  Check the tool <result/> and dispatch accordingly:
310
334
 
@@ -13,6 +13,7 @@ effort: xhigh
13
13
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
14
14
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
16
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
16
17
 
17
18
  Implement a Task Plan
18
19
  =====================
@@ -21,6 +22,12 @@ Implement a Task Plan
21
22
  Implement a Task Plan
22
23
  </skill>
23
24
 
25
+ <expand name="getopt"
26
+ arg1="ase-task-implement"
27
+ arg2="--next|-n=(none|DONE|DELETE)">
28
+ $ARGUMENTS
29
+ </expand>
30
+
24
31
  Your role is an experienced, *expert-level assistant*,
25
32
  specialized in the *implementation* of changes.
26
33
 
@@ -38,7 +45,7 @@ explicitly requested by this procedure via outputs based on a <template/>!
38
45
 
39
46
  1. **Determine Task:**
40
47
 
41
- 1. Set <instruction>$ARGUMENTS</instruction> initially.
48
+ 1. Set <instruction><getopt-arguments/></instruction> initially.
42
49
  Inherit the always existing <ase-task-id/> from the current context.
43
50
  Inherit the always existing <ase-session-id/> from the current context.
44
51
  Do not output anything.
@@ -117,14 +124,20 @@ explicitly requested by this procedure via outputs based on a <template/>!
117
124
 
118
125
  4. **Decide Next Step:**
119
126
 
120
- 1. *Ask user*: Let the *user interactively choose*
121
- what to do as the next step.
127
+ 1. *Determine next step*:
128
+
129
+ - If <getopt-option-next/> matches the regex `^(DONE|DELETE)$`:
130
+ Honor the pre-selection what to do as the next step.
131
+ Set <result><getopt-option-next/></result>.
132
+
133
+ - If <getopt-option-next/> is equal to `none`:
134
+ Let the *user interactively choose* what to do as the next step.
122
135
 
123
- <expand name="user-dialog>
124
- Next Step: How would you like to proceed with the plan?
125
- DONE: Stop processing and PRESERVE task plan.
126
- DELETE: Stop processing and DELETE the task plan.
127
- </expand>
136
+ <expand name="user-dialog>
137
+ Next Step: How would you like to proceed with the plan?
138
+ DONE: Stop processing and PRESERVE task plan.
139
+ DELETE: Stop processing and DELETE the task plan.
140
+ </expand>
128
141
 
129
142
  2. Check the tool <result/> and dispatch accordingly:
130
143
 
@@ -13,6 +13,7 @@ effort: xhigh
13
13
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
14
14
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
16
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
16
17
 
17
18
  Preflight a Task Plan
18
19
  =====================
@@ -21,6 +22,12 @@ Preflight a Task Plan
21
22
  Preflight a Task Plan
22
23
  </skill>
23
24
 
25
+ <expand name="getopt"
26
+ arg1="ase-task-preflight"
27
+ arg2="--next|-n=(none|DONE|EDIT|IMPLEMENT)">
28
+ $ARGUMENTS
29
+ </expand>
30
+
24
31
  Your role is an experienced, *expert-level assistant*,
25
32
  specialized in the *implementation* of changes.
26
33
 
@@ -38,7 +45,7 @@ explicitly requested by this procedure via outputs based on a <template/>!
38
45
 
39
46
  1. **Determine Task:**
40
47
 
41
- 1. Set <instruction>$ARGUMENTS</instruction> initially.
48
+ 1. Set <instruction><getopt-arguments/></instruction> initially.
42
49
  Inherit the always existing <ase-task-id/> from the current context.
43
50
  Inherit the always existing <ase-session-id/> from the current context.
44
51
  Do not output anything.
@@ -139,15 +146,21 @@ explicitly requested by this procedure via outputs based on a <template/>!
139
146
 
140
147
  4. **Decide Next Step:**
141
148
 
142
- 1. *Ask user*: Let the *user interactively choose*
143
- what to do as the next step.
149
+ 1. *Determine next step*:
150
+
151
+ - If <getopt-option-next/> matches the regex `^(DONE|EDIT|IMPLEMENT)$`:
152
+ Honor the pre-selection what to do as the next step.
153
+ Set <result><getopt-option-next/></result>.
154
+
155
+ - If <getopt-option-next/> is equal to `none`:
156
+ Let the *user interactively choose* what to do as the next step.
144
157
 
145
- <expand name="user-dialog>
146
- Next Step: How would you like to proceed with the plan?
147
- DONE: Stop processing.
148
- EDIT: Hand processing off to editing.
149
- IMPLEMENT: Hand processing off to implementation.
150
- </expand>
158
+ <expand name="user-dialog>
159
+ Next Step: How would you like to proceed with the plan?
160
+ DONE: Stop processing.
161
+ EDIT: Hand processing off to editing.
162
+ IMPLEMENT: Hand processing off to implementation.
163
+ </expand>
151
164
 
152
165
  2. Check the tool <result/> and dispatch accordingly:
153
166
 
@@ -13,6 +13,7 @@ effort: xhigh
13
13
  @${CLAUDE_SKILL_DIR}/../../meta/ase-persona.md
14
14
  @${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
15
15
  @${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
16
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
16
17
 
17
18
  Reboot a Task Plan
18
19
  ==================
@@ -21,6 +22,12 @@ Reboot a Task Plan
21
22
  Reboot a Task Plan
22
23
  </skill>
23
24
 
25
+ <expand name="getopt"
26
+ arg1="ase-task-reboot"
27
+ arg2="--next|-n=(none|DONE|EDIT)">
28
+ $ARGUMENTS
29
+ </expand>
30
+
24
31
  Your role is an experienced, *expert-level assistant*,
25
32
  specialized in the *planning* of changes.
26
33
 
@@ -40,7 +47,7 @@ explicitly requested by this procedure via outputs based on a <template/>!
40
47
 
41
48
  1. **Determine Task:**
42
49
 
43
- 1. Set <instruction>$ARGUMENTS</instruction> initially.
50
+ 1. Set <instruction><getopt-arguments/></instruction> initially.
44
51
  Inherit the always existing <ase-task-id/> from the current context.
45
52
  Inherit the always existing <ase-session-id/> from the current context.
46
53
  Do not output anything.
@@ -132,14 +139,20 @@ explicitly requested by this procedure via outputs based on a <template/>!
132
139
 
133
140
  4. **Decide Next Step:**
134
141
 
135
- 1. *Ask user*: Let the *user interactively choose*
136
- what to do as the next step.
142
+ 1. *Determine next step*:
143
+
144
+ - If <getopt-option-next/> matches the regex `^(DONE|EDIT)$`:
145
+ Honor the pre-selection what to do as the next step.
146
+ Set <result><getopt-option-next/></result>.
147
+
148
+ - If <getopt-option-next/> is equal to `none`:
149
+ Let the *user interactively choose* what to do as the next step.
137
150
 
138
- <expand name="user-dialog>
139
- Next Step: How would you like to proceed with the plan?
140
- DONE: Stop processing.
141
- EDIT: Hand processing off to editing.
142
- </expand>
151
+ <expand name="user-dialog>
152
+ Next Step: How would you like to proceed with the plan?
153
+ DONE: Stop processing.
154
+ EDIT: Hand processing off to editing.
155
+ </expand>
143
156
 
144
157
  2. Check the tool <result/> and dispatch accordingly:
145
158