@rse/ase 0.0.41 → 0.0.42
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-kv.js +105 -6
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.github/plugin/plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/plugin/skills/ase-code-analyze/SKILL.md +71 -72
- package/plugin/skills/ase-code-craft/SKILL.md +58 -20
- package/plugin/skills/ase-code-refactor/SKILL.md +46 -22
- package/plugin/skills/ase-code-resolve/SKILL.md +46 -33
package/dst/ase-kv.js
CHANGED
|
@@ -17,6 +17,11 @@ export class KV {
|
|
|
17
17
|
static validateKey(key) {
|
|
18
18
|
if (typeof key !== "string" || key.length === 0)
|
|
19
19
|
throw new Error("kv: key must be a non-empty string");
|
|
20
|
+
if (key.trim().length === 0)
|
|
21
|
+
throw new Error("kv: key must not consist solely of whitespace");
|
|
22
|
+
/* eslint-disable-next-line no-control-regex */
|
|
23
|
+
if (/[\x00-\x1F\x7F]/.test(key))
|
|
24
|
+
throw new Error("kv: key must not contain control characters");
|
|
20
25
|
if (key.length > KV.KEY_MAX_LEN)
|
|
21
26
|
throw new Error(`kv: key must be no longer than ${KV.KEY_MAX_LEN} characters`);
|
|
22
27
|
}
|
|
@@ -33,7 +38,7 @@ export class KV {
|
|
|
33
38
|
/* set a value under the given key; overwrites any existing value */
|
|
34
39
|
static set(key, val) {
|
|
35
40
|
KV.validateKey(key);
|
|
36
|
-
KV.store.set(key, val);
|
|
41
|
+
KV.store.set(key, structuredClone(val));
|
|
37
42
|
}
|
|
38
43
|
/* delete a value by key; returns true if a value existed */
|
|
39
44
|
static delete(key) {
|
|
@@ -46,6 +51,16 @@ export class KV {
|
|
|
46
51
|
KV.store.clear();
|
|
47
52
|
return n;
|
|
48
53
|
}
|
|
54
|
+
/* snapshot the entire store into a fresh map (for transactional batch) */
|
|
55
|
+
static snapshot() {
|
|
56
|
+
return new Map(KV.store);
|
|
57
|
+
}
|
|
58
|
+
/* restore the store from a previously taken snapshot */
|
|
59
|
+
static restore(snap) {
|
|
60
|
+
KV.store.clear();
|
|
61
|
+
for (const [k, v] of snap)
|
|
62
|
+
KV.store.set(k, v);
|
|
63
|
+
}
|
|
49
64
|
}
|
|
50
65
|
/* MCP registration entry point for in-memory key/value tools */
|
|
51
66
|
export class KVMCP {
|
|
@@ -57,14 +72,14 @@ export class KVMCP {
|
|
|
57
72
|
"Returns the value as JSON-encoded `text`; returns an empty string if no value is stored.",
|
|
58
73
|
inputSchema: {
|
|
59
74
|
key: z.string()
|
|
60
|
-
.describe("key identifier (non-empty
|
|
75
|
+
.describe("key identifier (non-empty, no whitespace-only, no control characters, up to 1024 characters)")
|
|
61
76
|
}
|
|
62
77
|
}, async (args) => {
|
|
63
78
|
try {
|
|
64
79
|
if (!KV.has(args.key))
|
|
65
80
|
return { content: [{ type: "text", text: "" }] };
|
|
66
81
|
const val = KV.get(args.key);
|
|
67
|
-
const text = JSON.stringify(val);
|
|
82
|
+
const text = val === undefined ? "" : JSON.stringify(val);
|
|
68
83
|
return { content: [{ type: "text", text }] };
|
|
69
84
|
}
|
|
70
85
|
catch (err) {
|
|
@@ -80,8 +95,8 @@ export class KVMCP {
|
|
|
80
95
|
"The value can be any JSON-compatible type (string, number, boolean, null, array, object).",
|
|
81
96
|
inputSchema: {
|
|
82
97
|
key: z.string()
|
|
83
|
-
.describe("key identifier (non-empty
|
|
84
|
-
val: z.any()
|
|
98
|
+
.describe("key identifier (non-empty, no whitespace-only, no control characters, up to 1024 characters)"),
|
|
99
|
+
val: z.union([z.string(), z.number(), z.boolean(), z.null(), z.array(z.any()), z.record(z.string(), z.any())])
|
|
85
100
|
.describe("arbitrary JSON-compatible value to store under `key`")
|
|
86
101
|
}
|
|
87
102
|
}, async (args) => {
|
|
@@ -117,7 +132,7 @@ export class KVMCP {
|
|
|
117
132
|
"Returns a status `text` indicating whether a value existed and was removed.",
|
|
118
133
|
inputSchema: {
|
|
119
134
|
key: z.string()
|
|
120
|
-
.describe("key identifier (non-empty
|
|
135
|
+
.describe("key identifier (non-empty, no whitespace-only, no control characters, up to 1024 characters)")
|
|
121
136
|
}
|
|
122
137
|
}, async (args) => {
|
|
123
138
|
try {
|
|
@@ -132,5 +147,89 @@ export class KVMCP {
|
|
|
132
147
|
return { isError: true, content: [{ type: "text", text: `kv_delete: ERROR: ${message}` }] };
|
|
133
148
|
}
|
|
134
149
|
});
|
|
150
|
+
/* key/value batch */
|
|
151
|
+
mcp.registerTool("kv_batch", {
|
|
152
|
+
title: "ASE key/value batch",
|
|
153
|
+
description: "Execute an array of in-memory key/value `commands` in a single MCP call. " +
|
|
154
|
+
"Each entry is an object `{ command: \"clear\"|\"set\"|\"get\"|\"delete\", key?, val? }` " +
|
|
155
|
+
"and is dispatched to the corresponding single-op tool. " +
|
|
156
|
+
"If `transactional` is true, the store is snapshotted up-front and rolled back on the " +
|
|
157
|
+
"first per-command error (remaining commands are skipped); otherwise per-command errors " +
|
|
158
|
+
"are recorded and execution continues. " +
|
|
159
|
+
"Returns a single `text` payload containing a JSON array of per-command result strings " +
|
|
160
|
+
"in the same format emitted by `kv_clear`/`kv_set`/`kv_get`/`kv_delete`. " +
|
|
161
|
+
"On transactional rollback, prior per-command result strings are rewritten to " +
|
|
162
|
+
"`kv_<cmd>: ROLLED-BACK` to truthfully reflect the post-rollback state, and the " +
|
|
163
|
+
"final entry remains `kv_batch: ERROR: <message>`.",
|
|
164
|
+
inputSchema: {
|
|
165
|
+
commands: z.array(z.object({
|
|
166
|
+
command: z.enum(["clear", "set", "get", "delete"])
|
|
167
|
+
.describe("the KV sub-command to execute"),
|
|
168
|
+
key: z.string().optional()
|
|
169
|
+
.describe("key identifier (required for `set`/`get`/`delete`)"),
|
|
170
|
+
val: z.union([z.string(), z.number(), z.boolean(), z.null(), z.array(z.any()), z.record(z.string(), z.any())]).optional()
|
|
171
|
+
.describe("value to store (required for `set`)")
|
|
172
|
+
}))
|
|
173
|
+
.describe("ordered list of KV commands to execute"),
|
|
174
|
+
transactional: z.boolean().optional()
|
|
175
|
+
.describe("if true, snapshot the store and roll back on first error")
|
|
176
|
+
}
|
|
177
|
+
}, async (args) => {
|
|
178
|
+
const results = [];
|
|
179
|
+
const cmdNames = [];
|
|
180
|
+
const tx = args.transactional === true;
|
|
181
|
+
const snapshot = tx ? KV.snapshot() : null;
|
|
182
|
+
for (const c of args.commands) {
|
|
183
|
+
try {
|
|
184
|
+
if (c.command === "clear") {
|
|
185
|
+
const n = KV.clear();
|
|
186
|
+
results.push(`kv_clear: OK: removed ${n} key(s)`);
|
|
187
|
+
cmdNames.push("clear");
|
|
188
|
+
}
|
|
189
|
+
else if (c.command === "set") {
|
|
190
|
+
if (c.key === undefined)
|
|
191
|
+
throw new Error("kv_set: missing `key`");
|
|
192
|
+
if (c.val === undefined)
|
|
193
|
+
throw new Error("kv_set: missing `val`");
|
|
194
|
+
KV.set(c.key, c.val);
|
|
195
|
+
results.push(`kv_set: OK: stored key "${c.key}"`);
|
|
196
|
+
cmdNames.push("set");
|
|
197
|
+
}
|
|
198
|
+
else if (c.command === "get") {
|
|
199
|
+
if (c.key === undefined)
|
|
200
|
+
throw new Error("kv_get: missing `key`");
|
|
201
|
+
if (!KV.has(c.key))
|
|
202
|
+
results.push("");
|
|
203
|
+
else {
|
|
204
|
+
const val = KV.get(c.key);
|
|
205
|
+
results.push(val === undefined ? "" : JSON.stringify(val));
|
|
206
|
+
}
|
|
207
|
+
cmdNames.push("get");
|
|
208
|
+
}
|
|
209
|
+
else if (c.command === "delete") {
|
|
210
|
+
if (c.key === undefined)
|
|
211
|
+
throw new Error("kv_delete: missing `key`");
|
|
212
|
+
const removed = KV.delete(c.key);
|
|
213
|
+
results.push(removed ?
|
|
214
|
+
`kv_delete: OK: removed key "${c.key}"` :
|
|
215
|
+
`kv_delete: WARNING: no key "${c.key}" to remove`);
|
|
216
|
+
cmdNames.push("delete");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
221
|
+
if (tx) {
|
|
222
|
+
if (snapshot !== null)
|
|
223
|
+
KV.restore(snapshot);
|
|
224
|
+
for (let i = 0; i < results.length; i++)
|
|
225
|
+
results[i] = `kv_${cmdNames[i]}: ROLLED-BACK`;
|
|
226
|
+
results.push(`kv_batch: ERROR: ${message}`);
|
|
227
|
+
return { isError: true, content: [{ type: "text", text: JSON.stringify(results) }] };
|
|
228
|
+
}
|
|
229
|
+
results.push(`kv_${c.command}: ERROR: ${message}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return { content: [{ type: "text", text: JSON.stringify(results) }] };
|
|
233
|
+
});
|
|
135
234
|
}
|
|
136
235
|
}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"homepage": "http://github.com/rse/ase",
|
|
7
7
|
"repository": { "url": "git+https://github.com/rse/ase.git", "type": "git" },
|
|
8
8
|
"bugs": { "url": "http://github.com/rse/ase/issues" },
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.42",
|
|
10
10
|
"license": "GPL-3.0-only",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "Dr. Ralf S. Engelschall",
|
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.0.
|
|
9
|
+
"version": "0.0.42",
|
|
10
10
|
"license": "GPL-3.0-only",
|
|
11
11
|
"author": {
|
|
12
12
|
"name": "Dr. Ralf S. Engelschall",
|
|
@@ -33,78 +33,77 @@ code, for problems in its *logic* and *semantics* and its related
|
|
|
33
33
|
|
|
34
34
|
<flow>
|
|
35
35
|
|
|
36
|
-
1.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
</step>
|
|
36
|
+
1. <step id="STEP 1: Investigate Code Base">
|
|
37
|
+
In this STEP 1, investigate on the code. If the code base is large,
|
|
38
|
+
you *MUST* use the `Agent` tool (not inline work) to create multiple
|
|
39
|
+
sub-agents to split the investigation task into appropriate chunks.
|
|
40
|
+
|
|
41
|
+
Tenets:
|
|
42
|
+
|
|
43
|
+
- **Quiet Operation**:
|
|
44
|
+
During investigation in this STEP 1, do *not* output anything else,
|
|
45
|
+
especially do not give any further explanations or information.
|
|
46
|
+
|
|
47
|
+
- **Practical Relevance Only**:
|
|
48
|
+
Focus on *practically relevant* cases and especially do *not*
|
|
49
|
+
investigate on theoretical or fictive cases.
|
|
50
|
+
|
|
51
|
+
- **Problem Focus Only**:
|
|
52
|
+
Still focus on the *problem only* and do *not* already
|
|
53
|
+
investigate on any possible *solution*.
|
|
54
|
+
</step>
|
|
55
|
+
|
|
56
|
+
2. <step id="STEP 2: Show Results">
|
|
57
|
+
In this STEP 2, for every detected problem, immediately report it
|
|
58
|
+
with the following output <template/>, based on concise bullet
|
|
59
|
+
points.
|
|
60
|
+
|
|
61
|
+
<template>
|
|
62
|
+
🟠 PROBLEM (Severity: **<severity/>**): **P<n/>**: **<title/>**
|
|
63
|
+
|
|
64
|
+
<description/>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
Hints:
|
|
68
|
+
|
|
69
|
+
- For the final results, do *not* output anything else, especially do
|
|
70
|
+
*not* give any further explanations or information.
|
|
71
|
+
|
|
72
|
+
- Uniquely identify the problems with `P<n/>` where <n/> is 1, 2, ...
|
|
73
|
+
|
|
74
|
+
- In <description/>, use *ultra brief* but still as *precise* as
|
|
75
|
+
possible problem descriptions.
|
|
76
|
+
|
|
77
|
+
- In <description/>, highlight *code* as <template>`<code/>`</template>
|
|
78
|
+
and *key aspects* as <template>*<aspect/>*</template>.
|
|
79
|
+
|
|
80
|
+
- In <description/>, add inline *references* to the related
|
|
81
|
+
code positions in the form of either
|
|
82
|
+
<template>(`<filename/>:<line-number/>`)</template>,
|
|
83
|
+
<template>(`<filename/>:<line-number/>-<line-number/>`)</template> or
|
|
84
|
+
<template>(`<filename/>#<function-or-method/>`)</template>.
|
|
85
|
+
|
|
86
|
+
- In <description/>, classify the problem with a <severity/>
|
|
87
|
+
of <template>LOW</template>, <template>MEDIUM</template> or
|
|
88
|
+
<template>HIGH</template>.
|
|
89
|
+
|
|
90
|
+
- *Additionally*, persist all reported problems in a *single*
|
|
91
|
+
`kv_batch` call to the `ase` MCP service with `transactional`
|
|
92
|
+
set to `true`. The `commands` parameter array of this call
|
|
93
|
+
starts with one `{ command: "clear" }` entry, followed by one
|
|
94
|
+
`{ command: "set", key: "ase-issue-P<n/>", val: "<title/>:
|
|
95
|
+
<description/>" }` entry per reported problem.
|
|
96
|
+
</step>
|
|
97
|
+
|
|
98
|
+
3. <step id="STEP 3: Give Final Hint">
|
|
99
|
+
Finally, in this STEP 3, output the following <template/> to give a
|
|
100
|
+
final hint:
|
|
101
|
+
|
|
102
|
+
<template>
|
|
103
|
+
⧉ **ASE**: ☻ skill: **<skill-name/>**, ▶ status: **skill finished**
|
|
104
|
+
⧉ **ASE**: ↪ hint: **For deeper analysis, suggestions on solution approaches and then final problem resolution, use `/ase-code-resolve P{n}` in the same or even a different session.**
|
|
105
|
+
</template>
|
|
106
|
+
</step>
|
|
108
107
|
|
|
109
108
|
</flow>
|
|
110
109
|
|
|
@@ -121,32 +121,58 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
121
121
|
|
|
122
122
|
3. **Internalize Crafting Tenets**:
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
You *MUST* internalize and honor the following tenets when crafting the new feature.
|
|
125
125
|
Do not output anything.
|
|
126
126
|
|
|
127
|
-
1.
|
|
127
|
+
1. Generic Tenets:
|
|
128
|
+
|
|
129
|
+
- **Separation of Concerns**:
|
|
130
|
+
Clearly separate all individual concerns as good as possible.
|
|
131
|
+
|
|
132
|
+
- **Code Base Alignment**:
|
|
133
|
+
Strictly align with the existing source code base by exactly
|
|
134
|
+
following its coding style, its structure, its naming
|
|
135
|
+
conventions, etc.
|
|
136
|
+
|
|
137
|
+
2. Specific Tenets:
|
|
128
138
|
|
|
129
139
|
- **Surgical Changes**:
|
|
130
140
|
Keep source code changes always as small as possible.
|
|
131
141
|
|
|
132
|
-
- **
|
|
133
|
-
|
|
142
|
+
- **Clear Minimal Scope**:
|
|
143
|
+
Establish explicit boundaries for the new feature.
|
|
144
|
+
Avoid feature scope creep and over-engineering.
|
|
145
|
+
|
|
146
|
+
- **Keep it Simple, Stupid (KISS)**:
|
|
147
|
+
Build with the simplest design that solves the real problem.
|
|
148
|
+
Avoid over-engineering.
|
|
149
|
+
|
|
150
|
+
- **You Aren't Gonna Need It (YAGNI)**:
|
|
151
|
+
Build for today's actual needs, not speculative futures.
|
|
152
|
+
Avoid premature optimizations, premature abstractions,
|
|
153
|
+
over-configurability, etc.
|
|
134
154
|
|
|
135
|
-
- **
|
|
136
|
-
|
|
155
|
+
- **Don't Repeat Yourself (DRY)**:
|
|
156
|
+
Avoid redundancies, but honor the *Rule of Three*: Don't
|
|
157
|
+
abstract on the first occurrence -- tolerate (small)
|
|
158
|
+
duplication on the second -- factor out on the third only.
|
|
137
159
|
|
|
138
|
-
- **
|
|
139
|
-
|
|
160
|
+
- **Single Responsibility Principle (SRP)**:
|
|
161
|
+
Every module, class, or function should have only one reason
|
|
162
|
+
to change.
|
|
140
163
|
|
|
141
|
-
- **
|
|
142
|
-
|
|
143
|
-
|
|
164
|
+
- **Loose Coupling, High Cohesion**:
|
|
165
|
+
Strike for good modularity by a set of small, focused parts
|
|
166
|
+
(high cohesion), connected by thin, explicit wires and
|
|
167
|
+
interfaces (loose coupling).
|
|
144
168
|
|
|
145
|
-
|
|
169
|
+
- **Clear Interfaces**:
|
|
170
|
+
Design clear interfaces, contracts, and data models --
|
|
171
|
+
with high attention to boundaries and modularity.
|
|
146
172
|
|
|
147
|
-
- **
|
|
148
|
-
|
|
149
|
-
|
|
173
|
+
- **Non-Functional Requirements**:
|
|
174
|
+
Honor the non-functional requirements Performance, Security,
|
|
175
|
+
Scalability, Comprehensibility.
|
|
150
176
|
|
|
151
177
|
4. **Find Feature Crafting Approaches**:
|
|
152
178
|
|
|
@@ -167,14 +193,20 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
167
193
|
` ⚝ **RECOMMENDATION** ⚝`. All other approaches receive an
|
|
168
194
|
empty <annotation/>. Do *not* output anything in this sub-step.
|
|
169
195
|
|
|
170
|
-
4.
|
|
196
|
+
4. Indicate start of reporting by showing the following <template/>:
|
|
197
|
+
|
|
198
|
+
<template>
|
|
199
|
+
⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `APPROACHES-BEGIN` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
|
|
200
|
+
</template>
|
|
201
|
+
|
|
202
|
+
5. Now report each approach with the following <template/>,
|
|
171
203
|
inlining its pros/cons derived in sub-step 2:
|
|
172
204
|
|
|
173
205
|
<template>
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
206
|
+
● **APPROACH A<n/>**<annotation/>: *<summary/>*
|
|
207
|
+
○ [...]
|
|
208
|
+
○ [...]
|
|
209
|
+
○ [...]
|
|
178
210
|
⊕ *pro*: [...]
|
|
179
211
|
⊖ *con*: [...]
|
|
180
212
|
<optional-diagram/>
|
|
@@ -199,6 +231,12 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
199
231
|
`**After:**`); never side-by-side. Omit <optional-diagram/>
|
|
200
232
|
entirely for simple or purely local situation.
|
|
201
233
|
|
|
234
|
+
6. Indicate end of reporting by showing the following <template/>:
|
|
235
|
+
|
|
236
|
+
<template>
|
|
237
|
+
⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `APPROACHES-END` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
|
|
238
|
+
</template>
|
|
239
|
+
|
|
202
240
|
5. **Choose Feature Crafting Approach**:
|
|
203
241
|
|
|
204
242
|
1. If <getopt-option-auto/> is equal `false`:
|
|
@@ -121,35 +121,47 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
121
121
|
|
|
122
122
|
3. **Internalize Refactoring Tenets**:
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
You *MUST* internalize and honor the following tenets when refactoring.
|
|
125
125
|
Do not output anything.
|
|
126
126
|
|
|
127
|
-
1.
|
|
128
|
-
|
|
129
|
-
- **Surgical Changes**:
|
|
130
|
-
Keep source code changes always as small as possible.
|
|
127
|
+
1. Generic Tenets:
|
|
131
128
|
|
|
132
129
|
- **Separation of Concerns**:
|
|
133
130
|
Clearly separate all individual concerns as good as possible.
|
|
134
131
|
|
|
135
|
-
- **
|
|
136
|
-
|
|
132
|
+
- **Code Base Alignment**:
|
|
133
|
+
Strictly align with the existing source code base by exactly
|
|
134
|
+
following its coding style, its structure, its naming
|
|
135
|
+
conventions, etc.
|
|
136
|
+
|
|
137
|
+
2. Specific Tenets:
|
|
137
138
|
|
|
138
139
|
- **Behavior Preservation**:
|
|
139
|
-
Refactoring changes only re-structure, never change any
|
|
140
|
+
Refactoring changes only re-structure, never change any
|
|
141
|
+
observable behavior at all. Especially, do not mix with
|
|
142
|
+
problem resolving and feature crafting.
|
|
140
143
|
|
|
141
|
-
- **
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
- **Boy Scout Rule**:
|
|
145
|
+
After the refactoring, leave the source code base cleaner
|
|
146
|
+
than you found it.
|
|
144
147
|
|
|
145
|
-
|
|
148
|
+
- **Don't Repeat Yourself (DRY)**:
|
|
149
|
+
Avoid redundancies, but honor the *Rule of Three*: Don't
|
|
150
|
+
abstract on the first occurrence -- tolerate (small)
|
|
151
|
+
duplication on the second -- factor out on the third only.
|
|
146
152
|
|
|
147
|
-
- **
|
|
148
|
-
|
|
153
|
+
- **Single Responsibility Principle (SRP)**:
|
|
154
|
+
Every module, class, or function should have only one reason
|
|
155
|
+
to change.
|
|
149
156
|
|
|
150
|
-
- **
|
|
151
|
-
Strike for a set of small, focused parts
|
|
152
|
-
thin, explicit wires
|
|
157
|
+
- **Loose Coupling, High Cohesion**:
|
|
158
|
+
Strike for good modularity by a set of small, focused parts
|
|
159
|
+
(high cohesion), connected by thin, explicit wires and
|
|
160
|
+
interfaces (loose coupling).
|
|
161
|
+
|
|
162
|
+
- **Clear Interfaces**:
|
|
163
|
+
Design clear interfaces, contracts, and data models --
|
|
164
|
+
with high attention to boundaries and modularity.
|
|
153
165
|
|
|
154
166
|
4. **Find Refactoring Approaches**:
|
|
155
167
|
|
|
@@ -170,15 +182,21 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
170
182
|
` ⚝ **RECOMMENDATION** ⚝`. All other approaches receive an
|
|
171
183
|
empty <annotation/>. Do *not* output anything in this sub-step.
|
|
172
184
|
|
|
173
|
-
4.
|
|
185
|
+
4. Indicate start of reporting by showing the following <template/>:
|
|
186
|
+
|
|
187
|
+
<template>
|
|
188
|
+
⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `APPROACHES-BEGIN` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
|
|
189
|
+
</template>
|
|
190
|
+
|
|
191
|
+
5. Now report each approach with the following <template/>,
|
|
174
192
|
inlining its pros/cons derived in sub-step 2, and do not output
|
|
175
193
|
anything else in this step:
|
|
176
194
|
|
|
177
195
|
<template>
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
196
|
+
● **APPROACH A<n/>**<annotation/>: *<summary/>*
|
|
197
|
+
○ [...]
|
|
198
|
+
○ [...]
|
|
199
|
+
○ [...]
|
|
182
200
|
⊕ *pro*: [...]
|
|
183
201
|
⊖ *con*: [...]
|
|
184
202
|
<optional-diagram/>
|
|
@@ -203,6 +221,12 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
203
221
|
`**After:**`); never side-by-side. Omit <optional-diagram/>
|
|
204
222
|
entirely for simple or purely local situation.
|
|
205
223
|
|
|
224
|
+
6. Indicate end of reporting by showing the following <template/>:
|
|
225
|
+
|
|
226
|
+
<template>
|
|
227
|
+
⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `APPROACHES-END` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
|
|
228
|
+
</template>
|
|
229
|
+
|
|
206
230
|
5. **Choose Refactoring Approach**:
|
|
207
231
|
|
|
208
232
|
1. If <getopt-option-auto/> is equal `false`:
|
|
@@ -169,33 +169,45 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
169
169
|
|
|
170
170
|
3. **Internalize Problem Resolution Tenets**:
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
You *MUST* internalize and honor the following tenets when resolving the problem.
|
|
173
173
|
Do not output anything.
|
|
174
174
|
|
|
175
|
-
1.
|
|
176
|
-
|
|
177
|
-
- **Surgical Changes**:
|
|
178
|
-
Keep source code changes always as small as possible.
|
|
175
|
+
1. Generic Tenets:
|
|
179
176
|
|
|
180
177
|
- **Separation of Concerns**:
|
|
181
178
|
Clearly separate all individual concerns as good as possible.
|
|
182
179
|
|
|
183
|
-
- **
|
|
184
|
-
|
|
180
|
+
- **Code Base Alignment**:
|
|
181
|
+
Strictly align with the existing source code base by exactly
|
|
182
|
+
following its coding style, its structure, its naming
|
|
183
|
+
conventions, etc.
|
|
185
184
|
|
|
186
|
-
|
|
187
|
-
Refactoring changes only re-structure, never change any observable behavior.
|
|
185
|
+
2. Specific Tenets:
|
|
188
186
|
|
|
189
|
-
- **
|
|
190
|
-
|
|
191
|
-
coding style, its structure, its naming conventions, etc.
|
|
192
|
-
|
|
193
|
-
2. *Essential* Tenets (problem resolving specific):
|
|
187
|
+
- **Surgical Changes**:
|
|
188
|
+
Keep source code changes always as small as possible.
|
|
194
189
|
|
|
195
190
|
- **No Cleanups**:
|
|
196
|
-
Strictly focus on resolving the problem and do not mix this
|
|
197
|
-
with any other necessary code cleanups, except they are
|
|
198
|
-
necessary for resolving the task.
|
|
191
|
+
Strictly focus on resolving the problem and do not mix this
|
|
192
|
+
task with any other necessary code cleanups, except they are
|
|
193
|
+
really necessary for resolving the task.
|
|
194
|
+
|
|
195
|
+
- **Minimum Flags**:
|
|
196
|
+
Use the absolute minimum total number of flags (boolean
|
|
197
|
+
variables) to span the entire space of scenarios. Prefer the
|
|
198
|
+
adjustment of existing flags over the introduction of new
|
|
199
|
+
flags.
|
|
200
|
+
|
|
201
|
+
- **Code Adequacy**:
|
|
202
|
+
As little increase in overall source code complexity as
|
|
203
|
+
possible, as much new problem resolution source code as
|
|
204
|
+
necessary.
|
|
205
|
+
|
|
206
|
+
- **Origin Proximity**:
|
|
207
|
+
Problems for *obvious, particular, or expected* errors
|
|
208
|
+
*should* be handled *near the origin*. Problems for
|
|
209
|
+
*theoretical, fictive, or unexpected* errors, *should* be
|
|
210
|
+
handled more general and in parent scopes.
|
|
199
211
|
|
|
200
212
|
4. **Find Problem Resolution Approaches**:
|
|
201
213
|
|
|
@@ -216,15 +228,21 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
216
228
|
` ⚝ **RECOMMENDATION** ⚝`. All other approaches receive an
|
|
217
229
|
empty <annotation/>. Do *not* output anything in this sub-step.
|
|
218
230
|
|
|
219
|
-
4.
|
|
231
|
+
4. Indicate start of reporting by showing the following <template/>:
|
|
232
|
+
|
|
233
|
+
<template>
|
|
234
|
+
⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `APPROACHES-BEGIN` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
|
|
235
|
+
</template>
|
|
236
|
+
|
|
237
|
+
5. Now report each approach with the following <template/>,
|
|
220
238
|
inlining its pros/cons derived in sub-step 2, and do not output
|
|
221
239
|
anything else in this step:
|
|
222
240
|
|
|
223
241
|
<template>
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
242
|
+
● **APPROACH A<n/>**<annotation/>: *<summary/>*
|
|
243
|
+
○ [...]
|
|
244
|
+
○ [...]
|
|
245
|
+
○ [...]
|
|
228
246
|
⊕ *pro*: [...]
|
|
229
247
|
⊖ *con*: [...]
|
|
230
248
|
<optional-diagram/>
|
|
@@ -236,17 +254,6 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
236
254
|
*precise* and *brief* resolution information. Try to keep the
|
|
237
255
|
number of bullet points (●) in the range of 1-4.
|
|
238
256
|
|
|
239
|
-
- Focus on resolution approaches for *practically relevant* cases and do *not*
|
|
240
|
-
investigate on theoretical or fictive cases. This is especially the case
|
|
241
|
-
for error handling cases and race condition cases.
|
|
242
|
-
|
|
243
|
-
- In case of resolution approaches for problems related to *obvious or
|
|
244
|
-
expected* errors, they *should* be handled *near the origin*.
|
|
245
|
-
|
|
246
|
-
- In case of resolution approaches for problems related to *theoretical
|
|
247
|
-
or unexpected* errors, they *should* be handled in parent scopes to
|
|
248
|
-
avoid cluttering the source code with too much error handling at all.
|
|
249
|
-
|
|
250
257
|
- In case of a *complex resolution situation* only,
|
|
251
258
|
visualize it with an optional diagram <optional-diagram/>
|
|
252
259
|
by building a Mermaid specification <mermaid-spec/>
|
|
@@ -260,6 +267,12 @@ permitted way to persist artifacts is via `task_save(...)`.
|
|
|
260
267
|
`**After:**`); never side-by-side. Omit <optional-diagram/>
|
|
261
268
|
entirely for simple or purely local situation.
|
|
262
269
|
|
|
270
|
+
6. Indicate end of reporting by showing the following <template/>:
|
|
271
|
+
|
|
272
|
+
<template>
|
|
273
|
+
⧉ **ASE**: ┈┈┈┈┈┈┈┈────────━━━━━━━━**(** `APPROACHES-END` **)**━━━━━━━━────────┈┈┈┈┈┈┈┈
|
|
274
|
+
</template>
|
|
275
|
+
|
|
263
276
|
5. **Choose Problem Resolution Approach**:
|
|
264
277
|
|
|
265
278
|
1. If <getopt-option-auto/> is equal `false`:
|