add-skill-kit 3.2.3 → 3.2.5

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 (126) hide show
  1. package/README.md +1 -1
  2. package/bin/lib/commands/help.js +0 -4
  3. package/bin/lib/commands/install.js +90 -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/agent.js +191 -0
  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 +154 -0
  15. package/lib/agent-cli/lib/audit.test.js +100 -0
  16. package/lib/agent-cli/lib/auto-learn.js +319 -0
  17. package/lib/agent-cli/lib/auto_preview.py +148 -0
  18. package/lib/agent-cli/lib/backup.js +138 -0
  19. package/lib/agent-cli/lib/backup.test.js +78 -0
  20. package/lib/agent-cli/lib/checklist.py +222 -0
  21. package/lib/agent-cli/lib/cognitive-lesson.js +476 -0
  22. package/lib/agent-cli/lib/completion.js +149 -0
  23. package/lib/agent-cli/lib/config.js +35 -0
  24. package/lib/agent-cli/lib/eslint-fix.js +238 -0
  25. package/lib/agent-cli/lib/evolution-signal.js +215 -0
  26. package/lib/agent-cli/lib/export.js +86 -0
  27. package/lib/agent-cli/lib/export.test.js +65 -0
  28. package/lib/agent-cli/lib/fix.js +337 -0
  29. package/lib/agent-cli/lib/fix.test.js +80 -0
  30. package/lib/agent-cli/lib/gemini-export.js +83 -0
  31. package/lib/agent-cli/lib/generate-registry.js +42 -0
  32. package/lib/agent-cli/lib/hooks/install-hooks.js +152 -0
  33. package/lib/agent-cli/lib/hooks/lint-learn.js +172 -0
  34. package/lib/agent-cli/lib/ignore.js +116 -0
  35. package/lib/agent-cli/lib/ignore.test.js +58 -0
  36. package/lib/agent-cli/lib/init.js +124 -0
  37. package/lib/agent-cli/lib/learn.js +255 -0
  38. package/lib/agent-cli/lib/learn.test.js +70 -0
  39. package/lib/agent-cli/lib/migrate-to-v4.js +322 -0
  40. package/lib/agent-cli/lib/proposals.js +199 -0
  41. package/lib/agent-cli/lib/proposals.test.js +56 -0
  42. package/lib/agent-cli/lib/recall.js +820 -0
  43. package/lib/agent-cli/lib/recall.test.js +107 -0
  44. package/lib/agent-cli/lib/selfevolution-bridge.js +167 -0
  45. package/lib/agent-cli/lib/session_manager.py +120 -0
  46. package/lib/agent-cli/lib/settings.js +227 -0
  47. package/lib/agent-cli/lib/skill-learn.js +296 -0
  48. package/lib/agent-cli/lib/stats.js +132 -0
  49. package/lib/agent-cli/lib/stats.test.js +94 -0
  50. package/lib/agent-cli/lib/types.js +33 -0
  51. package/lib/agent-cli/lib/ui/audit-ui.js +146 -0
  52. package/lib/agent-cli/lib/ui/backup-ui.js +107 -0
  53. package/lib/agent-cli/lib/ui/clack-helpers.js +317 -0
  54. package/lib/agent-cli/lib/ui/common.js +83 -0
  55. package/lib/agent-cli/lib/ui/completion-ui.js +126 -0
  56. package/lib/agent-cli/lib/ui/custom-select.js +69 -0
  57. package/lib/agent-cli/lib/ui/dashboard-ui.js +222 -0
  58. package/lib/agent-cli/lib/ui/evolution-signals-ui.js +107 -0
  59. package/lib/agent-cli/lib/ui/export-ui.js +94 -0
  60. package/lib/agent-cli/lib/ui/fix-all-ui.js +191 -0
  61. package/lib/agent-cli/lib/ui/help-ui.js +49 -0
  62. package/lib/agent-cli/lib/ui/index.js +199 -0
  63. package/lib/agent-cli/lib/ui/init-ui.js +56 -0
  64. package/lib/agent-cli/lib/ui/knowledge-ui.js +55 -0
  65. package/lib/agent-cli/lib/ui/learn-ui.js +706 -0
  66. package/lib/agent-cli/lib/ui/lessons-ui.js +148 -0
  67. package/lib/agent-cli/lib/ui/pretty.js +145 -0
  68. package/lib/agent-cli/lib/ui/proposals-ui.js +99 -0
  69. package/lib/agent-cli/lib/ui/recall-ui.js +342 -0
  70. package/lib/agent-cli/lib/ui/routing-demo.js +79 -0
  71. package/lib/agent-cli/lib/ui/routing-ui.js +325 -0
  72. package/lib/agent-cli/lib/ui/settings-ui.js +381 -0
  73. package/lib/agent-cli/lib/ui/stats-ui.js +123 -0
  74. package/lib/agent-cli/lib/ui/watch-ui.js +236 -0
  75. package/lib/agent-cli/lib/verify_all.py +327 -0
  76. package/lib/agent-cli/lib/watcher.js +181 -0
  77. package/lib/agent-cli/lib/watcher.test.js +85 -0
  78. package/lib/agent-cli/package.json +51 -0
  79. package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
  80. package/lib/agent-cli/scripts/dashboard_server.js +224 -0
  81. package/lib/agent-cli/scripts/error_sensor.js +565 -0
  82. package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
  83. package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
  84. package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
  85. package/lib/agent-cli/scripts/rule_sharing.js +374 -0
  86. package/lib/agent-cli/scripts/skill_injector.js +387 -0
  87. package/lib/agent-cli/scripts/success_sensor.js +500 -0
  88. package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
  89. package/lib/agent-cli/services/auto-learn-service.js +247 -0
  90. package/lib/agent-cli/src/MIGRATION.md +418 -0
  91. package/lib/agent-cli/src/README.md +367 -0
  92. package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
  93. package/lib/agent-cli/src/core/evolution/index.js +17 -0
  94. package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
  95. package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
  96. package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
  97. package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
  98. package/lib/agent-cli/src/core/index.js +15 -0
  99. package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
  100. package/lib/agent-cli/src/core/learning/index.js +12 -0
  101. package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
  102. package/lib/agent-cli/src/core/scanning/index.js +14 -0
  103. package/lib/agent-cli/src/data/index.js +13 -0
  104. package/lib/agent-cli/src/data/repositories/index.js +8 -0
  105. package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
  106. package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
  107. package/lib/agent-cli/src/data/storage/index.js +8 -0
  108. package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
  109. package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
  110. package/lib/agent-cli/src/infrastructure/index.js +13 -0
  111. package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
  112. package/lib/agent-cli/src/services/export-service.js +162 -0
  113. package/lib/agent-cli/src/services/index.js +13 -0
  114. package/lib/agent-cli/src/services/learning-service.js +99 -0
  115. package/lib/agent-cli/types/index.d.ts +343 -0
  116. package/lib/agent-cli/utils/benchmark.js +269 -0
  117. package/lib/agent-cli/utils/logger.js +303 -0
  118. package/lib/agent-cli/utils/ml_patterns.js +300 -0
  119. package/lib/agent-cli/utils/recovery.js +312 -0
  120. package/lib/agent-cli/utils/telemetry.js +290 -0
  121. package/lib/agentskillskit-cli/README.md +21 -0
  122. package/{node_modules/agentskillskit-cli/bin → lib/agentskillskit-cli}/ag-smart.js +15 -15
  123. package/lib/agentskillskit-cli/package.json +51 -0
  124. package/package.json +19 -9
  125. /package/bin/{cli.js → kit.js} +0 -0
  126. /package/{node_modules/agentskillskit-cli → lib/agent-cli}/README.md +0 -0
