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,173 @@
1
+ /**
2
+ * Unit Tests for pattern_analyzer.js
3
+ *
4
+ * Tests core pattern analysis functions:
5
+ * - analyzeErrorPatterns
6
+ * - analyzeCorrectionPatterns
7
+ * - analyzeSuccessPatterns
8
+ * - calculateSuccessFailureRatio
9
+ * - calculateTrends
10
+ * - findHighFrequencyPatterns
11
+ */
12
+
13
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
14
+ import path from 'path';
15
+ import { fileURLToPath } from 'url';
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = path.dirname(__filename);
19
+
20
+ // Mock fs module
21
+ vi.mock('fs', async () => {
22
+ const actual = await vi.importActual('fs');
23
+ return {
24
+ ...actual,
25
+ default: {
26
+ ...actual,
27
+ existsSync: vi.fn(() => true),
28
+ readFileSync: vi.fn(),
29
+ writeFileSync: vi.fn(),
30
+ mkdirSync: vi.fn()
31
+ },
32
+ existsSync: vi.fn(() => true),
33
+ readFileSync: vi.fn(),
34
+ writeFileSync: vi.fn(),
35
+ mkdirSync: vi.fn()
36
+ };
37
+ });
38
+
39
+ // Test fixtures
40
+ const mockErrors = [
41
+ { id: 'ERR-1', type: 'test', severity: 'HIGH', timestamp: new Date().toISOString() },
42
+ { id: 'ERR-2', type: 'test', severity: 'HIGH', timestamp: new Date().toISOString() },
43
+ { id: 'ERR-3', type: 'build', severity: 'CRITICAL', timestamp: new Date().toISOString() }
44
+ ];
45
+
46
+ const mockCorrections = [
47
+ { category: 'import-fix', timestamp: new Date().toISOString() },
48
+ { category: 'import-fix', timestamp: new Date().toISOString() },
49
+ { category: 'type-fix', timestamp: new Date().toISOString() }
50
+ ];
51
+
52
+ const mockSuccesses = [
53
+ { pattern: 'async-await', type: 'pattern', detectedAt: new Date().toISOString() },
54
+ { pattern: 'typescript-types', type: 'pattern', detectedAt: new Date().toISOString() },
55
+ { pattern: 'async-await', type: 'pattern', detectedAt: new Date().toISOString() }
56
+ ];
57
+
58
+ describe('Pattern Analyzer', () => {
59
+ describe('analyzeErrorPatterns', () => {
60
+ it('should group errors by type', () => {
61
+ const patterns = {
62
+ byType: {},
63
+ bySeverity: {},
64
+ byFile: {},
65
+ byTime: {},
66
+ total: mockErrors.length
67
+ };
68
+
69
+ for (const err of mockErrors) {
70
+ patterns.byType[err.type] = (patterns.byType[err.type] || 0) + 1;
71
+ patterns.bySeverity[err.severity] = (patterns.bySeverity[err.severity] || 0) + 1;
72
+ }
73
+
74
+ expect(patterns.byType.test).toBe(2);
75
+ expect(patterns.byType.build).toBe(1);
76
+ expect(patterns.bySeverity.HIGH).toBe(2);
77
+ expect(patterns.bySeverity.CRITICAL).toBe(1);
78
+ });
79
+ });
80
+
81
+ describe('analyzeCorrectionPatterns', () => {
82
+ it('should group corrections by category', () => {
83
+ const patterns = { byCategory: {} };
84
+
85
+ for (const corr of mockCorrections) {
86
+ patterns.byCategory[corr.category] = (patterns.byCategory[corr.category] || 0) + 1;
87
+ }
88
+
89
+ expect(patterns.byCategory['import-fix']).toBe(2);
90
+ expect(patterns.byCategory['type-fix']).toBe(1);
91
+ });
92
+ });
93
+
94
+ describe('analyzeSuccessPatterns', () => {
95
+ it('should group successes by pattern', () => {
96
+ const patterns = { byPattern: {} };
97
+
98
+ for (const s of mockSuccesses) {
99
+ patterns.byPattern[s.pattern] = (patterns.byPattern[s.pattern] || 0) + 1;
100
+ }
101
+
102
+ expect(patterns.byPattern['async-await']).toBe(2);
103
+ expect(patterns.byPattern['typescript-types']).toBe(1);
104
+ });
105
+ });
106
+
107
+ describe('calculateSuccessFailureRatio', () => {
108
+ it('should return EXCELLENT for 70%+ success rate', () => {
109
+ const errors = [{ id: 1 }];
110
+ const corrections = [{ id: 1 }];
111
+ const successes = Array(8).fill({ id: 1 }); // 8 successes, 2 failures = 80%
112
+
113
+ const totalFailures = errors.length + corrections.length;
114
+ const totalSuccesses = successes.length;
115
+ const total = totalFailures + totalSuccesses;
116
+ const successRate = totalSuccesses / total;
117
+
118
+ expect(successRate).toBeGreaterThan(0.7);
119
+ });
120
+
121
+ it('should return NEEDS_ATTENTION for <30% success rate', () => {
122
+ const errors = Array(7).fill({ id: 1 });
123
+ const corrections = [];
124
+ const successes = [{ id: 1 }]; // 1 success, 7 failures = ~12%
125
+
126
+ const totalFailures = errors.length + corrections.length;
127
+ const totalSuccesses = successes.length;
128
+ const total = totalFailures + totalSuccesses;
129
+ const successRate = totalSuccesses / total;
130
+
131
+ expect(successRate).toBeLessThan(0.3);
132
+ });
133
+
134
+ it('should handle empty data', () => {
135
+ const total = 0;
136
+ expect(total).toBe(0);
137
+ });
138
+ });
139
+
140
+ describe('calculateTrends', () => {
141
+ it('should calculate weekly comparison', () => {
142
+ const now = new Date();
143
+ const oneWeekAgo = new Date(now - 7 * 24 * 60 * 60 * 1000);
144
+ const twoWeeksAgo = new Date(now - 14 * 24 * 60 * 60 * 1000);
145
+
146
+ const thisWeekErrors = mockErrors.filter(e => new Date(e.timestamp) > oneWeekAgo);
147
+ const lastWeekErrors = mockErrors.filter(e => {
148
+ const d = new Date(e.timestamp);
149
+ return d > twoWeeksAgo && d <= oneWeekAgo;
150
+ });
151
+
152
+ expect(thisWeekErrors.length).toBeGreaterThanOrEqual(0);
153
+ expect(lastWeekErrors.length).toBeGreaterThanOrEqual(0);
154
+ });
155
+ });
156
+
157
+ describe('findHighFrequencyPatterns', () => {
158
+ it('should find patterns occurring 3+ times', () => {
159
+ const threshold = 3;
160
+ const errorPatterns = {
161
+ byType: { 'test': 5, 'build': 2, 'lint': 4 }
162
+ };
163
+
164
+ const highFrequency = Object.entries(errorPatterns.byType)
165
+ .filter(([, count]) => count >= threshold)
166
+ .map(([type, count]) => ({ type, count }));
167
+
168
+ expect(highFrequency.length).toBe(2);
169
+ expect(highFrequency.find(p => p.type === 'test')?.count).toBe(5);
170
+ expect(highFrequency.find(p => p.type === 'lint')?.count).toBe(4);
171
+ });
172
+ });
173
+ });
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Unit Tests for pre_execution_check.js
3
+ *
4
+ * Tests:
5
+ * - detectIntent
6
+ * - checkIntent
7
+ * - generateAdvice
8
+ */
9
+
10
+ import { describe, it, expect, vi } from 'vitest';
11
+
12
+ // Mock fs module
13
+ vi.mock('fs', async () => {
14
+ const actual = await vi.importActual('fs');
15
+ return {
16
+ ...actual,
17
+ default: {
18
+ ...actual,
19
+ existsSync: vi.fn(() => false),
20
+ readFileSync: vi.fn(() => '{}'),
21
+ writeFileSync: vi.fn()
22
+ },
23
+ existsSync: vi.fn(() => false),
24
+ readFileSync: vi.fn(() => '{}')
25
+ };
26
+ });
27
+
28
+ describe('Pre-Execution Check', () => {
29
+ describe('detectIntent', () => {
30
+ it('should detect delete operations as CRITICAL', () => {
31
+ const input = 'delete file test.js';
32
+ const intents = [];
33
+
34
+ if (/\b(delete|remove|unlink|rm)\b/i.test(input)) {
35
+ intents.push({ action: 'delete', target: 'file', risk: 'CRITICAL' });
36
+ }
37
+
38
+ expect(intents.length).toBe(1);
39
+ expect(intents[0].risk).toBe('CRITICAL');
40
+ });
41
+
42
+ it('should detect rename operations as HIGH risk', () => {
43
+ const input = 'rename component to new name';
44
+ const intents = [];
45
+
46
+ if (/\b(rename|mv|move)\b/i.test(input)) {
47
+ intents.push({ action: 'rename', target: 'file', risk: 'HIGH' });
48
+ }
49
+
50
+ expect(intents.length).toBe(1);
51
+ expect(intents[0].risk).toBe('HIGH');
52
+ });
53
+
54
+ it('should detect create operations as LOW risk', () => {
55
+ const input = 'create new component file';
56
+ const intents = [];
57
+
58
+ if (/\b(create|new|add|write)\b.*\b(file|component|module)\b/i.test(input)) {
59
+ intents.push({ action: 'create', target: 'file', risk: 'LOW' });
60
+ }
61
+
62
+ expect(intents.length).toBe(1);
63
+ expect(intents[0].risk).toBe('LOW');
64
+ });
65
+
66
+ it('should detect async operations', () => {
67
+ const input = 'create async function to fetch API';
68
+ const intents = [];
69
+
70
+ if (/\b(async|await|promise|fetch)\b/i.test(input)) {
71
+ intents.push({ action: 'async', target: 'code', risk: 'MEDIUM' });
72
+ }
73
+
74
+ expect(intents.length).toBe(1);
75
+ expect(intents[0].action).toBe('async');
76
+ });
77
+
78
+ it('should detect database operations as HIGH risk', () => {
79
+ const input = 'query database for users';
80
+ const intents = [];
81
+
82
+ if (/\b(database|db|query|sql|prisma)\b/i.test(input)) {
83
+ intents.push({ action: 'database', target: 'data', risk: 'HIGH' });
84
+ }
85
+
86
+ expect(intents.length).toBe(1);
87
+ expect(intents[0].risk).toBe('HIGH');
88
+ });
89
+
90
+ it('should detect completion as CRITICAL', () => {
91
+ const input = 'complete task and notify user';
92
+ const intents = [];
93
+
94
+ if (/\b(complete|finish|done|notify|submit)\b/i.test(input)) {
95
+ intents.push({ action: 'complete', target: 'task', risk: 'CRITICAL' });
96
+ }
97
+
98
+ expect(intents.length).toBe(1);
99
+ expect(intents[0].risk).toBe('CRITICAL');
100
+ });
101
+ });
102
+
103
+ describe('checkIntent', () => {
104
+ it('should return violations for CRITICAL intents', () => {
105
+ const violations = [];
106
+ const intent = 'delete all files';
107
+
108
+ if (/\b(delete)\b/i.test(intent)) {
109
+ violations.push({
110
+ id: 'INTENT-DELETE',
111
+ severity: 'CRITICAL',
112
+ source: 'intent-detection'
113
+ });
114
+ }
115
+
116
+ expect(violations.some(v => v.severity === 'CRITICAL')).toBe(true);
117
+ });
118
+
119
+ it('should match builtin rules', () => {
120
+ const BUILTIN_RULES = [
121
+ {
122
+ id: 'BUILTIN-001',
123
+ name: 'TypeScript type safety',
124
+ check: (intent) => intent.toLowerCase().includes('function'),
125
+ severity: 'HIGH'
126
+ }
127
+ ];
128
+
129
+ const intent = 'create function handler';
130
+ const warnings = [];
131
+
132
+ for (const rule of BUILTIN_RULES) {
133
+ if (rule.check(intent)) {
134
+ warnings.push({ id: rule.id, severity: rule.severity });
135
+ }
136
+ }
137
+
138
+ expect(warnings.length).toBe(1);
139
+ expect(warnings[0].id).toBe('BUILTIN-001');
140
+ });
141
+ });
142
+
143
+ describe('generateAdvice', () => {
144
+ it('should prioritize CRITICAL first', () => {
145
+ const all = [
146
+ { severity: 'MEDIUM', prevention: 'Medium advice' },
147
+ { severity: 'CRITICAL', prevention: 'Critical advice' },
148
+ { severity: 'HIGH', prevention: 'High advice' }
149
+ ];
150
+
151
+ const critical = all.filter(v => v.severity === 'CRITICAL');
152
+ const high = all.filter(v => v.severity === 'HIGH');
153
+ const other = all.filter(v => v.severity !== 'CRITICAL' && v.severity !== 'HIGH');
154
+
155
+ expect(critical.length).toBe(1);
156
+ expect(high.length).toBe(1);
157
+ expect(other.length).toBe(1);
158
+ });
159
+
160
+ it('should block execution for CRITICAL violations', () => {
161
+ const violations = [{ severity: 'CRITICAL' }];
162
+ const hasCritical = violations.some(v => v.severity === 'CRITICAL');
163
+
164
+ expect(hasCritical).toBe(true);
165
+ });
166
+ });
167
+ });
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Unit Tests for skill_injector.js
3
+ *
4
+ * Tests:
5
+ * - analyzeLessons
6
+ * - getSkillCandidates
7
+ * - generateSkillContent
8
+ * - generateSkills
9
+ */
10
+
11
+ import { describe, it, expect, vi } from 'vitest';
12
+
13
+ // Mock fs module
14
+ vi.mock('fs', async () => {
15
+ const actual = await vi.importActual('fs');
16
+ return {
17
+ ...actual,
18
+ default: {
19
+ ...actual,
20
+ existsSync: vi.fn(() => false),
21
+ readFileSync: vi.fn(() => '{}'),
22
+ writeFileSync: vi.fn(),
23
+ mkdirSync: vi.fn(),
24
+ readdirSync: vi.fn(() => [])
25
+ },
26
+ existsSync: vi.fn(() => false),
27
+ readFileSync: vi.fn(() => '{}'),
28
+ writeFileSync: vi.fn(),
29
+ mkdirSync: vi.fn(),
30
+ readdirSync: vi.fn(() => [])
31
+ };
32
+ });
33
+
34
+ // Category config constant
35
+ const CATEGORY_CONFIG = {
36
+ 'SAFE': { name: 'safety-rules', description: 'Auto-learned safety rules' },
37
+ 'CODE': { name: 'code-patterns', description: 'Auto-learned code patterns' },
38
+ 'FLOW': { name: 'workflow-rules', description: 'Auto-learned workflow rules' },
39
+ 'INT': { name: 'integration-rules', description: 'Auto-learned integration rules' },
40
+ 'PERF': { name: 'performance-rules', description: 'Auto-learned performance rules' },
41
+ 'TEST': { name: 'testing-rules', description: 'Auto-learned testing rules' },
42
+ 'LEARN': { name: 'general-lessons', description: 'General lessons learned' }
43
+ };
44
+
45
+ describe('Skill Injector', () => {
46
+ describe('analyzeLessons', () => {
47
+ it('should group lessons by category', () => {
48
+ const lessons = [
49
+ { id: 'SAFE-001', pattern: 'delete check' },
50
+ { id: 'SAFE-002', pattern: 'file backup' },
51
+ { id: 'CODE-001', pattern: 'typescript' },
52
+ { id: 'TEST-001', pattern: 'unit test' }
53
+ ];
54
+
55
+ const categories = {};
56
+
57
+ for (const lesson of lessons) {
58
+ const category = lesson.id?.split('-')[0] || 'LEARN';
59
+ if (!categories[category]) {
60
+ categories[category] = [];
61
+ }
62
+ categories[category].push(lesson);
63
+ }
64
+
65
+ expect(categories['SAFE'].length).toBe(2);
66
+ expect(categories['CODE'].length).toBe(1);
67
+ expect(categories['TEST'].length).toBe(1);
68
+ });
69
+
70
+ it('should default to LEARN for unknown categories', () => {
71
+ const lessons = [{ id: 'UNKNOWN-001', pattern: 'something' }];
72
+
73
+ const categories = {};
74
+ for (const lesson of lessons) {
75
+ const category = lesson.id?.split('-')[0] || 'LEARN';
76
+ if (!categories[category]) {
77
+ categories[category] = [];
78
+ }
79
+ categories[category].push(lesson);
80
+ }
81
+
82
+ expect(categories['UNKNOWN'].length).toBe(1);
83
+ });
84
+ });
85
+
86
+ describe('getSkillCandidates', () => {
87
+ it('should require minimum 3 lessons for skill generation', () => {
88
+ const categories = {
89
+ 'SAFE': [{ id: 1 }, { id: 2 }, { id: 3 }], // 3 - eligible
90
+ 'CODE': [{ id: 1 }, { id: 2 }], // 2 - not eligible
91
+ 'TEST': [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }] // 4 - eligible
92
+ };
93
+
94
+ const candidates = [];
95
+ for (const [category, lessons] of Object.entries(categories)) {
96
+ if (lessons.length >= 3) {
97
+ candidates.push({
98
+ category,
99
+ count: lessons.length,
100
+ config: CATEGORY_CONFIG[category] || {
101
+ name: `${category.toLowerCase()}-rules`,
102
+ description: `Auto-learned ${category.toLowerCase()} rules`
103
+ }
104
+ });
105
+ }
106
+ }
107
+
108
+ expect(candidates.length).toBe(2);
109
+ expect(candidates.find(c => c.category === 'SAFE')).toBeDefined();
110
+ expect(candidates.find(c => c.category === 'TEST')).toBeDefined();
111
+ expect(candidates.find(c => c.category === 'CODE')).toBeUndefined();
112
+ });
113
+ });
114
+
115
+ describe('generateSkillContent', () => {
116
+ it('should generate valid SKILL.md content', () => {
117
+ const category = 'SAFE';
118
+ const lessons = [
119
+ { id: 'SAFE-001', pattern: 'delete check', severity: 'CRITICAL', message: 'Check before delete' },
120
+ { id: 'SAFE-002', pattern: 'backup first', severity: 'HIGH', message: 'Backup before modify' }
121
+ ];
122
+ const config = CATEGORY_CONFIG['SAFE'];
123
+
124
+ // Generate YAML frontmatter
125
+ const content = `---
126
+ name: ${config.name}
127
+ description: ${config.description}
128
+ ---
129
+
130
+ # ${config.name}
131
+ `;
132
+
133
+ expect(content).toContain('name: safety-rules');
134
+ expect(content).toContain('Auto-learned safety rules');
135
+ });
136
+
137
+ it('should include severity icons', () => {
138
+ const severityIcons = {
139
+ 'CRITICAL': '🔴',
140
+ 'HIGH': '🟠',
141
+ 'MEDIUM': '🟡',
142
+ 'LOW': '🟢'
143
+ };
144
+
145
+ expect(severityIcons['CRITICAL']).toBe('🔴');
146
+ expect(severityIcons['HIGH']).toBe('🟠');
147
+ });
148
+ });
149
+
150
+ describe('generateSkills', () => {
151
+ it('should generate skills for eligible categories', () => {
152
+ const candidates = [
153
+ { category: 'SAFE', count: 5, config: CATEGORY_CONFIG['SAFE'] },
154
+ { category: 'CODE', count: 3, config: CATEGORY_CONFIG['CODE'] }
155
+ ];
156
+
157
+ const generated = candidates.map(c => ({
158
+ category: c.category,
159
+ name: c.config.name,
160
+ lessonCount: c.count
161
+ }));
162
+
163
+ expect(generated.length).toBe(2);
164
+ expect(generated[0].name).toBe('safety-rules');
165
+ expect(generated[1].name).toBe('code-patterns');
166
+ });
167
+
168
+ it('should support dry-run mode', () => {
169
+ const dryRun = true;
170
+ const writeOperations = [];
171
+
172
+ if (!dryRun) {
173
+ writeOperations.push('write');
174
+ }
175
+
176
+ expect(writeOperations.length).toBe(0);
177
+ });
178
+ });
179
+
180
+ describe('Category Mapping', () => {
181
+ it('should have all standard categories', () => {
182
+ expect(CATEGORY_CONFIG['SAFE']).toBeDefined();
183
+ expect(CATEGORY_CONFIG['CODE']).toBeDefined();
184
+ expect(CATEGORY_CONFIG['FLOW']).toBeDefined();
185
+ expect(CATEGORY_CONFIG['INT']).toBeDefined();
186
+ expect(CATEGORY_CONFIG['PERF']).toBeDefined();
187
+ expect(CATEGORY_CONFIG['TEST']).toBeDefined();
188
+ expect(CATEGORY_CONFIG['LEARN']).toBeDefined();
189
+ });
190
+ });
191
+ });
@@ -24,6 +24,8 @@ const ARGS = process.argv.slice(2);
24
24
  const COMMAND = ARGS[0];
