add-skill-kit 3.2.3 → 3.2.5
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/README.md +1 -1
- package/bin/lib/commands/help.js +0 -4
- package/bin/lib/commands/install.js +90 -9
- package/bin/lib/ui.js +1 -1
- package/lib/agent-cli/__tests__/adaptive_engine.test.js +190 -0
- package/lib/agent-cli/__tests__/integration/cross_script.test.js +222 -0
- package/lib/agent-cli/__tests__/integration/full_cycle.test.js +230 -0
- package/lib/agent-cli/__tests__/pattern_analyzer.test.js +173 -0
- package/lib/agent-cli/__tests__/pre_execution_check.test.js +167 -0
- package/lib/agent-cli/__tests__/skill_injector.test.js +191 -0
- package/lib/agent-cli/bin/agent.js +191 -0
- package/lib/agent-cli/dashboard/dashboard_server.js +340 -0
- package/lib/agent-cli/dashboard/index.html +538 -0
- package/lib/agent-cli/lib/audit.js +154 -0
- package/lib/agent-cli/lib/audit.test.js +100 -0
- package/lib/agent-cli/lib/auto-learn.js +319 -0
- package/lib/agent-cli/lib/auto_preview.py +148 -0
- package/lib/agent-cli/lib/backup.js +138 -0
- package/lib/agent-cli/lib/backup.test.js +78 -0
- package/lib/agent-cli/lib/checklist.py +222 -0
- package/lib/agent-cli/lib/cognitive-lesson.js +476 -0
- package/lib/agent-cli/lib/completion.js +149 -0
- package/lib/agent-cli/lib/config.js +35 -0
- package/lib/agent-cli/lib/eslint-fix.js +238 -0
- package/lib/agent-cli/lib/evolution-signal.js +215 -0
- package/lib/agent-cli/lib/export.js +86 -0
- package/lib/agent-cli/lib/export.test.js +65 -0
- package/lib/agent-cli/lib/fix.js +337 -0
- package/lib/agent-cli/lib/fix.test.js +80 -0
- package/lib/agent-cli/lib/gemini-export.js +83 -0
- package/lib/agent-cli/lib/generate-registry.js +42 -0
- package/lib/agent-cli/lib/hooks/install-hooks.js +152 -0
- package/lib/agent-cli/lib/hooks/lint-learn.js +172 -0
- package/lib/agent-cli/lib/ignore.js +116 -0
- package/lib/agent-cli/lib/ignore.test.js +58 -0
- package/lib/agent-cli/lib/init.js +124 -0
- package/lib/agent-cli/lib/learn.js +255 -0
- package/lib/agent-cli/lib/learn.test.js +70 -0
- package/lib/agent-cli/lib/migrate-to-v4.js +322 -0
- package/lib/agent-cli/lib/proposals.js +199 -0
- package/lib/agent-cli/lib/proposals.test.js +56 -0
- package/lib/agent-cli/lib/recall.js +820 -0
- package/lib/agent-cli/lib/recall.test.js +107 -0
- package/lib/agent-cli/lib/selfevolution-bridge.js +167 -0
- package/lib/agent-cli/lib/session_manager.py +120 -0
- package/lib/agent-cli/lib/settings.js +227 -0
- package/lib/agent-cli/lib/skill-learn.js +296 -0
- package/lib/agent-cli/lib/stats.js +132 -0
- package/lib/agent-cli/lib/stats.test.js +94 -0
- package/lib/agent-cli/lib/types.js +33 -0
- package/lib/agent-cli/lib/ui/audit-ui.js +146 -0
- package/lib/agent-cli/lib/ui/backup-ui.js +107 -0
- package/lib/agent-cli/lib/ui/clack-helpers.js +317 -0
- package/lib/agent-cli/lib/ui/common.js +83 -0
- package/lib/agent-cli/lib/ui/completion-ui.js +126 -0
- package/lib/agent-cli/lib/ui/custom-select.js +69 -0
- package/lib/agent-cli/lib/ui/dashboard-ui.js +222 -0
- package/lib/agent-cli/lib/ui/evolution-signals-ui.js +107 -0
- package/lib/agent-cli/lib/ui/export-ui.js +94 -0
- package/lib/agent-cli/lib/ui/fix-all-ui.js +191 -0
- package/lib/agent-cli/lib/ui/help-ui.js +49 -0
- package/lib/agent-cli/lib/ui/index.js +199 -0
- package/lib/agent-cli/lib/ui/init-ui.js +56 -0
- package/lib/agent-cli/lib/ui/knowledge-ui.js +55 -0
- package/lib/agent-cli/lib/ui/learn-ui.js +706 -0
- package/lib/agent-cli/lib/ui/lessons-ui.js +148 -0
- package/lib/agent-cli/lib/ui/pretty.js +145 -0
- package/lib/agent-cli/lib/ui/proposals-ui.js +99 -0
- package/lib/agent-cli/lib/ui/recall-ui.js +342 -0
- package/lib/agent-cli/lib/ui/routing-demo.js +79 -0
- package/lib/agent-cli/lib/ui/routing-ui.js +325 -0
- package/lib/agent-cli/lib/ui/settings-ui.js +381 -0
- package/lib/agent-cli/lib/ui/stats-ui.js +123 -0
- package/lib/agent-cli/lib/ui/watch-ui.js +236 -0
- package/lib/agent-cli/lib/verify_all.py +327 -0
- package/lib/agent-cli/lib/watcher.js +181 -0
- package/lib/agent-cli/lib/watcher.test.js +85 -0
- package/lib/agent-cli/package.json +51 -0
- package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
- package/lib/agent-cli/scripts/dashboard_server.js +224 -0
- package/lib/agent-cli/scripts/error_sensor.js +565 -0
- package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
- package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
- package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
- package/lib/agent-cli/scripts/rule_sharing.js +374 -0
- package/lib/agent-cli/scripts/skill_injector.js +387 -0
- package/lib/agent-cli/scripts/success_sensor.js +500 -0
- package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
- package/lib/agent-cli/services/auto-learn-service.js +247 -0
- package/lib/agent-cli/src/MIGRATION.md +418 -0
- package/lib/agent-cli/src/README.md +367 -0
- package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
- package/lib/agent-cli/src/core/evolution/index.js +17 -0
- package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
- package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
- package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
- package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
- package/lib/agent-cli/src/core/index.js +15 -0
- package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
- package/lib/agent-cli/src/core/learning/index.js +12 -0
- package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
- package/lib/agent-cli/src/core/scanning/index.js +14 -0
- package/lib/agent-cli/src/data/index.js +13 -0
- package/lib/agent-cli/src/data/repositories/index.js +8 -0
- package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
- package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
- package/lib/agent-cli/src/data/storage/index.js +8 -0
- package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
- package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
- package/lib/agent-cli/src/infrastructure/index.js +13 -0
- package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
- package/lib/agent-cli/src/services/export-service.js +162 -0
- package/lib/agent-cli/src/services/index.js +13 -0
- package/lib/agent-cli/src/services/learning-service.js +99 -0
- package/lib/agent-cli/types/index.d.ts +343 -0
- package/lib/agent-cli/utils/benchmark.js +269 -0
- package/lib/agent-cli/utils/logger.js +303 -0
- package/lib/agent-cli/utils/ml_patterns.js +300 -0
- package/lib/agent-cli/utils/recovery.js +312 -0
- package/lib/agent-cli/utils/telemetry.js +290 -0
- package/lib/agentskillskit-cli/README.md +21 -0
- package/{node_modules/agentskillskit-cli/bin → lib/agentskillskit-cli}/ag-smart.js +15 -15
- package/lib/agentskillskit-cli/package.json +51 -0
- package/package.json +19 -9
- /package/bin/{cli.js → kit.js} +0 -0
- /package/{node_modules/agentskillskit-cli → lib/agent-cli}/README.md +0 -0
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learn UI - Teach new patterns
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
showIntro,
|
|
6
|
+
showActionMenu,
|
|
7
|
+
textInput,
|
|
8
|
+
confirm,
|
|
9
|
+
createSpinner,
|
|
10
|
+
showSuccessNote,
|
|
11
|
+
showErrorNote,
|
|
12
|
+
showNote,
|
|
13
|
+
theme
|
|
14
|
+
} from "./clack-helpers.js";
|
|
15
|
+
import { getKnowledge } from "./common.js";
|
|
16
|
+
import { saveKnowledge } from "../recall.js";
|
|
17
|
+
import * as p from "@clack/prompts";
|
|
18
|
+
import { spawnSync } from 'child_process';
|
|
19
|
+
import path from 'path';
|
|
20
|
+
import { fileURLToPath } from 'url';
|
|
21
|
+
|
|
22
|
+
export async function runLearnUI() {
|
|
23
|
+
showIntro("📚 Learn New Pattern");
|
|
24
|
+
|
|
25
|
+
// Action menu - Simplified to core functions
|
|
26
|
+
const action = await showActionMenu({
|
|
27
|
+
message: "What would you like to do?",
|
|
28
|
+
items: [
|
|
29
|
+
{ value: "view", label: "📚 View Lessons", hint: "Browse all learned patterns" },
|
|
30
|
+
{ value: "add", label: "➕ Add Lesson", hint: "Teach a new pattern manually" },
|
|
31
|
+
{ value: "remove", label: "🗑️ Remove Lesson", hint: "Delete a pattern" },
|
|
32
|
+
// REMOVED: Query Lessons (niche, AI auto-recalls)
|
|
33
|
+
// REMOVED: Auto-Learn (redundant with Add)
|
|
34
|
+
// REMOVED: Status/Versions/History (broken execCommand, low value)
|
|
35
|
+
],
|
|
36
|
+
includeExit: true
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// ESC returns to main menu (don't execute action)
|
|
40
|
+
if (p.isCancel(action)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
switch (action) {
|
|
45
|
+
case "view":
|
|
46
|
+
await viewLessonsFlow();
|
|
47
|
+
break;
|
|
48
|
+
case "add":
|
|
49
|
+
await addLessonFlow();
|
|
50
|
+
break;
|
|
51
|
+
case "remove":
|
|
52
|
+
await removeLessonFlow();
|
|
53
|
+
break;
|
|
54
|
+
// REMOVED CASES (commented out for rollback):
|
|
55
|
+
// case "status": await statusFlow(); break;
|
|
56
|
+
// case "query": await queryLessonsFlow(); break;
|
|
57
|
+
// case "auto": await autoLearnFlow(); break;
|
|
58
|
+
// case "versions": await versionsFlow(); break;
|
|
59
|
+
// case "history": await historyFlow(); break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// CORE FLOWS - Simplified Menu
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* View all learned lessons (Cognitive Engine v4.x)
|
|
69
|
+
* Displays synthesis of mistakes + improvements
|
|
70
|
+
*/
|
|
71
|
+
async function viewLessonsFlow() {
|
|
72
|
+
// Import cognitive engine
|
|
73
|
+
const { synthesizeLessons } = await import('../cognitive-lesson.js');
|
|
74
|
+
|
|
75
|
+
const lessons = synthesizeLessons();
|
|
76
|
+
|
|
77
|
+
if (lessons.length === 0) {
|
|
78
|
+
showErrorNote("No lessons learned yet. Use 'Add Lesson' to teach your first pattern!", "No Lessons");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Build enhanced cognitive view
|
|
83
|
+
const content = lessons.map((lesson, i) => {
|
|
84
|
+
// State icon
|
|
85
|
+
const stateIcons = {
|
|
86
|
+
'RAW': '🟥',
|
|
87
|
+
'LEARNING': '🟨',
|
|
88
|
+
'MATURE': '🟩',
|
|
89
|
+
'IDEAL': '🟦',
|
|
90
|
+
};
|
|
91
|
+
const stateIcon = stateIcons[lesson.maturity.state] || '⚪';
|
|
92
|
+
|
|
93
|
+
const mistakeCount = lesson.mistakes.length;
|
|
94
|
+
const improveCount = lesson.improvements.length;
|
|
95
|
+
|
|
96
|
+
// Build lesson display
|
|
97
|
+
const parts = [
|
|
98
|
+
`${theme.primary(`${i + 1}.`)} ${stateIcon} ${theme.bold(lesson.id)}: ${lesson.title}`,
|
|
99
|
+
` ${theme.dim(`Intent: ${lesson.intent.goal} (${Math.round(lesson.intent.strength * 100)}%)`)}`,
|
|
100
|
+
` ${theme.dim(`Confidence: ${Math.round(lesson.maturity.confidence * 100)}% | ${lesson.maturity.recommendation}`)}`,
|
|
101
|
+
'',
|
|
102
|
+
` 🔴 Mistakes (${mistakeCount})`,
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
// Show first 2 mistakes
|
|
106
|
+
if (mistakeCount > 0) {
|
|
107
|
+
lesson.mistakes.slice(0, 2).forEach(m => {
|
|
108
|
+
parts.push(` • ${theme.dim(m.title || m.message.substring(0, 60))}`);
|
|
109
|
+
});
|
|
110
|
+
if (mistakeCount > 2) {
|
|
111
|
+
parts.push(` ${theme.dim(`... and ${mistakeCount - 2} more`)}`);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
parts.push(` ${theme.dim('None')}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
parts.push('');
|
|
118
|
+
parts.push(` 🟢 Improvements (${improveCount})`);
|
|
119
|
+
|
|
120
|
+
// Show first 2 improvements
|
|
121
|
+
if (improveCount > 0) {
|
|
122
|
+
lesson.improvements.slice(0, 2).forEach(imp => {
|
|
123
|
+
parts.push(` • ${theme.dim(imp.title || imp.message.substring(0, 60))}`);
|
|
124
|
+
});
|
|
125
|
+
if (improveCount > 2) {
|
|
126
|
+
parts.push(` ${theme.dim(`... and ${improveCount - 2} more`)}`);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
parts.push(` ${theme.warning('⚠️ No best practices learned yet')}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Show evolution signals if any
|
|
133
|
+
if (lesson.evolution.signals.length > 0) {
|
|
134
|
+
parts.push('');
|
|
135
|
+
parts.push(` 💡 Evolution Signals:`);
|
|
136
|
+
lesson.evolution.signals.slice(0, 1).forEach(signal => {
|
|
137
|
+
parts.push(` ${signal.type}: ${signal.reason}`);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return parts.join('\n');
|
|
142
|
+
}).join('\n\n');
|
|
143
|
+
|
|
144
|
+
showSuccessNote(content, `🧠 Cognitive Lessons (${lessons.length})`);
|
|
145
|
+
|
|
146
|
+
// Wait for user to read
|
|
147
|
+
await p.text({
|
|
148
|
+
message: "Press Enter to continue...",
|
|
149
|
+
placeholder: "",
|
|
150
|
+
initialValue: "",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Add a new lesson manually
|
|
156
|
+
* Renamed from addPatternFlow for consistency
|
|
157
|
+
*/
|
|
158
|
+
async function addLessonFlow() {
|
|
159
|
+
const pattern = await textInput({
|
|
160
|
+
message: "Pattern to detect:",
|
|
161
|
+
placeholder: "e.g., console.log",
|
|
162
|
+
validate: (value) => {
|
|
163
|
+
if (!value) return "Please enter a pattern";
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (p.isCancel(pattern)) {
|
|
168
|
+
p.cancel("Cancelled.");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const message = await textInput({
|
|
173
|
+
message: "Error message:",
|
|
174
|
+
placeholder: "e.g., Remove console.log in production",
|
|
175
|
+
validate: (value) => {
|
|
176
|
+
if (!value) return "Please enter a message";
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (p.isCancel(message)) {
|
|
181
|
+
p.cancel("Cancelled.");
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const severity = await p.select({
|
|
186
|
+
message: "Severity level:",
|
|
187
|
+
options: [
|
|
188
|
+
{ value: "ERROR", label: "Error", hint: "Critical issue" },
|
|
189
|
+
{ value: "WARNING", label: "Warning", hint: "Should be fixed" },
|
|
190
|
+
]
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (p.isCancel(severity)) {
|
|
194
|
+
p.cancel("Operation cancelled.");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const confirmed = await confirm(
|
|
199
|
+
`Add pattern "${theme.primary(pattern)}" with message "${message}"?`,
|
|
200
|
+
true
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
if (!confirmed) {
|
|
204
|
+
p.cancel("Cancelled.");
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const spinner = createSpinner("Adding lesson...");
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
const db = getKnowledge();
|
|
212
|
+
const id = `LEARN-${String(db.lessons.length + 1).padStart(3, '0')}`;
|
|
213
|
+
|
|
214
|
+
const lesson = {
|
|
215
|
+
id,
|
|
216
|
+
pattern,
|
|
217
|
+
message,
|
|
218
|
+
severity,
|
|
219
|
+
hitCount: 0,
|
|
220
|
+
added: new Date().toISOString()
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
db.lessons.push(lesson);
|
|
224
|
+
saveKnowledge(db);
|
|
225
|
+
|
|
226
|
+
spinner.stopSuccess("Lesson added");
|
|
227
|
+
|
|
228
|
+
showSuccessNote(
|
|
229
|
+
`${theme.primary('Pattern:')} ${pattern}\n` +
|
|
230
|
+
`${theme.primary('Message:')} ${message}\n` +
|
|
231
|
+
`${theme.primary('Severity:')} ${severity}`,
|
|
232
|
+
`✓ Lesson ${id} Added`
|
|
233
|
+
);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
spinner.stopError("Failed to add lesson");
|
|
236
|
+
showErrorNote(error.message, "✗ Error");
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Wait to continue
|
|
240
|
+
await p.text({
|
|
241
|
+
message: "Press Enter to continue...",
|
|
242
|
+
placeholder: "",
|
|
243
|
+
initialValue: "",
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Remove a lesson by ID
|
|
249
|
+
* Renamed from removePatternFlow for consistency
|
|
250
|
+
*/
|
|
251
|
+
async function removeLessonFlow() {
|
|
252
|
+
const db = getKnowledge();
|
|
253
|
+
const patterns = db.lessons || [];
|
|
254
|
+
|
|
255
|
+
if (patterns.length === 0) {
|
|
256
|
+
showErrorNote("No patterns to remove.", "No Patterns");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Show list first
|
|
261
|
+
const listContent = patterns.map((p, i) =>
|
|
262
|
+
`${theme.primary(p.id)}: ${p.message}`
|
|
263
|
+
).join('\n');
|
|
264
|
+
|
|
265
|
+
showNote(listContent, "Available Patterns");
|
|
266
|
+
|
|
267
|
+
const patternId = await textInput({
|
|
268
|
+
message: "Pattern ID to remove:",
|
|
269
|
+
placeholder: "e.g., LEARN-001",
|
|
270
|
+
validate: (value) => {
|
|
271
|
+
if (!value) return "Please enter a pattern ID";
|
|
272
|
+
if (!patterns.find(p => p.id === value)) {
|
|
273
|
+
return `Pattern ${value} not found`;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
if (p.isCancel(patternId)) {
|
|
279
|
+
p.cancel("Cancelled.");
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const confirmed = await confirm(
|
|
284
|
+
`Remove pattern ${theme.primary(patternId)}?`,
|
|
285
|
+
false
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
if (!confirmed) {
|
|
289
|
+
p.cancel("Cancelled.");
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
db.lessons = db.lessons.filter(l => l.id !== patternId);
|
|
294
|
+
saveKnowledge(db);
|
|
295
|
+
|
|
296
|
+
showSuccessNote(`Pattern ${patternId} removed`, "✓ Removed");
|
|
297
|
+
|
|
298
|
+
// Wait to continue
|
|
299
|
+
await p.text({
|
|
300
|
+
message: "Press Enter to continue...",
|
|
301
|
+
placeholder: "",
|
|
302
|
+
initialValue: "",
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// DEPRECATED FUNCTIONS (Kept for rollback safety)
|
|
308
|
+
// ============================================================================
|
|
309
|
+
|
|
310
|
+
// DEPRECATED: Query Lessons - Low usage, AI auto-recalls
|
|
311
|
+
/*
|
|
312
|
+
async function queryLessonsFlow() {
|
|
313
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
314
|
+
const scriptPath = path.join(__dirname, '../../../../.agent/skills/SelfEvolution/scripts/query_lessons.py');
|
|
315
|
+
|
|
316
|
+
p.note("Query learns what you learned before to avoid repeating mistakes.\nDescribe what you're about to code.", theme.primary("🔍 Query Lessons"));
|
|
317
|
+
|
|
318
|
+
// Get coding context
|
|
319
|
+
const context = await textInput({
|
|
320
|
+
message: "What are you about to code?",
|
|
321
|
+
placeholder: "e.g., menu navigation with ESC handling",
|
|
322
|
+
validate: (value) => {
|
|
323
|
+
if (!value || value.length < 5) return "Please describe what you're coding (min 5 chars)";
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
if (p.isCancel(context)) {
|
|
328
|
+
p.cancel("Cancelled.");
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Optional scope filter
|
|
333
|
+
const wantScope = await confirm("Filter by scope?", false);
|
|
334
|
+
|
|
335
|
+
let scope = null;
|
|
336
|
+
if (wantScope) {
|
|
337
|
+
const scopeOptions = [
|
|
338
|
+
{ value: "cli-navigation", label: "CLI Navigation" },
|
|
339
|
+
{ value: "api-design", label: "API Design" },
|
|
340
|
+
{ value: "code-quality", label: "Code Quality" },
|
|
341
|
+
{ value: "file-safety", label: "File Safety" },
|
|
342
|
+
{ value: "user-experience", label: "User Experience" },
|
|
343
|
+
];
|
|
344
|
+
|
|
345
|
+
scope = await p.select({
|
|
346
|
+
message: "Select scope:",
|
|
347
|
+
options: scopeOptions
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
if (p.isCancel(scope)) {
|
|
351
|
+
p.cancel("Cancelled.");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const spinner = createSpinner("Querying lessons...");
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
// Call Python script
|
|
360
|
+
const args = [scriptPath, context];
|
|
361
|
+
if (scope) {
|
|
362
|
+
args.push('--scope', scope);
|
|
363
|
+
}
|
|
364
|
+
args.push('--json');
|
|
365
|
+
|
|
366
|
+
const result = spawnSync('python', args, {
|
|
367
|
+
encoding: 'utf-8',
|
|
368
|
+
cwd: path.join(__dirname, '../../../..')
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
spinner.stop("Query complete");
|
|
372
|
+
|
|
373
|
+
if (result.error) {
|
|
374
|
+
throw new Error(`Failed to run query_lessons.py: ${result.error.message}`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (result.status !== 0) {
|
|
378
|
+
throw new Error(`query_lessons.py failed: ${result.stderr || result.stdout}`);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const lessons = JSON.parse(result.stdout);
|
|
382
|
+
|
|
383
|
+
if (lessons.length === 0) {
|
|
384
|
+
showNote("No relevant lessons found for this context.", "📭 No Matches");
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Display lessons
|
|
389
|
+
let output = `Found ${theme.primary(lessons.length)} relevant lesson(s):\n\n`;
|
|
390
|
+
|
|
391
|
+
for (const lesson of lessons) {
|
|
392
|
+
const relevance = Math.round(lesson.relevance * 100);
|
|
393
|
+
output += `${theme.primary('[' + lesson.id + ']')} ${relevance}% relevant | ${lesson.severity}\n`;
|
|
394
|
+
output += `${lesson.message}\n`;
|
|
395
|
+
if (lesson.scope) {
|
|
396
|
+
output += `${theme.dim('Scope: ' + lesson.scope)}\n`;
|
|
397
|
+
}
|
|
398
|
+
output += '\n';
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
output += theme.dim("💡 Use these lessons to avoid repeating past mistakes!");
|
|
402
|
+
|
|
403
|
+
showSuccessNote(output, `📚 ${lessons.length} Lesson(s) Found`);
|
|
404
|
+
|
|
405
|
+
} catch (error) {
|
|
406
|
+
spinner.stop("Failed");
|
|
407
|
+
showErrorNote(`Error: ${error.message}`, "❌ Query Failed");
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
*/
|
|
411
|
+
|
|
412
|
+
// DEPRECATED: Auto-Learn - Redundant with Add Lesson
|
|
413
|
+
/*
|
|
414
|
+
async function autoLearnFlow() {
|
|
415
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
416
|
+
const scriptPath = path.join(__dirname, '../../../../.agent/skills/SelfEvolution/scripts/auto_learn.py');
|
|
417
|
+
|
|
418
|
+
p.note("Auto-learn helps you capture mistakes automatically.\nDescribe what went wrong and what should be done instead.", theme.primary("📚 Auto-Learn"));
|
|
419
|
+
|
|
420
|
+
// Get mistake description
|
|
421
|
+
const mistake = await textInput({
|
|
422
|
+
message: "What went wrong?",
|
|
423
|
+
placeholder: "e.g., Used customSelect instead of p.select",
|
|
424
|
+
validate: (value) => {
|
|
425
|
+
if (!value || value.length < 10) return "Please describe the mistake (min 10 chars)";
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
if (p.isCancel(mistake)) {
|
|
430
|
+
p.cancel("Cancelled.");
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Get correction
|
|
435
|
+
const correction = await textInput({
|
|
436
|
+
message: "What should be done instead?",
|
|
437
|
+
placeholder: "e.g., Always use p.select() + p.isCancel()",
|
|
438
|
+
validate: (value) => {
|
|
439
|
+
if (!value || value.length < 10) return "Please describe the correction (min 10 chars)";
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
if (p.isCancel(correction)) {
|
|
444
|
+
p.cancel("Cancelled.");
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Get impact
|
|
449
|
+
const impact = await textInput({
|
|
450
|
+
message: "What was the impact?",
|
|
451
|
+
placeholder: "e.g., Menu navigation broken, ESC key stuck",
|
|
452
|
+
validate: (value) => {
|
|
453
|
+
if (!value) return "Please describe the impact";
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
if (p.isCancel(impact)) {
|
|
458
|
+
p.cancel("Cancelled.");
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const spinner = createSpinner("Extracting lesson...");
|
|
463
|
+
|
|
464
|
+
try {
|
|
465
|
+
// Call Python script to add lesson
|
|
466
|
+
const context = JSON.stringify({
|
|
467
|
+
mistake,
|
|
468
|
+
correction,
|
|
469
|
+
impact,
|
|
470
|
+
mistake_type: "auto-detected"
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
const result = spawnSync('python', [scriptPath, 'add', '--context', context], {
|
|
474
|
+
encoding: 'utf-8',
|
|
475
|
+
cwd: path.join(__dirname, '../../../..')
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
spinner.stop("Lesson extracted");
|
|
479
|
+
|
|
480
|
+
if (result.error) {
|
|
481
|
+
throw new Error(`Failed to run auto_learn.py: ${result.error.message}`);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (result.status !== 0) {
|
|
485
|
+
throw new Error(`auto_learn.py failed: ${result.stderr || result.stdout}`);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const output = JSON.parse(result.stdout);
|
|
489
|
+
|
|
490
|
+
if (!output.success) {
|
|
491
|
+
showErrorNote(output.message, "❌ Failed");
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
showSuccessNote(
|
|
496
|
+
`Lesson ID: ${theme.primary(output.lesson_id)}\n` +
|
|
497
|
+
`Pattern: ${theme.dim(output.lesson.pattern)}\n` +
|
|
498
|
+
`Message: ${output.lesson.message}`,
|
|
499
|
+
`📚 Đã học: ${output.lesson_id}`
|
|
500
|
+
);
|
|
501
|
+
|
|
502
|
+
} catch (error) {
|
|
503
|
+
spinner.stop("Failed");
|
|
504
|
+
showErrorNote(`Error: ${error.message}`, "❌ Auto-Learn Failed");
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
// DEPRECATED: Old addPatternFlow - Replaced by addLessonFlow
|
|
510
|
+
/*
|
|
511
|
+
async function addPatternFlow() {
|
|
512
|
+
const pattern = await textInput({
|
|
513
|
+
message: "Pattern to detect:",
|
|
514
|
+
placeholder: "e.g., console.log",
|
|
515
|
+
validate: (value) => {
|
|
516
|
+
if (!value) return "Please enter a pattern";
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
const message = await textInput({
|
|
521
|
+
message: "Error message:",
|
|
522
|
+
placeholder: "e.g., Remove console.log in production",
|
|
523
|
+
validate: (value) => {
|
|
524
|
+
if (!value) return "Please enter a message";
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
const severity = await p.select({
|
|
529
|
+
message: "Severity level:",
|
|
530
|
+
options: [
|
|
531
|
+
{ value: "ERROR", label: "Error", hint: "Critical issue" },
|
|
532
|
+
{ value: "WARNING", label: "Warning", hint: "Should be fixed" },
|
|
533
|
+
]
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
if (p.isCancel(severity)) {
|
|
537
|
+
p.cancel("Operation cancelled.");
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const confirmed = await confirm(
|
|
542
|
+
`Add pattern "${theme.primary(pattern)}" with message "${message}"?`,
|
|
543
|
+
true
|
|
544
|
+
);
|
|
545
|
+
|
|
546
|
+
if (!confirmed) {
|
|
547
|
+
p.cancel("Cancelled.");
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const spinner = createSpinner("Adding lesson...");
|
|
552
|
+
|
|
553
|
+
try {
|
|
554
|
+
const db = getKnowledge();
|
|
555
|
+
const id = `LEARN-${String(db.lessons.length + 1).padStart(3, '0')}`;
|
|
556
|
+
|
|
557
|
+
const lesson = {
|
|
558
|
+
id,
|
|
559
|
+
pattern,
|
|
560
|
+
message,
|
|
561
|
+
severity,
|
|
562
|
+
hitCount: 0,
|
|
563
|
+
added: new Date().toISOString()
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
db.lessons.push(lesson);
|
|
567
|
+
saveKnowledge(db);
|
|
568
|
+
|
|
569
|
+
spinner.stopSuccess("Lesson added");
|
|
570
|
+
|
|
571
|
+
showSuccessNote(
|
|
572
|
+
`${theme.primary('Pattern:')} ${pattern}\n` +
|
|
573
|
+
`${theme.primary('Message:')} ${message}\n` +
|
|
574
|
+
`${theme.primary('Severity:')} ${severity}`,
|
|
575
|
+
`✓ Lesson ${id} Added`
|
|
576
|
+
);
|
|
577
|
+
} catch (error) {
|
|
578
|
+
spinner.stopError("Failed to add lesson");
|
|
579
|
+
showErrorNote(error.message, "✗ Error");
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
*/
|
|
583
|
+
|
|
584
|
+
// DEPRECATED: Old listPatternsFlow - Replaced by viewLessonsFlow
|
|
585
|
+
/*
|
|
586
|
+
async function listPatternsFlow() {
|
|
587
|
+
const db = getKnowledge();
|
|
588
|
+
const patterns = db.lessons || [];
|
|
589
|
+
|
|
590
|
+
if (patterns.length === 0) {
|
|
591
|
+
showErrorNote("No patterns learned yet.", "No Patterns");
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const content = patterns.map((p, i) =>
|
|
596
|
+
`${theme.primary(`${i + 1}.`)} ${theme.bold(p.id)}: ${p.pattern}\n` +
|
|
597
|
+
` ${theme.dim(p.message)} ${theme.cyan(`[${p.severity}]`)}`
|
|
598
|
+
).join('\n\n');
|
|
599
|
+
|
|
600
|
+
showSuccessNote(content, `📚 Learned Patterns (${patterns.length})`);
|
|
601
|
+
}
|
|
602
|
+
*/
|
|
603
|
+
|
|
604
|
+
// DEPRECATED: Old removePatternFlow - Replaced by removeLessonFlow
|
|
605
|
+
/*
|
|
606
|
+
async function removePatternFlow() {
|
|
607
|
+
const db = getKnowledge();
|
|
608
|
+
const patterns = db.lessons || [];
|
|
609
|
+
|
|
610
|
+
if (patterns.length === 0) {
|
|
611
|
+
showErrorNote("No patterns to remove.", "No Patterns");
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const patternId = await textInput({
|
|
616
|
+
message: "Pattern ID to remove:",
|
|
617
|
+
placeholder: "e.g., LEARN-001",
|
|
618
|
+
validate: (value) => {
|
|
619
|
+
if (!value) return "Please enter a pattern ID";
|
|
620
|
+
if (!patterns.find(p => p.id === value)) {
|
|
621
|
+
return `Pattern ${value} not found`;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
const confirmed = await confirm(
|
|
627
|
+
`Remove pattern ${theme.primary(patternId)}?`,
|
|
628
|
+
false
|
|
629
|
+
);
|
|
630
|
+
|
|
631
|
+
if (!confirmed) {
|
|
632
|
+
p.cancel("Cancelled.");
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
db.lessons = db.lessons.filter(l => l.id !== patternId);
|
|
637
|
+
saveKnowledge(db);
|
|
638
|
+
|
|
639
|
+
showSuccessNote(`Pattern ${patternId} removed`, "✓ Removed");
|
|
640
|
+
}
|
|
641
|
+
*/
|
|
642
|
+
|
|
643
|
+
// ============================================================================
|
|
644
|
+
// DEPRECATED: v4.0 Flows (execCommand undefined, broken)
|
|
645
|
+
// ============================================================================
|
|
646
|
+
|
|
647
|
+
/*
|
|
648
|
+
async function statusFlow() {
|
|
649
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
650
|
+
const scriptPath = path.join(__dirname, '../../../../.agent/skills/SelfEvolution/scripts/learning_status.py');
|
|
651
|
+
|
|
652
|
+
p.note("View active mistakes and improvements for this project", theme.primary("📊 Learning Status"));
|
|
653
|
+
|
|
654
|
+
try {
|
|
655
|
+
const result = await execCommand('python', [scriptPath, 'status'], '.');
|
|
656
|
+
|
|
657
|
+
if (result.code === 0) {
|
|
658
|
+
showInfoNote(`${result.output}`, "📊 Learning Status");
|
|
659
|
+
} else {
|
|
660
|
+
showErrorNote(`Failed to get status:\n${result.error}`, "Error");
|
|
661
|
+
}
|
|
662
|
+
} catch (error) {
|
|
663
|
+
showErrorNote(`Python script failed: ${error.message}`, "Error");
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
async function versionsFlow() {
|
|
668
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
669
|
+
const scriptPath = path.join(__dirname, '../../../../.agent/skills/SelfEvolution/scripts/learning_status.py');
|
|
670
|
+
|
|
671
|
+
p.note("View version history of your learnings", theme.primary("📚 Version History"));
|
|
672
|
+
|
|
673
|
+
try {
|
|
674
|
+
const result = await execCommand('python', [scriptPath, 'versions'], '.');
|
|
675
|
+
|
|
676
|
+
if (result.code === 0) {
|
|
677
|
+
showInfoNote(`${result.output}`, "📚 Versions");
|
|
678
|
+
} else {
|
|
679
|
+
showErrorNote(`Failed to get versions:\n${result.error}`, "Error");
|
|
680
|
+
}
|
|
681
|
+
} catch (error) {
|
|
682
|
+
showErrorNote(`Python script failed: ${error.message}`, "Error");
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
async function historyFlow() {
|
|
687
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
688
|
+
const scriptPath = path.join(__dirname, '../../../../.agent/skills/SelfEvolution/scripts/learning_status.py');
|
|
689
|
+
|
|
690
|
+
p.note("View self-improve cycle history", theme.primary("🔄 Self-Improve History"));
|
|
691
|
+
|
|
692
|
+
try {
|
|
693
|
+
const result = await execCommand('python', [scriptPath, 'history'], '.');
|
|
694
|
+
|
|
695
|
+
if (result.code === 0) {
|
|
696
|
+
showInfoNote(`${result.output}`, "🔄 History");
|
|
697
|
+
} else {
|
|
698
|
+
showErrorNote(`Failed to get history:\n${result.error}`, "Error");
|
|
699
|
+
}
|
|
700
|
+
} catch (error) {
|
|
701
|
+
showErrorNote(`Python script failed: ${error.message}`, "Error");
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
*/
|
|
705
|
+
|
|
706
|
+
export default runLearnUI;
|