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.
@@ -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(" Remove skill(s) (interactive)"));
81
- step(c.cyan("uninstall all") + c.dim(" Remove everything (automatic)"));
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
- step(c.cyan("init") + c.dim(" Initialize skills directory"));
87
- step(c.cyan("validate [skill]") + c.dim(" Validate against Antigravity spec"));
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 (!isCancel(executeCmd) && executeCmd !== "none") {
117
+ if (isCancel(executeCmd) || executeCmd === "none") {
118
+ return;
119
+ }
120
+
121
+ // Handle advanced submenu
122
+ if (executeCmd === "advanced") {
109
123
  stepLine();
110
- step(c.cyan(`Running: kit ${executeCmd}`));
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(`./${executeCmd}.js`);
146
+ const commandModule = await import(`./${advCmd}.js`);
116
147
  await commandModule.run();
117
148
  } catch (err) {
118
- step(c.red(`Command not yet implemented: ${executeCmd}`));
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.19",
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();