@rse/ase 0.9.34 → 0.9.35

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.
@@ -295,6 +295,10 @@ export default class ServiceCommand {
295
295
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
296
296
  const mcp = buildMcpServer();
297
297
  request.raw.res.on("close", () => {
298
+ /* "h.abandon" (see below) bypasses "onPreResponse",
299
+ so undo the "onRequest" accounting here instead */
300
+ inFlight = Math.max(0, inFlight - 1);
301
+ lastActivity = Date.now();
298
302
  transport.close().catch(() => { });
299
303
  mcp.close().catch(() => { });
300
304
  });
package/dst/ase-setup.js CHANGED
@@ -163,7 +163,7 @@ export default class SetupCommand {
163
163
  `installing ASE ${spec.label} plugin (origin: ${dev ? "local" : "remote/bundled"})`);
164
164
  const pkgdir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
165
165
  const source = dev ? path.resolve(pkgdir, "..") : pkgdir;
166
- const scopeArgs = tool === "claude" ? ["--scope", scope] : [];
166
+ const scopeArgs = tool === "claude" && scope !== "user" ? ["--scope", scope] : [];
167
167
  await this.run(spec.cli, ["plugin", "marketplace", "add", source, ...scopeArgs]);
168
168
  await this.run(spec.cli, ["plugin", spec.pInstall, "ase@ase", ...scopeArgs], { retries: 3 });
169
169
  return 0;
@@ -174,7 +174,7 @@ export default class SetupCommand {
174
174
  const spec = toolSpecs[tool];
175
175
  await this.ensureTool("npm");
176
176
  await this.ensureTool(spec.cli);
177
- const scopeArgs = tool === "claude" ? ["--scope", scope] : [];
177
+ const scopeArgs = tool === "claude" && scope !== "user" ? ["--scope", scope] : [];
178
178
  /* best-effort stop of background service */
179
179
  this.log.write("info", `setup: update${dev ? "[dev]" : ""}: ` +
180
180
  "stopping potentially running ASE service");
@@ -230,8 +230,9 @@ export default class SetupCommand {
230
230
  this.log.write("info", `setup: enable: enabling ASE ${spec.label} plugin`);
231
231
  /* the GitHub Copilot CLI and OpenAI Codex CLI have no "plugin
232
232
  enable" subcommand, so (re-)install the plugin instead */
233
+ const scopeArgs = scope !== "user" ? ["--scope", scope] : [];
233
234
  const args = tool === "claude" ?
234
- ["plugin", "enable", "ase@ase", "--scope", scope] :
235
+ ["plugin", "enable", "ase@ase", ...scopeArgs] :
235
236
  ["plugin", spec.pInstall, "ase@ase"];
236
237
  await this.run(spec.cli, args, { retries: tool === "claude" ? 1 : 3 });
237
238
  return 0;
@@ -244,8 +245,9 @@ export default class SetupCommand {
244
245
  this.log.write("info", `setup: disable: disabling ASE ${spec.label} plugin`);
245
246
  /* the GitHub Copilot CLI and OpenAI Codex CLI have no "plugin
246
247
  disable" subcommand, so uninstall the plugin instead */
248
+ const scopeArgs = scope !== "user" ? ["--scope", scope] : [];
247
249
  const args = tool === "claude" ?
248
- ["plugin", "disable", "ase@ase", "--scope", scope] :
250
+ ["plugin", "disable", "ase@ase", ...scopeArgs] :
249
251
  ["plugin", spec.pRemove, "ase@ase"];
250
252
  await this.run(spec.cli, args, { retries: tool === "claude" ? 1 : 3 });
251
253
  return 0;
@@ -256,7 +258,7 @@ export default class SetupCommand {
256
258
  const spec = toolSpecs[tool];
257
259
  await this.ensureTool("npm");
258
260
  await this.ensureTool(spec.cli);
259
- const scopeArgs = tool === "claude" ? ["--scope", scope] : [];
261
+ const scopeArgs = tool === "claude" && scope !== "user" ? ["--scope", scope] : [];
260
262
  /* best-effort stop of background service */
261
263
  this.log.write("info", `setup: uninstall${dev ? "[dev]" : ""}: ` +
262
264
  "stopping potentially running ASE service");
@@ -376,7 +378,8 @@ export default class SetupCommand {
376
378
  async mcpAdd(tool, name, env, transport, scope) {
377
379
  const args = ["mcp", "add"];
378
380
  if (tool === "claude") {
379
- args.push("--scope", scope);
381
+ if (scope !== "user")
382
+ args.push("--scope", scope);
380
383
  args.push("--transport", transport.type);
381
384
  if (transport.type === "stdio") {
382
385
  for (const [key, val] of Object.entries(env))
@@ -429,9 +432,8 @@ export default class SetupCommand {
429
432
  /* unregister an MCP server from the tool; the per-tool command line
430
433
  differs between Anthropic Claude Code CLI, GitHub Copilot CLI, and OpenAI Codex CLI */
431
434
  async mcpRemove(tool, name, scope) {
432
- const args = tool === "claude" ?
433
- ["mcp", "remove", "--scope", scope, name] :
434
- ["mcp", "remove", name];
435
+ const scopeArgs = tool === "claude" && scope !== "user" ? ["--scope", scope] : [];
436
+ const args = ["mcp", "remove", ...scopeArgs, name];
435
437
  await this.run(toolSpecs[tool].cli, args, { ignoreError: `MCP server "${name}" not registered` });
436
438
  }
437
439
  /* build a chat-model MCP handler from the per-model direct and
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.9.34",
9
+ "version": "0.9.35",
10
10
  "license": "Apache-2.0",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -18,8 +18,8 @@
18
18
  "devDependencies": {
19
19
  "eslint": "9.39.4",
20
20
  "@eslint/js": "9.39.4",
21
- "@typescript-eslint/parser": "8.62.0",
22
- "@typescript-eslint/eslint-plugin": "8.62.0",
21
+ "@typescript-eslint/parser": "8.62.1",
22
+ "@typescript-eslint/eslint-plugin": "8.62.1",
23
23
  "eslint-plugin-promise": "7.3.0",
24
24
  "eslint-plugin-import": "2.32.0",
25
25
  "neostandard": "0.13.0",
@@ -30,7 +30,7 @@
30
30
  "nodemon": "3.1.14",
31
31
  "shx": "0.4.0",
32
32
 
33
- "@types/node": "26.0.1",
33
+ "@types/node": "26.1.0",
34
34
  "@types/luxon": "3.7.2",
35
35
  "@types/which": "3.0.4",
36
36
  "@types/update-notifier": "6.0.8",
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "commander": "15.0.0",
45
- "@dotenvx/dotenvx": "1.75.1",
45
+ "@dotenvx/dotenvx": "2.1.4",
46
46
  "yaml": "2.9.0",
47
- "valibot": "1.4.1",
47
+ "valibot": "1.4.2",
48
48
  "execa": "9.6.1",
49
49
  "mkdirp": "3.0.1",
50
50
  "@hapi/hapi": "21.4.9",
@@ -63,7 +63,7 @@
63
63
  "write-file-atomic": "8.0.0",
64
64
  "pacote": "22.0.0",
65
65
  "ofetch": "1.5.1",
66
- "picomatch": "4.0.4"
66
+ "picomatch": "4.0.5"
67
67
  },
68
68
  "engines": {
69
69
  "npm": ">=10.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.9.34",
3
+ "version": "0.9.35",
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.9.34",
3
+ "version": "0.9.35",
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.9.34",
3
+ "version": "0.9.35",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -0,0 +1,262 @@
1
+ ---
2
+ name: ase-code-analyze
3
+ description: "Analysis Investigation"
4
+ effort: high
5
+ ---
6
+
7
+ Your role is an experienced, *expert-level software developer*.
8
+
9
+ Your objective is to *analyze* source code for *problems* under a
10
+ single *analysis lens* - read-only, *without* applying any changes.
11
+
12
+ Workflow
13
+ --------
14
+
15
+ 1. Set the requested context: <context>$ARGUMENTS</context>.
16
+ The *first* whitespace-separated token of <context/> is the
17
+ *analysis lens* <lens/> (one of `logic`, `performance`, or
18
+ `security`). The *remaining* tokens are the source code files
19
+ to analyze.
20
+
21
+ 2. Use the `Read` tool to read all source code files referenced by
22
+ <context/>, plus all *related* source code files needed to really
23
+ comprehend the context.
24
+
25
+ 3. *Determine* the *target programming language* and apply all
26
+ subsequent checks according to its *idiomatic conventions* and *best
27
+ practices*.
28
+
29
+ 4. Set <problems/> to empty.
30
+ Then check the read source code for problems under the analysis
31
+ lens <lens/>:
32
+
33
+ - If <lens/> is `logic`:
34
+
35
+ Focus on problems in the *logic* and *semantics* and the related
36
+ *control flow* only - and do *not* investigate performance,
37
+ efficiency, or security problems.
38
+
39
+ Analysis Hints (not exhaustive, just indicators):
40
+ - incorrect conditionals and boolean logic
41
+ - off-by-one and boundary errors
42
+ - operator misuse
43
+ - mishandled edge cases
44
+ - broken or missing error handling
45
+ - incorrect async/await/promise handling
46
+ - control-flow defects (unreachable code, missing breaks, wrong early returns)
47
+ - state-mutation bugs
48
+ - incorrect default values
49
+ - null/undefined mishandling
50
+ - type-coercion bugs
51
+ - faulty parsing or merge/override semantics
52
+ - race conditions and unsynchronized shared state
53
+ - resource leaks (unclosed files, handles, connections)
54
+ - inverted or swapped function arguments
55
+ - incorrect loop termination or accumulator initialization
56
+ - shadowed or reassigned variables changing intent
57
+ - incomplete switch/case or enum coverage
58
+ - silent exception swallowing
59
+ - floating-point comparison and rounding errors
60
+ - integer overflow/underflow or truncating division
61
+ - sign and modulo errors with negative operands
62
+ - reference vs. value semantics (aliasing, shared mutable defaults)
63
+ - incorrect short-circuit evaluation or operator precedence
64
+ - logical vs. bitwise operator confusion
65
+ - negation mistakes in compound predicates
66
+ - wrong comparison operator (`==` instead of `===`, `<` vs. `<=`, etc)
67
+ - inverted condition or swapped if/else branches
68
+ - dead or duplicated conditional branches
69
+ - fall-through where a break or return was intended
70
+ - missing or misplaced base case in recursion (non-termination)
71
+ - mutation of a collection while iterating over it
72
+ - incorrect index, key, or bounds when accessing collections
73
+ - empty-collection or single-element edge cases unhandled
74
+ - wrong order of operations in initialization or teardown
75
+ - missing cleanup on early return, break, or exception path
76
+ - double-free, use-after-free, or double-close of resources
77
+ - incorrect time-zone, date arithmetic, or unit conversions
78
+ - stale cache or memoization not invalidated on change
79
+ - incorrect deep vs. shallow copy semantics
80
+ - partial or non-atomic updates leaving inconsistent state
81
+ - ignored or unchecked return values and status codes
82
+ - error code vs. exception path mismatch
83
+ - catching too broad an exception masking real failures
84
+ - re-throwing without preserving the original cause
85
+ - incorrect equality, hashing, or ordering for custom types
86
+ - regex anchoring, greediness, or escaping mistakes
87
+ - string encoding, normalization, or case-folding errors
88
+ - missing `await` causing unhandled or dropped promises
89
+ - incorrect promise concurrency (`all` vs. `allSettled`, races)
90
+ - callback invoked zero times, twice, or out of order
91
+ - unguarded re-entrancy or recursive lock acquisition
92
+ - incorrect guard ordering allowing invalid states through
93
+ - assumptions about iteration order of maps/sets/objects
94
+ - [...]
95
+
96
+ - If <lens/> is `performance`:
97
+
98
+ Focus on *performance* and *efficiency* only - and do *not*
99
+ investigate logic, semantics, control flow, or security
100
+ problems.
101
+
102
+ Analysis Hints (not exhaustive, just indicators):
103
+ - high algorithmic complexity
104
+ - needless resource allocations/copies
105
+ - redundant recomputation
106
+ - many I/O and query round-trips
107
+ - concurrency bottlenecks
108
+ - mismatched data structures
109
+ - N+1 query patterns (1 parent query, N child queries)
110
+ - missing caching/memoization of stable results
111
+ - blocking/synchronous calls on hot paths
112
+ - unbounded growth (memory leaks, ever-growing collections)
113
+ - inefficient string building/concatenation in loops
114
+ - premature or repeated serialization/parsing
115
+ - lack of batching/pagination for bulk operations
116
+ - excessive logging or instrumentation overhead
117
+ - chatty network protocols (no connection pooling/keep-alive)
118
+ - lock contention and overly coarse-grained locking
119
+ - eager/over-fetching of data that is never used
120
+ - missing database indexes
121
+ - repeated regex (re)compilation in hot paths
122
+ - busy-waiting/polling instead of event-driven waits
123
+ - transferring uncompressed or overly verbose payloads
124
+ - missing short-circuit evaluation in expensive conditions
125
+ - recomputing invariants inside loops (loop-invariant code)
126
+ - suboptimal batch sizes (too small = overhead, too large = latency)
127
+ - inefficient algorithms for sorting/searching already-ordered data
128
+ - redundant validation/sanitization of trusted internal data
129
+ - missing connection/resource reuse (open-close per operation)
130
+ - [...]
131
+
132
+ - If <lens/> is `security`:
133
+
134
+ Focus on *security* only - and do *not* investigate logic,
135
+ semantics, performance, or efficiency problems.
136
+
137
+ Analysis Hints (not exhaustive, just indicators):
138
+ - unsafe data deserialization
139
+ - missing input data validation/sanitization
140
+ - broken authentication/authorization
141
+ - sensitive-data exposure
142
+ - path traversal
143
+ - unsafe cryptography
144
+ - hard-coded secrets
145
+ - vulnerable dependencies
146
+ - injection flaws
147
+ - cross-site scripting (XSS) and output-encoding gaps
148
+ - cross-site request forgery (CSRF) and missing anti-forgery tokens
149
+ - insecure direct object references (IDOR)
150
+ - server-side request forgery (SSRF)
151
+ - insecure or missing transport encryption (TLS)
152
+ - weak session management (fixation, predictable tokens)
153
+ - missing rate limiting/anti-automation controls
154
+ - overly permissive CORS or file permissions
155
+ - verbose error messages leaking internals
156
+ - unsafe randomness for security-sensitive values
157
+ - mass assignment / over-binding of request parameters
158
+ - security misconfiguration (default credentials, debug modes, exposed admin endpoints)
159
+ - missing or misconfigured security headers (CSP, HSTS, X-Frame-Options)
160
+ - improper certificate/hostname validation (TLS verification disabled)
161
+ - insufficient logging and monitoring of security events
162
+ - race conditions / TOCTOU (time-of-check to time-of-use) flaws
163
+ - integer overflow/underflow and buffer overflows
164
+ - use-after-free and memory-safety violations
165
+ - privilege escalation through improper privilege dropping
166
+ - insecure file upload handling (unrestricted type/size, executable storage)
167
+ - unsafe handling of untrusted regular expressions (ReDoS)
168
+ - caching of sensitive data in shared or client-side caches
169
+ - secrets or sensitive data leaking into logs, traces, or telemetry
170
+ - insecure default-deny failures (fail-open instead of fail-closed)
171
+ - missing integrity verification (unsigned updates, no subresource integrity)
172
+ - excessive data exposure in API responses (returning more fields than needed)
173
+ - improper resource cleanup leading to exhaustion (connection/file-descriptor leaks)
174
+ - business-logic flaws (bypassable workflows, negative quantities, replay)
175
+ - [...]
176
+
177
+ Be practically relevant - focus on *practically relevant* cases
178
+ only and especially do *not* investigate theoretical or fictive
179
+ cases.
180
+
181
+ Be problem-focused - report the *problem only* and do *not*
182
+ already investigate any possible *solution* or apply any *change*.
183
+
184
+ Be conservative - only report clear, well-grounded problems.
185
+ Think twice to avoid *false positives*.
186
+
187
+ Be focused - only report problems which were found in the source
188
+ files referenced by <context/>. Ignore problems which are located
189
+ in related source files which were just read to better comprehend
190
+ the <context/>.
191
+
192
+ For *each* found problem:
193
+
194
+ 1. Set <file/> to the *relative* filename path of the source file
195
+ in which the problem is located.
196
+
197
+ 2. Set <line/> to the numeric 1-based line number in <file/> which
198
+ is most relevant to the problem.
199
+
200
+ 3. Set <severity/> to the string `LOW`, `MEDIUM`, `HIGH`, or
201
+ `ACCEPTED`, ranked by the estimated *impact* of the problem.
202
+ Use `ACCEPTED` when the problem is a deliberate, justified
203
+ trade-off that should remain on record.
204
+
205
+ 4. Set <description/> to an *ultra brief* but still as *precise*
206
+ as possible Markdown-formatted problem description. In it,
207
+ highlight *code* as <template>`<code/>`</template> and *key
208
+ aspects* as <template>*<aspect/>*</template>, and add inline
209
+ *references* to the related code positions in the form of either
210
+ <template>(`<filename/>:<line-number/>`)</template>,
211
+ <template>(`<filename/>:<line-number/>-<line-number/>`)</template> or
212
+ <template>(`<filename/>#<function-or-method/>`)</template>.
213
+
214
+ 5. Set <title/> to an ultra-compressed <description/>: a concise,
215
+ short, single sentence. Keep one inline reference to the code
216
+ position which is most relevant to the problem.
217
+
218
+ 6. If <lens/> is `performance`:
219
+
220
+ Set <evidence/> to ground the finding by citing either the
221
+ inferred *Big-O* time/space complexity (e.g. `O(n²)` reducible
222
+ to `O(n)`) with the exact driving loop or recursion, or the
223
+ matched performance *anti-pattern* (e.g. N+1 query,
224
+ sync-in-loop, repeated recompute, string concat in loop), with
225
+ an inline code reference.
226
+
227
+ Set <trade-off/> to state the *cost* of the optimization (e.g.
228
+ readability, additional memory for speed, added complexity), so
229
+ the user can make an informed decision; use *none* if there is
230
+ no meaningful trade-off.
231
+
232
+ Otherwise (for the other lenses), set both <evidence/> and
233
+ <trade-off/> to empty strings.
234
+
235
+ 7. If <problems/> is not empty, set
236
+ <problems><problems/>,</problems> (append a comma).
237
+ Then append the following <template/> to <problems/>:
238
+
239
+ <template>
240
+ {
241
+ "file": <file/>,
242
+ "line": <line/>,
243
+ "severity": <severity/>,
244
+ "title": <title/>,
245
+ "description": <description/>,
246
+ "evidence": <evidence/>,
247
+ "trade-off": <trade-off/>
248
+ }
249
+ </template>
250
+
251
+ 5. Return *exclusively* a single fenced JSON block (no prose,
252
+ no preamble, no summary) of the following shape:
253
+
254
+ ```json
255
+ [
256
+ <problems/>
257
+ ]
258
+ ```
259
+
260
+ 6. You *MUST* *NOT* propose, apply, or render any code
261
+ changes yourself.
262
+
@@ -13,167 +13,6 @@ User Dialog
13
13
  <user-dialog-tool>none</user-dialog-tool>
14
14
  </if>
15
15
 
16
- <define name="user-dialog">
17
-
18
- Let the *user interactively choose* an answer.
19
-
20
- 1. Take the following question specification:
21
-
22
- <spec>
23
- <content/>
24
- </spec>
25
-
26
- The first line of <spec/> (separated by newlines) is of the format:
27
- `<question-label/>: <question-description/>`
28
-
29
- The second and following lines of <spec/> (separated by newlines) are of the format:
30
- `<label/>: <description/>`
31
-
32
- The first line provides the question label and the question
33
- description. The second and following lines each provide an
34
- answer label and an answer description.
35
-
36
- Do not output anything in this step!
37
-
38
- 2. Dispatch according to the agent tool:
39
-
40
- - <if condition="<ase-agent-tool/> is 'claude'">
41
-
42
- 1. Start with <config></config> (set config to empty).
43
- Do not output anything in this step!
44
-
45
- Start with <n>0</n> (set entry count to zero).
46
- <for items="2 3 4 5">
47
- Take from <spec/> the line number <item/>.
48
- If this line does not exist, <break/>.
49
- If this line exists, parse it according to the format `<label/>: <description/>`.
50
- If <config/> is not empty, set <config><config/>, </config> (append comma).
51
- Set <config><config/>{ label: "<label/>",
52
- description: "<description/>" }</config> (append a config entry).
53
- Set <n/> to <n/> + 1 (increment entry count).
54
- </for>
55
-
56
- If <n/> is less than 2:
57
- Set <result>ERROR: user-dialog requires 2-4 answer lines, got <n/></result>
58
- and *SKIP* the following step 2.2 (do not call `AskUserQuestion`)
59
- and continue with step 2.3 dispatch.
60
-
61
- 2. Call the `AskUserQuestion` tool of the agent harness with:
62
-
63
- `AskUserQuestion({
64
- questions: [
65
- {
66
- header: "<question-label/>",
67
- question: "<question-description/>",
68
- multiSelect: false,
69
- options: [
70
- <config/>
71
- ]
72
- }
73
- ]
74
- })`
75
-
76
- 3. Check the tool result and dispatch accordingly:
77
-
78
- - If <result/> already starts with `ERROR:` (set by the
79
- guard in step 2.1 above), keep <result/> unchanged and
80
- *SKIP* all remaining dispatch in this step.
81
-
82
- - If the tool result contains `user doesn't want to proceed`,
83
- `tool use was rejected`, or `user declined to answer
84
- questions`, or the result clearly indicates that the
85
- dialog was cancelled, rejected or skipped, set
86
- <result>CANCEL</result>.
87
-
88
- - Otherwise, extract the selected <answer/> from the
89
- tool result `"<question-description/>"="<answer/>"`.
90
- Set <result><answer/></result>.
91
- If <result/> is then NOT one
92
- of the "label" values from <config/>, set
93
- <result>OTHER: <result/></result>
94
- (prefix result with "OTHER").
95
-
96
- Do not output anything in this step!
97
- </if>
98
-
99
- - <if condition="<ase-agent-tool/> is 'copilot'">
100
-
101
- 1. Start with <config></config> (set config to empty).
102
- Do not output anything in this step!
103
-
104
- Start with <n>0</n> (set entry count to zero).
105
- <for items="2 3 4 5">
106
- Take from <spec/> the line number <item/>.
107
- If this line does not exist, <break/>.
108
- If this line exists, parse it according to the format `<label/>: <description/>`.
109
- If <config/> is not empty, set <config><config/>, </config> (append comma).
110
- Set <config><config/>"<label/>: <description/>"</config> (append a config entry).
111
- Set <n/> to <n/> + 1 (increment entry count).
112
- </for>
113
-
114
- If <n/> is less than 2:
115
- Set <result>ERROR: user-dialog requires 2-4 answer lines, got <n/></result>
116
- and *SKIP* the following step 2.2 (do not call `ask_user`)
117
- and continue with step 2.3 dispatch.
118
-
119
- 2. Call the `ask_user` tool of the agent harness with:
120
-
121
- `ask_user({
122
- question: "<question-label/>: <question-description/>",
123
- allow_freeform: true,
124
- choices: [
125
- <config/>
126
- ]
127
- })`
128
-
129
- 3. Check the tool result and dispatch accordingly:
130
-
131
- - If <result/> already starts with `ERROR:` (set by the
132
- guard in step 2.1 above), keep <result/> unchanged and
133
- *SKIP* all remaining dispatch in this step.
134
-
135
- - If the tool result contains `User skipped question`
136
- or the result clearly indicates that the
137
- dialog was cancelled, rejected or skipped, set
138
- <result>CANCEL</result>.
139
-
140
- - Otherwise, extract the selected answer from the tool
141
- result and set <result/> accordingly. The harness may
142
- return either the full `<label/>: <description/>` line or
143
- just the bare `<label/>`. Determine the selected
144
- <label/> by mapping the <result/> to one of the answer
145
- labels parsed from <spec/> (lines 2 and following): if
146
- <result/> is of the format `<label/>: <description/>`,
147
- take its `<label/>` part; otherwise, if <result/> already
148
- equals one of the answer labels, take it as-is. Set
149
- <result><label/></result>. If <result/> is then NOT one
150
- of the answer labels parsed from <spec/>, set
151
- <result>OTHER: <result/></result>
152
- (prefix result with "OTHER").
153
-
154
- Do not output anything in this step!
155
-
156
- </if>
157
-
158
- - <if condition="<ase-agent-tool/> is 'codex'">
159
-
160
- OpenAI Codex CLI has *no* interactive user-dialog tool, so you
161
- *MUST* *NOT* call any tool here. Instead, render the question and
162
- answers as a custom Markdown dialog and let the user reply with a
163
- free-text choice -- exactly as defined by the following expansion,
164
- passing <spec/> as its question specification, and set <result/> to
165
- the result of that custom dialog:
166
-
167
- <expand name="custom-dialog" arg1="--other">
168
- <spec/>
169
- </expand>
170
-
171
- Do not output anything in this step!
172
-
173
- </if>
174
-
175
- </define>
176
-
177
16
  <define name="custom-dialog">
178
17
 
179
18
  In the following, you *MUST* *NOT* use the <user-dialog-tool/> tool!
@@ -216,7 +55,7 @@ following procedure:
216
55
  If this line does not exist, <break/>.
217
56
  If this line exists, parse it according to the format `<label/>: <description/>`.
218
57
  Set <n/> to <n/> + 1 (increment entry count).
219
- Set <label-key/> to <ase-tpl-key digit="<n/>"/>.
58
+ Set <label-key/> to `<ase-tpl-key digit="<n/>"/>`.
220
59
  Set <label-text/> to `<ase-tpl-pad width="<width/>" text="<label/>:"/>`.
221
60
  Append an entry to <text/>:
222
61
 
@@ -276,31 +115,31 @@ following procedure:
276
115
  3. Do not output anything in this step!
277
116
  Check the <result/> and dispatch accordingly:
278
117
 
279
- 0. If <result/> already starts with `ERROR:` (set by the
280
- guard in step 2.1 above), keep <result/> unchanged and
281
- *SKIP* all remaining sub-steps 3.1-3.3 of this dispatch.
118
+ 1. If <result/> already starts with `ERROR:` (potentially set by
119
+ the guard in step 2.1 above), keep <result/> unchanged and
120
+ *SKIP* all remaining steps 2.3.2 - 2.3.4 of this dispatch.
282
121
 
283
- 1. If <result/> is `cancel`, `CANCEL`, `reject`, `REJECT`, or
122
+ 2. If <result/> is `cancel`, `CANCEL`, `reject`, `REJECT`, or
284
123
  otherwise indicates that the user doesn't want to proceed,
285
124
  or the user declined to answer the question, or that
286
125
  the dialog was cancelled, rejected or skipped, set
287
126
  <result>CANCEL</result>.
288
127
 
289
- 2. Otherwise, determine the selected <label/>
128
+ 3. Otherwise, determine the selected <label/>
290
129
  by mapping the <result/> (usually containing one of the
291
130
  "key" or "label" strings) to one of the answer labels in
292
131
  <spec/>. Set <result><label/></result>.
293
132
 
294
- 3. If <result/> is then *NEITHER* one of the "key"
133
+ 4. If <result/> is then *NEITHER* one of the "key"
295
134
  *NOR* "label" values from <spec/>:
296
135
  <if condition="<opts/> contains `--other`">
297
136
  Set <result>OTHER: <result/></result>
298
- (prefix result with "OTHER").
137
+ (prefix result with `OTHER: `).
299
138
  </if>
300
139
  <else>
301
140
  Output the following <template/> and then *START OVER*
302
- by *GOING* to step 2.2 above, reusing the already-built
303
- <text/> from step 2.1 unchanged (do *NOT* re-enter step 2.1
141
+ by *GOING* to step 2.2.2 above, reusing the already-built
142
+ <text/> from step 2.2.1 unchanged (do *NOT* re-enter step 2.2.1
304
143
  and do *NOT* rebuild <text/>, <keys/>, <n/>, or <width/>).
305
144
 
306
145
  <template>
@@ -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.9.34",
9
+ "version": "0.9.35",
10
10
  "license": "Apache-2.0",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -16,10 +16,10 @@
16
16
  "devDependencies": {
17
17
  "@rse/stx": "1.1.6",
18
18
  "markdownlint": "0.41.0",
19
- "markdownlint-cli2": "0.22.1",
20
- "eslint": "10.5.0",
21
- "@eslint/markdown": "8.0.2",
22
- "eslint-markdown": "0.11.0"
19
+ "markdownlint-cli2": "0.23.0",
20
+ "eslint": "10.6.0",
21
+ "@eslint/markdown": "8.0.3",
22
+ "eslint-markdown": "0.11.1"
23
23
  },
24
24
  "engines": {
25
25
  "npm": ">=10.0.0",