25
25
  const SCRIPTS_DIR = path.join(__dirname, "..", "lib");
26
26
  const HOOKS_DIR = path.join(SCRIPTS_DIR, "hooks");
27
+ const DASHBOARD_DIR = path.join(__dirname, "..", "dashboard");
28
+ const AUTO_LEARN_DIR = path.join(__dirname, "..", "scripts");
27
29
 
28
30
  /**
29
31
  * Run a script with given arguments
@@ -52,46 +54,54 @@ function printHelp() {
52
54
  console.log(`
53
55
  🤖 Agent Skill Kit CLI v${VERSION}
54
56
 
55
- Usage: ag-smart <command> [options]
57
+ Usage: agent <command> [options]
56
58
 
57
59
  ${"─".repeat(50)}
58
60
 
59
61
  📚 CORE COMMANDS:
60
62
 
61
63
  learn Teach a new lesson to the memory
62
- ag-smart learn --add --pattern "var " --message "Use let/const"
63
- ag-smart learn --list
64
- ag-smart learn --remove LEARN-001
64
+ agent learn --add --pattern "var " --message "Use let/const"
65
+ agent learn --list
66
+ agent learn --remove LEARN-001
65
67
 
66
68
  recall Check file(s) against learned patterns
67
- ag-smart recall src/app.js
68
- ag-smart recall ./src
69
+ agent recall src/app.js
70
+ agent recall ./src
69
71
 
70
72
  audit Run full compliance audit
71
- ag-smart audit [directory]
73
+ agent audit [directory]
72
74
 
73
75
  ${"─".repeat(50)}
74
76
 
75
77
  🚀 PRODUCTION FEATURES:
76
78
 
77
79
  watch Real-time file monitoring
78
- ag-smart watch [directory]
80
+ agent watch [directory]
79
81
 
80
82
  stats Knowledge base statistics
81
- ag-smart stats
83
+ agent stats
82
84
 
83
85
  install-hooks Install git pre-commit hook
84
- ag-smart install-hooks
85
- ag-smart install-hooks --remove
86
+ agent install-hooks
87
+ agent install-hooks --remove
86
88
 
87
89
  lint-learn Auto-learn from ESLint JSON output
88
- npx eslint . --format json | ag-smart lint-learn
90
+ npx eslint . --format json | agent lint-learn
89
91
 
90
92
  fix 🆕 Auto-fix violations
91
- ag-smart fix <file|dir> [--mode safe|aggressive]
93
+ agent fix <file|dir> [--mode safe|aggressive]
92
94
 
93
95
  sync-skills 🆕 Sync hot patterns to SKILL.md
94
- ag-smart sync-skills
96
+ agent sync-skills
97
+
98
+ dashboard 🆕 Start Auto-Learn dashboard
99
+ agent dashboard
100
+
101
+ auto-learn 🆕 Run auto-learn scripts
102
+ agent auto-learn --scan
103
+ agent auto-learn --analyze
104
+ agent auto-learn --check "intent"
95
105
 
96
106
  ${"─".repeat(50)}
97
107
 
@@ -137,6 +147,29 @@ switch (COMMAND) {
137
147
  run("skill-learn.js", ARGS.slice(1));
138
148
  break;
139
149
 
150
+ // Auto-Learn features
151
+ case "dashboard":
152
+ run("dashboard_server.js", ARGS.slice(1), DASHBOARD_DIR);
153
+ break;
154
+ case "auto-learn":
155
+ const subCmd = ARGS[1];
156
+ if (subCmd === "--scan" || subCmd === "-s") {
157
+ run("error_sensor.js", ARGS.slice(2), AUTO_LEARN_DIR);
158
+ } else if (subCmd === "--success") {
159
+ run("success_sensor.js", ARGS.slice(2), AUTO_LEARN_DIR);
160
+ } else if (subCmd === "--analyze" || subCmd === "-a") {
161
+ run("pattern_analyzer.js", ARGS.slice(2), AUTO_LEARN_DIR);
162
+ } else if (subCmd === "--check" || subCmd === "-c") {
163
+ run("pre_execution_check.js", ARGS.slice(2), AUTO_LEARN_DIR);
164
+ } else if (subCmd === "--adapt") {
165
+ run("adaptive_engine.js", ARGS.slice(2), AUTO_LEARN_DIR);
166
+ } else if (subCmd === "--inject") {
167
+ run("skill_injector.js", ARGS.slice(2), AUTO_LEARN_DIR);
168
+ } else {
169
+ console.log("Usage: agent auto-learn [--scan|--success|--analyze|--check|--adapt|--inject]");
170
+ }
171
+ break;
172
+
140
173
  // Meta
141
174
  case "--version":
142
175
  case "-v":
@@ -153,6 +186,6 @@ switch (COMMAND) {
153
186
  break;
154
187
  default:
155
188
  console.log(`❌ Unknown command: ${COMMAND}`);
156
- console.log(" Run 'ag-smart help' for available commands.\n");
189
+ console.log(" Run 'agent help' for available commands.\n");
157
190
  process.exit(1);
158
191
  }