@rse/ase 0.9.50 → 0.9.51
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.
- package/dst/ase-hook.js +9 -13
- package/dst/ase-statusline.js +30 -4
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.github/plugin/plugin.json +1 -1
- package/plugin/agents/ase-code-lint.md +21 -1
- package/plugin/agents/ase-meta-proximity.md +133 -0
- package/plugin/package.json +1 -1
- package/plugin/skills/ase-code-analyze/SKILL.md +10 -2
- package/plugin/skills/ase-code-analyze/help.md +4 -2
- package/plugin/skills/ase-code-lint/SKILL.md +41 -10
- package/plugin/skills/ase-code-lint/help.md +43 -1
- package/plugin/skills/ase-help-skill/catalog.md +1 -0
- package/plugin/skills/ase-meta-eli5/help.md +1 -1
- package/plugin/skills/ase-meta-proximity/SKILL.md +49 -90
- package/plugin/skills/ase-meta-proximity/help.md +11 -10
- package/plugin/skills/ase-meta-quotes/SKILL.md +214 -0
- package/plugin/skills/ase-meta-quotes/help.md +109 -0
- package/plugin/skills/ase-meta-review/help.md +4 -3
package/dst/ase-hook.js
CHANGED
|
@@ -145,12 +145,9 @@ export default class HookCommand {
|
|
|
145
145
|
pluginRootVars = ["PLUGIN_ROOT", "CLAUDE_PLUGIN_ROOT"];
|
|
146
146
|
else
|
|
147
147
|
pluginRootVars = ["CLAUDE_PLUGIN_ROOT"];
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
pluginRoot = process.env[pluginRootVar];
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
148
|
+
const pluginRoot = pluginRootVars
|
|
149
|
+
.map((varName) => process.env[varName] ?? "")
|
|
150
|
+
.find((value) => value !== "") ?? "";
|
|
154
151
|
if (pluginRoot === "")
|
|
155
152
|
throw new Error(`${pluginRootVars.join("/")} environment variable is not set`);
|
|
156
153
|
return pluginRoot;
|
|
@@ -254,7 +251,7 @@ export default class HookCommand {
|
|
|
254
251
|
const guidance = setting("agent.guidance", "ASE_GUIDANCE_LEVEL", "normal");
|
|
255
252
|
const boxing = setting("project.boxing", "ASE_PROJECT_BOXING", "white");
|
|
256
253
|
/* determine headless mode */
|
|
257
|
-
const headless =
|
|
254
|
+
const headless = process.env.ASE_HEADLESS === "true" ? "true" : "false";
|
|
258
255
|
/* provide ASE information to Anthropic Claude Code CLI shell commands
|
|
259
256
|
(Anthropic Claude Code CLI only -- GitHub Copilot CLI has no equivalent mechanism) */
|
|
260
257
|
const envFile = tool === "claude" ? (process.env.CLAUDE_ENV_FILE ?? "") : "";
|
|
@@ -300,15 +297,14 @@ export default class HookCommand {
|
|
|
300
297
|
"systemMessage" field for this -- GitHub Copilot CLI has no equivalent);
|
|
301
298
|
the trailing help hint is emitted only if the guidance level asks for it */
|
|
302
299
|
const banner = "\n" +
|
|
303
|
-
`\n⧉ ASE: ⎈ version: ${versionCurrentPlugin}${versionHint !== "" ? " " + versionHint.
|
|
300
|
+
`\n⧉ ASE: ⎈ version: ${versionCurrentPlugin}${versionHint !== "" ? " " + versionHint.replace(/\*/g, "") : ""}` +
|
|
304
301
|
`\n⧉ ASE: ※ user: ${userId}, ⚑ project: ${projectId}` +
|
|
305
302
|
`\n⧉ ASE: ◉ task: ${taskId}, ⏻ session: ${sessionId}` +
|
|
306
303
|
`\n⧉ ASE: ☯ persona: ${persona}, ▶ guidance: ${guidance}, ▢ boxing: ${boxing}` +
|
|
307
304
|
(guidance === "normal" || guidance === "verbose" ?
|
|
308
305
|
"\n" +
|
|
309
306
|
"\n⧉ ASE: ▷ hint: use \"/ase-help-intent <intent-description>\" for skill command proposal" +
|
|
310
|
-
"\n⧉ ASE: ▷ hint: use \"/ase-help-skill [<skill-name>]\" for skill catalog or skill manpage" : "")
|
|
311
|
-
"\n";
|
|
307
|
+
"\n⧉ ASE: ▷ hint: use \"/ase-help-skill [<skill-name>]\" for skill catalog or skill manpage" : "");
|
|
312
308
|
/* inject markdown into session context.
|
|
313
309
|
Anthropic Claude Code CLI and OpenAI Codex CLI expect the context nested in
|
|
314
310
|
"hookSpecificOutput"; GitHub Copilot CLI expects a flat top-level
|
|
@@ -434,10 +430,10 @@ export default class HookCommand {
|
|
|
434
430
|
tools, but the decision logic is shared by the "pre-tool-use" and
|
|
435
431
|
"permission-request" handlers. */
|
|
436
432
|
decideApproval(tool, spec, input) {
|
|
437
|
-
const
|
|
438
|
-
input[spec.toolNameField] : "";
|
|
439
|
-
let toolInput = {};
|
|
433
|
+
const rawName = input[spec.toolNameField];
|
|
440
434
|
const rawInput = input[spec.toolInputField];
|
|
435
|
+
const toolName = typeof rawName === "string" ? rawName : "";
|
|
436
|
+
let toolInput = {};
|
|
441
437
|
if (spec.toolInputIsString && typeof rawInput === "string")
|
|
442
438
|
toolInput = this.parseJSON(rawInput, toolInputSchema);
|
|
443
439
|
else if (!spec.toolInputIsString && typeof rawInput === "object" && rawInput !== null) {
|
package/dst/ase-statusline.js
CHANGED
|
@@ -159,6 +159,23 @@ const probeMemory = () => {
|
|
|
159
159
|
return { used: 0, total: 0 };
|
|
160
160
|
}
|
|
161
161
|
};
|
|
162
|
+
/* set of reasoning effort levels GitHub Copilot CLI offers in its effort picker */
|
|
163
|
+
const EFFORTS = new Set([
|
|
164
|
+
"low", "medium", "high", "xhigh", "max"
|
|
165
|
+
]);
|
|
166
|
+
/* split a GitHub Copilot CLI "model.display_name" into its plain model name and its
|
|
167
|
+
reasoning effort: Copilot CLI renders the display name as the model label, followed
|
|
168
|
+
by the optional request multiplier, the optional reasoning effort and the optional
|
|
169
|
+
context tier, all separated by " · " (e.g. "gpt-5.4 (2x) · high · 1M context"), so
|
|
170
|
+
only a segment matching a known effort level is taken as the effort */
|
|
171
|
+
const splitCopilotModel = (display) => {
|
|
172
|
+
const parts = display.split(" · ");
|
|
173
|
+
const effort = parts.filter((part) => EFFORTS.has(part.toLowerCase()));
|
|
174
|
+
const name = parts.filter((part) => !EFFORTS.has(part.toLowerCase()));
|
|
175
|
+
if (effort.length === 0)
|
|
176
|
+
return { name: display, effort: "" };
|
|
177
|
+
return { name: name.join(" · "), effort: effort[0].toLowerCase() };
|
|
178
|
+
};
|
|
162
179
|
/* memoize a zero-argument function, computing its value at most once on first use */
|
|
163
180
|
const memoize = (fn) => {
|
|
164
181
|
let cache = null;
|
|
@@ -286,6 +303,15 @@ export default class StatuslineCommand {
|
|
|
286
303
|
}
|
|
287
304
|
return { taskId, persona, guidance };
|
|
288
305
|
});
|
|
306
|
+
const getModel = memoize(() => {
|
|
307
|
+
const display = data.model?.display_name ?? "";
|
|
308
|
+
/* under GitHub Copilot CLI the reasoning effort is only available as
|
|
309
|
+
a segment of the display name, so split it off again and let the
|
|
310
|
+
regular "effort" field of Anthropic Claude Code CLI still win */
|
|
311
|
+
const split = tool === "copilot" && display !== "" ?
|
|
312
|
+
splitCopilotModel(display) : { name: display, effort: "" };
|
|
313
|
+
return { name: split.name, effort: data.effort?.level ?? split.effort };
|
|
314
|
+
});
|
|
289
315
|
const getGit = memoize(() => probeGit(data.workspace?.current_dir ?? ""));
|
|
290
316
|
const getMem = memoize(() => probeMemory());
|
|
291
317
|
/* identifier to renderer map: each callback fetches its own information
|
|
@@ -308,12 +334,12 @@ export default class StatuslineCommand {
|
|
|
308
334
|
s: () => emit(`${prefix("⏻", "session")}${c.bold(getSession())}`),
|
|
309
335
|
/* ==== MODEL ==== */
|
|
310
336
|
m: () => {
|
|
311
|
-
const
|
|
312
|
-
emit(`${prefix("⚙", "model")}${c.bold(
|
|
337
|
+
const { name } = getModel();
|
|
338
|
+
emit(`${prefix("⚙", "model")}${c.bold(name)}`);
|
|
313
339
|
},
|
|
314
340
|
e: () => {
|
|
315
|
-
const effort =
|
|
316
|
-
emit(`${prefix("⚒", "effort")}${c.bold(effort)}`);
|
|
341
|
+
const { effort } = getModel();
|
|
342
|
+
emit(`${prefix("⚒", "effort")}${c.bold(effort !== "" ? effort : "unknown")}`);
|
|
317
343
|
},
|
|
318
344
|
t: () => {
|
|
319
345
|
const thinking = data.thinking?.enabled === true ? "yes" : "no";
|
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.
|
|
9
|
+
"version": "0.9.51",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "Dr. Ralf S. Engelschall",
|
|
@@ -13,6 +13,10 @@ Workflow
|
|
|
13
13
|
--------
|
|
14
14
|
|
|
15
15
|
1. Set the requested context: <context>$ARGUMENTS</context>.
|
|
16
|
+
The *first* whitespace-separated token of <context/> is the
|
|
17
|
+
comma-separated *aspect set* <aspects/> (a non-empty subset of the
|
|
18
|
+
aspect ids `A01`...`A20`). The *remaining* tokens are the source
|
|
19
|
+
code files to check.
|
|
16
20
|
|
|
17
21
|
2. Use the `Read` tool to read all source code files referenced by
|
|
18
22
|
<context/>, plus all *related* source code files needed to really
|
|
@@ -25,7 +29,9 @@ Workflow
|
|
|
25
29
|
4. Set <problems/> to empty.
|
|
26
30
|
Then check the read source code for the following aspects (each
|
|
27
31
|
aspect is uniquely identified by its `aspect` id `A01 - XXX`...`A20
|
|
28
|
-
- XXX`)
|
|
32
|
+
- XXX`), but *strictly limited* to those aspects whose id is
|
|
33
|
+
contained in the aspect set <aspects/> -- all other aspects are
|
|
34
|
+
*not* checked and their problems are *never* reported:
|
|
29
35
|
|
|
30
36
|
- **A01 - FORMATTING**:
|
|
31
37
|
Check for inconsistently formatted code and badly vertically
|
|
@@ -95,6 +101,20 @@ Workflow
|
|
|
95
101
|
site as close as possible. For R4, prefer *parameterization*
|
|
96
102
|
(table-driven, strategy map) over inheritance.
|
|
97
103
|
|
|
104
|
+
**PAYOFF GATE**: *Before* reporting any redundancy, draft the
|
|
105
|
+
solution diff and count its lines. The removed lines *MUST* be at
|
|
106
|
+
least *twice* the added lines (ratio >= 2:1, i.e. a net reduction
|
|
107
|
+
of at least 50%), where the added lines include the *entire*
|
|
108
|
+
extracted construct (signature, body, closing lines, comments,
|
|
109
|
+
type annotations) plus all replacing call sites. A break-even
|
|
110
|
+
proposal (e.g. 8 removed, 8 added) or any proposal below the 2:1
|
|
111
|
+
ratio *MUST* be *silently dropped* and *MUST* *NOT* be reported --
|
|
112
|
+
it merely relocates code instead of reducing it. Do *not* game
|
|
113
|
+
the ratio by compressing the extracted construct into unnatural
|
|
114
|
+
formatting or by omitting comments the code base style requires.
|
|
115
|
+
Two duplicated occurrences of a short block rarely pass this gate;
|
|
116
|
+
three or more occurrences usually do.
|
|
117
|
+
|
|
98
118
|
- **A07 - PATTERNS**:
|
|
99
119
|
Check for broken design patterns, broken conventions, or broken
|
|
100
120
|
best practices.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ase-meta-proximity
|
|
3
|
+
description: "Determine the Conceptual Proximity of a Topic"
|
|
4
|
+
effort: high
|
|
5
|
+
tools:
|
|
6
|
+
- "Agent"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
@../meta/ase-control.md
|
|
10
|
+
|
|
11
|
+
<define name="gather-facts">
|
|
12
|
+
<if condition="<ground/> is equal `true`">
|
|
13
|
+
Use the `ase-meta-search` skill in a sub-agent to gather facts with
|
|
14
|
+
the following tool call and store the returned facts in the placeholder
|
|
15
|
+
named `<arg2/>`:
|
|
16
|
+
|
|
17
|
+
`Agent(
|
|
18
|
+
description: "Query Web Search Service",
|
|
19
|
+
subagent_type: "ase:ase-meta-search",
|
|
20
|
+
prompt: "Search the Internet/Web and gather facts about <arg1/>",
|
|
21
|
+
run_in_background: false
|
|
22
|
+
)`
|
|
23
|
+
|
|
24
|
+
<if condition="the placeholder named `<arg2/>` contains no usable facts">
|
|
25
|
+
Set the placeholder named `<arg2/>` to empty, so the determination below
|
|
26
|
+
silently falls back to model knowledge. You *MUST* *NOT* output any
|
|
27
|
+
warning, because the caller expects the labeled list of step 4 as the
|
|
28
|
+
*only* output.
|
|
29
|
+
</if>
|
|
30
|
+
</if>
|
|
31
|
+
<else>
|
|
32
|
+
Use the model's world knowledge and determine facts about <arg1/> and
|
|
33
|
+
store those facts in the placeholder named `<arg2/>`.
|
|
34
|
+
</else>
|
|
35
|
+
</define>
|
|
36
|
+
|
|
37
|
+
1. Set <args>$ARGUMENTS</args>, the single whitespace-separated string.
|
|
38
|
+
|
|
39
|
+
<if condition="the *first* token of <args/> is equal `GROUND`">
|
|
40
|
+
Set <ground>true</ground> (grounding requested) and set <topic/>
|
|
41
|
+
to the *second and all following* tokens of <args/>.
|
|
42
|
+
</if>
|
|
43
|
+
<else>
|
|
44
|
+
Set <ground>false</ground> (no grounding requested) and set
|
|
45
|
+
<topic/> to *all* tokens of <args/>.
|
|
46
|
+
</else>
|
|
47
|
+
|
|
48
|
+
You *MUST* *NOT* output anything related to this step.
|
|
49
|
+
|
|
50
|
+
2. *Determine Topic*:
|
|
51
|
+
|
|
52
|
+
Determine the canonical name of the central *topic* which is stored
|
|
53
|
+
in <topic/>.
|
|
54
|
+
|
|
55
|
+
<expand name="gather-facts"
|
|
56
|
+
arg1="the following topic: <topic/>"
|
|
57
|
+
arg2="facts-topic"></expand>
|
|
58
|
+
|
|
59
|
+
Ground the determination of the canonical name of the topic <topic/>
|
|
60
|
+
in the facts of <facts-topic/> and do not contradict them. Update
|
|
61
|
+
<topic/> accordingly.
|
|
62
|
+
|
|
63
|
+
You *MUST* *NOT* output anything related to this step.
|
|
64
|
+
|
|
65
|
+
3. *Determine Proximity*:
|
|
66
|
+
|
|
67
|
+
Determine the *conceptual proximity* of the current <topic/> along
|
|
68
|
+
three *dimensions* in parallel:
|
|
69
|
+
|
|
70
|
+
- **PARENT**:
|
|
71
|
+
|
|
72
|
+
The single most relevant *parent* topic (the broader topic that
|
|
73
|
+
<topic/> is a specialization of), which will be stored in
|
|
74
|
+
<parent/>.
|
|
75
|
+
|
|
76
|
+
<expand name="gather-facts"
|
|
77
|
+
arg1="the PARENT topic (the broader topic that the given topic is a specialization of) of the following topic: <topic/>"
|
|
78
|
+
arg2="facts-parent"></expand>
|
|
79
|
+
|
|
80
|
+
Ground the determination of the canonical name of the parent
|
|
81
|
+
topic <parent/> in the facts of <facts-parent/> and do not
|
|
82
|
+
contradict them.
|
|
83
|
+
|
|
84
|
+
- **SIBLINGS**:
|
|
85
|
+
|
|
86
|
+
The *four* most relevant *sibling* topics (topics on the same
|
|
87
|
+
level that share the same parent), which will be stored in
|
|
88
|
+
<sibling-1/> to <sibling-4/>.
|
|
89
|
+
|
|
90
|
+
<expand name="gather-facts"
|
|
91
|
+
arg1="the SIBLING topics (topics on the same level that share the same parent) of the following topic: <topic/>"
|
|
92
|
+
arg2="facts-siblings"></expand>
|
|
93
|
+
|
|
94
|
+
Ground the determination of the canonical names of the most
|
|
95
|
+
relevant sibling topics <sibling-1/> to <sibling-4/> in the facts
|
|
96
|
+
of <facts-siblings/> and do not contradict them.
|
|
97
|
+
|
|
98
|
+
- **CHILDREN**:
|
|
99
|
+
|
|
100
|
+
The *four* most relevant *child* topics (narrower topics that
|
|
101
|
+
are specializations of <topic/>), stored in <child-1/> to
|
|
102
|
+
<child-4/>.
|
|
103
|
+
|
|
104
|
+
<expand name="gather-facts"
|
|
105
|
+
arg1="the CHILDREN topics (narrower topics that are specializations) of the following topic: <topic/>"
|
|
106
|
+
arg2="facts-children"></expand>
|
|
107
|
+
|
|
108
|
+
Ground the determination of the canonical names of the most
|
|
109
|
+
relevant child topics <child-1/> to <child-4/> in the facts of
|
|
110
|
+
<facts-children/> and do not contradict them.
|
|
111
|
+
|
|
112
|
+
You *MUST* determine *exactly* one parent, *exactly* four siblings,
|
|
113
|
+
and *exactly* four children. All nine proximity topics *MUST* be
|
|
114
|
+
*distinct* from each other and *MUST* *NOT* be <topic/> itself or a
|
|
115
|
+
mere synonym or spelling variant of it. You *MUST* *NOT* output
|
|
116
|
+
anything related to this step.
|
|
117
|
+
|
|
118
|
+
4. Return *exclusively* the following <template/> (no prose, no
|
|
119
|
+
preamble, no summary, and no Markdown formatting):
|
|
120
|
+
|
|
121
|
+
<template>
|
|
122
|
+
TOPIC: <topic/>
|
|
123
|
+
PARENT: <parent/>
|
|
124
|
+
SIBLING: <sibling-1/>
|
|
125
|
+
SIBLING: <sibling-2/>
|
|
126
|
+
SIBLING: <sibling-3/>
|
|
127
|
+
SIBLING: <sibling-4/>
|
|
128
|
+
CHILD: <child-1/>
|
|
129
|
+
CHILD: <child-2/>
|
|
130
|
+
CHILD: <child-3/>
|
|
131
|
+
CHILD: <child-4/>
|
|
132
|
+
</template>
|
|
133
|
+
|
package/plugin/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.
|
|
9
|
+
"version": "0.9.51",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "Dr. Ralf S. Engelschall",
|
|
@@ -137,9 +137,17 @@ problems in *performance* and *efficiency*, or problems in *security*.
|
|
|
137
137
|
persisted). With the default floor `LOW`, all problems are kept.
|
|
138
138
|
`ACCEPTED` problems are *never* dropped.
|
|
139
139
|
|
|
140
|
+
Then sort the surviving problems in <problems/> by their `severity`
|
|
141
|
+
field from highest to lowest in the fixed order `HIGH`, `MEDIUM`,
|
|
142
|
+
`LOW`, `ACCEPTED`, so the reporting starts with the most severe
|
|
143
|
+
problem. Within the same severity, keep the `file`/`line` order
|
|
144
|
+
established in STEP 2.
|
|
145
|
+
|
|
140
146
|
Then renumber the surviving problems contiguously as `P<n/>` with
|
|
141
|
-
<n/> = 1, 2, ... in
|
|
142
|
-
|
|
147
|
+
<n/> = 1, 2, ... in that sorted ordering, so `P1` is the most severe
|
|
148
|
+
problem and the persisted `ase-issue-P<n/>` keys follow the reported
|
|
149
|
+
sequence. If *all* problems are dropped, skip the per-problem report
|
|
150
|
+
but still purge any stale
|
|
143
151
|
persisted problems with a *single* `ase_kv_batch` call to the `ase`
|
|
144
152
|
MCP server with `transactional` set to `true` and a `commands`
|
|
145
153
|
parameter array holding exactly one `{ command: "clear", prefix:
|
|
@@ -33,8 +33,10 @@ The `--severity`|`-S`=(`LOW`|`MEDIUM`|`HIGH`) option sets a *severity
|
|
|
33
33
|
floor* (default `LOW`): problems below the chosen threshold are silently
|
|
34
34
|
suppressed (neither reported nor persisted), ordered `LOW` < `MEDIUM` <
|
|
35
35
|
`HIGH`. The default `LOW` keeps all problems; `ACCEPTED` problems are
|
|
36
|
-
never suppressed. Surviving problems are
|
|
37
|
-
`
|
|
36
|
+
never suppressed. Surviving problems are reported in *descending
|
|
37
|
+
severity* order `HIGH`, `MEDIUM`, `LOW`, `ACCEPTED` - keeping the
|
|
38
|
+
`file`/`line` order within the same severity - and are renumbered
|
|
39
|
+
contiguously as `P<n>`, so `P1` is the most severe problem.
|
|
38
40
|
|
|
39
41
|
The skill investigates the code base silently, reports each detected
|
|
40
42
|
problem as a `PROBLEM` entry with severity (`LOW`, `MEDIUM`, `HIGH`) and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ase-code-lint
|
|
3
|
-
argument-hint: "[--help|-h] [--auto|-a] [--severity|-S=(LOW|MEDIUM|HIGH)] <source-reference>"
|
|
3
|
+
argument-hint: "[--help|-h] [--auto|-a] [--severity|-S=(LOW|MEDIUM|HIGH)] [--include|-i=<aspect>[,...]] [--exclude|-e=<aspect>[,...]] <source-reference>"
|
|
4
4
|
description: >
|
|
5
5
|
Lint source code for potential code quality problems.
|
|
6
6
|
Use when the user wants to "lint" or "check" source code.
|
|
@@ -20,7 +20,7 @@ Lint Source Code
|
|
|
20
20
|
|
|
21
21
|
<expand name="getopt"
|
|
22
22
|
arg1="ase-code-lint"
|
|
23
|
-
arg2="--auto|-a --severity|-S=(LOW|MEDIUM|HIGH)">
|
|
23
|
+
arg2="--auto|-a --severity|-S=(LOW|MEDIUM|HIGH) --include|-i=(none|A01|A02|A03|A04|A05|A06|A07|A08|A09|A10|A11|A12|A13|A14|A15|A16|A17|A18|A19|A20)... --exclude|-e=(none|A01|A02|A03|A04|A05|A06|A07|A08|A09|A10|A11|A12|A13|A14|A15|A16|A17|A18|A19|A20)...">
|
|
24
24
|
$ARGUMENTS
|
|
25
25
|
</expand>
|
|
26
26
|
|
|
@@ -48,7 +48,31 @@ related to a set of code quality aspects.
|
|
|
48
48
|
|
|
49
49
|
</if>
|
|
50
50
|
|
|
51
|
-
First,
|
|
51
|
+
First, determine the *effective aspect set* <aspects/>, i.e., the
|
|
52
|
+
code quality aspects which are checked at all. For this, parse
|
|
53
|
+
<getopt-option-include/> and <getopt-option-exclude/> as
|
|
54
|
+
comma-separated token lists, silently dropping the `none` sentinel
|
|
55
|
+
and any empty token. If a token <token/> is *not* one of the aspect
|
|
56
|
+
ids `A01`...`A20`, only output the following <template/> and then
|
|
57
|
+
*STOP* the entire flow (do not perform any further steps):
|
|
58
|
+
|
|
59
|
+
<template>
|
|
60
|
+
⧉ **ASE**: ✪ skill: **ase-code-lint**, ▶ ERROR: invalid aspect id: **<token/>**
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
Otherwise set <aspects/> to *all* twenty aspect ids `A01`...`A20`
|
|
64
|
+
if both lists are empty, to the *include* list if only it is
|
|
65
|
+
non-empty, to all twenty *minus* the *exclude* list if only it is
|
|
66
|
+
non-empty, and to the *include* list *minus* the *exclude* list if
|
|
67
|
+
both are non-empty. If the resulting <aspects/> is *empty*, only
|
|
68
|
+
output the following <template/> and then *STOP* the entire flow
|
|
69
|
+
(do not perform any further steps):
|
|
70
|
+
|
|
71
|
+
<template>
|
|
72
|
+
⧉ **ASE**: ✪ skill: **ase-code-lint**, ▶ ERROR: options `--include` and `--exclude` cancel out to an empty aspect set
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
Then, use the following <template/> to give a hint on this step:
|
|
52
76
|
|
|
53
77
|
<template>
|
|
54
78
|
<ase-tpl-bullet-secondary/> **LINT INVESTIGATION**
|
|
@@ -72,16 +96,17 @@ related to a set of code quality aspects.
|
|
|
72
96
|
Agent(
|
|
73
97
|
description: "Lint Investigation (<batch-index/>/<batch-count/>)",
|
|
74
98
|
subagent_type: "ase:ase-code-lint",
|
|
75
|
-
prompt: <batch
|
|
99
|
+
prompt: "<aspects/> <batch/>",
|
|
76
100
|
run_in_background: false
|
|
77
101
|
)
|
|
78
102
|
```
|
|
79
103
|
|
|
80
|
-
Here <
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
the
|
|
104
|
+
Here <aspects/> is the comma-separated list of the effective aspect
|
|
105
|
+
ids (without any spaces), <batch/> is the space-separated list of
|
|
106
|
+
the source code file paths of the corresponding batch,
|
|
107
|
+
<batch-index/> is the 1-based index of that batch, and
|
|
108
|
+
<batch-count/> is the total number of batches, so that each
|
|
109
|
+
parallel invocation is distinguishable in the progress display.
|
|
85
110
|
|
|
86
111
|
Parse the result message of each `Agent` tool invocation as a JSON
|
|
87
112
|
array and concatenate all those arrays. Then *deduplicate* the
|
|
@@ -104,6 +129,12 @@ related to a set of code quality aspects.
|
|
|
104
129
|
*silently drop* all other problems. With the default floor `LOW`, all
|
|
105
130
|
problems are kept. `ACCEPTED` problems are *never* dropped.
|
|
106
131
|
|
|
132
|
+
Finally, sort the surviving problems in <problems/> by their
|
|
133
|
+
`severity` field from highest to lowest in the fixed order `HIGH`,
|
|
134
|
+
`MEDIUM`, `LOW`, `ACCEPTED`, so the subsequent reporting starts with
|
|
135
|
+
the most severe problem. Within the same severity, keep the
|
|
136
|
+
`file`/`line` order established above.
|
|
137
|
+
|
|
107
138
|
You *MUST* *NOT* output anything else in this STEP 1.
|
|
108
139
|
|
|
109
140
|
</step>
|
|
@@ -443,7 +474,7 @@ related to a set of code quality aspects.
|
|
|
443
474
|
|
|
444
475
|
<if condition="<getopt-option-auto/> is not equal `true`">
|
|
445
476
|
<ase-tpl-hint level="verbose">
|
|
446
|
-
Use `/ase-code-lint --auto` to apply all corrections unattended,
|
|
477
|
+
Use `/ase-code-lint --auto` to apply all corrections unattended, `--severity` to raise the reporting floor, and `--include`/`--exclude` to narrow the checked aspects.
|
|
447
478
|
</ase-tpl-hint>
|
|
448
479
|
</if>
|
|
449
480
|
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
[`--help`|`-h`]
|
|
10
10
|
[`--auto`|`-a`]
|
|
11
11
|
[`--severity`|`-S`=(`LOW`|`MEDIUM`|`HIGH`)]
|
|
12
|
+
[`--include`|`-i`=*aspect*[`,`...]]
|
|
13
|
+
[`--exclude`|`-e`=*aspect*[`,`...]]
|
|
12
14
|
*source-reference*
|
|
13
15
|
|
|
14
16
|
## DESCRIPTION
|
|
@@ -25,6 +27,22 @@ correction interactively (or refine it via a free-text hint, which
|
|
|
25
27
|
re-proposes the correction without limit) or - with `--auto` - applies
|
|
26
28
|
all corrections automatically.
|
|
27
29
|
|
|
30
|
+
By default all twenty code quality aspects are checked. The `--include`
|
|
31
|
+
and `--exclude` options narrow this to an *effective aspect set*: with
|
|
32
|
+
`--include` only, exactly the listed aspects are checked; with
|
|
33
|
+
`--exclude` only, all aspects except the listed ones; with both, the
|
|
34
|
+
included ones minus the excluded ones. An unknown aspect id, or a
|
|
35
|
+
combination which cancels out to an empty set, aborts the skill with an
|
|
36
|
+
error. The twenty aspect ids are:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
A01 FORMATTING A06 REDUNDANCY A11 TYPING A16 SECURITY
|
|
40
|
+
A02 COMPREHENSION A07 PATTERNS A12 ERROR-HANDLING A17 ARCHITECTURE
|
|
41
|
+
A03 CLEANLINESS A08 COMPLICATEDNESS A13 MEMORY-LEAK A18 LOGIC
|
|
42
|
+
A04 SPELLING A09 CONCISENESS A14 CONCURRENCY A19 FLOW
|
|
43
|
+
A05 COMPLEXITY A10 SMELLS A15 PERFORMANCE A20 DEAD-CODE
|
|
44
|
+
```
|
|
45
|
+
|
|
28
46
|
## OPTIONS
|
|
29
47
|
|
|
30
48
|
`--auto`|`-a`:
|
|
@@ -35,7 +53,19 @@ all corrections automatically.
|
|
|
35
53
|
Set the *severity floor* (default `LOW`): findings below the chosen
|
|
36
54
|
threshold are silently suppressed, ordered `LOW` < `MEDIUM` <
|
|
37
55
|
`HIGH`. The default `LOW` keeps all findings; `ACCEPTED` findings are
|
|
38
|
-
never suppressed.
|
|
56
|
+
never suppressed. Surviving findings are reported in *descending
|
|
57
|
+
severity* order `HIGH`, `MEDIUM`, `LOW`, `ACCEPTED`, keeping the
|
|
58
|
+
`file`/`line` order within the same severity.
|
|
59
|
+
|
|
60
|
+
`--include`|`-i`=*aspect*[`,`...]:
|
|
61
|
+
Restrict the checked code quality aspects to the given
|
|
62
|
+
comma-separated list of aspect ids (e.g. `A01,A04`). Without this
|
|
63
|
+
option, all twenty aspects are checked.
|
|
64
|
+
|
|
65
|
+
`--exclude`|`-e`=*aspect*[`,`...]:
|
|
66
|
+
Remove the given comma-separated list of aspect ids from the checked
|
|
67
|
+
code quality aspects. Applied *after* `--include`, so `-i A01,A02 -e
|
|
68
|
+
A02` checks `A01` only.
|
|
39
69
|
|
|
40
70
|
## ARGUMENTS
|
|
41
71
|
|
|
@@ -62,6 +92,18 @@ Lint a directory, reporting only `MEDIUM` and `HIGH` findings:
|
|
|
62
92
|
❯ /ase-code-lint -S MEDIUM src/handlers/
|
|
63
93
|
```
|
|
64
94
|
|
|
95
|
+
Lint a source file for the formatting and spelling aspects only:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
❯ /ase-code-lint -i A01,A04 src/server.ts
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Lint a directory for all aspects except dead code:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
❯ /ase-code-lint --exclude A20 src/handlers/
|
|
105
|
+
```
|
|
106
|
+
|
|
65
107
|
## SEE ALSO
|
|
66
108
|
|
|
67
109
|
[`ase-code-analyze`](../ase-code-analyze/help.md), [`ase-code-resolve`](../ase-code-resolve/help.md), [`ase-code-refactor`](../ase-code-refactor/help.md),
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
⎈ **RESEARCH**
|
|
7
7
|
○ `ase-meta-search`: Search the Internet/Web
|
|
8
8
|
○ `ase-meta-proximity`: Determine the Conceptual Proximity of a Topic
|
|
9
|
+
○ `ase-meta-quotes`: Find Quotes on a Topic
|
|
9
10
|
○ `ase-meta-brainstorm`: Collaboratively Brainstorm a Topic
|
|
10
11
|
○ `ase-meta-chat`: Query Foreign LLM for Chat
|
|
11
12
|
○ `ase-meta-quorum`: Query Multiple AIs for Quorum Answer
|
|
@@ -58,4 +58,4 @@ Explain a recent topic grounded in Internet/Web facts:
|
|
|
58
58
|
|
|
59
59
|
## SEE ALSO
|
|
60
60
|
|
|
61
|
-
[`ase-code-explain`](../ase-code-explain/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-docs-distill`](../ase-docs-distill/help.md).
|
|
61
|
+
[`ase-code-explain`](../ase-code-explain/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-meta-quotes`](../ase-meta-quotes/help.md), [`ase-docs-distill`](../ase-docs-distill/help.md).
|
|
@@ -37,37 +37,6 @@ relevant *child* topics:
|
|
|
37
37
|
<topic><getopt-arguments/></topic>
|
|
38
38
|
</objective>
|
|
39
39
|
|
|
40
|
-
<define name="gather-facts">
|
|
41
|
-
<if condition="<getopt-option-ground/> is equal `true`">
|
|
42
|
-
Set <prompt>Search the Internet/Web and gather facts about
|
|
43
|
-
<arg1/></prompt>.
|
|
44
|
-
|
|
45
|
-
Then use the `ase-meta-search` skill in a sub-agent to gather facts with
|
|
46
|
-
the following tool call and store the returned facts in the placeholder
|
|
47
|
-
named `<arg2/>`:
|
|
48
|
-
|
|
49
|
-
`Agent(
|
|
50
|
-
description: "Query Web Search Service",
|
|
51
|
-
subagent_type: "ase:ase-meta-search",
|
|
52
|
-
prompt: "<prompt/>",
|
|
53
|
-
run_in_background: false
|
|
54
|
-
)`
|
|
55
|
-
|
|
56
|
-
<if condition="the placeholder named `<arg2/>` contains no usable facts">
|
|
57
|
-
Set the placeholder named `<arg2/>` to empty, so the determination below
|
|
58
|
-
falls back to model knowledge, and output the following <template/>:
|
|
59
|
-
|
|
60
|
-
<template>
|
|
61
|
-
<ase-tpl-bullet-secondary/> **WARNING**: grounding found no usable facts -- falling back to model knowledge.
|
|
62
|
-
</template>
|
|
63
|
-
</if>
|
|
64
|
-
</if>
|
|
65
|
-
<else>
|
|
66
|
-
Use the model's world knowledge and determine facts about <arg1/> and
|
|
67
|
-
store those facts in the placeholder named `<arg2/>`.
|
|
68
|
-
</else>
|
|
69
|
-
</define>
|
|
70
|
-
|
|
71
40
|
<flow>
|
|
72
41
|
|
|
73
42
|
1. <step id="STEP 1: Check Topic">
|
|
@@ -88,69 +57,59 @@ store those facts in the placeholder named `<arg2/>`.
|
|
|
88
57
|
*REPEAT* the following sub-steps in a *LOOP* until either
|
|
89
58
|
<getopt-option-loop/> is *not* equal `true` (then the loop runs
|
|
90
59
|
exactly *once* and stops after rendering), or the user declines/cancels
|
|
91
|
-
the dialog in sub-step
|
|
92
|
-
|
|
93
|
-
1. *Determine Topic*:
|
|
94
|
-
|
|
95
|
-
Determine the canonical name of the central *topic* which is stored
|
|
96
|
-
in <topic/>.
|
|
97
|
-
|
|
98
|
-
<expand name="gather-facts"
|
|
99
|
-
arg1="the following topic: <topic/>"
|
|
100
|
-
arg2="facts-topic"></expand>
|
|
101
|
-
|
|
102
|
-
Ground the determination of the canonical name of the topic
|
|
103
|
-
<topic/> in the facts of <facts-topic/> and do not contradict
|
|
104
|
-
them. Update <topic/> accordingly.
|
|
105
|
-
|
|
106
|
-
2. *Determine Proximity*:
|
|
107
|
-
|
|
108
|
-
Determine the *conceptual proximity* of the current <topic/>
|
|
109
|
-
along three *dimensions*:
|
|
110
|
-
|
|
111
|
-
- **PARENT**:
|
|
112
|
-
|
|
113
|
-
The single most relevant *parent* topic (the broader topic
|
|
114
|
-
that <topic/> is a specialization of), which will be stored
|
|
115
|
-
in <parent/>.
|
|
60
|
+
the dialog in sub-step 4:
|
|
116
61
|
|
|
117
|
-
|
|
118
|
-
arg1="the PARENT topic (the broader topic that the given topic is a specialization of) of the following topic: <topic/>"
|
|
119
|
-
arg2="facts-parent"></expand>
|
|
62
|
+
1. *Determine Proximity*:
|
|
120
63
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
64
|
+
Set <parent/>, <sibling-1/> to <sibling-4/>, and <child-1/> to
|
|
65
|
+
<child-4/> to empty, so that a stale proximity of a previously
|
|
66
|
+
navigated topic can never leak into the rendering below.
|
|
124
67
|
|
|
125
|
-
|
|
68
|
+
Set <prompt><topic/></prompt>.
|
|
126
69
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
arg1="the SIBLING topics (topics on the same level that share the same parent) of the following topic: <topic/>"
|
|
133
|
-
arg2="facts-siblings"></expand>
|
|
134
|
-
|
|
135
|
-
Ground the determination of the canonical names of the most
|
|
136
|
-
relevant sibling topics <sibling-1/> to <sibling-4/> in the
|
|
137
|
-
facts of <facts-siblings/> and do not contradict them.
|
|
138
|
-
|
|
139
|
-
- **CHILDREN**:
|
|
140
|
-
|
|
141
|
-
The *four* most relevant *children* topics (narrower topics
|
|
142
|
-
that are specializations of <topic/>), stored in <child-1/>
|
|
143
|
-
to <child-4/>.
|
|
70
|
+
<if condition="<getopt-option-ground/> is equal `true`">
|
|
71
|
+
Set <prompt>GROUND <topic/></prompt>, so the agent grounds its
|
|
72
|
+
determination in Internet/Web facts instead of using model
|
|
73
|
+
knowledge only.
|
|
74
|
+
</if>
|
|
144
75
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
76
|
+
Determine the canonical name of the central *topic* and its
|
|
77
|
+
*conceptual proximity* along the three *dimensions* **PARENT**
|
|
78
|
+
(the single broader topic that <topic/> is a specialization of),
|
|
79
|
+
**SIBLINGS** (the four most relevant topics on the same level
|
|
80
|
+
that share the same parent), and **CHILDREN** (the four most
|
|
81
|
+
relevant narrower topics that are specializations of <topic/>) by
|
|
82
|
+
using the `ase-meta-proximity` agent in a sub-agent with the
|
|
83
|
+
following tool call:
|
|
84
|
+
|
|
85
|
+
`Agent(
|
|
86
|
+
description: "Determine Conceptual Proximity",
|
|
87
|
+
subagent_type: "ase:ase-meta-proximity",
|
|
88
|
+
prompt: "<prompt/>",
|
|
89
|
+
run_in_background: false
|
|
90
|
+
)`
|
|
91
|
+
|
|
92
|
+
Parse the returned labeled list and set <topic/> to the value of
|
|
93
|
+
its `TOPIC:` line, <parent/> to the value of its `PARENT:` line,
|
|
94
|
+
<sibling-1/> to <sibling-4/> to the values of its four `SIBLING:`
|
|
95
|
+
lines, and <child-1/> to <child-4/> to the values of its four
|
|
96
|
+
`CHILD:` lines.
|
|
97
|
+
|
|
98
|
+
<if condition="
|
|
99
|
+
the sub-agent returned no usable proximity OR
|
|
100
|
+
it did not yield a canonical topic, exactly one parent,
|
|
101
|
+
exactly four siblings, and exactly four children
|
|
102
|
+
">
|
|
103
|
+
Determine the canonical topic name, the parent, the siblings, and
|
|
104
|
+
the children from model knowledge instead, and output the
|
|
105
|
+
following <template/>:
|
|
148
106
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
107
|
+
<template>
|
|
108
|
+
<ase-tpl-bullet-secondary/> **WARNING**: proximity agent returned no usable result -- falling back to model knowledge.
|
|
109
|
+
</template>
|
|
110
|
+
</if>
|
|
152
111
|
|
|
153
|
-
|
|
112
|
+
2. *Render Proximity*:
|
|
154
113
|
|
|
155
114
|
Output the result with the following <template/>, listing each
|
|
156
115
|
proximity topic under its bullet-prefixed section header.
|
|
@@ -179,12 +138,12 @@ store those facts in the placeholder named `<arg2/>`.
|
|
|
179
138
|
<ase-tpl-foot title="PROXIMITY TOPICS"/>
|
|
180
139
|
</template>
|
|
181
140
|
|
|
182
|
-
|
|
141
|
+
3. <if condition="<getopt-option-loop/> is not equal `true`">
|
|
183
142
|
The loop runs only once in non-interactive mode: *break* out of
|
|
184
143
|
the *loop* and stop processing without any further output.
|
|
185
144
|
</if>
|
|
186
145
|
|
|
187
|
-
|
|
146
|
+
4. *Navigate Proximity*:
|
|
188
147
|
|
|
189
148
|
In the following, you *MUST* *NOT* use your built-in
|
|
190
149
|
<user-dialog-tool/> tool! Instead, you *MUST* just show a custom
|
|
@@ -207,7 +166,7 @@ store those facts in the placeholder named `<arg2/>`.
|
|
|
207
166
|
CHILD-4: ↓ <child-4/>
|
|
208
167
|
</expand>
|
|
209
168
|
|
|
210
|
-
Check the
|
|
169
|
+
Check the <result/> and dispatch accordingly:
|
|
211
170
|
|
|
212
171
|
- If <result/> is `CANCEL`:
|
|
213
172
|
*Break* out of the *loop* and stop processing without any
|
|
@@ -20,11 +20,12 @@ topic that *topic* specializes), *SIBLINGS* (the four most relevant
|
|
|
20
20
|
topics on the same level, sharing the same parent), and *CHILDREN* (the
|
|
21
21
|
four most relevant narrower topics that specialize *topic*).
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
The determination itself is delegated to the `ase-meta-proximity` agent,
|
|
24
|
+
which is shared with the `ase-meta-quotes` skill. By default the
|
|
25
|
+
proximity is derived from model knowledge only. With the `--ground`/`-g`
|
|
26
|
+
option, the agent first searches the Internet/Web for facts about the
|
|
27
|
+
topic, about its broader topic, and about its narrower topics, and
|
|
28
|
+
grounds the determination in the found facts.
|
|
28
29
|
|
|
29
30
|
Without the `--loop`/`-l` option, the skill determines and prints the
|
|
30
31
|
proximity of the given topic once and then stops. With the `--loop`/`-l`
|
|
@@ -33,14 +34,14 @@ interactive dialog; selecting one of them makes it the new *current
|
|
|
33
34
|
topic* and restarts the determination from the beginning, so the user
|
|
34
35
|
can *navigate* the topic taxonomy up (parent), sideways (siblings), and
|
|
35
36
|
down (children). Cancelling the dialog exits the loop. When `--loop` is
|
|
36
|
-
combined with `--ground`, each newly selected topic is re-grounded
|
|
37
|
-
the `ase-meta-
|
|
37
|
+
combined with `--ground`, each newly selected topic is re-grounded by
|
|
38
|
+
the `ase-meta-proximity` sub-agent before its proximity is re-determined.
|
|
38
39
|
|
|
39
40
|
## OPTIONS
|
|
40
41
|
|
|
41
42
|
`--ground`|`-g`:
|
|
42
|
-
Ground the determination in Internet/Web facts gathered
|
|
43
|
-
`ase-meta-
|
|
43
|
+
Ground the determination in Internet/Web facts gathered by the
|
|
44
|
+
`ase-meta-proximity` agent before determining the proximity. Without
|
|
44
45
|
this option, the determination is derived from model knowledge only.
|
|
45
46
|
When combined with `--loop`, every newly navigated-to topic is
|
|
46
47
|
re-grounded.
|
|
@@ -75,4 +76,4 @@ Internet/Web facts:
|
|
|
75
76
|
|
|
76
77
|
## SEE ALSO
|
|
77
78
|
|
|
78
|
-
[`ase-meta-eli5`](../ase-meta-eli5/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-code-explain`](../ase-code-explain/help.md).
|
|
79
|
+
[`ase-meta-quotes`](../ase-meta-quotes/help.md), [`ase-meta-eli5`](../ase-meta-eli5/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-code-explain`](../ase-code-explain/help.md).
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ase-meta-quotes
|
|
3
|
+
argument-hint: "[--help|-h] [--ground|-g] [--proximity|-p] [--count|-c <count>] <topic-keywords>"
|
|
4
|
+
description: >
|
|
5
|
+
Find quotes for a set of topic keywords and place them into a
|
|
6
|
+
2x2 matrix, spanned by the presence of an author/origin and by
|
|
7
|
+
the literal containment of a keyword, optionally grounded in
|
|
8
|
+
Internet/Web facts and optionally widened to the conceptual
|
|
9
|
+
neighborhood of the topic. Use when the user wants "quotes",
|
|
10
|
+
"sayings", "aphorisms", or "citations" on a topic.
|
|
11
|
+
user-invocable: true
|
|
12
|
+
disable-model-invocation: false
|
|
13
|
+
effort: high
|
|
14
|
+
allowed-tools:
|
|
15
|
+
- "Agent"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
@${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
|
|
19
|
+
@${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
|
|
20
|
+
@${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
|
|
21
|
+
|
|
22
|
+
<skill name="ase-meta-quotes">
|
|
23
|
+
Find Quotes on a Topic
|
|
24
|
+
</skill>
|
|
25
|
+
|
|
26
|
+
<expand name="getopt"
|
|
27
|
+
arg1="ase-meta-quotes"
|
|
28
|
+
arg2="--ground|-g --proximity|-p --count|-c=8">
|
|
29
|
+
$ARGUMENTS
|
|
30
|
+
</expand>
|
|
31
|
+
|
|
32
|
+
<objective>
|
|
33
|
+
*Find* quotes for the following topic keywords:
|
|
34
|
+
<keywords><getopt-arguments/></keywords>
|
|
35
|
+
</objective>
|
|
36
|
+
|
|
37
|
+
<flow>
|
|
38
|
+
|
|
39
|
+
1. <step id="STEP 1: Sanity Check Usage">
|
|
40
|
+
|
|
41
|
+
1. <if condition="<keywords/> is empty">
|
|
42
|
+
Only output the following <template/> and then immediately *STOP*
|
|
43
|
+
processing the entire current skill:
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
⧉ **ASE**: ✪ skill: **ase-meta-quotes**, ▶ ERROR: expected a `<topic-keywords>` argument
|
|
47
|
+
</template>
|
|
48
|
+
</if>
|
|
49
|
+
|
|
50
|
+
2. Set <quotes></quotes> (set to empty).
|
|
51
|
+
|
|
52
|
+
3. Determine the maximum total number of *quotes* to surface: set
|
|
53
|
+
<count/> to <getopt-option-count/>; if <getopt-option-count/> is
|
|
54
|
+
*non-numeric* or *less than or equal to 0*, use the default *8*
|
|
55
|
+
instead.
|
|
56
|
+
|
|
57
|
+
</step>
|
|
58
|
+
|
|
59
|
+
2. <step id="STEP 2: Harvest Quotes">
|
|
60
|
+
|
|
61
|
+
1. Determine *quotes* -- sayings, aphorisms, maxims, proverbs, and
|
|
62
|
+
citations -- which are about the topic <keywords/>, and store them in
|
|
63
|
+
<quotes/>. Per quote, record its *text*, its *author* (a named person
|
|
64
|
+
or organization, if any is known), its *origin* (a named work,
|
|
65
|
+
standard, or document, if any is known), and <keywords/> as its
|
|
66
|
+
*source topic*.
|
|
67
|
+
|
|
68
|
+
2. <if condition="<getopt-option-ground/> is equal `true`">
|
|
69
|
+
|
|
70
|
+
*Additionally* -- and never *instead* -- gather quotes from the
|
|
71
|
+
Internet/Web by using the `ase-meta-search` skill in a sub-agent
|
|
72
|
+
with the following tool call:
|
|
73
|
+
|
|
74
|
+
`Agent(
|
|
75
|
+
description: "Query Web Search Service",
|
|
76
|
+
subagent_type: "ase:ase-meta-search",
|
|
77
|
+
prompt: "Search the Internet/Web and gather quotes about the following topic: <keywords/>",
|
|
78
|
+
run_in_background: false
|
|
79
|
+
)`
|
|
80
|
+
|
|
81
|
+
Merge the returned quotes into <quotes/>, deduplicating quotes which
|
|
82
|
+
differ only in punctuation, capitalization, or attribution wording,
|
|
83
|
+
and remember for every quote whether the search *confirmed* its exact
|
|
84
|
+
wording and attribution.
|
|
85
|
+
|
|
86
|
+
<if condition="the sub-agent returned no usable quotes">
|
|
87
|
+
Output the following <template/> and continue with the model
|
|
88
|
+
knowledge only:
|
|
89
|
+
|
|
90
|
+
<template>
|
|
91
|
+
<ase-tpl-bullet-secondary/> **WARNING**: grounding found no usable quotes -- falling back to model knowledge.
|
|
92
|
+
</template>
|
|
93
|
+
</if>
|
|
94
|
+
|
|
95
|
+
</if>
|
|
96
|
+
|
|
97
|
+
</step>
|
|
98
|
+
|
|
99
|
+
3. <step id="STEP 3: Widen Topic via Proximity" condition="<getopt-option-proximity/> is equal `true`">
|
|
100
|
+
|
|
101
|
+
1. Set <prompt><keywords/></prompt>.
|
|
102
|
+
|
|
103
|
+
2. <if condition="<getopt-option-ground/> is equal `true`">
|
|
104
|
+
Set <prompt>GROUND <keywords/></prompt>, so the agent grounds
|
|
105
|
+
its determination in Internet/Web facts instead of using model
|
|
106
|
+
knowledge only.
|
|
107
|
+
</if>
|
|
108
|
+
|
|
109
|
+
3. Determine the *conceptual neighborhood* of <keywords/> by using the
|
|
110
|
+
`ase-meta-proximity` agent in a sub-agent with the following
|
|
111
|
+
tool call:
|
|
112
|
+
|
|
113
|
+
`Agent(
|
|
114
|
+
description: "Determine Conceptual Proximity",
|
|
115
|
+
subagent_type: "ase:ase-meta-proximity",
|
|
116
|
+
prompt: "<prompt/>",
|
|
117
|
+
run_in_background: false
|
|
118
|
+
)`
|
|
119
|
+
|
|
120
|
+
4. <if condition="the sub-agent returned no usable neighborhood">
|
|
121
|
+
Output the following <template/>, *SKIP* the remaining sub-steps
|
|
122
|
+
of this step, and continue with the quotes harvested in STEP 2
|
|
123
|
+
only:
|
|
124
|
+
|
|
125
|
+
<template>
|
|
126
|
+
<ase-tpl-bullet-secondary/> **WARNING**: proximity agent returned no usable result -- keeping the narrow topic only.
|
|
127
|
+
</template>
|
|
128
|
+
</if>
|
|
129
|
+
|
|
130
|
+
5. Parse the returned labeled list and set <neighborhood/> to the values
|
|
131
|
+
of its `PARENT:` line (the *broader* topic), of its four
|
|
132
|
+
`SIBLING:` lines (the *same-level* topics), and of its four
|
|
133
|
+
`CHILD:` lines (the *narrower* topics).
|
|
134
|
+
|
|
135
|
+
6. Harvest quotes for *each* topic of <neighborhood/> exactly as in
|
|
136
|
+
STEP 2 (Harvest Quotes), record the contributing neighborhood
|
|
137
|
+
topic as the *source topic* of each of those quotes, and merge
|
|
138
|
+
the results into <quotes/>.
|
|
139
|
+
|
|
140
|
+
</step>
|
|
141
|
+
|
|
142
|
+
4. <step id="STEP 4: Classify and Render Quotes">
|
|
143
|
+
|
|
144
|
+
1. *Classify Quotes*:
|
|
145
|
+
|
|
146
|
+
Classify every quote of <quotes/> along two *orthogonal* axes:
|
|
147
|
+
|
|
148
|
+
- **ATTRIBUTION**:
|
|
149
|
+
A quote is `ATTRIBUTED` if a named *author* and/or a named
|
|
150
|
+
*origin* is known for it, and `ANONYMOUS` otherwise.
|
|
151
|
+
|
|
152
|
+
- **LITERALNESS**:
|
|
153
|
+
A quote is `LITERAL` if its text contains at least one of
|
|
154
|
+
the topic keywords of <keywords/> as a *whole word* --
|
|
155
|
+
matched *case-insensitively* and tolerating *inflections*
|
|
156
|
+
(e.g. `architect` and `architectural` match the keyword
|
|
157
|
+
`architecture`), but *never* as a mere *substring* (e.g.
|
|
158
|
+
`art` does *not* match `architecture`). A quote is
|
|
159
|
+
`THEMATIC` otherwise.
|
|
160
|
+
|
|
161
|
+
Both axes span the four *quadrants*:
|
|
162
|
+
|
|
163
|
+
- `Q1` (`ATTRIBUTED` and `LITERAL`)
|
|
164
|
+
- `Q2` (`ATTRIBUTED` and `THEMATIC`)
|
|
165
|
+
- `Q3` (`ANONYMOUS` and `LITERAL`)
|
|
166
|
+
- `Q4` (`ANONYMOUS` and `THEMATIC`)
|
|
167
|
+
|
|
168
|
+
2. Finally, reduce <quotes/> to at most <count/> quotes in *total*,
|
|
169
|
+
distributed as evenly as possible across the four quadrants
|
|
170
|
+
and preferring the most relevant and most well-known quote per
|
|
171
|
+
quadrant.
|
|
172
|
+
|
|
173
|
+
3. *Render Quotes*:
|
|
174
|
+
|
|
175
|
+
Render every quote on its own `○`-prefixed line, with the
|
|
176
|
+
following *suffixes* appended in this order:
|
|
177
|
+
|
|
178
|
+
- ` — *<author/>*, <origin/>` in the two `ATTRIBUTED` quadrants,
|
|
179
|
+
omitting whichever of <author/> and <origin/> is unknown.
|
|
180
|
+
|
|
181
|
+
- ` [from proximity: `<source-topic/>`]` if the quote was
|
|
182
|
+
harvested for a *neighborhood* topic in STEP 3 rather than for
|
|
183
|
+
<keywords/> itself.
|
|
184
|
+
|
|
185
|
+
- ` *(unverified)*` if the exact wording or the attribution of
|
|
186
|
+
the quote could not be established with confidence -- but
|
|
187
|
+
omit this marker for a quote whose wording and attribution
|
|
188
|
+
the Internet/Web search of STEP 2.2 confirmed -- including
|
|
189
|
+
its re-application for a neighborhood topic in STEP 3.
|
|
190
|
+
|
|
191
|
+
Render the single line `○ (none)` for a quadrant without any
|
|
192
|
+
quote. Output the result with the following <template/>:
|
|
193
|
+
|
|
194
|
+
<template>
|
|
195
|
+
<ase-tpl-head title="QUOTES"/>
|
|
196
|
+
|
|
197
|
+
● **Q1 - ATTRIBUTED / LITERAL**:
|
|
198
|
+
○ [...]
|
|
199
|
+
|
|
200
|
+
● **Q2 - ATTRIBUTED / THEMATIC**:
|
|
201
|
+
○ [...]
|
|
202
|
+
|
|
203
|
+
● **Q3 - ANONYMOUS / LITERAL**:
|
|
204
|
+
○ [...]
|
|
205
|
+
|
|
206
|
+
● **Q4 - ANONYMOUS / THEMATIC**:
|
|
207
|
+
○ [...]
|
|
208
|
+
|
|
209
|
+
<ase-tpl-foot title="QUOTES"/>
|
|
210
|
+
</template>
|
|
211
|
+
|
|
212
|
+
</step>
|
|
213
|
+
|
|
214
|
+
</flow>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
|
|
2
|
+
## NAME
|
|
3
|
+
|
|
4
|
+
`ase-meta-quotes` - Find Quotes on a Topic
|
|
5
|
+
|
|
6
|
+
## SYNOPSIS
|
|
7
|
+
|
|
8
|
+
`ase-meta-quotes`
|
|
9
|
+
[`--help`|`-h`]
|
|
10
|
+
[`--ground`|`-g`]
|
|
11
|
+
[`--proximity`|`-p`]
|
|
12
|
+
[`--count`|`-c` *count*]
|
|
13
|
+
*topic-keywords*
|
|
14
|
+
|
|
15
|
+
## DESCRIPTION
|
|
16
|
+
|
|
17
|
+
The `ase-meta-quotes` skill finds *quotes* -- sayings, aphorisms,
|
|
18
|
+
maxims, proverbs, and citations -- for the supplied *topic-keywords* and
|
|
19
|
+
places them into a *2x2 matrix*, reported as four labeled *quadrant*
|
|
20
|
+
sections.
|
|
21
|
+
|
|
22
|
+
Per quote, the skill records its *text*, its *author* (a named person or
|
|
23
|
+
organization, if known), its *origin* (a named work, standard, or
|
|
24
|
+
document, if known), and the topic it was harvested for (its *source
|
|
25
|
+
topic*).
|
|
26
|
+
|
|
27
|
+
The first dimension of the matrix is the *attribution* of a quote: a
|
|
28
|
+
quote is `ATTRIBUTED` when a named author and/or a named origin is known
|
|
29
|
+
for it, and `ANONYMOUS` otherwise. The second dimension is the
|
|
30
|
+
*literalness* of a quote: a quote is `LITERAL` when its text contains at
|
|
31
|
+
least one of the *topic-keywords* as a whole word -- matched
|
|
32
|
+
case-insensitively and tolerating inflections (e.g. `architect` and
|
|
33
|
+
`architectural` match the keyword `architecture`), but never as a mere
|
|
34
|
+
substring (e.g. `art` does not match `architecture`) -- and `THEMATIC`
|
|
35
|
+
otherwise. The two dimensions span the quadrants `Q1`
|
|
36
|
+
(`ATTRIBUTED`/`LITERAL`), `Q2` (`ATTRIBUTED`/`THEMATIC`), `Q3`
|
|
37
|
+
(`ANONYMOUS`/`LITERAL`), and `Q4` (`ANONYMOUS`/`THEMATIC`). A quadrant
|
|
38
|
+
without any quote is rendered as `(none)`.
|
|
39
|
+
|
|
40
|
+
Every quote is rendered on its own line and carries, where applicable,
|
|
41
|
+
the suffixes `— <author>, <origin>` (in the two `ATTRIBUTED`
|
|
42
|
+
quadrants, omitting whichever part is unknown), `[from proximity:
|
|
43
|
+
<source-topic>]` (when the quote was contributed by a neighborhood topic
|
|
44
|
+
under `--proximity` instead of by *topic-keywords* itself), and
|
|
45
|
+
`(unverified)` (when the exact wording or the attribution could not be
|
|
46
|
+
established with confidence). The `(unverified)` marker is dropped as
|
|
47
|
+
soon as the Internet/Web search under `--ground` confirms the wording and
|
|
48
|
+
the attribution of the quote.
|
|
49
|
+
|
|
50
|
+
## OPTIONS
|
|
51
|
+
|
|
52
|
+
`--ground`|`-g`:
|
|
53
|
+
Gather quotes from the Internet/Web via the `ase-meta-search` skill
|
|
54
|
+
(dispatched in a sub-agent, querying all available search backends)
|
|
55
|
+
*in addition to* -- and never *instead* of -- the model knowledge,
|
|
56
|
+
merge them into the harvest while deduplicating quotes which differ
|
|
57
|
+
only in punctuation, capitalization, or attribution wording, and use
|
|
58
|
+
the search results to confirm the wording and the attribution of the
|
|
59
|
+
found quotes. When combined with `--proximity`, the determination of
|
|
60
|
+
the conceptual neighborhood is grounded in Internet/Web facts as
|
|
61
|
+
well. Should the search return no usable quotes, a warning is emitted
|
|
62
|
+
and the skill falls back to the model knowledge only. Without this
|
|
63
|
+
option, the quotes are derived from model knowledge only.
|
|
64
|
+
|
|
65
|
+
`--proximity`|`-p`:
|
|
66
|
+
Widen the harvest beyond the given topic to its *conceptual
|
|
67
|
+
neighborhood* -- the parent (more general) topic, the four sibling
|
|
68
|
+
(same-level) topics, and the four child (more specialized) topics --
|
|
69
|
+
as determined by the `ase-meta-proximity` agent, which is shared with
|
|
70
|
+
the `ase-meta-proximity` skill. Each of these nine neighborhood
|
|
71
|
+
topics is harvested exactly like the given topic itself. Quotes
|
|
72
|
+
contributed by a neighborhood topic carry that topic in brackets and
|
|
73
|
+
mostly land in the `THEMATIC` quadrants, which is exactly where the
|
|
74
|
+
widening pays off. Should the agent return no usable neighborhood, a
|
|
75
|
+
warning is emitted and the skill continues with the narrow topic
|
|
76
|
+
only. Without this option, only the given topic is harvested.
|
|
77
|
+
|
|
78
|
+
`--count`|`-c` *count*:
|
|
79
|
+
Maximum total number of quotes across all four quadrants (default:
|
|
80
|
+
`8`, i.e. about two quotes per quadrant). The quotes are distributed
|
|
81
|
+
as evenly as possible across the quadrants, preferring the most
|
|
82
|
+
relevant and most well-known quote per quadrant. A non-numeric value
|
|
83
|
+
or a value less than or equal to `0` falls back to the default.
|
|
84
|
+
|
|
85
|
+
## ARGUMENTS
|
|
86
|
+
|
|
87
|
+
*topic-keywords*:
|
|
88
|
+
The topic keywords the quotes are searched for. They act both as the
|
|
89
|
+
search query and as the keyword set of the *literalness* dimension of
|
|
90
|
+
the matrix.
|
|
91
|
+
|
|
92
|
+
## EXAMPLES
|
|
93
|
+
|
|
94
|
+
Find quotes from model knowledge:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
❯ /ase-meta-quotes software architecture
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Find a wider set of quotes, grounded in Internet/Web facts and widened
|
|
101
|
+
to the conceptual neighborhood of the topic:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
❯ /ase-meta-quotes --ground --proximity --count 12 technical debt
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## SEE ALSO
|
|
108
|
+
|
|
109
|
+
[`ase-meta-proximity`](../ase-meta-proximity/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-meta-eli5`](../ase-meta-eli5/help.md).
|
|
@@ -59,9 +59,10 @@ before it is committed.
|
|
|
59
59
|
Set the *severity floor* (default `LOW`): findings below the chosen
|
|
60
60
|
threshold are silently suppressed, ordered `LOW` < `MEDIUM` <
|
|
61
61
|
`HIGH`. The default `LOW` keeps all findings; `ACCEPTED` findings are
|
|
62
|
-
never suppressed.
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
never suppressed. Surviving findings are rendered in *descending
|
|
63
|
+
severity* order `HIGH`, `MEDIUM`, `LOW`, `ACCEPTED`. The floor only
|
|
64
|
+
affects the rendered findings table, not the overall *verdict*, which
|
|
65
|
+
is always derived from all findings before the floor is applied.
|
|
65
66
|
|
|
66
67
|
## ARGUMENTS
|
|
67
68
|
|