@@ -0,0 +1,623 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Pre-Execution Check - Prevent known errors before they happen
4
+ *
5
+ * Part of FAANG-Grade Auto-Learn System Phase 3
6
+ *
7
+ * Before AI writes code, this checks:
8
+ * - Active rules from lessons-learned
9
+ * - Auto-generated rules from pattern_analyzer
10
+ * - Known anti-patterns
11
+ *
12
+ * Usage:
13
+ * node pre_execution_check.js --check "code intent description"
14
+ * node pre_execution_check.js --list-rules
15
+ * node pre_execution_check.js --approve RULE-ID
16
+ */
17
+
18
+ import fs from 'fs';
19
+ import path from 'path';
20
+ import { fileURLToPath } from 'url';
21
+
22
+ const __filename = fileURLToPath(import.meta.url);
23
+ const __dirname = path.dirname(__filename);
24
+
25
+ // Colors
26
+ const c = {
27
+ reset: '\x1b[0m',
28
+ red: '\x1b[31m',
29
+ green: '\x1b[32m',
30
+ yellow: '\x1b[33m',
31
+ blue: '\x1b[34m',
32
+ cyan: '\x1b[36m',
33
+ gray: '\x1b[90m',
34
+ bold: '\x1b[1m'
35
+ };
36
+
37
+ // Find project root
38
+ function findProjectRoot() {
39
+ let current = process.cwd();
40
+ while (current !== path.dirname(current)) {
41
+ if (fs.existsSync(path.join(current, '.agent'))) {
42
+ return current;
43
+ }
44
+ current = path.dirname(current);
45
+ }
46
+ return process.cwd();
47
+ }
48
+
49
+ const projectRoot = findProjectRoot();
50
+ const knowledgePath = path.join(projectRoot, '.agent', 'knowledge');
51
+ const lessonsPath = path.join(knowledgePath, 'lessons-learned.json');
52
+ const autoRulesPath = path.join(knowledgePath, 'auto-rules.yaml');
53
+ const activeRulesPath = path.join(knowledgePath, 'active-rules.json');
54
+ const errorsPath = path.join(knowledgePath, 'detected-errors.json');
55
+ const successesPath = path.join(knowledgePath, 'successes.json');
56
+
57
+ // Load lessons
58
+ function loadLessons() {
59
+ try {
60
+ if (fs.existsSync(lessonsPath)) {
61
+ const data = JSON.parse(fs.readFileSync(lessonsPath, 'utf8'));
62
+ return data.lessons || [];
63
+ }
64
+ } catch { }
65
+ return [];
66
+ }
67
+
68
+ // Load errors for pattern analysis
69
+ function loadErrors() {
70
+ try {
71
+ if (fs.existsSync(errorsPath)) {
72
+ const data = JSON.parse(fs.readFileSync(errorsPath, 'utf8'));
73
+ return data.errors || [];
74
+ }
75
+ } catch { }
76
+ return [];
77
+ }
78
+
79
+ // Load successes for positive patterns
80
+ function loadSuccesses() {
81
+ try {
82
+ if (fs.existsSync(successesPath)) {
83
+ const data = JSON.parse(fs.readFileSync(successesPath, 'utf8'));
84
+ return data.successes || [];
85
+ }
86
+ } catch { }
87
+ return [];
88
+ }
89
+
90
+ // Load auto-rules (parse YAML)
91
+ function loadAutoRules() {
92
+ try {
93
+ if (fs.existsSync(autoRulesPath)) {
94
+ const content = fs.readFileSync(autoRulesPath, 'utf8');
95
+ // Simple YAML parsing for rules
96
+ const rules = [];
97
+ const ruleBlocks = content.split(/\n\s*-\s+id:/);
98
+
99
+ for (let i = 1; i < ruleBlocks.length; i++) {
100
+ const block = '- id:' + ruleBlocks[i];
101
+ const rule = {};
102
+
103
+ const idMatch = block.match(/id:\s*(\S+)/);
104
+ const patternMatch = block.match(/pattern:\s*"([^"]+)"/);
105
+ const preventionMatch = block.match(/prevention:\s*"([^"]+)"/);
106
+ const statusMatch = block.match(/status:\s*(\S+)/);
107
+ const severityMatch = block.match(/severity:\s*(\S+)/);
108
+
109
+ if (idMatch) rule.id = idMatch[1];
110
+ if (patternMatch) rule.pattern = patternMatch[1];
111
+ if (preventionMatch) rule.prevention = preventionMatch[1];
112
+ if (statusMatch) rule.status = statusMatch[1];
113
+ if (severityMatch) rule.severity = severityMatch[1];
114
+
115
+ if (rule.id) rules.push(rule);
116
+ }
117
+
118
+ return rules;
119
+ }
120
+ } catch { }
121
+ return [];
122
+ }
123
+
124
+ // Load active rules
125
+ function loadActiveRules() {
126
+ try {
127
+ if (fs.existsSync(activeRulesPath)) {
128
+ const data = JSON.parse(fs.readFileSync(activeRulesPath, 'utf8'));
129
+ return data.rules || [];
130
+ }
131
+ } catch { }
132
+ return [];
133
+ }
134
+
135
+ // Save active rules
136
+ function saveActiveRules(rules) {
137
+ const data = {
138
+ _comment: "Active prevention rules",
139
+ updatedAt: new Date().toISOString(),
140
+ rules
141
+ };
142
+ fs.writeFileSync(activeRulesPath, JSON.stringify(data, null, 2));
143
+ }
144
+
145
+ // ==================== INTENT DETECTION ====================
146
+
147
+ /**
148
+ * Advanced intent detection from code/description
149
+ */
150
+ function detectIntent(input) {
151
+ const intents = [];
152
+ const inputLower = input.toLowerCase();
153
+
154
+ // File operations
155
+ if (/\b(rename|mv|move)\b/i.test(input)) {
156
+ intents.push({ action: 'rename', target: 'file', risk: 'HIGH' });
157
+ }
158
+ if (/\b(delete|remove|unlink|rm)\b/i.test(input)) {
159
+ intents.push({ action: 'delete', target: 'file', risk: 'CRITICAL' });
160
+ }
161
+ if (/\b(create|new|add|write)\b.*\b(file|component|module)\b/i.test(input)) {
162
+ intents.push({ action: 'create', target: 'file', risk: 'LOW' });
163
+ }
164
+ if (/\b(modify|update|change|edit)\b/i.test(input)) {
165
+ intents.push({ action: 'modify', target: 'file', risk: 'MEDIUM' });
166
+ }
167
+
168
+ // Code patterns
169
+ if (/\b(async|await|promise|fetch)\b/i.test(input)) {
170
+ intents.push({ action: 'async', target: 'code', risk: 'MEDIUM' });
171
+ }
172
+ if (/\b(import|require|from)\b/i.test(input)) {
173
+ intents.push({ action: 'import', target: 'module', risk: 'MEDIUM' });
174
+ }
175
+ if (/\b(function|method|handler)\b/i.test(input)) {
176
+ intents.push({ action: 'function', target: 'code', risk: 'LOW' });
177
+ }
178
+ if (/\b(api|endpoint|request|response)\b/i.test(input)) {
179
+ intents.push({ action: 'api', target: 'network', risk: 'MEDIUM' });
180
+ }
181
+ if (/\b(database|db|query|sql|prisma)\b/i.test(input)) {
182
+ intents.push({ action: 'database', target: 'data', risk: 'HIGH' });
183
+ }
184
+
185
+ // Completion/notification
186
+ if (/\b(complete|finish|done|notify|submit)\b/i.test(input)) {
187
+ intents.push({ action: 'complete', target: 'task', risk: 'CRITICAL' });
188
+ }
189
+
190
+ return intents;
191
+ }
192
+
193
+ /**
194
+ * Get high-frequency error patterns for matching
195
+ */
196
+ function getHighFrequencyPatterns() {
197
+ const errors = loadErrors();
198
+ const patterns = {};
199
+
200
+ for (const err of errors) {
201
+ const key = err.pattern || err.type;
202
+ patterns[key] = (patterns[key] || 0) + 1;
203
+ }
204
+
205
+ // Return patterns that occurred 2+ times
206
+ return Object.entries(patterns)
207
+ .filter(([, count]) => count >= 2)
208
+ .map(([pattern, count]) => ({ pattern, count, type: 'error' }));
209
+ }
210
+
211
+ /**
212
+ * Get success patterns for positive reinforcement
213
+ */
214
+ function getSuccessPatterns() {
215
+ const successes = loadSuccesses();
216
+ const patterns = {};
217
+
218
+ for (const s of successes) {
219
+ patterns[s.pattern] = (patterns[s.pattern] || 0) + 1;
220
+ }
221
+
222
+ return Object.entries(patterns)
223
+ .map(([pattern, count]) => ({ pattern, count, type: 'success' }));
224
+ }
225
+
226
+ // ==================== RULE MATCHING ====================
227
+
228
+ /**
229
+ * Built-in prevention rules
230
+ */
231
+ const BUILTIN_RULES = [
232
+ {
233
+ id: 'BUILTIN-001',
234
+ name: 'TypeScript type safety',
235
+ keywords: ['function', 'param', 'return', 'type'],
236
+ check: (intent) => intent.toLowerCase().includes('function'),
237
+ prevention: 'Add explicit TypeScript types to all function parameters and return types',
238
+ severity: 'HIGH'
239
+ },
240
+ {
241
+ id: 'BUILTIN-002',
242
+ name: 'Async/await usage',
243
+ keywords: ['async', 'await', 'promise', 'fetch', 'api'],
244
+ check: (intent) => /async|await|promise|fetch|api/i.test(intent),
245
+ prevention: 'Always use async/await pattern. Never mix callbacks and promises.',
246
+ severity: 'HIGH'
247
+ },
248
+ {
249
+ id: 'BUILTIN-003',
250
+ name: 'Error handling',
251
+ keywords: ['try', 'catch', 'error', 'exception'],
252
+ check: (intent) => /async|fetch|api|database|file/i.test(intent),
253
+ prevention: 'Wrap async operations in try/catch. Never use empty catch blocks.',
254
+ severity: 'HIGH'
255
+ },
256
+ {
257
+ id: 'BUILTIN-004',
258
+ name: 'Import paths',
259
+ keywords: ['import', 'require', 'from'],
260
+ check: (intent) => /import|require|module/i.test(intent),
261
+ prevention: 'Verify import paths exist. Use relative imports from project root.',
262
+ severity: 'MEDIUM'
263
+ },
264
+ {
265
+ id: 'BUILTIN-005',
266
+ name: 'Null safety',
267
+ keywords: ['null', 'undefined', 'optional'],
268
+ check: (intent) => /optional|null|undefined|maybe|might/i.test(intent),
269
+ prevention: 'Use optional chaining (?.) and nullish coalescing (??). Check for null/undefined.',
270
+ severity: 'HIGH'
271
+ },
272
+ {
273
+ id: 'BUILTIN-006',
274
+ name: 'React component types',
275
+ keywords: ['react', 'component', 'jsx', 'tsx'],
276
+ check: (intent) => /react|component|jsx|tsx/i.test(intent),
277
+ prevention: 'Use React.FC for components. Use ReactNode instead of JSX.Element.',
278
+ severity: 'MEDIUM'
279
+ },
280
+ {
281
+ id: 'BUILTIN-007',
282
+ name: 'Test before completion',
283
+ keywords: ['complete', 'finish', 'done', 'notify'],
284
+ check: (intent) => /complete|finish|done|notify/i.test(intent),
285
+ prevention: 'Run tests before marking task complete. Verify no TypeScript errors.',
286
+ severity: 'CRITICAL'
287
+ }
288
+ ];
289
+
290
+ /**
291
+ * Check intent against all rules (ENHANCED)
292
+ */
293
+ function checkIntent(intent) {
294
+ const violations = [];
295
+ const warnings = [];
296
+ const recommendations = [];
297
+
298
+ // PHASE 1: Intent Detection
299
+ const detectedIntents = detectIntent(intent);
300
+
301
+ // Add risk warnings from detected intents
302
+ for (const di of detectedIntents) {
303
+ if (di.risk === 'CRITICAL') {
304
+ violations.push({
305
+ id: `INTENT-${di.action.toUpperCase()}`,
306
+ pattern: `${di.action} ${di.target}`,
307
+ prevention: `CRITICAL: ${di.action} operation detected. Verify safety before proceeding.`,
308
+ severity: 'CRITICAL',
309
+ source: 'intent-detection'
310
+ });
311
+ } else if (di.risk === 'HIGH') {
312
+ warnings.push({
313
+ id: `INTENT-${di.action.toUpperCase()}`,
314
+ name: `High-risk: ${di.action}`,
315
+ prevention: `${di.action} on ${di.target} - use extra caution`,
316
+ severity: 'HIGH',
317
+ source: 'intent-detection'
318
+ });
319
+ }
320
+ }
321
+
322
+ // Check builtin rules
323
+ for (const rule of BUILTIN_RULES) {
324
+ if (rule.check(intent)) {
325
+ warnings.push({
326
+ id: rule.id,
327
+ name: rule.name,
328
+ prevention: rule.prevention,
329
+ severity: rule.severity,
330
+ source: 'builtin'
331
+ });
332
+ }
333
+ }
334
+
335
+ // Check lessons
336
+ const lessons = loadLessons();
337
+ for (const lesson of lessons) {
338
+ if (lesson.pattern && intent.toLowerCase().includes(lesson.pattern.toLowerCase().split(' ')[0])) {
339
+ violations.push({
340
+ id: lesson.id,
341
+ pattern: lesson.pattern,
342
+ prevention: lesson.message,
343
+ severity: lesson.severity,
344
+ source: 'lesson'
345
+ });
346
+ }
347
+ }
348
+
349
+ // PHASE 2: High-Frequency Error Pattern Matching
350
+ const errorPatterns = getHighFrequencyPatterns();
351
+ for (const ep of errorPatterns) {
352
+ if (ep.pattern && intent.toLowerCase().includes(ep.pattern.toLowerCase())) {
353
+ violations.push({
354
+ id: `FREQ-${ep.pattern.toUpperCase().replace(/\s+/g, '-').slice(0, 10)}`,
355
+ pattern: ep.pattern,
356
+ prevention: `This pattern caused ${ep.count} errors before. Apply extra care.`,
357
+ severity: ep.count >= 5 ? 'HIGH' : 'MEDIUM',
358
+ source: 'error-frequency'
359
+ });
360
+ }
361
+ }
362
+
363
+ // PHASE 3: Success Pattern Recommendations
364
+ const successPatterns = getSuccessPatterns();
365
+ for (const sp of successPatterns) {
366
+ // If intent matches a success pattern, recommend it
367
+ const matchWords = sp.pattern.split('-').map(w => w.toLowerCase());
368
+ if (matchWords.some(w => intent.toLowerCase().includes(w))) {
369
+ recommendations.push({
370
+ id: `SUCCESS-${sp.pattern}`,
371
+ pattern: sp.pattern,
372
+ message: `Good pattern! "${sp.pattern}" has ${sp.count} successes.`,
373
+ type: 'positive'
374
+ });
375
+ }
376
+ }
377
+
378
+ // Check approved auto-rules
379
+ const autoRules = loadAutoRules().filter(r => r.status === 'approved');
380
+ for (const rule of autoRules) {
381
+ if (rule.pattern && intent.toLowerCase().includes(rule.pattern.toLowerCase())) {
382
+ violations.push({
383
+ id: rule.id,
384
+ pattern: rule.pattern,
385
+ prevention: rule.prevention,
386
+ severity: rule.severity,
387
+ source: 'auto-rule'
388
+ });
389
+ }
390
+ }
391
+
392
+ // Check active rules
393
+ const activeRules = loadActiveRules();
394
+ for (const rule of activeRules) {
395
+ if (rule.keywords?.some(kw => intent.toLowerCase().includes(kw))) {
396
+ warnings.push({
397
+ id: rule.id,
398
+ name: rule.name,
399
+ prevention: rule.prevention,
400
+ severity: rule.severity,
401
+ source: 'active'
402
+ });
403
+ }
404
+ }
405
+
406
+ return { violations, warnings, recommendations, detectedIntents };
407
+ }
408
+
409
+ /**
410
+ * Generate prevention advice
411
+ */
412
+ function generateAdvice(violations, warnings) {
413
+ const advice = [];
414
+
415
+ // Critical violations first
416
+ const critical = [...violations, ...warnings].filter(v => v.severity === 'CRITICAL');
417
+ if (critical.length > 0) {
418
+ advice.push({
419
+ level: 'STOP',
420
+ message: 'Critical rules triggered. Address these before proceeding:',
421
+ items: critical.map(v => `[${v.id}] ${v.prevention}`)
422
+ });
423
+ }
424
+
425
+ // High severity
426
+ const high = [...violations, ...warnings].filter(v => v.severity === 'HIGH');
427
+ if (high.length > 0) {
428
+ advice.push({
429
+ level: 'CAUTION',
430
+ message: 'High-priority checks to apply:',
431
+ items: high.map(v => `[${v.id}] ${v.prevention}`)
432
+ });
433
+ }
434
+
435
+ // Medium/Low as tips
436
+ const other = [...violations, ...warnings].filter(v => v.severity === 'MEDIUM' || v.severity === 'LOW');
437
+ if (other.length > 0) {
438
+ advice.push({
439
+ level: 'TIP',
440
+ message: 'Best practices to consider:',
441
+ items: other.map(v => `[${v.id}] ${v.prevention}`)
442
+ });
443
+ }
444
+
445
+ return advice;
446
+ }
447
+
448
+ // ==================== MAIN ====================
449
+
450
+ function runCheck(intent) {
451
+ console.log(`${c.cyan}🛡️ Pre-Execution Check${c.reset}\n`);
452
+ console.log(`${c.gray}Intent: "${intent}"${c.reset}\n`);
453
+
454
+ const { violations, warnings } = checkIntent(intent);
455
+ const advice = generateAdvice(violations, warnings);
456
+
457
+ if (advice.length === 0) {
458
+ console.log(`${c.green}✓ No known issues for this intent${c.reset}`);
459
+ console.log(`${c.gray}Proceed with standard best practices${c.reset}`);
460
+ return { proceed: true, violations: [], warnings: [] };
461
+ }
462
+
463
+ for (const a of advice) {
464
+ const color = {
465
+ 'STOP': c.red,
466
+ 'CAUTION': c.yellow,
467
+ 'TIP': c.blue
468
+ }[a.level] || c.gray;
469
+
470
+ console.log(`${color}${c.bold}${a.level}${c.reset} ${a.message}`);
471
+ for (const item of a.items) {
472
+ console.log(` ${color}●${c.reset} ${item}`);
473
+ }
474
+ console.log('');
475
+ }
476
+
477
+ // Determine if should proceed
478
+ const hasCritical = violations.some(v => v.severity === 'CRITICAL') ||
479
+ warnings.some(v => v.severity === 'CRITICAL');
480
+
481
+ if (hasCritical) {
482
+ console.log(`${c.red}${c.bold}⛔ BLOCKED${c.reset} - Critical rules violated`);
483
+ console.log(`${c.gray}Address critical issues before proceeding${c.reset}`);
484
+ return { proceed: false, violations, warnings };
485
+ }
486
+
487
+ console.log(`${c.yellow}⚠️ PROCEED WITH CAUTION${c.reset}`);
488
+ console.log(`${c.gray}Apply the recommendations above${c.reset}`);
489
+ return { proceed: true, violations, warnings };
490
+ }
491
+
492
+ function listRules() {
493
+ console.log(`${c.cyan}📋 Active Prevention Rules${c.reset}\n`);
494
+
495
+ console.log(`${c.bold}Built-in Rules:${c.reset}`);
496
+ for (const rule of BUILTIN_RULES) {
497
+ const sevColor = { CRITICAL: c.red, HIGH: c.yellow, MEDIUM: c.blue }[rule.severity] || c.gray;
498
+ console.log(` ${c.cyan}${rule.id}${c.reset} ${sevColor}[${rule.severity}]${c.reset}`);
499
+ console.log(` ${rule.name}`);
500
+ console.log(` ${c.gray}${rule.prevention}${c.reset}\n`);
501
+ }
502
+
503
+ const lessons = loadLessons();
504
+ if (lessons.length > 0) {
505
+ console.log(`${c.bold}Lessons (${lessons.length}):${c.reset}`);
506
+ for (const lesson of lessons.slice(0, 5)) {
507
+ console.log(` ${c.cyan}${lesson.id}${c.reset}: ${lesson.pattern}`);
508
+ }
509
+ if (lessons.length > 5) {
510
+ console.log(` ${c.gray}... and ${lessons.length - 5} more${c.reset}`);
511
+ }
512
+ console.log('');
513
+ }
514
+
515
+ const autoRules = loadAutoRules();
516
+ const approved = autoRules.filter(r => r.status === 'approved');
517
+ const pending = autoRules.filter(r => r.status === 'pending');
518
+
519
+ if (approved.length > 0) {
520
+ console.log(`${c.bold}Approved Auto-Rules (${approved.length}):${c.reset}`);
521
+ for (const rule of approved) {
522
+ console.log(` ${c.green}${rule.id}${c.reset}: ${rule.pattern}`);
523
+ }
524
+ console.log('');
525
+ }
526
+
527
+ if (pending.length > 0) {
528
+ console.log(`${c.bold}${c.yellow}Pending Auto-Rules (${pending.length}):${c.reset}`);
529
+ for (const rule of pending) {
530
+ console.log(` ${c.yellow}${rule.id}${c.reset}: ${rule.pattern}`);
531
+ }
532
+ console.log(`\n${c.gray}Approve pending rules with: --approve RULE-ID${c.reset}`);
533
+ }
534
+ }
535
+
536
+ function approveRule(ruleId) {
537
+ const content = fs.readFileSync(autoRulesPath, 'utf8');
538
+ const updated = content.replace(
539
+ new RegExp(`(id:\\s*${ruleId}[\\s\\S]*?status:\\s*)pending`, 'm'),
540
+ '$1approved'
541
+ );
542
+
543
+ if (updated === content) {
544
+ console.log(`${c.red}Rule ${ruleId} not found or already approved${c.reset}`);
545
+ return;
546
+ }
547
+
548
+ fs.writeFileSync(autoRulesPath, updated);
549
+ console.log(`${c.green}✓ Approved rule: ${ruleId}${c.reset}`);
550
+ }
551
+
552
+ function rejectRule(ruleId) {
553
+ const content = fs.readFileSync(autoRulesPath, 'utf8');
554
+ const updated = content.replace(
555
+ new RegExp(`(id:\\s*${ruleId}[\\s\\S]*?status:\\s*)pending`, 'm'),
556
+ '$1rejected'
557
+ );
558
+
559
+ if (updated === content) {
560
+ console.log(`${c.red}Rule ${ruleId} not found or already processed${c.reset}`);
561
+ return;
562
+ }
563
+
564
+ fs.writeFileSync(autoRulesPath, updated);
565
+ console.log(`${c.yellow}✓ Rejected rule: ${ruleId}${c.reset}`);
566
+ }
567
+
568
+ // Parse CLI args
569
+ const args = process.argv.slice(2);
570
+
571
+ if (args.includes('--check') || args.includes('-c')) {
572
+ const idx = args.findIndex(a => a === '--check' || a === '-c');
573
+ const intent = args.slice(idx + 1).join(' ');
574
+ if (intent) {
575
+ runCheck(intent);
576
+ } else {
577
+ console.log(`${c.red}Error: --check requires an intent description${c.reset}`);
578
+ }
579
+ } else if (args.includes('--list') || args.includes('-l')) {
580
+ listRules();
581
+ } else if (args.includes('--approve')) {
582
+ const idx = args.findIndex(a => a === '--approve');
583
+ const ruleId = args[idx + 1];
584
+ if (ruleId) {
585
+ approveRule(ruleId);
586
+ } else {
587
+ console.log(`${c.red}Error: --approve requires a rule ID${c.reset}`);
588
+ }
589
+ } else if (args.includes('--reject')) {
590
+ const idx = args.findIndex(a => a === '--reject');
591
+ const ruleId = args[idx + 1];
592
+ if (ruleId) {
593
+ rejectRule(ruleId);
594
+ } else {
595
+ console.log(`${c.red}Error: --reject requires a rule ID${c.reset}`);
596
+ }
597
+ } else {
598
+ console.log(`${c.cyan}pre_execution_check - Prevent known errors before they happen${c.reset}
599
+
600
+ ${c.bold}Usage:${c.reset}
601
+ node pre_execution_check.js --check "intent" Check intent against rules
602
+ node pre_execution_check.js --list List all active rules
603
+ node pre_execution_check.js --approve ID Approve an auto-rule
604
+ node pre_execution_check.js --reject ID Reject an auto-rule
605
+
606
+ ${c.bold}Examples:${c.reset}
607
+ node pre_execution_check.js --check "create async function to fetch API"
608
+ node pre_execution_check.js --check "complete task and notify user"
609
+ node pre_execution_check.js --approve AUTO-IMPORT
610
+
611
+ ${c.bold}Rule sources:${c.reset}
612
+ • Built-in rules (7 core patterns)
613
+ • Lessons from lessons-learned.json
614
+ • Approved auto-rules from auto-rules.yaml
615
+
616
+ ${c.bold}Output levels:${c.reset}
617
+ STOP - Critical violation, must address
618
+ CAUTION - High priority, should address
619
+ TIP - Best practice recommendation
620
+ `);
621
+ }
622
+
623
+ export { runCheck, checkIntent, generateAdvice, loadActiveRules };