@rse/ase 0.9.35 → 0.9.37
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 +8 -1
- package/dst/ase-skills.js +69 -17
- 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/meta/ase-constitution.md +1 -1
- package/plugin/meta/ase-skill.md +41 -0
- package/plugin/package.json +1 -1
- package/plugin/skills/ase-arch-analyze/SKILL.md +16 -0
- package/plugin/skills/ase-arch-discover/SKILL.md +34 -19
- package/plugin/skills/ase-arch-discover/help.md +28 -3
- package/plugin/skills/ase-code-analyze/SKILL.md +27 -8
- package/plugin/skills/ase-code-craft/SKILL.md +6 -3
- package/plugin/skills/ase-code-explain/SKILL.md +29 -0
- package/plugin/skills/ase-code-insight/SKILL.md +15 -0
- package/plugin/skills/ase-code-lint/SKILL.md +89 -16
- package/plugin/skills/ase-code-refactor/SKILL.md +6 -3
- package/plugin/skills/ase-code-resolve/SKILL.md +6 -3
- package/plugin/skills/ase-docs-proofread/SKILL.md +36 -2
- package/plugin/skills/ase-meta-changelog/SKILL.md +31 -6
- package/plugin/skills/ase-meta-changelog/help.md +7 -4
- package/plugin/skills/ase-meta-diff/SKILL.md +21 -3
- package/plugin/skills/ase-meta-review/SKILL.md +27 -7
package/dst/ase-hook.js
CHANGED
|
@@ -250,6 +250,11 @@ export default class HookCommand {
|
|
|
250
250
|
const val = cfg.get("agent.persona");
|
|
251
251
|
if (typeof val === "string")
|
|
252
252
|
persona = val;
|
|
253
|
+
/* determine project boxing transparency */
|
|
254
|
+
let boxing = process.env.ASE_PROJECT_BOXING ?? "white";
|
|
255
|
+
const valBoxing = cfg.get("project.boxing");
|
|
256
|
+
if (typeof valBoxing === "string")
|
|
257
|
+
boxing = valBoxing;
|
|
253
258
|
/* determine headless mode */
|
|
254
259
|
const headless = (process.env.ASE_HEADLESS ?? "false") === "true" ? "true" : "false";
|
|
255
260
|
/* provide ASE information to Anthropic Claude Code CLI shell commands
|
|
@@ -260,6 +265,7 @@ export default class HookCommand {
|
|
|
260
265
|
`export ASE_PLUGIN_ROOT=${quote([pluginRoot])}\n` +
|
|
261
266
|
`export ASE_USER_ID=${quote([userId])}\n` +
|
|
262
267
|
`export ASE_PROJECT_ID=${quote([projectId])}\n` +
|
|
268
|
+
`export ASE_PROJECT_BOXING=${quote([boxing])}\n` +
|
|
263
269
|
`export ASE_TASK_ID=${quote([taskId])}\n` +
|
|
264
270
|
`export ASE_SESSION_ID=${quote([sessionId])}\n` +
|
|
265
271
|
`export ASE_HEADLESS=${quote([headless])}\n` +
|
|
@@ -274,6 +280,7 @@ export default class HookCommand {
|
|
|
274
280
|
`<ase-persona-style>${persona}</ase-persona-style>\n` +
|
|
275
281
|
`<ase-user-id>${userId}</ase-user-id>\n` +
|
|
276
282
|
`<ase-project-id>${projectId}</ase-project-id>\n` +
|
|
283
|
+
`<ase-project-boxing>${boxing}</ase-project-boxing>\n` +
|
|
277
284
|
`<ase-task-id>${taskId}</ase-task-id>\n` +
|
|
278
285
|
`<ase-session-id>${sessionId}</ase-session-id>\n` +
|
|
279
286
|
`<ase-headless>${headless}</ase-headless>\n` +
|
|
@@ -289,7 +296,7 @@ export default class HookCommand {
|
|
|
289
296
|
const banner = `\n⧉ ASE: ⎈ version: ${versionCurrentPlugin}${versionHint !== "" ? " " + versionHint.replaceAll(/\*/g, "") : ""}` +
|
|
290
297
|
`\n⧉ ASE: ※ user: ${userId}, ⚑ project: ${projectId}` +
|
|
291
298
|
`\n⧉ ASE: ◉ task: ${taskId}, ⏻ session: ${sessionId}` +
|
|
292
|
-
`\n⧉ ASE: ☯ persona: ${persona}`;
|
|
299
|
+
`\n⧉ ASE: ☯ persona: ${persona}, ▢ boxing: ${boxing}`;
|
|
293
300
|
/* inject markdown into session context.
|
|
294
301
|
Anthropic Claude Code CLI and OpenAI Codex CLI expect the context nested in
|
|
295
302
|
"hookSpecificOutput"; GitHub Copilot CLI expects a flat top-level
|
package/dst/ase-skills.js
CHANGED
|
@@ -37,17 +37,19 @@ export class Skills {
|
|
|
37
37
|
const time = pkg.time ?? {};
|
|
38
38
|
const verEntry = version !== "" ? pkg.versions?.[version] : undefined;
|
|
39
39
|
let repository = "";
|
|
40
|
+
let deps = "N.A.";
|
|
40
41
|
if (verEntry !== undefined) {
|
|
41
42
|
const r = verEntry.repository;
|
|
42
43
|
if (typeof r === "string")
|
|
43
44
|
repository = r;
|
|
44
45
|
else if (r !== undefined && typeof r.url === "string")
|
|
45
46
|
repository = r.url;
|
|
47
|
+
deps = Object.keys(verEntry.dependencies ?? {}).length;
|
|
46
48
|
}
|
|
47
|
-
return { version, time, repository };
|
|
49
|
+
return { version, time, repository, deps };
|
|
48
50
|
}
|
|
49
51
|
catch {
|
|
50
|
-
return { version: "", time: {}, repository: "" };
|
|
52
|
+
return { version: "", time: {}, repository: "", deps: "N.A." };
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
/* fetch GitHub stars given a repository URL (or empty string) */
|
|
@@ -83,7 +85,7 @@ export class Skills {
|
|
|
83
85
|
static async fetchMavenInfo(coord) {
|
|
84
86
|
const [groupId, artifactId] = coord.split(":", 2);
|
|
85
87
|
if (groupId === undefined || artifactId === undefined || groupId === "" || artifactId === "")
|
|
86
|
-
return { version: "", created: "", updated: "", repository: "" };
|
|
88
|
+
return { version: "", created: "", updated: "", repository: "", deps: "N.A." };
|
|
87
89
|
try {
|
|
88
90
|
const latest = await Skills.httpLimit(() => ofetch("https://search.maven.org/solrsearch/select" +
|
|
89
91
|
`?q=g:%22${encodeURIComponent(groupId)}%22+AND+a:%22${encodeURIComponent(artifactId)}%22` +
|
|
@@ -113,6 +115,7 @@ export class Skills {
|
|
|
113
115
|
}
|
|
114
116
|
const created = typeof firstTs === "number" ? new Date(firstTs).toISOString() : updated;
|
|
115
117
|
let repository = "";
|
|
118
|
+
let deps = "N.A.";
|
|
116
119
|
if (version !== "") {
|
|
117
120
|
try {
|
|
118
121
|
const pom = await Skills.httpLimit(() => ofetch(`https://repo1.maven.org/maven2/${groupId.replace(/\./g, "/")}` +
|
|
@@ -126,16 +129,31 @@ export class Skills {
|
|
|
126
129
|
if (url !== null)
|
|
127
130
|
repository = url[1];
|
|
128
131
|
}
|
|
132
|
+
/* count the `<dependency>` entries of the direct
|
|
133
|
+
`<dependencies>` block, skipping `test`/`provided`
|
|
134
|
+
scopes; a `<dependencyManagement>` block is ignored
|
|
135
|
+
as it only declares versions, not real dependencies */
|
|
136
|
+
const managed = /<dependencyManagement>[\s\S]*?<\/dependencyManagement>/gi;
|
|
137
|
+
const stripped = pom.replace(managed, "");
|
|
138
|
+
const depRe = /<dependency>([\s\S]*?)<\/dependency>/gi;
|
|
139
|
+
let count = 0;
|
|
140
|
+
let dep;
|
|
141
|
+
while ((dep = depRe.exec(stripped)) !== null) {
|
|
142
|
+
const scope = /<scope>\s*([^<\s]+)\s*<\/scope>/i.exec(dep[1]);
|
|
143
|
+
if (scope === null || (scope[1] !== "test" && scope[1] !== "provided"))
|
|
144
|
+
count++;
|
|
145
|
+
}
|
|
146
|
+
deps = count;
|
|
129
147
|
}
|
|
130
148
|
}
|
|
131
149
|
catch {
|
|
132
150
|
repository = "";
|
|
133
151
|
}
|
|
134
152
|
}
|
|
135
|
-
return { version, created, updated, repository };
|
|
153
|
+
return { version, created, updated, repository, deps };
|
|
136
154
|
}
|
|
137
155
|
catch {
|
|
138
|
-
return { version: "", created: "", updated: "", repository: "" };
|
|
156
|
+
return { version: "", created: "", updated: "", repository: "", deps: "N.A." };
|
|
139
157
|
}
|
|
140
158
|
}
|
|
141
159
|
/* fetch the "Used By" count from `mvnrepository.com` as a downloads proxy
|
|
@@ -180,7 +198,7 @@ export class Skills {
|
|
|
180
198
|
- "JavaScript"/"TypeScript": NPM registry (pacote) + GitHub stars + npm-downloads
|
|
181
199
|
- "Java"/"Kotlin": Maven Central + GitHub stars + mvnrepository.com "Used By"
|
|
182
200
|
- "Unknown": not supported -- return empty result */
|
|
183
|
-
static async info(stack, components) {
|
|
201
|
+
static async info(stack, components, staleMonths = 18, smallScope = false) {
|
|
184
202
|
if (stack === "JavaScript" || stack === "TypeScript") {
|
|
185
203
|
/* per package: kick off packument and downloads in parallel,
|
|
186
204
|
then stars as soon as the packument resolves; across packages
|
|
@@ -194,7 +212,7 @@ export class Skills {
|
|
|
194
212
|
]);
|
|
195
213
|
const created = p.time.created ?? "";
|
|
196
214
|
const updated = p.version !== "" ? (p.time[p.version] ?? "") : "";
|
|
197
|
-
const rank = Skills.computeRank(downloads, stars, created, updated);
|
|
215
|
+
const rank = Skills.computeRank(downloads, stars, created, updated, p.deps, staleMonths, smallScope);
|
|
198
216
|
return {
|
|
199
217
|
name,
|
|
200
218
|
version: p.version,
|
|
@@ -203,6 +221,7 @@ export class Skills {
|
|
|
203
221
|
repository: p.repository,
|
|
204
222
|
stars,
|
|
205
223
|
downloads,
|
|
224
|
+
deps: p.deps,
|
|
206
225
|
rank
|
|
207
226
|
};
|
|
208
227
|
}));
|
|
@@ -222,7 +241,7 @@ export class Skills {
|
|
|
222
241
|
const [i, downloads, stars] = await Promise.all([
|
|
223
242
|
infoPromise, downloadsPromise, starsPromise
|
|
224
243
|
]);
|
|
225
|
-
const rank = Skills.computeRank(downloads, stars, i.created, i.updated);
|
|
244
|
+
const rank = Skills.computeRank(downloads, stars, i.created, i.updated, i.deps, staleMonths, smallScope);
|
|
226
245
|
return {
|
|
227
246
|
name,
|
|
228
247
|
version: i.version,
|
|
@@ -231,6 +250,7 @@ export class Skills {
|
|
|
231
250
|
repository: i.repository,
|
|
232
251
|
stars,
|
|
233
252
|
downloads,
|
|
253
|
+
deps: i.deps,
|
|
234
254
|
rank
|
|
235
255
|
};
|
|
236
256
|
}));
|
|
@@ -253,7 +273,7 @@ export class Skills {
|
|
|
253
273
|
is structurally unavailable, e.g. Maven Central exposes no
|
|
254
274
|
per-artifact download counts) is likewise treated as neutral `1`, so
|
|
255
275
|
such stacks can still be ranked by the remaining metrics. */
|
|
256
|
-
static computeRank(downloads, stars, created, updated) {
|
|
276
|
+
static computeRank(downloads, stars, created, updated, deps, staleMonths, smallScope) {
|
|
257
277
|
const d = typeof downloads === "number" ? downloads + 1 : 1;
|
|
258
278
|
const s = typeof stars === "number" ? stars + 1 : 1;
|
|
259
279
|
const cMs = created !== "" ? Date.parse(created) : NaN;
|
|
@@ -277,7 +297,31 @@ export class Skills {
|
|
|
277
297
|
entry rankable without rewarding the missing date. */
|
|
278
298
|
const lifespan = (!Number.isNaN(cMs) && !Number.isNaN(uMs)) ? Math.max(0, uMs - cMs) : 1;
|
|
279
299
|
const recentness = !Number.isNaN(uMs) ? Math.exp(-Math.max(0, (now - uMs) / msPerDay) / halfLife) : 0.5;
|
|
280
|
-
|
|
300
|
+
let rank = d * s * lifespan * recentness;
|
|
301
|
+
/* hard, caller-tunable staleness penalty on top of the soft
|
|
302
|
+
`recentness` decay: unlike the smooth exp-decay above, this is a
|
|
303
|
+
two-tier *cliff* keyed off the `staleMonths` threshold. Past the
|
|
304
|
+
first tier (`staleMonths`) the rank is cut to `0.3x`, past the
|
|
305
|
+
second tier (`2 x staleMonths`, i.e. long abandoned) to `0.1x`.
|
|
306
|
+
A component below the first tier -- or one whose `updated` date
|
|
307
|
+
is unknown -- is left unpenalized. */
|
|
308
|
+
if (!Number.isNaN(uMs)) {
|
|
309
|
+
const ageMonths = (now - uMs) / msPerDay / 30;
|
|
310
|
+
if (ageMonths > 2 * staleMonths)
|
|
311
|
+
rank *= 0.1;
|
|
312
|
+
else if (ageMonths > staleMonths)
|
|
313
|
+
rank *= 0.3;
|
|
314
|
+
}
|
|
315
|
+
/* small-scope dependency-weight penalty: for a narrow, self-
|
|
316
|
+
contained need, dragging in a heavy dependency tree is usually
|
|
317
|
+
the wrong call, so each real component is demoted in proportion
|
|
318
|
+
to its own number of *direct* dependencies (`1 / (1 + deps)`).
|
|
319
|
+
A zero-dep component is left unpenalized; an unknown `deps` count
|
|
320
|
+
(`"N.A."`) is treated neutrally. This only applies when the
|
|
321
|
+
caller flags the need as small-scope. */
|
|
322
|
+
if (smallScope && typeof deps === "number")
|
|
323
|
+
rank *= 1 / (1 + deps);
|
|
324
|
+
return rank;
|
|
281
325
|
}
|
|
282
326
|
/* compute the per-alternative product-sum (rating) row from a
|
|
283
327
|
weighted decision matrix. Each input row has the shape
|
|
@@ -318,20 +362,28 @@ export class SkillsMCP {
|
|
|
318
362
|
"version + earliest/latest release timestamps from the Maven Central Solr " +
|
|
319
363
|
"search endpoint, the SCM/project URL from the latest POM at `repo1.maven.org`, " +
|
|
320
364
|
"GitHub stars (if applicable), and the \"Used By\" count from `mvnrepository.com` " +
|
|
321
|
-
"as the `downloads` proxy.
|
|
322
|
-
"
|
|
323
|
-
"
|
|
324
|
-
"
|
|
325
|
-
"
|
|
365
|
+
"as the `downloads` proxy. The number of *direct* dependencies is read as `deps` " +
|
|
366
|
+
"(from the packument version entry for NPM, or the latest POM's `<dependencies>` " +
|
|
367
|
+
"block for Maven). Returns a JSON `text` array of " +
|
|
368
|
+
"`{ name, version, created, updated, repository, stars, downloads, deps, rank }` " +
|
|
369
|
+
"objects, sorted in descending order by `rank`. The `rank` applies a two-tier hard " +
|
|
370
|
+
"staleness penalty keyed off `staleMonths` (0.3x past the threshold, 0.1x past twice " +
|
|
371
|
+
"it) and, when `smallScope` is set, a dependency-weight penalty of `1/(1+deps)` so " +
|
|
372
|
+
"dependency-heavy components sink. Failures of individual side calls are isolated " +
|
|
373
|
+
"and reported as `\"N.A.\"` or empty string so every entry has the full shape.",
|
|
326
374
|
inputSchema: {
|
|
327
375
|
stack: z.string()
|
|
328
376
|
.describe("Technology stack: \"JavaScript\", \"TypeScript\", \"Java\", \"Kotlin\", or \"Unknown\""),
|
|
329
377
|
components: z.array(z.string())
|
|
330
|
-
.describe("List of package names (NPM) or Maven coordinates `groupId:artifactId` (Java/Kotlin)")
|
|
378
|
+
.describe("List of package names (NPM) or Maven coordinates `groupId:artifactId` (Java/Kotlin)"),
|
|
379
|
+
staleMonths: z.number().optional()
|
|
380
|
+
.describe("Staleness threshold in months (default 18); a release older than this is rank-penalized"),
|
|
381
|
+
smallScope: z.boolean().optional()
|
|
382
|
+
.describe("If true, penalize each component by its direct-dependency count (small-scope need)")
|
|
331
383
|
}
|
|
332
384
|
}, async (args) => {
|
|
333
385
|
try {
|
|
334
|
-
const result = await Skills.info(args.stack, args.components);
|
|
386
|
+
const result = await Skills.info(args.stack, args.components, args.staleMonths, args.smallScope);
|
|
335
387
|
return {
|
|
336
388
|
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
337
389
|
};
|
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.
|
|
9
|
+
"version": "0.9.37",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "Dr. Ralf S. Engelschall",
|
|
@@ -16,7 +16,7 @@ any skill flow:
|
|
|
16
16
|
⧉ **ASE**: ⎈ version: **<ase-version/>** <ase-version-hint/>
|
|
17
17
|
⧉ **ASE**: ※ user: **<ase-user-id/>**, ⚑ project: **<ase-project-id/>**
|
|
18
18
|
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ⏻ session: **<ase-session-id/>**
|
|
19
|
-
⧉ **ASE**: ☯ persona: **<ase-persona-style/>**
|
|
19
|
+
⧉ **ASE**: ☯ persona: **<ase-persona-style/>**, ▢ boxing: **<ase-project-boxing/>**
|
|
20
20
|
</template>
|
|
21
21
|
|
|
22
22
|
Prohibitions
|
package/plugin/meta/ase-skill.md
CHANGED
|
@@ -243,6 +243,46 @@ Skill Identification
|
|
|
243
243
|
steps at the end of a skill beside the explicit outputs via any
|
|
244
244
|
<template/>.
|
|
245
245
|
|
|
246
|
+
Artifact Boxing Transparency
|
|
247
|
+
----------------------------
|
|
248
|
+
|
|
249
|
+
- *IMPORTANT*: The *boxing* of a project (indicated by
|
|
250
|
+
<ase-project-boxing/> configuration) classifies how *transparent*
|
|
251
|
+
its *source artifacts* (specification, architecture, source code,
|
|
252
|
+
documentation, infrastructure, task plan, and other artifacts) are,
|
|
253
|
+
and thus how *deeply* you *MUST* inspect or produce them and how
|
|
254
|
+
*much* of their internals you *MUST* surface.
|
|
255
|
+
|
|
256
|
+
- *IMPORTANT*: Boxing modulates only the *work depth* (inspection and
|
|
257
|
+
production thoroughness) and the *output visibility* (surfaced
|
|
258
|
+
content and findings) of *artifact-touching* skills, per the three
|
|
259
|
+
lists below. It *MUST* *NOT* alter the *communication style*
|
|
260
|
+
(governed exclusively by the persona), and it *MUST* *NOT* apply to
|
|
261
|
+
skills that neither read, critique, nor write any project source
|
|
262
|
+
artifact.
|
|
263
|
+
|
|
264
|
+
- If <ase-project-boxing/> is `white`:
|
|
265
|
+
- Transparency: *fully*
|
|
266
|
+
- Work depth: inspect *fully*, produce *thoroughly*
|
|
267
|
+
- Findings surfaced: *all*
|
|
268
|
+
- Internals exposed: *full* (complete diffs, exhaustive rationale)
|
|
269
|
+
|
|
270
|
+
- If <ase-project-boxing/> is `grey`:
|
|
271
|
+
- Transparency: *partially*
|
|
272
|
+
- Work depth: inspect *significant* parts, produce *reasonably*
|
|
273
|
+
- Findings surfaced: *essentials*, summarize rest
|
|
274
|
+
- Internals exposed: *key* only (essential hunks, condensed rationale), summarize rest
|
|
275
|
+
|
|
276
|
+
- If <ase-project-boxing/> is `black`:
|
|
277
|
+
- Transparency: *none*
|
|
278
|
+
- Work depth: *minimum* work to satisfy the request
|
|
279
|
+
- Findings surfaced: *none* (report only the *outcome*)
|
|
280
|
+
- Internals exposed: *none* (no diffs, no code, no per-artifact explanation)
|
|
281
|
+
|
|
282
|
+
- *IMPORTANT*: Precedence rule: skill's *explicit* `black` branches
|
|
283
|
+
deterministically skip or suppress and *win* over the implicit decisions
|
|
284
|
+
above. Where no such branches exist, the decisions above apply.
|
|
285
|
+
|
|
246
286
|
Template Patterns
|
|
247
287
|
-----------------
|
|
248
288
|
|
|
@@ -360,3 +400,4 @@ Template Patterns
|
|
|
360
400
|
clamped to zero so an over-long text never yields a negative count):
|
|
361
401
|
|
|
362
402
|
<template><text/><ws/></template>
|
|
403
|
+
|
package/plugin/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.
|
|
9
|
+
"version": "0.9.37",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "Dr. Ralf S. Engelschall",
|
|
@@ -121,6 +121,22 @@ interface quality, quality attributes, and architecture governance.
|
|
|
121
121
|
|
|
122
122
|
<flow>
|
|
123
123
|
1. <step id="STEP 1: Investigate Code Base">
|
|
124
|
+
|
|
125
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
126
|
+
|
|
127
|
+
The project source artifacts are classified as a *black box*, so
|
|
128
|
+
the user does *not* want the architecture inspected or its findings
|
|
129
|
+
surfaced. *Skip* the entire investigation and reporting: do *not*
|
|
130
|
+
invoke any `Agent` tool and do *not* read any source, only output
|
|
131
|
+
the following <template/> and then *SKIP* the remaining steps STEP 2
|
|
132
|
+
through STEP 4:
|
|
133
|
+
|
|
134
|
+
<template>
|
|
135
|
+
<ase-tpl-bullet-normal/> **ARCHITECTURE ANALYSIS**: *suppressed* (`project.boxing` is `black`)
|
|
136
|
+
</template>
|
|
137
|
+
|
|
138
|
+
</if>
|
|
139
|
+
|
|
124
140
|
Investigate the code from an *architectural* perspective. If the
|
|
125
141
|
code base is large, you *MUST* use the `Agent` tool (not inline
|
|
126
142
|
work) to create multiple sub-agents to split the investigation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ase-arch-discover
|
|
3
|
-
argument-hint: "[--help|-h] [--limit|-l=12] <functionality>"
|
|
3
|
+
argument-hint: "[--help|-h] [--limit|-l=12] [--staleness|-s=18] [--small-scope|-S] <functionality>"
|
|
4
4
|
description: >
|
|
5
5
|
Discover additional, third-party components (libraries/frameworks) for
|
|
6
6
|
the technology stack to provide needed functionality.
|
|
@@ -25,7 +25,7 @@ Discover Components
|
|
|
25
25
|
|
|
26
26
|
<expand name="getopt"
|
|
27
27
|
arg1="ase-arch-discover"
|
|
28
|
-
arg2="--limit|-l=12">
|
|
28
|
+
arg2="--limit|-l=12 --staleness|-s=18 --small-scope|-S">
|
|
29
29
|
$ARGUMENTS
|
|
30
30
|
</expand>
|
|
31
31
|
|
|
@@ -166,18 +166,25 @@ for the technology stack to *provide* the *needed functionality*
|
|
|
166
166
|
entries by Maven coordinate.
|
|
167
167
|
|
|
168
168
|
6. Call the `ase_component_info(stack: "<stack/>", components:
|
|
169
|
-
[ "<package-1/>", ..., "<package-C/>" ]
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
169
|
+
[ "<package-1/>", ..., "<package-C/>" ], staleMonths:
|
|
170
|
+
<getopt-option-staleness/>, smallScope: <getopt-option-small-scope/>)`
|
|
171
|
+
tool of the `ase` MCP server *once* for the entire candidate set of
|
|
172
|
+
discovered packages. When the <getopt-option-small-scope/> option is
|
|
173
|
+
enabled, the ranking treats the <functionality/> as *small-scope*,
|
|
174
|
+
i.e. narrow, self-contained, and low-effort enough that a
|
|
175
|
+
*dependency-free/hand-rolled* implementation is a realistic
|
|
176
|
+
alternative to pulling in a third-party component. The tool
|
|
177
|
+
dispatches internally on <stack/>
|
|
178
|
+
and fetches all metadata in maximum parallel and returns an array
|
|
179
|
+
of objects `{ name, version, created, updated, repository, stars,
|
|
180
|
+
downloads, deps, rank }`. For each component <component-K/>
|
|
181
|
+
(K=1-C) read from its corresponding entry: <version-K/> from
|
|
182
|
+
`version`, <updated-K/> from `updated`, <created-K/> from
|
|
183
|
+
`created`, <repository-K/> from `repository`, <stars-K/> from
|
|
184
|
+
`stars` (numeric or `N.A.`), <downloads-K/> from `downloads`
|
|
185
|
+
(numeric or `N.A.`), <deps-K/> from `deps` (numeric or `N.A.`)
|
|
186
|
+
and <rank-K/> from `rank` (numeric). The returned `rank` already
|
|
187
|
+
reflects the staleness and small-scope dependency penalties.
|
|
181
188
|
|
|
182
189
|
7. Sort, in descending order, the discovered candidate components
|
|
183
190
|
<component-K/> (K=1-C) by their `rank` field and trim the result
|
|
@@ -192,7 +199,15 @@ for the technology stack to *provide* the *needed functionality*
|
|
|
192
199
|
you should not stumble over) is its single most distinguishing
|
|
193
200
|
perspective, and remember this as an <info-K/> (K=1-N) formatted
|
|
194
201
|
like `<type/>: <hint/>` where <type/> is one of `USP`, `Crux`,
|
|
195
|
-
or `Gotcha` and <hint/> is a 1-6 word hint.
|
|
202
|
+
or `Gotcha` and <hint/> is a 1-6 word hint.
|
|
203
|
+
|
|
204
|
+
*Staleness override*: determine the coarse age <age-K/> (like
|
|
205
|
+
`2y`) of the last release from <updated-K/>. If <updated-K/> is
|
|
206
|
+
known and its age exceeds *twice* <getopt-option-staleness/>
|
|
207
|
+
months, *append* to <info-K/> the hint `Gotcha: stale/abandoned
|
|
208
|
+
-- last release <age-K/> ago`; else if its age exceeds
|
|
209
|
+
<getopt-option-staleness/> months, *append* to <info-K/> the
|
|
210
|
+
hint `Gotcha: aging -- last release <age-K/> ago`. Do not output
|
|
196
211
|
anything.
|
|
197
212
|
</step>
|
|
198
213
|
|
|
@@ -217,11 +232,11 @@ for the technology stack to *provide* the *needed functionality*
|
|
|
217
232
|
<template>
|
|
218
233
|
<ase-tpl-bullet-normal/> **COMPONENT RANKING**:
|
|
219
234
|
|
|
220
|
-
| ⚑ *Component* | ▣ *Package* | ❖ *Version* | ↓ *Downloads* | ⎈ *Stars* | ⏲ *Updated* | ☆ *Created* |
|
|
221
|
-
| :------------ | :------------- | -----------: | -----------------: | -------------: | :--------------- | :----------- |
|
|
222
|
-
| **<name-1/>** | `<package-1/>` | <version-1/> | **<downloads-1/>** | **<stars-1/>** | **<updated-1/>** | <created-1/> |
|
|
235
|
+
| ⚑ *Component* | ▣ *Package* | ❖ *Version* | ↓ *Downloads* | ⎈ *Stars* | ⏲ *Updated* | ☆ *Created* | ⚭ *Dep.* |
|
|
236
|
+
| :------------ | :------------- | -----------: | -----------------: | -------------: | :--------------- | :----------- | ---------: |
|
|
237
|
+
| **<name-1/>** | `<package-1/>` | <version-1/> | **<downloads-1/>** | **<stars-1/>** | **<updated-1/>** | <created-1/> | <deps-1/> |
|
|
223
238
|
[...]
|
|
224
|
-
| **<name-N/>** | `<package-N/>` | <version-N/> | **<downloads-N/>** | **<stars-N/>** | **<updated-N/>** | <created-N/> |
|
|
239
|
+
| **<name-N/>** | `<package-N/>` | <version-N/> | **<downloads-N/>** | **<stars-N/>** | **<updated-N/>** | <created-N/> | <deps-N/> |
|
|
225
240
|
</template>
|
|
226
241
|
</step>
|
|
227
242
|
</flow>
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
`ase-arch-discover`
|
|
9
9
|
[`--help`|`-h`]
|
|
10
10
|
[`--limit`|`-l=12`]
|
|
11
|
+
[`--staleness`|`-s=18`]
|
|
12
|
+
[`--small-scope`|`-S`]
|
|
11
13
|
*functionality*
|
|
12
14
|
|
|
13
15
|
## DESCRIPTION
|
|
@@ -20,9 +22,13 @@ The skill determines the project's technology stack (TypeScript,
|
|
|
20
22
|
JavaScript, Kotlin, or Java), derives essential keywords from the
|
|
21
23
|
requested functionality, queries the corresponding package registry
|
|
22
24
|
(NPM or Maven Central), retrieves metadata (version, downloads,
|
|
23
|
-
stars, dates) via the `ase_component_info` MCP tool,
|
|
24
|
-
the top-ranked components as a Markdown table together with
|
|
25
|
-
distinguishing hint (USP, Crux, or Gotcha) per component.
|
|
25
|
+
stars, dates, dependency count) via the `ase_component_info` MCP tool,
|
|
26
|
+
and reports the top-ranked components as a Markdown table together with
|
|
27
|
+
a single distinguishing hint (USP, Crux, or Gotcha) per component.
|
|
28
|
+
|
|
29
|
+
The ranking penalizes *stale* components (last release older than the
|
|
30
|
+
`--staleness` threshold) and, when the `--small-scope` option is given,
|
|
31
|
+
demotes dependency-heavy components.
|
|
26
32
|
|
|
27
33
|
## OPTIONS
|
|
28
34
|
|
|
@@ -31,6 +37,19 @@ distinguishing hint (USP, Crux, or Gotcha) per component.
|
|
|
31
37
|
in the final ranking (default: 12). Raise it for a broader, more
|
|
32
38
|
exhaustive survey, lower it for a quicker, narrower lookup.
|
|
33
39
|
|
|
40
|
+
`--staleness`|`-s=18`:
|
|
41
|
+
The *staleness threshold* in months (default: 18). A component whose
|
|
42
|
+
last release is older than this is rank-penalized and flagged with an
|
|
43
|
+
`aging` gotcha; older than *twice* the threshold, it is penalized
|
|
44
|
+
harder and flagged as `stale/abandoned`.
|
|
45
|
+
|
|
46
|
+
`--small-scope`|`-S`:
|
|
47
|
+
Treat the requested *functionality* as *small-scope* (default: off).
|
|
48
|
+
When enabled, the ranking demotes dependency-heavy components by a
|
|
49
|
+
dependency-weight penalty, since a dependency-free/hand-rolled
|
|
50
|
+
implementation is a realistic alternative for narrow, self-contained
|
|
51
|
+
functionality.
|
|
52
|
+
|
|
34
53
|
## ARGUMENTS
|
|
35
54
|
|
|
36
55
|
*functionality*:
|
|
@@ -57,6 +76,12 @@ Discover a broader set of up to 20 HTTP client components:
|
|
|
57
76
|
❯ /ase-arch-discover --limit 20 HTTP client with retries
|
|
58
77
|
```
|
|
59
78
|
|
|
79
|
+
Discover HTTP clients, flagging any without a release in the last 12 months:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
❯ /ase-arch-discover --staleness 12 HTTP client with retries
|
|
83
|
+
```
|
|
84
|
+
|
|
60
85
|
## SEE ALSO
|
|
61
86
|
|
|
62
87
|
[`ase-arch-analyze`](../ase-arch-analyze/help.md), [`ase-meta-search`](../ase-meta-search/help.md), [`ase-meta-evaluate`](../ase-meta-evaluate/help.md).
|
|
@@ -54,6 +54,20 @@ problems in *performance* and *efficiency*, or problems in *security*.
|
|
|
54
54
|
|
|
55
55
|
2. <step id="STEP 2: Investigate Code Base">
|
|
56
56
|
|
|
57
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
58
|
+
|
|
59
|
+
The project source artifacts are classified as a *black box*, so
|
|
60
|
+
the user does *not* want them inspected or their problems surfaced.
|
|
61
|
+
*Skip* the entire investigation and analysis: do *not* invoke any
|
|
62
|
+
`Glob` or `Agent` tool and do *not* read any source, only output
|
|
63
|
+
the following <template/> and then *SKIP* the remaining step STEP 3:
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<ase-tpl-bullet-normal/> **CODE ANALYSIS**: *suppressed* (`project.boxing` is `black`)
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
</if>
|
|
70
|
+
|
|
57
71
|
First, use the following <template/> to give a hint on this step:
|
|
58
72
|
|
|
59
73
|
<template>
|
|
@@ -109,14 +123,19 @@ problems in *performance* and *efficiency*, or problems in *security*.
|
|
|
109
123
|
|
|
110
124
|
3. <step id="STEP 3: Show Results">
|
|
111
125
|
|
|
112
|
-
Before reporting,
|
|
113
|
-
|
|
114
|
-
`LOW
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
Before reporting, determine the *effective severity floor* <floor/>:
|
|
127
|
+
define the ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
|
|
128
|
+
<floor><getopt-option-severity/></floor> (default `LOW`), and - if
|
|
129
|
+
<ase-project-boxing/> is equal `grey` - raise <floor/> to `MEDIUM`
|
|
130
|
+
whenever its current rank is below `rank(MEDIUM)` (grey boxing
|
|
131
|
+
surfaces only *material* findings of severity `MEDIUM` and above).
|
|
132
|
+
|
|
133
|
+
Then *apply the effective severity floor* <floor/>: *Keep* a detected
|
|
134
|
+
problem if and only if its `severity` field is `ACCEPTED` *or*
|
|
135
|
+
`rank(severity)` is greater than or equal to `rank(<floor/>)`;
|
|
136
|
+
*silently drop* all other problems (they are neither reported nor
|
|
137
|
+
persisted). With the default floor `LOW`, all problems are kept.
|
|
138
|
+
`ACCEPTED` problems are *never* dropped.
|
|
120
139
|
|
|
121
140
|
Then renumber the surviving problems contiguously as `P<n/>` with
|
|
122
141
|
<n/> = 1, 2, ... in the original ordering. If *all* problems are
|
|
@@ -140,8 +140,11 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
|
|
|
140
140
|
You *MUST* perform the following sub-steps *internally* and *without
|
|
141
141
|
any output* until and including the recommendation decision. Only
|
|
142
142
|
sub-steps 4-6 below are allowed to produce output, and only if
|
|
143
|
-
<getopt-option-auto/> is equal `false
|
|
144
|
-
|
|
143
|
+
<getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
|
|
144
|
+
is *not* equal `black`.
|
|
145
|
+
|
|
146
|
+
If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
|
|
147
|
+
equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
|
|
145
148
|
no output at all) to speed up processing.
|
|
146
149
|
|
|
147
150
|
1. *Propose* corresponding *feature approach*, including optionally,
|
|
@@ -187,7 +190,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
|
|
|
187
190
|
<ase-tpl-foot title="APPROACHES"/>
|
|
188
191
|
</template>
|
|
189
192
|
|
|
190
|
-
7. <if condition="<getopt-option-auto/> is not equal `true`">
|
|
193
|
+
7. <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
|
|
191
194
|
|
|
192
195
|
In the following, you *MUST* *NOT* use your built-in
|
|
193
196
|
<user-dialog-tool/> tool! Instead, you *MUST* just show a
|
|
@@ -43,6 +43,23 @@ code and *explain* it in a *brief*, *standardized*, and *concise* way.
|
|
|
43
43
|
Second, explain *WHY* the code does it (*rationale*).
|
|
44
44
|
|
|
45
45
|
Keep your explanations *brief* and *concise*.
|
|
46
|
+
|
|
47
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
48
|
+
|
|
49
|
+
The project source artifacts are classified as a *black box*, so the
|
|
50
|
+
user wants only the *minimal* surface explanation. Output *only* the
|
|
51
|
+
*WHAT* block (omit the *WHY* block) with the following <template/>:
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<ase-tpl-bullet-normal/> **WHAT** (You should know what):
|
|
55
|
+
- [...]
|
|
56
|
+
- [...]
|
|
57
|
+
- [...]
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
</if>
|
|
61
|
+
<else>
|
|
62
|
+
|
|
46
63
|
Output the result with the following <template/>:
|
|
47
64
|
|
|
48
65
|
<template>
|
|
@@ -56,9 +73,21 @@ code and *explain* it in a *brief*, *standardized*, and *concise* way.
|
|
|
56
73
|
- [...]
|
|
57
74
|
- [...]
|
|
58
75
|
</template>
|
|
76
|
+
|
|
77
|
+
</else>
|
|
59
78
|
</step>
|
|
60
79
|
|
|
61
80
|
3. <step id="STEP 3: ANALOGY and DIAGRAM">
|
|
81
|
+
|
|
82
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
83
|
+
|
|
84
|
+
The project source artifacts are classified as a *black box*, so
|
|
85
|
+
deeper elaboration is *not* wanted. *Skip* this STEP 3 and the
|
|
86
|
+
following STEP 4 entirely: do *not* output any ANALOGY, DIAGRAM,
|
|
87
|
+
CRUXES, or GOTCHAS, and do *not* dispatch any diagram rendering.
|
|
88
|
+
|
|
89
|
+
</if>
|
|
90
|
+
|
|
62
91
|
**Give insights with ANALOGY and DIAGRAM**.
|
|
63
92
|
|
|
64
93
|
First, give an analogy by comparing the code to something from
|
|
@@ -34,6 +34,21 @@ Give *insights* into the project through the source code of <getopt-arguments/>.
|
|
|
34
34
|
|
|
35
35
|
<flow>
|
|
36
36
|
1. <step id="STEP 1: PROJECT ABSTRACT">
|
|
37
|
+
|
|
38
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
39
|
+
|
|
40
|
+
The project source artifacts are classified as a *black box*, so the
|
|
41
|
+
user does *not* want them inspected or their internals surfaced.
|
|
42
|
+
*Skip* the entire insight gathering: do *not* read any source, only
|
|
43
|
+
output the following <template/> and then *SKIP* the remaining steps
|
|
44
|
+
STEP 2 through STEP 4:
|
|
45
|
+
|
|
46
|
+
<template>
|
|
47
|
+
<ase-tpl-bullet-normal/> **PROJECT INSIGHT**: *suppressed* (`project.boxing` is `black`)
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
</if>
|
|
51
|
+
|
|
37
52
|
Determine an <abstract/> summary of this project.
|
|
38
53
|
For this, check a potentially existing `README.*` file
|
|
39
54
|
or scan the source files and figure it out indirectly.
|
|
@@ -33,6 +33,21 @@ related to a set of code quality aspects.
|
|
|
33
33
|
|
|
34
34
|
1. <step id="STEP 1: Investigation">
|
|
35
35
|
|
|
36
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
37
|
+
|
|
38
|
+
The project source artifacts are classified as a *black box*, so
|
|
39
|
+
the user does *not* want them inspected or their problems surfaced.
|
|
40
|
+
*Skip* the entire investigation and reporting: do *not* invoke any
|
|
41
|
+
`Glob` or `Agent` tool and do *not* read any source, only output
|
|
42
|
+
the following <template/> and then *SKIP* the remaining steps STEP 2
|
|
43
|
+
and STEP 3:
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<ase-tpl-bullet-normal/> **LINT**: *suppressed* (`project.boxing` is `black`)
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
</if>
|
|
50
|
+
|
|
36
51
|
First, use the following <template/> to give a hint on this step:
|
|
37
52
|
|
|
38
53
|
<template>
|
|
@@ -76,13 +91,18 @@ related to a set of code quality aspects.
|
|
|
76
91
|
sort the list by `file` and then numerically by `line`, and set
|
|
77
92
|
<problems/> to that list.
|
|
78
93
|
|
|
79
|
-
Then
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
94
|
+
Then determine the *effective severity floor* <floor/>: define the
|
|
95
|
+
ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
|
|
96
|
+
<floor><getopt-option-severity/></floor> (default `LOW`), and - if
|
|
97
|
+
<ase-project-boxing/> is equal `grey` - raise <floor/> to `MEDIUM`
|
|
98
|
+
whenever its current rank is below `rank(MEDIUM)` (grey boxing
|
|
99
|
+
surfaces only *material* findings of severity `MEDIUM` and above).
|
|
100
|
+
|
|
101
|
+
Then *apply the effective severity floor* <floor/>: *Keep* a problem
|
|
102
|
+
in <problems/> if and only if its `severity` field is `ACCEPTED` *or*
|
|
103
|
+
`rank(severity)` is greater than or equal to `rank(<floor/>)`;
|
|
104
|
+
*silently drop* all other problems. With the default floor `LOW`, all
|
|
105
|
+
problems are kept. `ACCEPTED` problems are *never* dropped.
|
|
86
106
|
|
|
87
107
|
You *MUST* *NOT* output anything else in this step 1.
|
|
88
108
|
|
|
@@ -145,6 +165,7 @@ related to a set of code quality aspects.
|
|
|
145
165
|
|
|
146
166
|
2. Set <context></context> (set to empty).
|
|
147
167
|
Set <diff></diff> (set to empty).
|
|
168
|
+
Set <diff-condensed></diff-condensed> (set to empty).
|
|
148
169
|
|
|
149
170
|
3. Iterate over the change set:
|
|
150
171
|
|
|
@@ -153,7 +174,9 @@ related to a set of code quality aspects.
|
|
|
153
174
|
1. Set <file/> to the `file` field of <item/>.
|
|
154
175
|
Set <change-hunks/> to the `change-hunks` field of <item/>.
|
|
155
176
|
|
|
156
|
-
|
|
177
|
+
Unless <ase-project-boxing/> is equal `grey` (where the
|
|
178
|
+
full unified diff is suppressed and this per-file header is
|
|
179
|
+
unused), set <diff-file/> to the following <template/>:
|
|
157
180
|
|
|
158
181
|
<template>
|
|
159
182
|
--- <file/> (original)
|
|
@@ -170,11 +193,18 @@ related to a set of code quality aspects.
|
|
|
170
193
|
Set <new-text/> to the `new_text` field of <item/>.
|
|
171
194
|
Set <context-after/> to the `context_after` field of <item/>.
|
|
172
195
|
|
|
173
|
-
2.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
196
|
+
2. *Skip* this substep entirely when <ase-project-boxing/>
|
|
197
|
+
is equal `grey` - the full unified diff is suppressed
|
|
198
|
+
there, so none of the <hunk-body/>, <old-count/>,
|
|
199
|
+
<new-count/>, <old-start/>, or <new-start/> values
|
|
200
|
+
below are consumed (substep 4 builds only the condensed
|
|
201
|
+
one-liner instead).
|
|
202
|
+
|
|
203
|
+
Otherwise, determine the hunk *body* as an ordered list
|
|
204
|
+
of lines, each carrying a one-character prefix (` ` for
|
|
205
|
+
context, `-` for old-side, `+` for new-side). Build it
|
|
206
|
+
by concatenating, in order and *skipping any part that
|
|
207
|
+
is empty*:
|
|
178
208
|
|
|
179
209
|
- one ` `-prefixed line for *each* line of
|
|
180
210
|
<context-before/> (if non-empty),
|
|
@@ -217,7 +247,27 @@ related to a set of code quality aspects.
|
|
|
217
247
|
|
|
218
248
|
<template>`<file/>`:<line/></template>
|
|
219
249
|
|
|
220
|
-
4.
|
|
250
|
+
4. <if condition="<ase-project-boxing/> is equal `grey`">
|
|
251
|
+
|
|
252
|
+
The full unified diff is *suppressed* under grey boxing
|
|
253
|
+
(see substep 5 below), so *skip* the full-diff append
|
|
254
|
+
and instead build only a *condensed* one-line
|
|
255
|
+
representation of this hunk: determine <old-snippet/>
|
|
256
|
+
as the *single-line* collapse of <old-text/> (join its
|
|
257
|
+
lines with ` ⏎ `, or `∅` when <old-text/> is empty for
|
|
258
|
+
a pure insertion) and <new-snippet/> as the same
|
|
259
|
+
collapse of <new-text/> (or `∅` when empty for a pure
|
|
260
|
+
deletion). Then append the following <template/> to
|
|
261
|
+
<diff-condensed/> as a new line:
|
|
262
|
+
|
|
263
|
+
<template>
|
|
264
|
+
<ase-tpl-bullet-signal/> `<file/>`:<line/>: `<old-snippet/>` → `<new-snippet/>`
|
|
265
|
+
</template>
|
|
266
|
+
|
|
267
|
+
</if>
|
|
268
|
+
<else>
|
|
269
|
+
|
|
270
|
+
Append the following <template/> to <diff-file/>,
|
|
221
271
|
emitting <hunk-body/> verbatim (one already-prefixed
|
|
222
272
|
line per line, with no extra blank or space-only lines):
|
|
223
273
|
|
|
@@ -226,9 +276,12 @@ related to a set of code quality aspects.
|
|
|
226
276
|
<hunk-body/>
|
|
227
277
|
</template>
|
|
228
278
|
|
|
279
|
+
</else>
|
|
280
|
+
|
|
229
281
|
</for>
|
|
230
282
|
|
|
231
|
-
3.
|
|
283
|
+
3. Unless <ase-project-boxing/> is equal `grey` (where
|
|
284
|
+
<diff-file/> is unused), append <diff-file/> to <diff/>.
|
|
232
285
|
|
|
233
286
|
</for>
|
|
234
287
|
|
|
@@ -241,7 +294,25 @@ related to a set of code quality aspects.
|
|
|
241
294
|
|
|
242
295
|
</template>
|
|
243
296
|
|
|
244
|
-
5. <if condition="<getopt-option-auto/> is not 'true'">
|
|
297
|
+
5. <if condition="<getopt-option-auto/> is not 'true' and <ase-project-boxing/> is not equal `black`">
|
|
298
|
+
|
|
299
|
+
<if condition="<ase-project-boxing/> is equal `grey`">
|
|
300
|
+
|
|
301
|
+
The project source artifacts are classified as a *grey box*, so
|
|
302
|
+
the user does *not* want the full artifact internals surfaced:
|
|
303
|
+
*suppress* the full unified diff and instead show only the
|
|
304
|
+
*condensed* one-line-per-hunk representation. Report the
|
|
305
|
+
solution with the following <template/>:
|
|
306
|
+
|
|
307
|
+
<template>
|
|
308
|
+
<ase-tpl-bullet-normal/> **<aspect/> SOLUTION**:
|
|
309
|
+
|
|
310
|
+
<diff-condensed/>
|
|
311
|
+
|
|
312
|
+
</template>
|
|
313
|
+
|
|
314
|
+
</if>
|
|
315
|
+
<else>
|
|
245
316
|
|
|
246
317
|
Report the solution with the following <template/>:
|
|
247
318
|
|
|
@@ -254,6 +325,8 @@ related to a set of code quality aspects.
|
|
|
254
325
|
|
|
255
326
|
</template>
|
|
256
327
|
|
|
328
|
+
</else>
|
|
329
|
+
|
|
257
330
|
</if>
|
|
258
331
|
<else>
|
|
259
332
|
|
|
@@ -140,8 +140,11 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
|
|
|
140
140
|
You *MUST* perform the following sub-steps *internally* and *without
|
|
141
141
|
any output* until and including the recommendation decision. Only
|
|
142
142
|
sub-steps 4-6 below are allowed to produce output, and only if
|
|
143
|
-
<getopt-option-auto/> is equal `false
|
|
144
|
-
|
|
143
|
+
<getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
|
|
144
|
+
is *not* equal `black`.
|
|
145
|
+
|
|
146
|
+
If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
|
|
147
|
+
equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
|
|
145
148
|
no output at all) to speed up processing.
|
|
146
149
|
|
|
147
150
|
1. *Propose* corresponding *refactoring approach*, including
|
|
@@ -187,7 +190,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
|
|
|
187
190
|
<ase-tpl-foot title="APPROACHES"/>
|
|
188
191
|
</template>
|
|
189
192
|
|
|
190
|
-
7. <if condition="<getopt-option-auto/> is not `true`">
|
|
193
|
+
7. <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
|
|
191
194
|
|
|
192
195
|
In the following, you *MUST* *NOT* use your built-in
|
|
193
196
|
<user-dialog-tool/> tool! Instead, you *MUST* just show a
|
|
@@ -194,8 +194,11 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
|
|
|
194
194
|
You *MUST* perform the following sub-steps *internally* and *without
|
|
195
195
|
any output* until and including the recommendation decision. Only
|
|
196
196
|
sub-steps 4-6 below are allowed to produce output, and only if
|
|
197
|
-
<getopt-option-auto/> is equal `false
|
|
198
|
-
|
|
197
|
+
<getopt-option-auto/> is equal `false` *and* <ase-project-boxing/>
|
|
198
|
+
is *not* equal `black`.
|
|
199
|
+
|
|
200
|
+
If <getopt-option-auto/> is equal `true` or <ase-project-boxing/> is
|
|
201
|
+
equal `black`, *skip* the reporting sub-steps 4-6 entirely (perform
|
|
199
202
|
no output at all) to speed up processing.
|
|
200
203
|
|
|
201
204
|
1. *Propose* corresponding *resolution approach*, including optionally,
|
|
@@ -241,7 +244,7 @@ permitted way to persist artifacts is via `ase_task_save(...)`.
|
|
|
241
244
|
<ase-tpl-foot title="APPROACHES"/>
|
|
242
245
|
</template>
|
|
243
246
|
|
|
244
|
-
7. <if condition="<getopt-option-auto/> is not `true`">
|
|
247
|
+
7. <if condition="<getopt-option-auto/> is not equal `true` and <ase-project-boxing/> is not equal `black`">
|
|
245
248
|
|
|
246
249
|
In the following, you *MUST* *NOT* use your built-in
|
|
247
250
|
<user-dialog-tool/> tool! Instead, you *MUST* just show a
|
|
@@ -33,6 +33,21 @@ Analyze documents for spelling, punctuation, or grammar errors
|
|
|
33
33
|
|
|
34
34
|
1. <step id="STEP 1: Investigation">
|
|
35
35
|
|
|
36
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
37
|
+
|
|
38
|
+
The project source artifacts are classified as a *black box*, so
|
|
39
|
+
the user does *not* want them inspected or their problems surfaced.
|
|
40
|
+
*Skip* the entire investigation and reporting: do *not* invoke any
|
|
41
|
+
`Glob` or `Agent` tool and do *not* read any document, only output
|
|
42
|
+
the following <template/> and then *SKIP* the remaining steps STEP 2
|
|
43
|
+
and STEP 3:
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<ase-tpl-bullet-normal/> **PROOFREAD**: *suppressed* (`project.boxing` is `black`)
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
</if>
|
|
50
|
+
|
|
36
51
|
First, use the following <template/> to give a hint on this step:
|
|
37
52
|
|
|
38
53
|
<template>
|
|
@@ -141,7 +156,26 @@ Analyze documents for spelling, punctuation, or grammar errors
|
|
|
141
156
|
<description/>
|
|
142
157
|
</template>
|
|
143
158
|
|
|
144
|
-
3. <if condition="<getopt-option-auto/> is not 'true'">
|
|
159
|
+
3. <if condition="<getopt-option-auto/> is not 'true' and <ase-project-boxing/> is equal `grey`">
|
|
160
|
+
|
|
161
|
+
The project source artifacts are classified as a *grey box*, so
|
|
162
|
+
the user does *not* want the full artifact internals surfaced:
|
|
163
|
+
*suppress* the full unified diff and instead show only a
|
|
164
|
+
*condensed* one-line representation. Determine <old-snippet/>
|
|
165
|
+
as the *single-line* collapse of <old-text/> (join its lines
|
|
166
|
+
with ` ⏎ `, or `∅` when <old-text/> is empty for a pure
|
|
167
|
+
insertion) and <new-snippet/> as the same collapse of
|
|
168
|
+
<new-text/> (or `∅` when empty for a pure deletion). Then
|
|
169
|
+
report the correction with the following <template/>:
|
|
170
|
+
|
|
171
|
+
<template>
|
|
172
|
+
|
|
173
|
+
<ase-tpl-bullet-normal/> **<type/> CORRECTION**: `<old-snippet/>` → `<new-snippet/>`
|
|
174
|
+
|
|
175
|
+
</template>
|
|
176
|
+
|
|
177
|
+
</if>
|
|
178
|
+
<elseif condition="<getopt-option-auto/> is not 'true'">
|
|
145
179
|
|
|
146
180
|
Determine the hunk *body* as an ordered list of lines, each
|
|
147
181
|
carrying a one-character prefix (` ` for context, `-` for
|
|
@@ -195,7 +229,7 @@ Analyze documents for spelling, punctuation, or grammar errors
|
|
|
195
229
|
|
|
196
230
|
</template>
|
|
197
231
|
|
|
198
|
-
</
|
|
232
|
+
</elseif>
|
|
199
233
|
|
|
200
234
|
4. <if condition="<getopt-option-auto/> is not 'true'">
|
|
201
235
|
|
|
@@ -38,9 +38,12 @@ Format
|
|
|
38
38
|
The *ChangeLog* file is a Markdown formatted file named `CHANGELOG.md`,
|
|
39
39
|
and contains sections with headers in the style `N.M.K (YYYY-MM-DD)`.
|
|
40
40
|
|
|
41
|
-
Each *ChangeLog* entry is always formatted as
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
Each *ChangeLog* entry is always formatted as...
|
|
42
|
+
|
|
43
|
+
`<change-type/> [<artifact-kind/>]: <summary/>`
|
|
44
|
+
|
|
45
|
+
...where the <change-type/> is one of the following tags and their usual
|
|
46
|
+
related changes:
|
|
44
47
|
|
|
45
48
|
- `FEATURE`: new functionality or configuration
|
|
46
49
|
- `IMPROVEMENT`: improved functionality or configuration
|
|
@@ -49,9 +52,21 @@ changes:
|
|
|
49
52
|
- `CLEANUP`: cleaned up functionality or configuration
|
|
50
53
|
- `REFACTOR`: refactored functionality or configuration
|
|
51
54
|
|
|
55
|
+
The <artifact-kind/> is one or more of the following *artifact* tags,
|
|
56
|
+
classifying which kind of artifact the change primarily touches. If
|
|
57
|
+
multiple artifact kinds apply, comma-separate them
|
|
58
|
+
(e.g. `[arch, code]`):
|
|
59
|
+
|
|
60
|
+
- `spec`: requirement/specification artifacts
|
|
61
|
+
- `arch`: architecture/design artifacts
|
|
62
|
+
- `code`: source code artifacts
|
|
63
|
+
- `docs`: documentation artifacts
|
|
64
|
+
- `infr`: infrastructure/build/tooling artifacts
|
|
65
|
+
- `othr`: any other artifacts
|
|
66
|
+
|
|
52
67
|
The <summary/> is not longer than about 60-80 characters. The
|
|
53
68
|
*ChangeLog* entries for a single product release version are also always
|
|
54
|
-
grouped and sorted according to the above <
|
|
69
|
+
grouped and sorted according to the above <change-type/> list.
|
|
55
70
|
|
|
56
71
|
Processing
|
|
57
72
|
----------
|
|
@@ -123,6 +138,16 @@ Processing
|
|
|
123
138
|
For each Git commit, reduce the Git commit messages to a single
|
|
124
139
|
short <summary/> sentence, not longer than 60-80 characters.
|
|
125
140
|
|
|
141
|
+
For each entry, also determine the <artifact-kind/> *artifact kind*
|
|
142
|
+
tag(s) from the paths of the changed files. To classify a changed
|
|
143
|
+
file to its artifact class, call the `ase_artifact_list(kind: [
|
|
144
|
+
... ])` tool of the `ase` MCP server *once*, passing the `kind`
|
|
145
|
+
tokens (`spec`, `arch`, `code`, `docs`, `infr`, `othr`), and read
|
|
146
|
+
the returned `artifacts` array of `{ kind, files }` objects to match
|
|
147
|
+
each changed file to its kind. Map the matched lower-cased kind back
|
|
148
|
+
to its upper-cased <artifact-kind/> tag, and comma-separate multiple
|
|
149
|
+
tags when more than one artifact class applies.
|
|
150
|
+
|
|
126
151
|
If a <summary/> is too short or especially is not comprehensible
|
|
127
152
|
enough because of too little context information, add some essential
|
|
128
153
|
context, especially references to the class/module/package, etc.
|
|
@@ -144,11 +169,11 @@ Processing
|
|
|
144
169
|
Without immediately modifying the `CHANGELOG.md` file, *consolidate*
|
|
145
170
|
the entries in the first (most recent) section only, by summarizing
|
|
146
171
|
and merging closely related entries. Perform the entry consolidation
|
|
147
|
-
per <
|
|
172
|
+
per <change-type/> group only.
|
|
148
173
|
|
|
149
174
|
Without immediately modifying the `CHANGELOG.md` file, *sort* the
|
|
150
175
|
entries in the first (most recent) section only. Instead of the
|
|
151
|
-
chronological commit order, group the entries by the <
|
|
176
|
+
chronological commit order, group the entries by the <change-type/>s.
|
|
152
177
|
|
|
153
178
|
</step>
|
|
154
179
|
|
|
@@ -15,10 +15,13 @@ The `ase-meta-changelog` skill helps to *complete*, *consolidate*, and
|
|
|
15
15
|
file, based on the underlying *Git* commits and the currently staged
|
|
16
16
|
changes in the Git *index*.
|
|
17
17
|
|
|
18
|
-
Each entry is formatted as `<
|
|
19
|
-
one of `FEATURE`, `IMPROVEMENT`, `BUGFIX`,
|
|
20
|
-
`
|
|
21
|
-
|
|
18
|
+
Each entry is formatted as `<change-type> [<artifact-kind>]: <summary>`
|
|
19
|
+
where *change-type* is one of `FEATURE`, `IMPROVEMENT`, `BUGFIX`,
|
|
20
|
+
`UPDATE`, `CLEANUP`, or `REFACTOR`, and *artifact-kind* is one or more
|
|
21
|
+
comma-separated *artifact class* tags out of `spec`, `arch`, `code`,
|
|
22
|
+
`docs`, `infr`, or `othr`. Entries are grouped and sorted by this
|
|
23
|
+
prefix. The date in the section header is also updated to the current
|
|
24
|
+
date.
|
|
22
25
|
|
|
23
26
|
## EXAMPLES
|
|
24
27
|
|
|
@@ -123,10 +123,28 @@ Procedure
|
|
|
123
123
|
*not* output any further explanation.
|
|
124
124
|
</if>
|
|
125
125
|
|
|
126
|
+
4. <if condition="
|
|
127
|
+
<ase-project-boxing/> is equal `black` and
|
|
128
|
+
(<getopt-option-coherence/> is equal `true` or
|
|
129
|
+
<getopt-option-risk/> is equal `true` or
|
|
130
|
+
<getopt-option-blast/> is equal `true`)
|
|
131
|
+
">
|
|
132
|
+
The project source artifacts are classified as a *black box*, so
|
|
133
|
+
the user does *not* want the staged changes scrutinized or their
|
|
134
|
+
coherence, risk, and blast-radius findings surfaced. The
|
|
135
|
+
requested scrutiny of STEP 3 through STEP 5 is therefore
|
|
136
|
+
suppressed: only output the following <template/> and then *SKIP*
|
|
137
|
+
the remaining steps STEP 3 through STEP 5:
|
|
138
|
+
|
|
139
|
+
<template>
|
|
140
|
+
<ase-tpl-bullet-normal/> **DIFF SCRUTINY**: *suppressed* (`project.boxing` is `black`)
|
|
141
|
+
</template>
|
|
142
|
+
</if>
|
|
143
|
+
|
|
126
144
|
</step>
|
|
127
145
|
|
|
128
146
|
3. <step id="STEP 3: Assess Intent Coherence"
|
|
129
|
-
condition="<getopt-option-coherence/> is equal `true` and <diff/> is NOT empty">
|
|
147
|
+
condition="<getopt-option-coherence/> is equal `true` and <diff/> is NOT empty and <ase-project-boxing/> is not equal `black`">
|
|
130
148
|
|
|
131
149
|
1. From the *same* captured <diff/> and <stat/>, *reconstruct the
|
|
132
150
|
single intended change* as a thesis - the one logical, coherent purpose
|
|
@@ -203,7 +221,7 @@ Procedure
|
|
|
203
221
|
</step>
|
|
204
222
|
|
|
205
223
|
4. <step id="STEP 4: Score Against Risk Rubric"
|
|
206
|
-
condition="<getopt-option-risk/> is equal `true` and <diff/> is NOT empty">
|
|
224
|
+
condition="<getopt-option-risk/> is equal `true` and <diff/> is NOT empty and <ase-project-boxing/> is not equal `black`">
|
|
207
225
|
|
|
208
226
|
1. Score the *same* captured <diff/> and <stat/> information
|
|
209
227
|
against the four-axis rubric below. Each axis is scored on an
|
|
@@ -275,7 +293,7 @@ Procedure
|
|
|
275
293
|
</step>
|
|
276
294
|
|
|
277
295
|
5. <step id="STEP 5: Render Blast-Radius Map"
|
|
278
|
-
condition="<getopt-option-blast/> is equal `true` and <diff/> is NOT empty">
|
|
296
|
+
condition="<getopt-option-blast/> is equal `true` and <diff/> is NOT empty and <ase-project-boxing/> is not equal `black`">
|
|
279
297
|
|
|
280
298
|
1. From the *same* captured <diff/> and <stat/>, *extract the
|
|
281
299
|
touched modules* - the distinct changed source files (or their
|
|
@@ -67,6 +67,19 @@ Procedure
|
|
|
67
67
|
|
|
68
68
|
2. <step id="STEP 2: Review Investigation">
|
|
69
69
|
|
|
70
|
+
<if condition="<ase-project-boxing/> is equal `black`">
|
|
71
|
+
|
|
72
|
+
The project source artifacts are classified as a *black box*, so
|
|
73
|
+
the user does *not* want the staged changes scrutinized or their
|
|
74
|
+
findings surfaced. *Skip* the entire review investigation: do
|
|
75
|
+
*not* invoke the `Agent` tool and do *not* read any change, set
|
|
76
|
+
<findings/> to the *empty* list, set <verdict/> to `SKIPPED (boxing:
|
|
77
|
+
black)`, set <summary/> to a *one-line* neutral restatement of the
|
|
78
|
+
change intent derived solely from STEP 1, and proceed *directly* to
|
|
79
|
+
STEP 3.
|
|
80
|
+
|
|
81
|
+
</if>
|
|
82
|
+
|
|
70
83
|
First, use the following <template/> to give a hint on this step:
|
|
71
84
|
|
|
72
85
|
<template>
|
|
@@ -102,13 +115,20 @@ Procedure
|
|
|
102
115
|
severity floor below, so the floor only affects which findings are
|
|
103
116
|
*rendered*, never the verdict.
|
|
104
117
|
|
|
105
|
-
Then
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
118
|
+
Then determine the *effective severity floor* <floor/>: define the
|
|
119
|
+
ordinal rank `LOW`=1, `MEDIUM`=2, `HIGH`=3, start from
|
|
120
|
+
<floor><getopt-option-severity/></floor> (default `LOW`), and - if
|
|
121
|
+
<ase-project-boxing/> is equal `grey` - raise <floor/> to `MEDIUM`
|
|
122
|
+
whenever its current rank is below `rank(MEDIUM)` (grey boxing
|
|
123
|
+
surfaces only *material* findings of severity `MEDIUM` and above).
|
|
124
|
+
The floor affects only which findings are *rendered*, never the
|
|
125
|
+
<verdict/> derived above.
|
|
126
|
+
|
|
127
|
+
Then *apply the effective severity floor* <floor/>: *Keep* a finding
|
|
128
|
+
in <findings/> if and only if its `severity` field is `ACCEPTED` *or*
|
|
129
|
+
`rank(severity)` is greater than or equal to `rank(<floor/>)`;
|
|
130
|
+
*silently drop* all other findings. With the default floor `LOW`, all
|
|
131
|
+
findings are kept. `ACCEPTED` findings are *never* dropped.
|
|
112
132
|
|
|
113
133
|
You *MUST* *NOT* output anything else in this STEP 2.
|
|
114
134
|
|