add-skill-kit 3.2.4 → 3.2.6

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.
Files changed (78) hide show
  1. package/README.md +179 -119
  2. package/bin/lib/commands/help.js +0 -4
  3. package/bin/lib/commands/install.js +129 -9
  4. package/bin/lib/ui.js +1 -1
  5. package/lib/agent-cli/__tests__/adaptive_engine.test.js +190 -0
  6. package/lib/agent-cli/__tests__/integration/cross_script.test.js +222 -0
  7. package/lib/agent-cli/__tests__/integration/full_cycle.test.js +230 -0
  8. package/lib/agent-cli/__tests__/pattern_analyzer.test.js +173 -0
  9. package/lib/agent-cli/__tests__/pre_execution_check.test.js +167 -0
  10. package/lib/agent-cli/__tests__/skill_injector.test.js +191 -0
  11. package/lib/agent-cli/bin/{ag-smart.js → agent.js} +48 -15
  12. package/lib/agent-cli/dashboard/dashboard_server.js +340 -0
  13. package/lib/agent-cli/dashboard/index.html +538 -0
  14. package/lib/agent-cli/lib/audit.js +2 -2
  15. package/lib/agent-cli/lib/auto-learn.js +8 -8
  16. package/lib/agent-cli/lib/eslint-fix.js +1 -1
  17. package/lib/agent-cli/lib/fix.js +5 -5
  18. package/lib/agent-cli/lib/hooks/install-hooks.js +4 -4
  19. package/lib/agent-cli/lib/hooks/lint-learn.js +4 -4
  20. package/lib/agent-cli/lib/learn.js +10 -10
  21. package/lib/agent-cli/lib/recall.js +1 -1
  22. package/lib/agent-cli/lib/settings.js +24 -0
  23. package/lib/agent-cli/lib/skill-learn.js +2 -2
  24. package/lib/agent-cli/lib/stats.js +3 -3
  25. package/lib/agent-cli/lib/ui/dashboard-ui.js +103 -4
  26. package/lib/agent-cli/lib/ui/index.js +36 -6
  27. package/lib/agent-cli/lib/watcher.js +2 -2
  28. package/lib/agent-cli/package.json +4 -4
  29. package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
  30. package/lib/agent-cli/scripts/dashboard_server.js +224 -0
  31. package/lib/agent-cli/scripts/error_sensor.js +565 -0
  32. package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
  33. package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
  34. package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
  35. package/lib/agent-cli/scripts/rule_sharing.js +374 -0
  36. package/lib/agent-cli/scripts/skill_injector.js +387 -0
  37. package/lib/agent-cli/scripts/success_sensor.js +500 -0
  38. package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
  39. package/lib/agent-cli/services/auto-learn-service.js +247 -0
  40. package/lib/agent-cli/src/MIGRATION.md +418 -0
  41. package/lib/agent-cli/src/README.md +367 -0
  42. package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
  43. package/lib/agent-cli/src/core/evolution/index.js +17 -0
  44. package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
  45. package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
  46. package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
  47. package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
  48. package/lib/agent-cli/src/core/index.js +15 -0
  49. package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
  50. package/lib/agent-cli/src/core/learning/index.js +12 -0
  51. package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
  52. package/lib/agent-cli/src/core/scanning/index.js +14 -0
  53. package/lib/agent-cli/src/data/index.js +13 -0
  54. package/lib/agent-cli/src/data/repositories/index.js +8 -0
  55. package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
  56. package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
  57. package/lib/agent-cli/src/data/storage/index.js +8 -0
  58. package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
  59. package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
  60. package/lib/agent-cli/src/infrastructure/index.js +13 -0
  61. package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
  62. package/lib/agent-cli/src/services/export-service.js +162 -0
  63. package/lib/agent-cli/src/services/index.js +13 -0
  64. package/lib/agent-cli/src/services/learning-service.js +99 -0
  65. package/lib/agent-cli/types/index.d.ts +343 -0
  66. package/lib/agent-cli/utils/benchmark.js +269 -0
  67. package/lib/agent-cli/utils/logger.js +303 -0
  68. package/lib/agent-cli/utils/ml_patterns.js +300 -0
  69. package/lib/agent-cli/utils/recovery.js +312 -0
  70. package/lib/agent-cli/utils/telemetry.js +290 -0
  71. package/lib/agentskillskit-cli/ag-smart.js +15 -15
  72. package/lib/agentskillskit-cli/package.json +3 -3
  73. package/package.json +12 -6
  74. package/lib/agent-cli/lib/auto_preview.py +0 -148
  75. package/lib/agent-cli/lib/checklist.py +0 -222
  76. package/lib/agent-cli/lib/session_manager.py +0 -120
  77. package/lib/agent-cli/lib/verify_all.py +0 -327
  78. /package/bin/{cli.js → kit.js} +0 -0
