@rse/ase 0.9.63 → 0.9.65

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 (60) hide show
  1. package/dst/ase-hook.js +1 -1
  2. package/dst/ase-spec.js +53 -13
  3. package/package.json +2 -2
  4. package/plugin/.claude-plugin/plugin.json +1 -1
  5. package/plugin/.codex-plugin/plugin.json +1 -1
  6. package/plugin/.github/plugin/plugin.json +1 -1
  7. package/plugin/meta/ase-constitution.md +2 -0
  8. package/plugin/meta/ase-tenets.md +12 -0
  9. package/plugin/package.json +2 -2
  10. package/plugin/skills/ase-arch-analyze/help.md +7 -0
  11. package/plugin/skills/ase-arch-discover/help.md +7 -0
  12. package/plugin/skills/ase-code-analyze/help.md +8 -0
  13. package/plugin/skills/ase-code-craft/help.md +7 -0
  14. package/plugin/skills/ase-code-dissect/help.md +7 -0
  15. package/plugin/skills/ase-code-edit/help.md +7 -0
  16. package/plugin/skills/ase-code-explain/help.md +7 -0
  17. package/plugin/skills/ase-code-insight/help.md +7 -0
  18. package/plugin/skills/ase-code-lint/help.md +8 -0
  19. package/plugin/skills/ase-code-refactor/help.md +7 -0
  20. package/plugin/skills/ase-code-resolve/help.md +7 -0
  21. package/plugin/skills/ase-docs-distill/help.md +7 -0
  22. package/plugin/skills/ase-docs-proofread/help.md +7 -0
  23. package/plugin/skills/ase-help-intent/SKILL.md +66 -43
  24. package/plugin/skills/ase-help-intent/help.md +27 -16
  25. package/plugin/skills/ase-help-skill/help.md +7 -0
  26. package/plugin/skills/ase-meta-brainstorm/help.md +8 -0
  27. package/plugin/skills/ase-meta-changelog/help.md +6 -0
  28. package/plugin/skills/ase-meta-chat/help.md +6 -0
  29. package/plugin/skills/ase-meta-commit/help.md +6 -0
  30. package/plugin/skills/ase-meta-compat/help.md +6 -0
  31. package/plugin/skills/ase-meta-config/help.md +7 -0
  32. package/plugin/skills/ase-meta-diaboli/help.md +7 -0
  33. package/plugin/skills/ase-meta-diff/help.md +7 -0
  34. package/plugin/skills/ase-meta-eli5/help.md +6 -0
  35. package/plugin/skills/ase-meta-evaluate/help.md +7 -0
  36. package/plugin/skills/ase-meta-proximity/help.md +7 -0
  37. package/plugin/skills/ase-meta-quorum/help.md +6 -0
  38. package/plugin/skills/ase-meta-quotes/help.md +7 -0
  39. package/plugin/skills/ase-meta-review/help.md +7 -0
  40. package/plugin/skills/ase-meta-search/help.md +6 -0
  41. package/plugin/skills/ase-meta-steelman/help.md +6 -0
  42. package/plugin/skills/ase-meta-why/help.md +7 -0
  43. package/plugin/skills/ase-meta-workflow/help.md +7 -0
  44. package/plugin/skills/ase-spec-edit/help.md +7 -0
  45. package/plugin/skills/ase-sync-export/SKILL.md +18 -3
  46. package/plugin/skills/ase-sync-export/help.md +15 -0
  47. package/plugin/skills/ase-sync-import/help.md +7 -0
  48. package/plugin/skills/ase-sync-reconcile/help.md +7 -0
  49. package/plugin/skills/ase-task-condense/help.md +6 -0
  50. package/plugin/skills/ase-task-delete/help.md +6 -0
  51. package/plugin/skills/ase-task-dissect/help.md +7 -0
  52. package/plugin/skills/ase-task-edit/help.md +7 -0
  53. package/plugin/skills/ase-task-grill/help.md +7 -0
  54. package/plugin/skills/ase-task-id/help.md +6 -0
  55. package/plugin/skills/ase-task-implement/help.md +7 -0
  56. package/plugin/skills/ase-task-list/help.md +6 -0
  57. package/plugin/skills/ase-task-preflight/help.md +7 -0
  58. package/plugin/skills/ase-task-reboot/help.md +6 -0
  59. package/plugin/skills/ase-task-rename/help.md +6 -0
  60. package/plugin/skills/ase-task-view/help.md +6 -0
