pikakit 1.0.19 → 1.0.21
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/bin/lib/commands/help.js +57 -13
- package/package.json +1 -1
- package/lib/agent-cli/lib/migrate-to-v4.js +0 -322
package/bin/lib/commands/help.js
CHANGED
|
@@ -76,47 +76,91 @@ async function showCommands() {
|
|
|
76
76
|
step(c.dim("Example: kit pikakit/agent-skills#react-patterns"));
|
|
77
77
|
stepLine();
|
|
78
78
|
|
|
79
|
+
// Basic Commands (Essential)
|
|
80
|
+
step(c.bold(c.green("Essential Commands")));
|
|
79
81
|
step(c.cyan("list") + c.dim(" List installed skills"));
|
|
80
|
-
step(c.cyan("uninstall") + c.dim("
|
|
81
|
-
step(c.cyan("
|
|
82
|
+
step(c.cyan("uninstall") + c.dim(" Remove skill(s) (interactive)"));
|
|
83
|
+
step(c.cyan("init") + c.dim(" Initialize skills directory"));
|
|
84
|
+
stepLine();
|
|
85
|
+
|
|
86
|
+
// Advanced Commands (collapsed by default)
|
|
87
|
+
step(c.bold(c.yellow("Advanced Commands")));
|
|
82
88
|
step(c.cyan("update <skill>") + c.dim(" Update a skill"));
|
|
83
89
|
step(c.cyan("verify") + c.dim(" Verify checksums"));
|
|
84
90
|
step(c.cyan("doctor") + c.dim(" Check health"));
|
|
85
91
|
step(c.cyan("lock") + c.dim(" Generate skill-lock.json"));
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
stepLine();
|
|
93
|
+
|
|
94
|
+
// Developer Commands
|
|
95
|
+
step(c.bold(c.magenta("Developer Commands")));
|
|
96
|
+
step(c.cyan("validate [skill]") + c.dim(" Validate against spec"));
|
|
88
97
|
step(c.cyan("analyze <skill>") + c.dim(" Analyze skill structure"));
|
|
89
98
|
step(c.cyan("cache [info|clear]") + c.dim(" Manage cache"));
|
|
90
99
|
step(c.cyan("info <skill>") + c.dim(" Show skill info"));
|
|
91
100
|
|
|
92
101
|
stepLine();
|
|
93
102
|
|
|
94
|
-
// Interactive command selection
|
|
103
|
+
// Interactive command selection - only essential commands
|
|
95
104
|
const executeCmd = await select({
|
|
96
105
|
message: "Execute a command?",
|
|
97
106
|
options: [
|
|
107
|
+
// Essential (most used)
|
|
98
108
|
{ value: "list", label: "list", hint: "List installed skills" },
|
|
99
|
-
{ value: "doctor", label: "doctor", hint: "Check health" },
|
|
100
|
-
{ value: "verify", label: "verify", hint: "Verify checksums" },
|
|
101
109
|
{ value: "uninstall", label: "uninstall", hint: "Interactive removal" },
|
|
102
|
-
{ value: "lock", label: "lock", hint: "Generate lockfile" },
|
|
103
110
|
{ value: "init", label: "init", hint: "Initialize directory" },
|
|
111
|
+
// Separator
|
|
112
|
+
{ value: "advanced", label: "→ Show advanced...", hint: "More options" },
|
|
104
113
|
{ value: "none", label: "← Back", hint: "Return to topics" }
|
|
105
114
|
]
|
|
106
115
|
});
|
|
107
116
|
|
|
108
|
-
if (
|
|
117
|
+
if (isCancel(executeCmd) || executeCmd === "none") {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Handle advanced submenu
|
|
122
|
+
if (executeCmd === "advanced") {
|
|
109
123
|
stepLine();
|
|
110
|
-
|
|
124
|
+
const advCmd = await select({
|
|
125
|
+
message: "Advanced commands",
|
|
126
|
+
options: [
|
|
127
|
+
{ value: "doctor", label: "doctor", hint: "Check health" },
|
|
128
|
+
{ value: "verify", label: "verify", hint: "Verify checksums" },
|
|
129
|
+
{ value: "lock", label: "lock", hint: "Generate lockfile" },
|
|
130
|
+
{ value: "validate", label: "validate", hint: "Validate skill" },
|
|
131
|
+
{ value: "analyze", label: "analyze", hint: "Analyze structure" },
|
|
132
|
+
{ value: "cache", label: "cache", hint: "Manage cache" },
|
|
133
|
+
{ value: "none", label: "← Back", hint: "Return" }
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (isCancel(advCmd) || advCmd === "none") {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
stepLine();
|
|
142
|
+
step(c.cyan(`Running: kit ${advCmd}`));
|
|
111
143
|
stepLine();
|
|
112
144
|
|
|
113
|
-
// Dynamic import and execute command
|
|
114
145
|
try {
|
|
115
|
-
const commandModule = await import(`./${
|
|
146
|
+
const commandModule = await import(`./${advCmd}.js`);
|
|
116
147
|
await commandModule.run();
|
|
117
148
|
} catch (err) {
|
|
118
|
-
step(c.red(`Command not yet implemented: ${
|
|
149
|
+
step(c.red(`Command not yet implemented: ${advCmd}`));
|
|
119
150
|
}
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
stepLine();
|
|
155
|
+
step(c.cyan(`Running: kit ${executeCmd}`));
|
|
156
|
+
stepLine();
|
|
157
|
+
|
|
158
|
+
// Dynamic import and execute command
|
|
159
|
+
try {
|
|
160
|
+
const commandModule = await import(`./${executeCmd}.js`);
|
|
161
|
+
await commandModule.run();
|
|
162
|
+
} catch (err) {
|
|
163
|
+
step(c.red(`Command not yet implemented: ${executeCmd}`));
|
|
120
164
|
}
|
|
121
165
|
}
|
|
122
166
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pikakit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
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>",
|
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Migration Script: v3.x → v4.x Cognitive Lesson Engine
|
|
4
|
-
*
|
|
5
|
-
* This script:
|
|
6
|
-
* 1. Backs up current lessons-learned.yaml
|
|
7
|
-
* 2. Classifies lessons into mistakes vs improvements
|
|
8
|
-
* 3. Generates mistakes.yaml and improvements.yaml
|
|
9
|
-
* 4. Preserves all existing data
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import fs from 'fs';
|
|
13
|
-
import path from 'path';
|
|
14
|
-
import yaml from 'js-yaml';
|
|
15
|
-
import { fileURLToPath } from 'url';
|
|
16
|
-
|
|
17
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
const PROJECT_ROOT = path.join(__dirname, '../../..');
|
|
19
|
-
const KNOWLEDGE_DIR = path.join(PROJECT_ROOT, '.agent/knowledge');
|
|
20
|
-
const LESSONS_PATH = path.join(KNOWLEDGE_DIR, 'lessons-learned.yaml');
|
|
21
|
-
const BACKUP_DIR = path.join(KNOWLEDGE_DIR, '_migration_backup');
|
|
22
|
-
const MISTAKES_PATH = path.join(KNOWLEDGE_DIR, 'mistakes.yaml');
|
|
23
|
-
const IMPROVEMENTS_PATH = path.join(KNOWLEDGE_DIR, 'improvements.yaml');
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// STEP 1: Backup Current Data
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
function backupCurrentLessons() {
|
|
30
|
-
console.log('📦 Step 1: Backing up current lessons...');
|
|
31
|
-
|
|
32
|
-
if (!fs.existsSync(LESSONS_PATH)) {
|
|
33
|
-
console.log('⚠️ No lessons-learned.yaml found, skipping backup');
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Create backup directory
|
|
38
|
-
fs.mkdirSync(BACKUP_DIR, { recursive: true });
|
|
39
|
-
|
|
40
|
-
// Backup with timestamp
|
|
41
|
-
const timestamp = new Date().toISOString().replace(/:/g, '-');
|
|
42
|
-
const backupPath = path.join(BACKUP_DIR, `lessons-learned_${timestamp}.yaml`);
|
|
43
|
-
|
|
44
|
-
fs.copyFileSync(LESSONS_PATH, backupPath);
|
|
45
|
-
console.log(`✅ Backup created: ${backupPath}`);
|
|
46
|
-
|
|
47
|
-
// Load and return data
|
|
48
|
-
const content = fs.readFileSync(LESSONS_PATH, 'utf8');
|
|
49
|
-
return yaml.load(content);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// ============================================================================
|
|
53
|
-
// STEP 2: Classification Logic
|
|
54
|
-
// ============================================================================
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Auto-classify lesson as mistake or improvement
|
|
58
|
-
* Conservative: default to mistake (safer assumption)
|
|
59
|
-
*/
|
|
60
|
-
function classifyLesson(lesson) {
|
|
61
|
-
const message = lesson.message.toLowerCase();
|
|
62
|
-
|
|
63
|
-
// Keywords that indicate improvement/best practice
|
|
64
|
-
const improvementKeywords = [
|
|
65
|
-
'use ', 'always use', 'prefer ', 'should use',
|
|
66
|
-
'best practice', 'recommended', 'instead use',
|
|
67
|
-
'better to', 'proper way', 'correct approach'
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
// Keywords that indicate mistake/anti-pattern
|
|
71
|
-
const mistakeKeywords = [
|
|
72
|
-
'never', 'avoid', 'don\'t', 'do not', 'incorrect',
|
|
73
|
-
'wrong', 'bad', 'conflicts', 'causes', 'breaks'
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
const hasMistakeKeyword = mistakeKeywords.some(kw => message.includes(kw));
|
|
77
|
-
const hasImprovementKeyword = improvementKeywords.some(kw => message.includes(kw));
|
|
78
|
-
|
|
79
|
-
// Both keywords present - need manual review
|
|
80
|
-
if (hasMistakeKeyword && hasImprovementKeyword) {
|
|
81
|
-
return 'mixed';
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Clear improvement
|
|
85
|
-
if (hasImprovementKeyword && !hasMistakeKeyword) {
|
|
86
|
-
return 'improvement';
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Default: mistake (conservative)
|
|
90
|
-
return 'mistake';
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Extract tags from lesson data
|
|
95
|
-
* Tags used for grouping into Cognitive Lessons
|
|
96
|
-
*/
|
|
97
|
-
function extractTags(lesson) {
|
|
98
|
-
const tags = new Set();
|
|
99
|
-
|
|
100
|
-
// Add category as tag
|
|
101
|
-
if (lesson.category) {
|
|
102
|
-
tags.add(lesson.category);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Extract from pattern
|
|
106
|
-
const pattern = lesson.pattern.toLowerCase();
|
|
107
|
-
if (pattern.includes('select')) tags.add('cli-navigation');
|
|
108
|
-
if (pattern.includes('menu')) tags.add('ux');
|
|
109
|
-
if (pattern.includes('rename') || pattern.includes('move') || pattern.includes('rebrand')) {
|
|
110
|
-
tags.add('file-safety');
|
|
111
|
-
tags.add('rebranding');
|
|
112
|
-
}
|
|
113
|
-
if (pattern.includes('import')) tags.add('imports');
|
|
114
|
-
if (pattern.includes('recursive')) tags.add('architecture');
|
|
115
|
-
|
|
116
|
-
// Extract from message
|
|
117
|
-
const message = lesson.message.toLowerCase();
|
|
118
|
-
if (message.includes('esc')) tags.add('cli-navigation');
|
|
119
|
-
if (message.includes('clack')) tags.add('clack-framework');
|
|
120
|
-
if (message.includes('menu')) tags.add('ux');
|
|
121
|
-
if (message.includes('security')) tags.add('security');
|
|
122
|
-
if (message.includes('performance')) tags.add('performance');
|
|
123
|
-
|
|
124
|
-
return Array.from(tags);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Split mixed lessons into mistake + improvement
|
|
129
|
-
*/
|
|
130
|
-
function splitMixedLesson(lesson) {
|
|
131
|
-
const message = lesson.message;
|
|
132
|
-
|
|
133
|
-
// Try to extract both parts
|
|
134
|
-
// Pattern: "NEVER X. Use Y instead"
|
|
135
|
-
const neverMatch = message.match(/(NEVER|Don't|Avoid)\s+([^.]+)\./i);
|
|
136
|
-
const useMatch = message.match(/(Use|Always use|Instead use)\s+([^.]+)/i);
|
|
137
|
-
|
|
138
|
-
const mistake = {
|
|
139
|
-
...lesson,
|
|
140
|
-
id: lesson.id.replace('LEARN', 'MISTAKE'),
|
|
141
|
-
title: neverMatch ? neverMatch[0] : message.split('.')[0],
|
|
142
|
-
message: neverMatch ? neverMatch[0] : message.split('.')[0],
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
let improvement = null;
|
|
146
|
-
if (useMatch) {
|
|
147
|
-
improvement = {
|
|
148
|
-
id: lesson.id.replace('LEARN', 'IMPROVE'),
|
|
149
|
-
title: useMatch[0],
|
|
150
|
-
message: useMatch[0],
|
|
151
|
-
pattern: lesson.pattern,
|
|
152
|
-
priority: lesson.severity === 'ERROR' ? 'HIGH' : 'MEDIUM',
|
|
153
|
-
tags: extractTags(lesson),
|
|
154
|
-
added: lesson.addedAt,
|
|
155
|
-
appliedCount: 0,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return { mistake, improvement };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// ============================================================================
|
|
163
|
-
// STEP 3: Migration Logic
|
|
164
|
-
// ============================================================================
|
|
165
|
-
|
|
166
|
-
function migrateToV4(oldData) {
|
|
167
|
-
console.log('\n🔄 Step 2: Classifying lessons...');
|
|
168
|
-
|
|
169
|
-
const mistakes = [];
|
|
170
|
-
const improvements = [];
|
|
171
|
-
const needsReview = [];
|
|
172
|
-
|
|
173
|
-
oldData.lessons.forEach((lesson, index) => {
|
|
174
|
-
const classification = classifyLesson(lesson);
|
|
175
|
-
const tags = extractTags(lesson);
|
|
176
|
-
|
|
177
|
-
console.log(` ${lesson.id}: ${classification} (tags: ${tags.join(', ')})`);
|
|
178
|
-
|
|
179
|
-
if (classification === 'mistake') {
|
|
180
|
-
mistakes.push({
|
|
181
|
-
id: lesson.id.replace('LEARN', 'MISTAKE'),
|
|
182
|
-
title: lesson.message.split('.')[0], // First sentence as title
|
|
183
|
-
pattern: lesson.pattern,
|
|
184
|
-
message: lesson.message,
|
|
185
|
-
severity: lesson.severity,
|
|
186
|
-
tags,
|
|
187
|
-
context: lesson.category,
|
|
188
|
-
hitCount: lesson.hitCount || 0,
|
|
189
|
-
lastHit: lesson.lastHit,
|
|
190
|
-
added: lesson.addedAt,
|
|
191
|
-
source: lesson.source,
|
|
192
|
-
excludePaths: lesson.excludePaths || [],
|
|
193
|
-
});
|
|
194
|
-
} else if (classification === 'improvement') {
|
|
195
|
-
improvements.push({
|
|
196
|
-
id: lesson.id.replace('LEARN', 'IMPROVE'),
|
|
197
|
-
title: lesson.message.split('.')[0],
|
|
198
|
-
pattern: lesson.pattern,
|
|
199
|
-
message: lesson.message,
|
|
200
|
-
priority: lesson.severity === 'ERROR' ? 'HIGH' : 'MEDIUM',
|
|
201
|
-
tags,
|
|
202
|
-
added: lesson.addedAt,
|
|
203
|
-
appliedCount: lesson.hitCount || 0,
|
|
204
|
-
lastApplied: lesson.lastHit,
|
|
205
|
-
source: lesson.source,
|
|
206
|
-
});
|
|
207
|
-
} else {
|
|
208
|
-
// Mixed - split into both
|
|
209
|
-
const { mistake, improvement } = splitMixedLesson(lesson);
|
|
210
|
-
mistakes.push({
|
|
211
|
-
...mistake,
|
|
212
|
-
severity: lesson.severity,
|
|
213
|
-
tags,
|
|
214
|
-
hitCount: lesson.hitCount || 0,
|
|
215
|
-
lastHit: lesson.lastHit,
|
|
216
|
-
added: lesson.addedAt,
|
|
217
|
-
source: lesson.source,
|
|
218
|
-
excludePaths: lesson.excludePaths || [],
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
if (improvement) {
|
|
222
|
-
improvements.push({
|
|
223
|
-
...improvement,
|
|
224
|
-
source: lesson.source,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
needsReview.push({
|
|
229
|
-
...lesson,
|
|
230
|
-
reason: 'Mixed mistake + improvement keywords, auto-split but needs verification',
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
console.log(`\n✅ Classification complete:`);
|
|
236
|
-
console.log(` ${mistakes.length} mistakes`);
|
|
237
|
-
console.log(` ${improvements.length} improvements`);
|
|
238
|
-
console.log(` ${needsReview.length} need manual review`);
|
|
239
|
-
|
|
240
|
-
return { mistakes, improvements, needsReview };
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// ============================================================================
|
|
244
|
-
// STEP 4: Save New Files
|
|
245
|
-
// ============================================================================
|
|
246
|
-
|
|
247
|
-
function saveYAML(filename, data) {
|
|
248
|
-
const filepath = path.join(KNOWLEDGE_DIR, filename);
|
|
249
|
-
const yamlStr = yaml.dump(data, {
|
|
250
|
-
lineWidth: -1,
|
|
251
|
-
noRefs: true,
|
|
252
|
-
sortKeys: false,
|
|
253
|
-
});
|
|
254
|
-
fs.writeFileSync(filepath, yamlStr, 'utf8');
|
|
255
|
-
console.log(`✅ Created: ${filename}`);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function saveNewStructure(result) {
|
|
259
|
-
console.log('\n📝 Step 3: Creating new data files...');
|
|
260
|
-
|
|
261
|
-
// Save mistakes
|
|
262
|
-
saveYAML('mistakes.yaml', {
|
|
263
|
-
version: 4.0,
|
|
264
|
-
mistakes: result.mistakes,
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// Save improvements
|
|
268
|
-
saveYAML('improvements.yaml', {
|
|
269
|
-
version: 4.0,
|
|
270
|
-
improvements: result.improvements,
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
// Save review queue if needed
|
|
274
|
-
if (result.needsReview.length > 0) {
|
|
275
|
-
saveYAML('_needs_review.yaml', {
|
|
276
|
-
note: 'These lessons contained both mistake and improvement keywords and were auto-split. Please review.',
|
|
277
|
-
items: result.needsReview,
|
|
278
|
-
});
|
|
279
|
-
console.log(`⚠️ ${result.needsReview.length} items saved to _needs_review.yaml`);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// ============================================================================
|
|
284
|
-
// MAIN MIGRATION
|
|
285
|
-
// ============================================================================
|
|
286
|
-
|
|
287
|
-
async function main() {
|
|
288
|
-
console.log('🧠 Cognitive Lesson Engine v4.x Migration\n');
|
|
289
|
-
console.log('This script will transform your lessons into the new architecture.');
|
|
290
|
-
console.log('All existing data will be preserved in backups.\n');
|
|
291
|
-
|
|
292
|
-
try {
|
|
293
|
-
// Step 1: Backup
|
|
294
|
-
const oldData = backupCurrentLessons();
|
|
295
|
-
|
|
296
|
-
if (!oldData || !oldData.lessons || oldData.lessons.length === 0) {
|
|
297
|
-
console.log('❌ No lessons found to migrate.');
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// Step 2: Classify
|
|
302
|
-
const result = migrateToV4(oldData);
|
|
303
|
-
|
|
304
|
-
// Step 3: Save
|
|
305
|
-
saveNewStructure(result);
|
|
306
|
-
|
|
307
|
-
// Step 4: Summary
|
|
308
|
-
console.log('\n🎉 Migration complete!');
|
|
309
|
-
console.log('\nNext steps:');
|
|
310
|
-
console.log(' 1. Review _needs_review.yaml (if exists)');
|
|
311
|
-
console.log(' 2. Test with: node packages/cli/lib/ui/index.js');
|
|
312
|
-
console.log(' 3. Original file preserved in _migration_backup/');
|
|
313
|
-
console.log('\n✅ You can now use the Cognitive Lesson Engine!');
|
|
314
|
-
|
|
315
|
-
} catch (error) {
|
|
316
|
-
console.error('\n❌ Migration failed:', error.message);
|
|
317
|
-
console.error(error.stack);
|
|
318
|
-
process.exit(1);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
main();
|