@@ -0,0 +1,500 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Success Sensor - Detect successful patterns and best practices
4
+ *
5
+ * Part of FAANG-Grade Auto-Learn System
6
+ *
7
+ * Scans for:
8
+ * - Test successes (all tests pass)
9
+ * - Lint successes (no errors)
10
+ * - Build successes (compiled OK)
11
+ * - Code pattern successes (good practices)
12
+ *
13
+ * Usage:
14
+ * node success_sensor.js --scan all
15
+ * node success_sensor.js --scan test
16
+ * node success_sensor.js --stats
17
+ */
18
+
19
+ import fs from 'fs';
20
+ import path from 'path';
21
+ import { execSync } from 'child_process';
22
+ import { fileURLToPath } from 'url';
23
+
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = path.dirname(__filename);
26
+
27
+ // Colors
28
+ const c = {
29
+ reset: '\x1b[0m',
30
+ red: '\x1b[31m',
31
+ green: '\x1b[32m',
32
+ yellow: '\x1b[33m',
33
+ blue: '\x1b[34m',
34
+ cyan: '\x1b[36m',
35
+ gray: '\x1b[90m',
36
+ bold: '\x1b[1m'
37
+ };
38
+
39
+ // Find project root
40
+ function findProjectRoot() {
41
+ let current = process.cwd();
42
+ while (current !== path.dirname(current)) {
43
+ if (fs.existsSync(path.join(current, '.agent'))) {
44
+ return current;
45
+ }
46
+ current = path.dirname(current);
47
+ }
48
+ return process.cwd();
49
+ }
50
+
51
+ const projectRoot = findProjectRoot();
52
+ const knowledgePath = path.join(projectRoot, '.agent', 'knowledge');
53
+ const successesPath = path.join(knowledgePath, 'successes.json');
54
+
55
+ // Ensure knowledge directory exists
56
+ if (!fs.existsSync(knowledgePath)) {
57
+ fs.mkdirSync(knowledgePath, { recursive: true });
58
+ }
59
+
60
+ // Load existing successes
61
+ function loadSuccesses() {
62
+ try {
63
+ if (fs.existsSync(successesPath)) {
64
+ return JSON.parse(fs.readFileSync(successesPath, 'utf8'));
65
+ }
66
+ } catch { }
67
+ return { successes: [], totalSuccesses: 0, lastScan: null };
68
+ }
69
+
70
+ // Save successes
71
+ function saveSuccesses(data) {
72
+ data.lastScan = new Date().toISOString();
73
+ fs.writeFileSync(successesPath, JSON.stringify(data, null, 2));
74
+ }
75
+
76
+ // Generate success ID
77
+ function generateSuccessId(type) {
78
+ const data = loadSuccesses();
79
+ const count = data.successes.filter(s => s.type === type).length + 1;
80
+ return `SUCCESS-${type.toUpperCase()}-${String(count).padStart(3, '0')}`;
81
+ }
82
+
83
+ // ==================== CONTEXT DETECTION ====================
84
+
85
+ /**
86
+ * Detect project context
87
+ */
88
+ function detectProjectContext() {
89
+ const context = {
90
+ projectType: 'unknown',
91
+ framework: null,
92
+ language: 'javascript'
93
+ };
94
+
95
+ try {
96
+ const pkgPath = path.join(projectRoot, 'package.json');
97
+ if (fs.existsSync(pkgPath)) {
98
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
99
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
100
+
101
+ if (deps['next']) context.projectType = 'nextjs';
102
+ else if (deps['react-native'] || deps['expo']) context.projectType = 'react-native';
103
+ else if (deps['react']) context.projectType = 'react';
104
+ else if (deps['express']) context.projectType = 'backend';
105
+
106
+ if (deps['typescript']) context.language = 'typescript';
107
+ }
108
+ } catch { }
109
+
110
+ return context;
111
+ }
112
+
113
+ /**
114
+ * Detect file context
115
+ */
116
+ function detectFileContext(filePath) {
117
+ const ext = path.extname(filePath).toLowerCase();
118
+ const relativePath = path.relative(projectRoot, filePath);
119
+
120
+ return {
121
+ fileType: ext,
122
+ isTypeScript: ext === '.ts' || ext === '.tsx',
123
+ directory: relativePath.split(path.sep)[0] || 'root',
124
+ fullPath: relativePath
125
+ };
126
+ }
127
+
128
+ // ==================== SUCCESS SENSORS ====================
129
+
130
+ /**
131
+ * Scan for test successes
132
+ */
133
+ function scanTestSuccesses() {
134
+ const successes = [];
135
+
136
+ try {
137
+ // Try running tests
138
+ const output = execSync('npm test 2>&1', {
139
+ encoding: 'utf8',
140
+ timeout: 60000,
141
+ cwd: projectRoot
142
+ });
143
+
144
+ // Check for success indicators
145
+ const successPatterns = [
146
+ /(\d+) pass/i,
147
+ /all tests passed/i,
148
+ /tests?\s+passed/i,
149
+ /0 failed/i,
150
+ /✓.*(\d+) tests?/,
151
+ /PASS\s+/
152
+ ];
153
+
154
+ for (const pattern of successPatterns) {
155
+ const match = output.match(pattern);
156
+ if (match) {
157
+ successes.push({
158
+ id: generateSuccessId('test'),
159
+ type: 'test',
160
+ pattern: 'test-pass',
161
+ message: `Tests passed: ${match[0]}`,
162
+ source: 'npm test',
163
+ severity: 'SUCCESS',
164
+ detectedAt: new Date().toISOString()
165
+ });
166
+ break;
167
+ }
168
+ }
169
+ } catch (error) {
170
+ // Test failed or not configured - not a success
171
+ }
172
+
173
+ return successes;
174
+ }
175
+
176
+ /**
177
+ * Scan for lint successes
178
+ */
179
+ function scanLintSuccesses() {
180
+ const successes = [];
181
+
182
+ try {
183
+ // Try running lint
184
+ const output = execSync('npm run lint 2>&1', {
185
+ encoding: 'utf8',
186
+ timeout: 30000,
187
+ cwd: projectRoot
188
+ });
189
+
190
+ // Check for success indicators
191
+ const successPatterns = [
192
+ /0 errors/i,
193
+ /no issues found/i,
194
+ /no problems/i,
195
+ /all files pass/i,
196
+ /✓ no issues/i
197
+ ];
198
+
199
+ for (const pattern of successPatterns) {
200
+ if (pattern.test(output)) {
201
+ successes.push({
202
+ id: generateSuccessId('lint'),
203
+ type: 'lint',
204
+ pattern: 'lint-clean',
205
+ message: 'Lint passed with no errors',
206
+ source: 'npm run lint',
207
+ severity: 'SUCCESS',
208
+ detectedAt: new Date().toISOString()
209
+ });
210
+ break;
211
+ }
212
+ }
213
+
214
+ // Also count as success if no output (many linters silent on success)
215
+ if (output.trim() === '' || !output.includes('error')) {
216
+ successes.push({
217
+ id: generateSuccessId('lint'),
218
+ type: 'lint',
219
+ pattern: 'lint-clean',
220
+ message: 'Lint passed (no output = clean)',
221
+ source: 'npm run lint',
222
+ severity: 'SUCCESS',
223
+ detectedAt: new Date().toISOString()
224
+ });
225
+ }
226
+ } catch (error) {
227
+ // Lint failed or not configured - not a success
228
+ }
229
+
230
+ return successes;
231
+ }
232
+
233
+ /**
234
+ * Scan for code pattern successes
235
+ */
236
+ function scanCodePatternSuccesses() {
237
+ const successes = [];
238
+
239
+ // Good patterns to detect
240
+ const goodPatterns = [
241
+ {
242
+ name: 'proper-error-handling',
243
+ pattern: /try\s*\{[\s\S]*?\}\s*catch\s*\([^)]+\)\s*\{[\s\S]*?console\.(error|log)|throw/,
244
+ message: 'Proper try-catch with error logging/re-throw',
245
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
246
+ },
247
+ {
248
+ name: 'typescript-types',
249
+ pattern: /:\s*(string|number|boolean|object|\w+\[\]|Promise<|React\.FC|void)/,
250
+ message: 'TypeScript type annotations used',
251
+ fileTypes: ['.ts', '.tsx']
252
+ },
253
+ {
254
+ name: 'async-await',
255
+ pattern: /async\s+function|\basync\s+\(|await\s+/,
256
+ message: 'Modern async/await pattern used',
257
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
258
+ },
259
+ {
260
+ name: 'destructuring',
261
+ pattern: /const\s+\{[^}]+\}\s*=|const\s+\[[^\]]+\]\s*=/,
262
+ message: 'Modern destructuring used',
263
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
264
+ },
265
+ {
266
+ name: 'optional-chaining',
267
+ pattern: /\?\.\w+|\?\.\[/,
268
+ message: 'Optional chaining (?.) used for null safety',
269
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
270
+ },
271
+ {
272
+ name: 'nullish-coalescing',
273
+ pattern: /\?\?/,
274
+ message: 'Nullish coalescing (??) used',
275
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
276
+ },
277
+ {
278
+ name: 'es6-exports',
279
+ pattern: /^export\s+(default\s+)?(function|class|const|let|var|async)/m,
280
+ message: 'ES6 module exports used',
281
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
282
+ },
283
+ {
284
+ name: 'jsdoc-comments',
285
+ pattern: /\/\*\*[\s\S]*?@(param|returns|type|description)/,
286
+ message: 'JSDoc documentation present',
287
+ fileTypes: ['.js', '.ts', '.jsx', '.tsx']
288
+ }
289
+ ];
290
+
291
+ // Scan source files
292
+ const srcDirs = ['src', 'lib', 'bin', 'scripts'];
293
+ const scannedFiles = new Set();
294
+
295
+ for (const dir of srcDirs) {
296
+ const dirPath = path.join(projectRoot, dir);
297
+ if (!fs.existsSync(dirPath)) continue;
298
+
299
+ scanDirectory(dirPath, (filePath) => {
300
+ if (scannedFiles.has(filePath)) return;
301
+ scannedFiles.add(filePath);
302
+
303
+ const ext = path.extname(filePath);
304
+ const content = fs.readFileSync(filePath, 'utf8');
305
+
306
+ for (const gp of goodPatterns) {
307
+ if (!gp.fileTypes.includes(ext)) continue;
308
+
309
+ const matches = content.match(new RegExp(gp.pattern, 'g'));
310
+ if (matches && matches.length > 0) {
311
+ // Only add if significant (at least 2 occurrences or important pattern)
312
+ if (matches.length >= 2 || ['typescript-types', 'jsdoc-comments'].includes(gp.name)) {
313
+ successes.push({
314
+ id: generateSuccessId('pattern'),
315
+ type: 'pattern',
316
+ pattern: gp.name,
317
+ message: `${gp.message} (${matches.length}x)`,
318
+ file: path.relative(projectRoot, filePath),
319
+ count: matches.length,
320
+ severity: 'SUCCESS',
321
+ detectedAt: new Date().toISOString()
322
+ });
323
+ }
324
+ }
325
+ }
326
+ });
327
+ }
328
+
329
+ return successes;
330
+ }
331
+
332
+ /**
333
+ * Helper: Scan directory recursively
334
+ */
335
+ function scanDirectory(dir, callback) {
336
+ const items = fs.readdirSync(dir);
337
+
338
+ for (const item of items) {
339
+ if (item.startsWith('.') || item === 'node_modules') continue;
340
+
341
+ const fullPath = path.join(dir, item);
342
+ const stat = fs.statSync(fullPath);
343
+
344
+ if (stat.isDirectory()) {
345
+ scanDirectory(fullPath, callback);
346
+ } else if (stat.isFile()) {
347
+ callback(fullPath);
348
+ }
349
+ }
350
+ }
351
+
352
+ // ==================== DEDUPLICATION ====================
353
+
354
+ function deduplicateSuccesses(newSuccesses, existingSuccesses) {
355
+ const added = [];
356
+
357
+ for (const newS of newSuccesses) {
358
+ // Check if similar success exists
359
+ const exists = existingSuccesses.some(existing =>
360
+ existing.type === newS.type &&
361
+ existing.pattern === newS.pattern &&
362
+ existing.file === newS.file
363
+ );
364
+
365
+ if (!exists) {
366
+ added.push(newS);
367
+ } else {
368
+ // Update hit count for existing
369
+ const existing = existingSuccesses.find(e =>
370
+ e.type === newS.type && e.pattern === newS.pattern && e.file === newS.file
371
+ );
372
+ if (existing) {
373
+ existing.hitCount = (existing.hitCount || 1) + 1;
374
+ existing.lastHit = new Date().toISOString();
375
+ }
376
+ }
377
+ }
378
+
379
+ return added;
380
+ }
381
+
382
+ // ==================== MAIN ====================
383
+
384
+ function runScan(type) {
385
+ console.log(`${c.green}🎯 Success Sensor - Scanning ${type}...${c.reset}\n`);
386
+
387
+ let newSuccesses = [];
388
+
389
+ if (type === 'all' || type === 'test') {
390
+ console.log(` ${c.cyan}Scanning test results...${c.reset}`);
391
+ const testSuccesses = scanTestSuccesses();
392
+ console.log(` Found ${testSuccesses.length} test successes`);
393
+ newSuccesses = newSuccesses.concat(testSuccesses);
394
+ }
395
+
396
+ if (type === 'all' || type === 'lint') {
397
+ console.log(` ${c.cyan}Scanning lint results...${c.reset}`);
398
+ const lintSuccesses = scanLintSuccesses();
399
+ console.log(` Found ${lintSuccesses.length} lint successes`);
400
+ newSuccesses = newSuccesses.concat(lintSuccesses);
401
+ }
402
+
403
+ if (type === 'all' || type === 'pattern') {
404
+ console.log(` ${c.cyan}Scanning code patterns...${c.reset}`);
405
+ const patternSuccesses = scanCodePatternSuccesses();
406
+ console.log(` Found ${patternSuccesses.length} pattern successes`);
407
+ newSuccesses = newSuccesses.concat(patternSuccesses);
408
+ }
409
+
410
+ // Load existing and merge
411
+ const data = loadSuccesses();
412
+ const added = deduplicateSuccesses(newSuccesses, data.successes);
413
+ data.successes = [...data.successes, ...added];
414
+ data.totalSuccesses = data.successes.length;
415
+
416
+ // Save
417
+ saveSuccesses(data);
418
+
419
+ console.log(`\n${c.green}════════════════════════════════════════${c.reset}`);
420
+ console.log(`${c.bold}Scan Complete${c.reset}`);
421
+ console.log(` Total detected: ${newSuccesses.length}`);
422
+ console.log(` New successes: ${added.length}`);
423
+ console.log(`${c.gray}Saved to: ${successesPath}${c.reset}`);
424
+ console.log(`${c.green}════════════════════════════════════════${c.reset}`);
425
+
426
+ return { detected: newSuccesses.length, added: added.length };
427
+ }
428
+
429
+ function showStats() {
430
+ const data = loadSuccesses();
431
+
432
+ console.log(`${c.cyan}╔════════════════════════════════════════╗${c.reset}`);
433
+ console.log(`${c.cyan}║${c.reset} ${c.green}🎯 Success Sensor Statistics${c.reset} ${c.cyan}║${c.reset}`);
434
+ console.log(`${c.cyan}╚════════════════════════════════════════╝${c.reset}\n`);
435
+
436
+ if (data.successes.length === 0) {
437
+ console.log(`${c.gray}No successes tracked yet.${c.reset}`);
438
+ console.log(`${c.gray}Run: node success_sensor.js --scan all${c.reset}`);
439
+ return;
440
+ }
441
+
442
+ // Group by type
443
+ const byType = {};
444
+ for (const s of data.successes) {
445
+ byType[s.type] = (byType[s.type] || 0) + 1;
446
+ }
447
+
448
+ // Group by pattern
449
+ const byPattern = {};
450
+ for (const s of data.successes) {
451
+ byPattern[s.pattern] = (byPattern[s.pattern] || 0) + 1;
452
+ }
453
+
454
+ console.log(`${c.bold}By Type:${c.reset}`);
455
+ for (const [type, count] of Object.entries(byType)) {
456
+ console.log(` ${c.green}${type}${c.reset}: ${count}`);
457
+ }
458
+
459
+ console.log(`\n${c.bold}By Pattern:${c.reset}`);
460
+ for (const [pattern, count] of Object.entries(byPattern)) {
461
+ console.log(` ${c.blue}${pattern}${c.reset}: ${count}`);
462
+ }
463
+
464
+ console.log(`\n${c.bold}Total successes tracked:${c.reset} ${c.green}${data.totalSuccesses}${c.reset}`);
465
+ if (data.lastScan) {
466
+ console.log(`${c.gray}Last scan: ${data.lastScan}${c.reset}`);
467
+ }
468
+ }
469
+
470
+ // Parse CLI args
471
+ const args = process.argv.slice(2);
472
+
473
+ if (args.includes('--scan') || args.includes('-s')) {
474
+ const idx = args.findIndex(a => a === '--scan' || a === '-s');
475
+ const type = args[idx + 1] || 'all';
476
+ runScan(type);
477
+ } else if (args.includes('--stats') || args.includes('-t')) {
478
+ showStats();
479
+ } else {
480
+ console.log(`${c.green}success_sensor - Detect successful patterns${c.reset}
481
+
482
+ ${c.bold}Usage:${c.reset}
483
+ node success_sensor.js --scan all Scan all sources
484
+ node success_sensor.js --scan test Scan test results only
485
+ node success_sensor.js --scan lint Scan lint results only
486
+ node success_sensor.js --scan pattern Scan code patterns only
487
+ node success_sensor.js --stats Show statistics
488
+
489
+ ${c.bold}Success Types:${c.reset}
490
+ test - Tests passing
491
+ lint - Lint clean
492
+ pattern - Good code patterns (async/await, types, etc.)
493
+
494
+ ${c.bold}Example:${c.reset}
495
+ node success_sensor.js --scan all
496
+ node success_sensor.js --stats
497
+ `);
498
+ }
499
+
500
+ export { runScan, showStats, scanTestSuccesses, scanLintSuccesses, scanCodePatternSuccesses };