package/dst/ase-hook.js CHANGED
@@ -353,7 +353,7 @@ export default class HookCommand {
353
353
  `\n⧉ ASE: ☯ persona: ${persona}, ▶ guidance: ${guidance}, ▢ boxing: ${boxing}` +
354
354
  (guidance === "normal" || guidance === "verbose" ?
355
355
  "\n" +
356
- "\n⧉ ASE: ▷ hint: use \"/ase-help-intent <intent-description>\" for skill command proposal" +
356
+ "\n⧉ ASE: ▷ hint: use \"/ase-help-intent <intent-description>\" for skill command proposals" +
357
357
  "\n⧉ ASE: ▷ hint: use \"/ase-help-skill [<skill-name>]\" for skill catalog or skill manpage" : "");
358
358
  /* inject markdown into session context.
359
359
  Anthropic Claude Code CLI and OpenAI Codex CLI expect the context nested in
package/dst/ase-spec.js CHANGED
@@ -32,12 +32,36 @@ export class Spec {
32
32
  return path.resolve(Task.projectRoot(), file);
33
33
  }
34
34
  /* create the SpecBook API instance, routing its verbose processing
35
- messages into the info log if requested, else into the debug log */
36
- static api(log, verbose) {
35
+ messages into the info log if requested, else into the debug log,
36
+ while its "notice" messages always reach the warning log and, for
37
+ consumers which never see the log, the given collector */
38
+ static api(log, verbose, notices) {
37
39
  return new SpecBook({
38
- verbose: (cmd, msg) => log.write(verbose ? "info" : "debug", `specbook: ${cmd}: ${renderVerbose(msg)}`)
40
+ verbose: (cmd, msg, level) => {
41
+ const text = renderVerbose(msg);
42
+ if (level === "notice") {
43
+ log.write("warning", `specbook: ${cmd}: ${text}`);
44
+ notices?.push(text);
45
+ }
46
+ else
47
+ log.write(verbose ? "info" : "debug", `specbook: ${cmd}: ${text}`);
48
+ }
39
49
  });
40
50
  }
51
+ /* SpecBook marks the literal values inside its messages, but only
52
+ its verbose messages ever reach a renderer, so strip the markers
53
+ off the error messages here at the API boundary -- unstyled, as
54
+ they travel on into the log and the MCP tool results */
55
+ static async unmarked(result) {
56
+ try {
57
+ return await result;
58
+ }
59
+ catch (err) {
60
+ if (err instanceof Error)
61
+ err.message = renderVerbose(err.message);
62
+ throw err;
63
+ }
64
+ }
41
65
  /* render a diagnostic file path relative to the project root,
42
66
  keeping paths outside the project (like the bundled schema) as-is */
43
67
  static relativize(file) {
@@ -49,10 +73,10 @@ export class Spec {
49
73
  /* lint the specification Markdown files below the "spec" artifact
50
74
  base directory against the schema configuration */
51
75
  static async lint(log, verbose = false) {
52
- const result = await Spec.api(log, verbose).lint({
76
+ const result = await Spec.unmarked(Spec.api(log, verbose).lint({
53
77
  config: Spec.configFile(log),
54
78
  basedir: Artifact.basedir(log, "spec")
55
- });
79
+ }));
56
80
  return result.diagnostics.map((d) => ({ ...d, file: Spec.relativize(d.file) }));
57
81
  }
58
82
  /* render a diagnostic as a multi-line message with the affected
@@ -79,13 +103,14 @@ export class Spec {
79
103
  });
80
104
  }
81
105
  /* export the specification Markdown files below the "spec" artifact
82
- base directory into the requested formats, one buffer per format */
83
- static export(log, formats, verbose = false) {
84
- return Spec.api(log, verbose).export({
106
+ base directory into the requested formats, one buffer per format,
107
+ collecting the emitted environment notices if requested */
108
+ static export(log, formats, verbose = false, notices) {
109
+ return Spec.unmarked(Spec.api(log, verbose, notices).export({
85
110
  config: Spec.configFile(log),
86
111
  basedir: Artifact.basedir(log, "spec"),
87
112
  formats
88
- });
113
+ }));
89
114
  }
90
115
  }
91
116
  /* CLI command "ase spec" */
@@ -204,34 +229,49 @@ export class SpecMCP {
204
229
  "`project.artifact.spec.basedir` configuration) as JSON, JSON5, YAML, TOON, HTML, PDF, " +
205
230
  "or normalized Markdown. The result is written to the `output` file (a relative path " +
206
231
  "resolves against the project root) if given, else it is returned directly " +
207
- "(PDF as a base64-encoded resource). The export fails on any lint diagnostic.",
232
+ "(PDF as a base64-encoded resource). The export fails on any lint diagnostic. " +
233
+ "The `notices` array carries the environment notices emitted during the export " +
234
+ "(like a PDF rendering falling back onto a system-installed browser), which are " +
235
+ "worth reporting to the user verbatim.",
208
236
  inputSchema: {
209
237
  format: z.enum(formats).optional()
210
238
  .describe("output format (default: inferred from the `output` file extension, else `json`)"),
211
239
  output: z.string().optional()
212
240
  .describe("output file path (\"-\" or omitted returns the result directly)")
241
+ },
242
+ outputSchema: {
243
+ notices: z.array(z.string())
244
+ .describe("environment notices emitted during the export, empty if there were none")
213
245
  }
214
246
  }, async (args) => {
247
+ const notices = new Array();
215
248
  try {
216
249
  /* an explicit format takes the output as a plain file path, while
217
250
  otherwise the output is an "[<format>:]<file>" specification */
218
251
  const spec = args.format !== undefined || args.output === undefined ?
219
252
  { format: args.format ?? "json", output: args.output } :
220
253
  parseOutputSpec(args.output);
221
- const [data] = await Spec.export(this.log, [spec.format]);
254
+ const [data] = await Spec.export(this.log, [spec.format], false, notices);
222
255
  if (spec.output !== undefined && spec.output !== "-") {
223
256
  await fs.promises.writeFile(path.resolve(Task.projectRoot(), spec.output), data);
224
- return { content: [{ type: "text", text: `exported specification into "${spec.output}" (${data.length} bytes)` }] };
257
+ return {
258
+ structuredContent: { notices },
259
+ content: [{ type: "text", text: `exported specification into "${spec.output}" (${data.length} bytes)` }]
260
+ };
225
261
  }
226
262
  else if (spec.format === "pdf")
227
263
  return {
264
+ structuredContent: { notices },
228
265
  content: [{
229
266
  type: "resource",
230
267
  resource: { uri: "ase:specbook-export.pdf", mimeType: "application/pdf", blob: data.toString("base64") }
231
268
  }]
232
269
  };
233
270
  else
234
- return { content: [{ type: "text", text: data.toString("utf8") }] };
271
+ return {
272
+ structuredContent: { notices },
273
+ content: [{ type: "text", text: data.toString("utf8") }]
274
+ };
235
275
  }
236
276
  catch (err) {
237
277
  return mcpToolError(err);
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "homepage": "https://ase.tools",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "https://github.com/rse/ase/issues" },
9
- "version": "0.9.63",
9
+ "version": "0.9.65",
10
10
  "license": "Apache-2.0",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -66,7 +66,7 @@
66
66
  "ofetch": "1.5.1",
67
67
  "picomatch": "4.0.7",
68
68
  "lru-cache": "11.5.2",
69
- "@rse/specbook": "1.0.2",
69
+ "@rse/specbook": "1.0.3",
70
70
  "source-code-error": "1.2.0"
71
71
  },
72
72
  "allowScripts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ase",
3
- "version": "0.9.63",
3
+ "version": "0.9.65",
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.63",
3
+ "version": "0.9.65",
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.63",
3
+ "version": "0.9.65",
4
4
  "description": "Agentic Software Engineering (ASE)",
5
5
  "keywords": [ "agentic", "software", "engineering" ],
6
6
  "homepage": "https://ase.tools",
@@ -19,6 +19,8 @@ which boosts you to an expert-level Software Engineering AI agent.
19
19
  ## Commandments
20
20
 
21
21
  - Be *honest* and *transparent* in all your responses.
22
+ - *Check first, then worry*: check facts and avoid theoretical assumptions.
23
+ - *Comprehension* before *acting*: first comprehend the facts before you act on them.
22
24
  - *Ground* factual and technical claims in verifiable evidence (code base, local files, or web)
23
25
  with a reference, rather than unverified model knowledge; state explicitly when a claim cannot be verified.
24
26
  - Assume your *internal knowledge of dependencies* (libraries, frameworks, tools, and their implementations)
@@ -117,6 +117,10 @@ you *MUST* honor the following so-called **CRAFTING TENETS**:
117
117
  Honor the non-functional requirements Performance, Security,
118
118
  Scalability, Comprehensibility.
119
119
 
120
+ - **Factual Locality**:
121
+ Keep data as local as possible to the using component and avoid
122
+ global or shared data stores.
123
+
120
124
  RECONCILIATION TENETS
121
125
  ---------------------
122
126
 
@@ -196,12 +200,20 @@ you *MUST* honor the following so-called **REFACTORING TENETS**:
196
200
  Design clear interfaces, contracts, and data models -- with high
197
201
  attention to boundaries and modularity.
198
202
 
203
+ - **Factual Locality**:
204
+ Keep data as local as possible to the using component and avoid
205
+ global or shared data stores.
206
+
199
207
  RESOLVING TENETS
200
208
  ----------------
201
209
 
202
210
  When *resolving* a problem or challenge (bug-fixing),
203
211
  you *MUST* honor the following so-called **RESOLVING TENETS**:
204
212
 
213
+ - **Cause before Symptom**:
214
+ Find and fix the root cause of a problem before too hasty applying a
215
+ "band-aid" fix just for the symptom.
216
+
205
217
  - **No Cleanups**:
206
218
  Strictly focus on resolving the problem and do not mix the task with
207
219
  any other necessary code cleanups, unless they are really necessary
@@ -6,7 +6,7 @@
6
6
  "homepage": "https://ase.tools",
7
7
  "repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
8
8
  "bugs": { "url": "https://github.com/rse/ase/issues" },
9
- "version": "0.9.63",
9
+ "version": "0.9.65",
10
10
  "license": "Apache-2.0",
11
11
  "author": {
12
12
  "name": "Dr. Ralf S. Engelschall",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "devDependencies": {
17
17
  "@rse/stx": "1.1.6",
18
- "@rse/specbook": "1.0.2",
18
+ "@rse/specbook": "1.0.3",
19
19
  "markdownlint": "0.41.1",
20
20
  "markdownlint-cli2": "0.23.2",
21
21
  "eslint": "10.9.1",
@@ -40,6 +40,13 @@ covers the *entire* `ase-issue-*` space, including any prefixed results.
40
40
  A file, directory, or other reference to the source code that
41
41
  is to be analyzed architecturally.
42
42
 
43
+ ## SCENARIOS
44
+
45
+ - You want the software architecture of your code base reviewed
46
+ - You want coupling and cohesion problems between packages found
47
+ - You want an architecture diagram plus PROBLEM and TRADEOFF findings
48
+ - You want architecture findings persisted for later resolution
49
+
43
50
  ## EXAMPLES
44
51
 
45
52
  Analyze architecture of the current project:
@@ -57,6 +57,13 @@ demotes dependency-heavy components.
57
57
  A short description of the desired functionality the third-party
58
58
  component should provide.
59
59
 
60
+ ## SCENARIOS
61
+
62
+ - You want a third-party library or framework for a needed functionality
63
+ - You want a ranked survey of candidate components from NPM or Maven Central
64
+ - You want to know whether a package is healthy or stale and abandoned
65
+ - You want to decide between a dependency and hand-rolling a small feature
66
+
60
67
  ## EXAMPLES
61
68
 
62
69
  Discover components for JSON schema validation:
@@ -61,6 +61,14 @@ fixed via `ase-code-edit P<n>`.
61
61
  A file, directory, function, or other reference to the source code
62
62
  to analyze.
63
63
 
64
+ ## SCENARIOS
65
+
66
+ - You want your code checked for logic, semantics, and control-flow problems
67
+ - You want a read-only report of problems without any changes applied
68
+ - You want performance and efficiency opportunities surfaced
69
+ - You want a security-focused inspection of your code
70
+ - You want problems persisted as issue ids like `P1` for later resolving
71
+
64
72
  ## EXAMPLES
65
73
 
66
74
  Analyze a specific source file for logic/semantic problems:
@@ -89,6 +89,13 @@ entirely and applies the change set to the affected artifacts itself.
89
89
  a *task-id* followed by a colon to bind the resulting plan to
90
90
  a specific task id.
91
91
 
92
+ ## SCENARIOS
93
+
94
+ - You want to add a new feature to the code base
95
+ - You want feature approaches with pros and cons before any code changes
96
+ - You want a task plan composed for building something new
97
+ - You want a fast one-shot crafting without any plan ceremony
98
+
92
99
  ## EXAMPLES
93
100
 
94
101
  Craft a new logging feature:
@@ -89,6 +89,13 @@ cleanly and are then reported as failed; stage everything and use
89
89
  The worktree names are *not* argument-driven: they are always derived
90
90
  from the *current* project id and the per-part feature slug.
91
91
 
92
+ ## SCENARIOS
93
+
94
+ - You want a large uncommitted change set split into atomic parts
95
+ - You want each cohesive part of a diff in its own Git worktree
96
+ - You want mixed-up changes untangled before committing them
97
+ - You want a preview of how a change set would be divided
98
+
92
99
  ## EXAMPLES
93
100
 
94
101
  Dissect the current working copy changes:
@@ -101,6 +101,13 @@ implementation until it passes). The *querying* state and every
101
101
  for the query via an interactive `Edit Query` dialog, carrying the
102
102
  fixed `STOP SKILL` option plus free-text input.
103
103
 
104
+ ## SCENARIOS
105
+
106
+ - You want the code base edited in one shot from a plain description
107
+ - You want an analyzer issue like `P1` fixed directly without a plan
108
+ - You want a quick change with optional grilling and verification
109
+ - You want several edits chained in a loop, optionally in a worktree
110
+
104
111
  ## EXAMPLES
105
112
 
106
113
  Edit in one shot, without any questions or verification:
@@ -24,6 +24,13 @@ notice), and *GOTCHAS* (what to not stumble over).
24
24
  A file, directory, function, or other reference to the source code
25
25
  to explain.
26
26
 
27
+ ## SCENARIOS
28
+
29
+ - You want to understand how a piece of code works
30
+ - You want an explanation with WHAT, WHY, analogy, and diagram
31
+ - You want the cruxes and gotchas of unfamiliar code pointed out
32
+ - You want a quick orientation before touching foreign code
33
+
27
34
  ## EXAMPLES
28
35
 
29
36
  Explain a single source file:
@@ -24,6 +24,13 @@ a *MODULE STRUCTURE* Mermaid diagram of modules and their imports.
24
24
  One or more file or directory references to source code that
25
25
  should be inspected for insights.
26
26
 
27
+ ## SCENARIOS
28
+
29
+ - You want a high-level overview of a project
30
+ - You want to know who wrote the project and which files churn most
31
+ - You want a module structure diagram of the imports
32
+ - You want to get familiar with an unknown code base quickly
33
+
27
34
  ## EXAMPLES
28
35
 
29
36
  Get insights into the current project:
@@ -81,6 +81,14 @@ the code, and comments contradicting the code.
81
81
  *source-reference*:
82
82
  A file, directory, or other reference to the source code to lint.
83
83
 
84
+ ## SCENARIOS
85
+
86
+ - You want your code checked for code quality problems
87
+ - You want corrections proposed which you accept or reject one by one
88
+ - You want all quality corrections applied automatically
89
+ - You want only specific quality aspects like formatting or spelling checked
90
+ - You want missing or excessive code documentation flagged
91
+
84
92
  ## EXAMPLES
85
93
 
86
94
  Lint a source file interactively:
@@ -82,6 +82,13 @@ entirely and applies the change set to the affected artifacts itself.
82
82
  with a *task-id* followed by a colon to bind the resulting plan
83
83
  to a specific task id.
84
84
 
85
+ ## SCENARIOS
86
+
87
+ - You want existing code restructured without changing its behavior
88
+ - You want refactoring approaches with pros and cons before any changes
89
+ - You want a task plan composed for a cleanup
90
+ - You want a one-shot refactoring applied directly in place
91
+
85
92
  ## EXAMPLES
86
93
 
87
94
  Refactor a module into smaller files:
@@ -88,6 +88,13 @@ entirely and applies the change set to the affected artifacts itself.
88
88
  skill. Optionally prefixed with a *task-id* followed by a colon
89
89
  to bind the resulting plan to a specific task id.
90
90
 
91
+ ## SCENARIOS
92
+
93
+ - You want a bug fixed or a problem resolved in the code
94
+ - You want an issue like `P1` reported by an analyzer resolved
95
+ - You want resolution approaches with pros and cons before any changes
96
+ - You want a task plan composed for a bugfix
97
+
91
98
  ## EXAMPLES
92
99
 
93
100
  Resolve a free-text problem:
@@ -52,6 +52,13 @@ non-numeric value falls back to the default *5*.
52
52
  *text* itself pasted inline. If it resolves to a readable file the
53
53
  file is read; otherwise it is treated verbatim as pasted text.
54
54
 
55
+ ## SCENARIOS
56
+
57
+ - You want the key points of a document extracted and ranked
58
+ - You want the essence of a long text without reading all of it
59
+ - You want each key point backed by verbatim, line-cited evidence
60
+ - You want a pasted text or file boiled down to what matters
61
+
55
62
  ## EXAMPLES
56
63
 
57
64
  Distill the key points of a document file:
@@ -36,6 +36,13 @@ hint, which re-proposes the correction without limit) or - with
36
36
  A file, directory, or other reference to the documents to
37
37
  proofread.
38
38
 
39
+ ## SCENARIOS
40
+
41
+ - You want documents checked for spelling, punctuation, and grammar
42
+ - You want corrections proposed which you accept or reject one by one
43
+ - You want a whole documentation directory corrected automatically
44
+ - You want a final language pass over a text before publishing
45
+
39
46
  ## EXAMPLES
40
47
 
41
48
  Proofread a single document interactively:
@@ -3,11 +3,12 @@ name: ase-help-intent
3
3
  argument-hint: "[--help|-h] <intent>"
4
4
  description: >
5
5
  Match a free-text intent against the accumulated help of all ASE
6
- skills, generate the single best-fitting `/ase:ase-xxx-xxx` command
7
- with concrete options and arguments, and let the user execute it,
8
- refine the intent, or cancel. Use when the user knows what they want
9
- but not which skill or flags realize it, or mentions "intent" or
10
- requests "help".
6
+ skills, generate all adequately fitting `/ase:ase-xxx-xxx` commands
7
+ -- ranked best-fitting first, each with concrete options and
8
+ arguments -- and let the user execute one of them, refine the
9
+ intent, or cancel. Use when the user knows what they want but not
10
+ which skill or flags realize it, or mentions "intent" or requests
11
+ "help".
11
12
  user-invocable: true
12
13
  disable-model-invocation: false
13
14
  effort: high
@@ -21,7 +22,7 @@ allowed-tools:
21
22
  @${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
22
23
 
23
24
  <purpose name="ase-help-intent">
24
- Match an Intent to an ASE Command
25
+ Match an Intent to ASE Commands
25
26
  </purpose>
26
27
 
27
28
  <expand name="getopt"
@@ -32,8 +33,8 @@ Match an Intent to an ASE Command
32
33
 
33
34
  <objective>
34
35
  *Match* the following free-text intent against the accumulated help of
35
- all ASE skills and *generate* the single best-fitting `/ase:ase-xxx-xxx`
36
- command that realizes it:
36
+ all ASE skills and *generate* every adequately fitting `/ase:ase-xxx-xxx`
37
+ command that realizes it, ranked best-fitting first:
37
38
  <intent><getopt-arguments/></intent>
38
39
  </objective>
39
40
 
@@ -63,32 +64,43 @@ catalog you match <intent/> against:
63
64
  2. <step id="STEP 2: Match Intent and Dialog">
64
65
 
65
66
  *REPEAT* the following sub-steps in a *LOOP* until the user either
66
- *executes* the generated command or *cancels* the dialog in sub-step 4:
67
+ *executes* one of the generated commands or *cancels* the dialog in
68
+ sub-step 4:
67
69
 
68
70
  1. *Match Intent*:
69
71
 
70
- Match the current <intent/> against the <corpus/> and select the
71
- *single* best-fitting skill. From that skill's `## SYNOPSIS`,
72
- `## OPTIONS`, and `## ARGUMENTS` sections in <corpus/>,
73
- *generate* a concrete command that realizes <intent/>:
74
-
75
- - Set <name/> to the selected skill's name (e.g. `ase-code-lint`).
76
- - Set <arguments/> to the concrete option flags and positional
77
- arguments -- derived from the skill's `## OPTIONS` and
78
- `## ARGUMENTS` -- that best realize <intent/> (may be empty).
79
- - Set <command>/ase:<name/> <arguments/></command> (the full
80
- command line, with surplus inner spaces collapsed).
81
- - Set <rationale/> to a *very brief*, single-sentence
82
- justification of why the selected skill and its options match
72
+ Match the current <intent/> against the <corpus/> and select
73
+ *every* skill that adequately fits it -- judging the fit
74
+ primarily by each skill's `## SCENARIOS` ("You want ...") and
75
+ `## DESCRIPTION` sections. Order the selected skills from
76
+ best-fitting to worst-fitting and keep at most the *8* best
77
+ ones, so the dispatch dialog of sub-step 4 stays addressable.
78
+ Set <count/> to the number of kept skills. Then, for each kept
79
+ skill <n/> (numbered `1` to <count/> in rank order), from that
80
+ skill's `## SYNOPSIS`, `## OPTIONS`, and `## ARGUMENTS`
81
+ sections in <corpus/>, *generate* a concrete command that
82
+ realizes <intent/>:
83
+
84
+ - Set <name<n/>/> to the skill's name (e.g. `ase-code-lint`).
85
+ - Set <arguments<n/>/> to the concrete option flags and
86
+ positional arguments -- derived from the skill's
87
+ `## OPTIONS` and `## ARGUMENTS` -- that best realize
88
+ <intent/> (may be empty).
89
+ - Set <command<n/>>/ase:<name<n/>/> <arguments<n/>/></command<n/>>
90
+ (the full command line, with surplus inner spaces collapsed).
91
+ - Set <rationale<n/>/> to a *very brief*, single-sentence
92
+ justification of why this skill and its options match
83
93
  <intent/>.
84
- - Set <matched>yes</matched>.
94
+
95
+ Finally set <matched>yes</matched>.
85
96
 
86
97
  2. *Guard No Match*:
87
98
 
88
99
  <if condition="no skill in <corpus/> adequately matches <intent/>">
89
100
  Set <matched>no</matched> and discard the inadequate selection of
90
- sub-step 1 by setting <name></name>, <arguments></arguments>, and
91
- <command></command> (all set to empty), so that no stale command
101
+ sub-step 1 by setting <count>0</count> and clearing all
102
+ <name<n/>/>, <arguments<n/>/>, and <command<n/>/> placeholders
103
+ (all set to empty), so that no stale command
92
104
  can survive into the dialog of sub-step 4. Then output the
93
105
  following <template/> and *continue* the *loop* at sub-step 4 to
94
106
  prompt the user for a refined or clearer intent via the dialog's
@@ -99,18 +111,22 @@ catalog you match <intent/> against:
99
111
  </template>
100
112
  </if>
101
113
 
102
- 3. *Render Command*:
114
+ 3. *Render Commands*:
103
115
 
104
- Output the generated command with the following <template/>:
116
+ Output the generated commands, in rank order, with the following
117
+ <template/>, where the `[...]` marks the repetition of the
118
+ command/rationale line pair for each kept skill <n/> from `1`
119
+ to <count/>:
105
120
 
106
121
  <template>
107
- <ase-tpl-head title="SKILL COMMAND PROPOSAL"/>
122
+ <ase-tpl-head title="SKILL COMMAND PROPOSALS"/>
108
123
 
109
- ❯ `<command/>`
124
+ **C<n/>** ❯ `<command<n/>/>`
125
+ ▷ *<rationale<n/>/>*
110
126
 
111
- <ase-tpl-foot title="SKILL COMMAND PROPOSAL"/>
127
+ [...]
112
128
 
113
- **RATIONALE**: <rationale/>
129
+ <ase-tpl-foot title="SKILL COMMAND PROPOSALS"/>
114
130
  </template>
115
131
 
116
132
  4. *Dispatch Command*:
@@ -123,9 +139,9 @@ catalog you match <intent/> against:
123
139
  Let the user decide how to proceed by raising a question with the
124
140
  following custom dialog (invoked with `--other`, so that any
125
141
  free-text instruction is accepted as an intent refinement). Which
126
- dialog is raised depends on <matched/>, so that `EXECUTE` is
127
- offered *only* when a command was actually generated in sub-step 1
128
- *and* rendered in sub-step 3:
142
+ dialog is raised depends on <matched/>, so that the `C<n/>`
143
+ command options are offered *only* when commands were actually
144
+ generated in sub-step 1 *and* rendered in sub-step 3:
129
145
 
130
146
  <if condition="<matched/> is `no`">
131
147
  <expand name="custom-dialog" arg1="--other">
@@ -136,10 +152,16 @@ catalog you match <intent/> against:
136
152
  </if>
137
153
  <else>
138
154
  <expand name="custom-dialog" arg1="--other">
139
- Dispatch: What would you like to do with the generated command?
140
- EXECUTE: Execute the generated command now.
141
- CANCEL: Cancel this dialog.
155
+ Dispatch: Which of the proposed commands would you like to execute?
156
+ C1: Execute: `<command1/>`
157
+ [...]
158
+ CANCEL: Cancel this dialog.
142
159
  </expand>
160
+
161
+ The `[...]` line stands for one further answer line
162
+ `C<n/>: Execute `<command<n/>/>` now.` per additionally kept
163
+ skill <n/> from `2` to <count/>, in rank order, so the dialog
164
+ offers exactly <count/> command options plus `CANCEL`.
143
165
  </else>
144
166
 
145
167
  Check the tool <result/> and dispatch accordingly:
@@ -148,7 +170,7 @@ catalog you match <intent/> against:
148
170
  *Break* out of the *loop* and stop processing without any
149
171
  further output.
150
172
 
151
- - If <result/> is `REFINE`, or <result/> is `EXECUTE` while
173
+ - If <result/> is `REFINE`, or <result/> matches `C<n/>` while
152
174
  <matched/> is `no`: do *not* execute anything -- output the
153
175
  following <template/> and *continue* the *loop* at sub-step 4
154
176
  to obtain a refined intent via the dialog's free-text channel:
@@ -157,13 +179,14 @@ catalog you match <intent/> against:
157
179
  <ase-tpl-bullet-secondary/> **HINT**: please enter a refined or clearer intent as free text.
158
180
  </template>
159
181
 
160
- - If <result/> is `EXECUTE` (which implies <matched/> is `yes`):
161
- *Break* out of the *loop*, output the following <template/>,
162
- and then call the tool `Skill(skill: "ase:<name/>", args:
163
- "<arguments/>")` to *execute* the generated command:
182
+ - If <result/> matches `C<n/>` (which implies <matched/> is
183
+ `yes`): *Break* out of the *loop*, output the following
184
+ <template/>, and then call the tool `Skill(skill:
185
+ "ase:<name<n/>/>", args: "<arguments<n/>/>")` to *execute*
186
+ the selected command:
164
187
 
165
188
  <template>
166
- ⧉ **ASE**: ◉ intent: **<intent/>**, ⌘ command: **<command/>**, ▶ status: **command executing**
189
+ ⧉ **ASE**: ◉ intent: **<intent/>**, ⌘ command: **<command<n/>/>**, ▶ status: **command executing**
167
190
  </template>
168
191
 
169
192
  - If <result/> matches `OTHER: <text/>`: