pikakit 1.0.36 → 1.0.38
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.
|
@@ -571,6 +571,12 @@ export async function run(spec) {
|
|
|
571
571
|
const targetKnowledgeDir = path.join(WORKSPACE, "..", "knowledge");
|
|
572
572
|
let knowledgeInstalled = false;
|
|
573
573
|
|
|
574
|
+
// DEBUG: Log paths for troubleshooting
|
|
575
|
+
console.log(`[Install] baseAgentDir: ${baseAgentDir}`);
|
|
576
|
+
console.log(`[Install] knowledgeDir: ${knowledgeDir}`);
|
|
577
|
+
console.log(`[Install] knowledgeDir exists: ${fs.existsSync(knowledgeDir)}`);
|
|
578
|
+
console.log(`[Install] targetKnowledgeDir: ${targetKnowledgeDir}`);
|
|
579
|
+
|
|
574
580
|
// Create target directory if not exists
|
|
575
581
|
if (!fs.existsSync(targetKnowledgeDir)) {
|
|
576
582
|
fs.mkdirSync(targetKnowledgeDir, { recursive: true });
|
|
@@ -580,6 +586,11 @@ export async function run(spec) {
|
|
|
580
586
|
const knowledgeSrc = path.join(knowledgeDir, "knowledge.yaml");
|
|
581
587
|
const knowledgeDest = path.join(targetKnowledgeDir, "knowledge.yaml");
|
|
582
588
|
|
|
589
|
+
console.log(`[Install] knowledgeSrc: ${knowledgeSrc}`);
|
|
590
|
+
console.log(`[Install] knowledgeSrc exists: ${fs.existsSync(knowledgeSrc)}`);
|
|
591
|
+
console.log(`[Install] knowledgeDest: ${knowledgeDest}`);
|
|
592
|
+
console.log(`[Install] knowledgeDest exists: ${fs.existsSync(knowledgeDest)}`);
|
|
593
|
+
|
|
583
594
|
if (fs.existsSync(knowledgeSrc) && !fs.existsSync(knowledgeDest)) {
|
|
584
595
|
fs.copyFileSync(knowledgeSrc, knowledgeDest);
|
|
585
596
|
step("Installed knowledge.yaml (4 default lessons)");
|
|
@@ -594,6 +605,8 @@ lessons: []
|
|
|
594
605
|
fs.writeFileSync(knowledgeDest, defaultKnowledge);
|
|
595
606
|
step("Created knowledge.yaml (Agent CLI ready)");
|
|
596
607
|
knowledgeInstalled = true;
|
|
608
|
+
} else {
|
|
609
|
+
console.log(`[Install] knowledge.yaml already exists at destination, skipping copy`);
|
|
597
610
|
}
|
|
598
611
|
|
|
599
612
|
// Install config/ if it exists (required for skill configuration)
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Failure Learner v1.0
|
|
3
|
+
*
|
|
4
|
+
* Learns from terminal command failures and prevents recurring mistakes.
|
|
5
|
+
* Part of PikaKit AutoLearn system.
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
* @author PikaKit
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { addLesson, loadKnowledge } from './knowledge.js';
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// KNOWN COMMAND FAILURE PATTERNS
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Pre-defined patterns for common command failures
|
|
21
|
+
* These are learned from real-world agent execution errors
|
|
22
|
+
*/
|
|
23
|
+
const COMMAND_PATTERNS = [
|
|
24
|
+
{
|
|
25
|
+
id: 'CMD-001',
|
|
26
|
+
match: /&& is not a valid statement separator/i,
|
|
27
|
+
shell: 'powershell',
|
|
28
|
+
message: 'PowerShell không hỗ trợ &&. Dùng ; hoặc chạy lệnh riêng biệt.',
|
|
29
|
+
fix: 'Replace && with ; or run commands separately',
|
|
30
|
+
severity: 'ERROR'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'CMD-002',
|
|
34
|
+
match: /pre-commit.*hook.*(failed|exit|error)/i,
|
|
35
|
+
shell: 'all',
|
|
36
|
+
message: 'Pre-commit hook failed. Thử dùng --no-verify flag.',
|
|
37
|
+
fix: 'git commit --no-verify -m "message"',
|
|
38
|
+
severity: 'WARNING'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'CMD-003',
|
|
42
|
+
match: /ENOENT.*npm|npm.*not found/i,
|
|
43
|
+
shell: 'all',
|
|
44
|
+
message: 'npm không tìm thấy. Chạy npm install trước.',
|
|
45
|
+
fix: 'Run npm install first',
|
|
46
|
+
severity: 'ERROR'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'CMD-004',
|
|
50
|
+
match: /Cannot find module/i,
|
|
51
|
+
shell: 'all',
|
|
52
|
+
message: 'Module không tìm thấy. Kiểm tra dependencies.',
|
|
53
|
+
fix: 'Run npm install or check import path',
|
|
54
|
+
severity: 'ERROR'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'CMD-005',
|
|
58
|
+
match: /permission denied/i,
|
|
59
|
+
shell: 'all',
|
|
60
|
+
message: 'Permission denied. Cần quyền admin hoặc sudo.',
|
|
61
|
+
fix: 'Run with elevated permissions',
|
|
62
|
+
severity: 'ERROR'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'CMD-006',
|
|
66
|
+
match: /EADDRINUSE.*port/i,
|
|
67
|
+
shell: 'all',
|
|
68
|
+
message: 'Port đang được sử dụng bởi process khác.',
|
|
69
|
+
fix: 'Kill existing process or use different port',
|
|
70
|
+
severity: 'ERROR'
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'CMD-007',
|
|
74
|
+
match: /fatal: not a git repository/i,
|
|
75
|
+
shell: 'all',
|
|
76
|
+
message: 'Không phải git repository. Cần git init trước.',
|
|
77
|
+
fix: 'Run git init or navigate to correct directory',
|
|
78
|
+
severity: 'ERROR'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'CMD-008',
|
|
82
|
+
match: /npm ERR! code ERESOLVE/i,
|
|
83
|
+
shell: 'all',
|
|
84
|
+
message: 'Dependency conflict. Thử --legacy-peer-deps.',
|
|
85
|
+
fix: 'npm install --legacy-peer-deps',
|
|
86
|
+
severity: 'WARNING'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'CMD-009',
|
|
90
|
+
match: /the term .* is not recognized/i,
|
|
91
|
+
shell: 'powershell',
|
|
92
|
+
message: 'Command không được nhận dạng trong PowerShell.',
|
|
93
|
+
fix: 'Check command name or install required tool',
|
|
94
|
+
severity: 'ERROR'
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: 'CMD-010',
|
|
98
|
+
match: /TypeError|ReferenceError|SyntaxError/i,
|
|
99
|
+
shell: 'all',
|
|
100
|
+
message: 'JavaScript runtime error.',
|
|
101
|
+
fix: 'Check code syntax and variable definitions',
|
|
102
|
+
severity: 'ERROR'
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// CORE FUNCTIONS
|
|
108
|
+
// ============================================================================
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Analyze command output for failure patterns
|
|
112
|
+
* @param {string} command - The command that was executed
|
|
113
|
+
* @param {string} output - The command output/error message
|
|
114
|
+
* @param {number} exitCode - Command exit code
|
|
115
|
+
* @param {string} shell - Shell type (powershell, bash, cmd)
|
|
116
|
+
* @returns {Object|null} - Matched pattern with suggestion, or null
|
|
117
|
+
*/
|
|
118
|
+
export function analyzeFailure(command, output, exitCode, shell = 'powershell') {
|
|
119
|
+
// Only analyze failures (non-zero exit code)
|
|
120
|
+
if (exitCode === 0) return null;
|
|
121
|
+
|
|
122
|
+
const outputLower = (output || '').toLowerCase();
|
|
123
|
+
const commandLower = (command || '').toLowerCase();
|
|
124
|
+
|
|
125
|
+
for (const pattern of COMMAND_PATTERNS) {
|
|
126
|
+
// Check if pattern applies to this shell
|
|
127
|
+
if (pattern.shell !== 'all' && pattern.shell !== shell) continue;
|
|
128
|
+
|
|
129
|
+
// Test against output
|
|
130
|
+
if (pattern.match.test(output)) {
|
|
131
|
+
return {
|
|
132
|
+
patternId: pattern.id,
|
|
133
|
+
command,
|
|
134
|
+
shell,
|
|
135
|
+
message: pattern.message,
|
|
136
|
+
fix: pattern.fix,
|
|
137
|
+
severity: pattern.severity,
|
|
138
|
+
matchedPattern: pattern.match.toString()
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Learn from a command failure and save to knowledge base
|
|
148
|
+
* @param {string} command - The failed command
|
|
149
|
+
* @param {string} output - Error output
|
|
150
|
+
* @param {number} exitCode - Exit code
|
|
151
|
+
* @param {string} shell - Shell type
|
|
152
|
+
* @returns {boolean} - True if lesson was learned/matched
|
|
153
|
+
*/
|
|
154
|
+
export function learnFromFailure(command, output, exitCode, shell = 'powershell') {
|
|
155
|
+
const analysis = analyzeFailure(command, output, exitCode, shell);
|
|
156
|
+
|
|
157
|
+
if (!analysis) {
|
|
158
|
+
// Unknown pattern - could add to pending for review
|
|
159
|
+
console.log('[CommandLearner] Unknown failure pattern, no lesson available');
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
console.log(`[CommandLearner] Detected: ${analysis.patternId}`);
|
|
164
|
+
console.log(`[CommandLearner] Fix: ${analysis.fix}`);
|
|
165
|
+
|
|
166
|
+
// Check if already in knowledge base
|
|
167
|
+
const knowledge = loadKnowledge();
|
|
168
|
+
const existing = knowledge.lessons.find(l => l.id === analysis.patternId);
|
|
169
|
+
|
|
170
|
+
if (existing) {
|
|
171
|
+
console.log(`[CommandLearner] Pattern ${analysis.patternId} already known`);
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Add as new lesson
|
|
176
|
+
const lesson = {
|
|
177
|
+
id: analysis.patternId,
|
|
178
|
+
type: 'command',
|
|
179
|
+
shell: analysis.shell,
|
|
180
|
+
pattern: analysis.matchedPattern,
|
|
181
|
+
message: analysis.message,
|
|
182
|
+
severity: analysis.severity,
|
|
183
|
+
intent: 'prevent',
|
|
184
|
+
confidence: 0.9,
|
|
185
|
+
maturity: 'stable',
|
|
186
|
+
hitCount: 1,
|
|
187
|
+
lastHit: new Date().toISOString(),
|
|
188
|
+
excludePaths: [],
|
|
189
|
+
tags: ['command', 'shell', analysis.shell],
|
|
190
|
+
autoFix: { suggestion: analysis.fix }
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const added = addLesson(lesson);
|
|
194
|
+
if (added) {
|
|
195
|
+
console.log(`[CommandLearner] Learned new pattern: ${analysis.patternId}`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get suggestion for a command before execution
|
|
203
|
+
* Checks if command matches any known failure patterns
|
|
204
|
+
* @param {string} command - Command to check
|
|
205
|
+
* @param {string} shell - Target shell
|
|
206
|
+
* @returns {Object|null} - Warning if pattern detected
|
|
207
|
+
*/
|
|
208
|
+
export function checkCommandBeforeExec(command, shell = 'powershell') {
|
|
209
|
+
// Pre-execution checks
|
|
210
|
+
if (shell === 'powershell' && command.includes('&&')) {
|
|
211
|
+
return {
|
|
212
|
+
warning: true,
|
|
213
|
+
patternId: 'CMD-001',
|
|
214
|
+
message: 'PowerShell không hỗ trợ &&. Dùng ; thay thế.',
|
|
215
|
+
suggestedCommand: command.replace(/\s*&&\s*/g, '; ')
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get all known command patterns
|
|
224
|
+
* @returns {Array} - Array of patterns
|
|
225
|
+
*/
|
|
226
|
+
export function getKnownPatterns() {
|
|
227
|
+
return COMMAND_PATTERNS.map(p => ({
|
|
228
|
+
id: p.id,
|
|
229
|
+
shell: p.shell,
|
|
230
|
+
message: p.message,
|
|
231
|
+
severity: p.severity
|
|
232
|
+
}));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Get pattern count
|
|
237
|
+
* @returns {number}
|
|
238
|
+
*/
|
|
239
|
+
export function getPatternCount() {
|
|
240
|
+
return COMMAND_PATTERNS.length;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ============================================================================
|
|
244
|
+
// EXPORTS
|
|
245
|
+
// ============================================================================
|
|
246
|
+
|
|
247
|
+
export default {
|
|
248
|
+
analyzeFailure,
|
|
249
|
+
learnFromFailure,
|
|
250
|
+
checkCommandBeforeExec,
|
|
251
|
+
getKnownPatterns,
|
|
252
|
+
getPatternCount,
|
|
253
|
+
COMMAND_PATTERNS
|
|
254
|
+
};
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { getKPIs, getMetricValue, getMetricHistory } from './metrics-collector.js';
|
|
12
|
-
import { loadKnowledge } from './knowledge.js';
|
|
12
|
+
import { loadKnowledge, getCommandLessons } from './knowledge.js';
|
|
13
|
+
import { getPatternCount } from './command-failure-learner.js';
|
|
13
14
|
|
|
14
15
|
// ============================================================================
|
|
15
16
|
// DASHBOARD DATA AGGREGATION
|
|
@@ -24,15 +25,19 @@ export function getFullDashboardData() {
|
|
|
24
25
|
const kpis = getKPIs();
|
|
25
26
|
const knowledge = loadKnowledge();
|
|
26
27
|
const lessons = knowledge.lessons || [];
|
|
28
|
+
const commandLessons = getCommandLessons();
|
|
29
|
+
const commandPatternCount = getPatternCount();
|
|
27
30
|
|
|
28
31
|
return {
|
|
29
|
-
version: '7.
|
|
32
|
+
version: '7.1.0',
|
|
30
33
|
timestamp: new Date().toISOString(),
|
|
31
34
|
kpis,
|
|
32
35
|
summary: {
|
|
33
36
|
totalTasks: getMetricValue('total_tasks') || 0,
|
|
34
37
|
patternsLearned: lessons.length,
|
|
35
38
|
lessonsCount: lessons.length,
|
|
39
|
+
commandPatterns: commandPatternCount,
|
|
40
|
+
commandLessonsLearned: commandLessons.length,
|
|
36
41
|
skillsGenerated: 0,
|
|
37
42
|
abTestsActive: 0
|
|
38
43
|
},
|
|
@@ -32,8 +32,9 @@ const LEGACY_FILES = {
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @typedef {Object} Lesson
|
|
35
|
-
* @property {string} id - Unique identifier (LESSON-XXX)
|
|
36
|
-
* @property {string} type - Type: 'mistake' | 'improvement' | 'pattern'
|
|
35
|
+
* @property {string} id - Unique identifier (LESSON-XXX or CMD-XXX)
|
|
36
|
+
* @property {string} type - Type: 'mistake' | 'improvement' | 'pattern' | 'command'
|
|
37
|
+
* @property {string} [shell] - Shell type for command lessons: 'powershell' | 'bash' | 'all'
|
|
37
38
|
* @property {string} pattern - Regex pattern to match
|
|
38
39
|
* @property {string} message - Human-readable explanation
|
|
39
40
|
* @property {string} severity - 'ERROR' | 'WARNING' | 'INFO'
|
|
@@ -283,7 +284,7 @@ export function removeLesson(id) {
|
|
|
283
284
|
|
|
284
285
|
/**
|
|
285
286
|
* Get lessons by type
|
|
286
|
-
* @param {'mistake' | 'improvement' | 'pattern'} type
|
|
287
|
+
* @param {'mistake' | 'improvement' | 'pattern' | 'command'} type
|
|
287
288
|
* @returns {Lesson[]}
|
|
288
289
|
*/
|
|
289
290
|
export function getLessonsByType(type) {
|
|
@@ -291,6 +292,20 @@ export function getLessonsByType(type) {
|
|
|
291
292
|
return knowledge.lessons.filter(l => l.type === type);
|
|
292
293
|
}
|
|
293
294
|
|
|
295
|
+
/**
|
|
296
|
+
* Get command-type lessons (for Command Failure Learner)
|
|
297
|
+
* @param {string} [shell] - Optional filter by shell type
|
|
298
|
+
* @returns {Lesson[]}
|
|
299
|
+
*/
|
|
300
|
+
export function getCommandLessons(shell = null) {
|
|
301
|
+
const knowledge = loadKnowledge();
|
|
302
|
+
return knowledge.lessons.filter(l => {
|
|
303
|
+
if (l.type !== 'command') return false;
|
|
304
|
+
if (shell && l.shell !== shell && l.shell !== 'all') return false;
|
|
305
|
+
return true;
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
294
309
|
/**
|
|
295
310
|
* Get total lesson count
|
|
296
311
|
* @returns {number}
|
|
@@ -336,6 +351,7 @@ export default {
|
|
|
336
351
|
updateLesson,
|
|
337
352
|
removeLesson,
|
|
338
353
|
getLessonsByType,
|
|
354
|
+
getCommandLessons,
|
|
339
355
|
getLessonCount,
|
|
340
356
|
recordHit,
|
|
341
357
|
createEmptyKnowledge,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pikakit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.38",
|
|
4
4
|
"description": "Enterprise-grade Agent Skill Manager with Antigravity Skills support, Progressive Disclosure detection, and semantic routing validation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "pikakit <pikakit@gmail.com>",
|