@rulecatch/ai-pooler 0.4.0

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.
@@ -0,0 +1,625 @@
1
+ /**
2
+ * Rulecatch AI - MCP Development Analytics Types
3
+ *
4
+ * Event types and interfaces for tracking AI-assisted development metrics.
5
+ */
6
+ /**
7
+ * Types of events tracked by Rulecatch AI
8
+ */
9
+ type AIEventType = 'ai_request' | 'ai_response' | 'tool_call' | 'tool_result' | 'code_accept' | 'code_reject' | 'code_modify' | 'session_start' | 'session_end' | 'session_pause' | 'session_resume' | 'conversation_turn' | 'file_operation' | 'rule_deviation' | 'error';
10
+ /**
11
+ * Categories of rule violations that can be tracked
12
+ */
13
+ type RuleViolationCategory = 'coding_standard' | 'db_pattern' | 'security' | 'performance' | 'architecture' | 'documentation' | 'testing' | 'custom';
14
+ /**
15
+ * Severity levels for rule violations
16
+ */
17
+ type RuleViolationSeverity = 'info' | 'warning' | 'error';
18
+ /**
19
+ * Supported AI models for cost calculation
20
+ * Updated January 2026
21
+ */
22
+ type AIModel = 'claude-opus-4-5' | 'claude-sonnet-4' | 'claude-3.5-sonnet' | 'claude-3.5-haiku' | 'claude-3-opus' | 'claude-3-sonnet' | 'claude-3-haiku' | 'gpt-4' | 'gpt-4-turbo' | 'gpt-4o' | 'gpt-4o-mini' | 'o1' | 'o1-mini' | 'o1-pro' | 'gemini-2.0-flash' | 'gemini-1.5-pro' | 'gemini-1.5-flash' | 'unknown';
23
+ /**
24
+ * Base event interface for all AI development events
25
+ */
26
+ interface AIDevEvent {
27
+ /** Event type identifier */
28
+ type: AIEventType;
29
+ /** ISO 8601 timestamp */
30
+ timestamp: string;
31
+ /** Unique session identifier */
32
+ sessionId: string;
33
+ /** Project identifier (from license) */
34
+ projectId: string;
35
+ /** Input tokens consumed */
36
+ inputTokens?: number;
37
+ /** Output tokens generated */
38
+ outputTokens?: number;
39
+ /** Cache read tokens (prompt caching) */
40
+ cacheReadTokens?: number;
41
+ /** Cache write tokens (prompt caching) */
42
+ cacheWriteTokens?: number;
43
+ /** Thinking tokens (extended thinking) */
44
+ thinkingTokens?: number;
45
+ /** Prompt character length */
46
+ promptLength?: number;
47
+ /** Response character length */
48
+ responseLength?: number;
49
+ /** Context window usage (0-1) */
50
+ contextUsage?: number;
51
+ /** Time to first token in ms */
52
+ timeToFirstToken?: number;
53
+ /** Total response time in ms */
54
+ totalResponseTime?: number;
55
+ /** Active coding time in ms (excludes idle) */
56
+ activeTime?: number;
57
+ /** Request latency in ms */
58
+ latency?: number;
59
+ /** AI model used */
60
+ model?: AIModel | string;
61
+ /** Estimated cost in USD */
62
+ estimatedCost?: number;
63
+ /** Was prompt cached */
64
+ promptCached?: boolean;
65
+ /** MCP tool name (for tool events) */
66
+ toolName?: string;
67
+ /** Whether the tool call succeeded */
68
+ toolSuccess?: boolean;
69
+ /** Tool execution duration in ms */
70
+ toolDuration?: number;
71
+ /** Tool input size (for Bash commands, file content, etc.) */
72
+ toolInputSize?: number;
73
+ /** Tool output size */
74
+ toolOutputSize?: number;
75
+ /** Lines of code added */
76
+ linesAdded?: number;
77
+ /** Lines of code removed */
78
+ linesRemoved?: number;
79
+ /** Files modified in this event */
80
+ filesModified?: string[];
81
+ /** Programming language */
82
+ language?: string;
83
+ /** Framework or library context */
84
+ framework?: string;
85
+ /** File operation type */
86
+ fileOperation?: 'read' | 'write' | 'edit' | 'delete' | 'create';
87
+ /** Conversation turn number */
88
+ turnNumber?: number;
89
+ /** Whether user intervened/modified */
90
+ userIntervention?: boolean;
91
+ /** Task/feature being worked on */
92
+ taskContext?: string;
93
+ /** Error message if event is an error */
94
+ errorMessage?: string;
95
+ /** Error was recovered from */
96
+ errorRecovered?: boolean;
97
+ /** Retry attempt number */
98
+ retryAttempt?: number;
99
+ /** Rule that was deviated from (for rule_deviation events) */
100
+ ruleName?: string;
101
+ /** Source of the rule (e.g., "CLAUDE.md", "eslint", "project-standards") */
102
+ ruleSource?: string;
103
+ /** Category of the rule violation */
104
+ ruleCategory?: RuleViolationCategory;
105
+ /** Severity of the violation */
106
+ ruleSeverity?: RuleViolationSeverity;
107
+ /** Description of what rule was violated (rule violation) */
108
+ ruleDescription?: string;
109
+ /** The problematic code or pattern that violated the rule */
110
+ violatingCode?: string;
111
+ /** Suggested fix or correct pattern */
112
+ suggestedFix?: string;
113
+ /** File where the violation occurred */
114
+ violationFile?: string;
115
+ /** Line number(s) where violation occurred */
116
+ violationLine?: number;
117
+ /** Whether the violation was auto-corrected */
118
+ corrected?: boolean;
119
+ /** Confidence score that this is actually a violation (0-1) */
120
+ violationConfidence?: number;
121
+ /** Git username */
122
+ gitUsername?: string;
123
+ /** Git email */
124
+ gitEmail?: string;
125
+ /** Repository name (e.g., "user/repo") */
126
+ gitRepo?: string;
127
+ /** Current branch */
128
+ gitBranch?: string;
129
+ /** Current commit (short hash) */
130
+ gitCommit?: string;
131
+ /** Whether there are uncommitted changes */
132
+ gitDirty?: boolean;
133
+ /** Additional metadata */
134
+ metadata?: Record<string, unknown>;
135
+ }
136
+ /**
137
+ * Session metrics aggregated from events
138
+ */
139
+ interface SessionMetrics {
140
+ /** Session identifier */
141
+ sessionId: string;
142
+ /** Session start time */
143
+ startTime: string;
144
+ /** Session end time (if ended) */
145
+ endTime?: string;
146
+ /** Total elapsed duration in seconds */
147
+ duration: number;
148
+ /** Active coding time in seconds (excludes idle) */
149
+ activeDuration: number;
150
+ /** Total input tokens */
151
+ totalInputTokens: number;
152
+ /** Total output tokens */
153
+ totalOutputTokens: number;
154
+ /** Total thinking tokens */
155
+ totalThinkingTokens: number;
156
+ /** Total cache read tokens */
157
+ totalCacheReadTokens: number;
158
+ /** Cache hit rate (0-1) */
159
+ cacheHitRate: number;
160
+ /** Average context usage (0-1) */
161
+ avgContextUsage: number;
162
+ /** Total estimated cost in USD */
163
+ totalCost: number;
164
+ /** Cost breakdown by file */
165
+ costByFile: Record<string, number>;
166
+ /** Cost breakdown by language */
167
+ costByLanguage: Record<string, number>;
168
+ /** Number of AI requests */
169
+ requestCount: number;
170
+ /** Number of conversation turns */
171
+ conversationTurns: number;
172
+ /** Average response time in ms */
173
+ avgResponseTime: number;
174
+ /** Average time to first token in ms */
175
+ avgTimeToFirstToken: number;
176
+ /** Number of tool calls */
177
+ toolCallCount: number;
178
+ /** Tool success rate (0-1) */
179
+ toolSuccessRate: number;
180
+ /** Tool calls by name */
181
+ toolCallsByName: Record<string, number>;
182
+ /** Tool failures by name */
183
+ toolFailuresByName: Record<string, number>;
184
+ /** Lines of code added */
185
+ totalLinesAdded: number;
186
+ /** Lines of code removed */
187
+ totalLinesRemoved: number;
188
+ /** Net lines changed */
189
+ netLinesChanged: number;
190
+ /** Unique files modified */
191
+ uniqueFilesModified: number;
192
+ /** Files with most changes */
193
+ topModifiedFiles: Array<{
194
+ file: string;
195
+ changes: number;
196
+ }>;
197
+ /** Code acceptance rate (0-1) */
198
+ codeAcceptanceRate: number;
199
+ /** User intervention rate (0-1) */
200
+ userInterventionRate: number;
201
+ /** Most used model */
202
+ primaryModel: string;
203
+ /** Models used with request counts */
204
+ modelUsage: Record<string, number>;
205
+ /** Languages used */
206
+ languages: string[];
207
+ /** Tokens per minute */
208
+ tokensPerMinute: number;
209
+ /** Lines per hour */
210
+ linesPerHour: number;
211
+ /** Cost per line of code */
212
+ costPerLine: number;
213
+ /** Errors encountered */
214
+ errorCount: number;
215
+ /** Error recovery rate */
216
+ errorRecoveryRate: number;
217
+ /** Total rule violations detected */
218
+ totalRuleViolations: number;
219
+ /** Rule violations by category */
220
+ violationsByCategory: Record<RuleViolationCategory, number>;
221
+ /** Rule violations by severity */
222
+ violationsBySeverity: Record<RuleViolationSeverity, number>;
223
+ /** Rule violations by source (CLAUDE.md, eslint, etc.) */
224
+ violationsBySource: Record<string, number>;
225
+ /** Most common rule violations */
226
+ topRuleViolations: Array<{
227
+ rule: string;
228
+ count: number;
229
+ severity: RuleViolationSeverity;
230
+ }>;
231
+ /** Percentage of violations that were auto-corrected */
232
+ violationCorrectionRate: number;
233
+ /** Files with most violations */
234
+ filesWithMostViolations: Array<{
235
+ file: string;
236
+ count: number;
237
+ }>;
238
+ }
239
+ /**
240
+ * Git context information collected automatically
241
+ */
242
+ interface GitContext {
243
+ /** Git username (from git config user.name) */
244
+ username?: string;
245
+ /** Git email (from git config user.email) */
246
+ email?: string;
247
+ /** Remote repository URL */
248
+ repoUrl?: string;
249
+ /** Repository name (extracted from URL) */
250
+ repoName?: string;
251
+ /** Current branch name */
252
+ branch?: string;
253
+ /** Current commit hash (short) */
254
+ commit?: string;
255
+ /** Full commit hash */
256
+ commitFull?: string;
257
+ /** Commit message (first line) */
258
+ commitMessage?: string;
259
+ /** Commit author */
260
+ commitAuthor?: string;
261
+ /** Commit timestamp */
262
+ commitTimestamp?: string;
263
+ /** Whether there are uncommitted changes */
264
+ isDirty?: boolean;
265
+ /** Number of uncommitted files */
266
+ uncommittedFiles?: number;
267
+ /** Root directory of the git repository */
268
+ rootDir?: string;
269
+ }
270
+ /**
271
+ * Configuration for the MCP server
272
+ */
273
+ interface MCPConfig {
274
+ /** Rulecatch AI license key */
275
+ licenseKey?: string;
276
+ /** Project identifier */
277
+ projectId: string;
278
+ /** Rulecatch API endpoint */
279
+ endpoint?: string;
280
+ /** Enable debug logging */
281
+ debug?: boolean;
282
+ /** Batch events before sending */
283
+ batchSize?: number;
284
+ /** Flush interval in ms */
285
+ flushInterval?: number;
286
+ /** Include file paths in events */
287
+ includeFilePaths?: boolean;
288
+ /** Languages to track (empty = all) */
289
+ trackLanguages?: string[];
290
+ /** Track active time (requires more events) */
291
+ trackActiveTime?: boolean;
292
+ /** Idle timeout in ms (default: 5 minutes) */
293
+ idleTimeout?: number;
294
+ /** Automatically collect and send git context */
295
+ trackGitContext?: boolean;
296
+ /** Working directory for git context collection */
297
+ cwd?: string;
298
+ /** Project version (semver) for version correlation */
299
+ version?: string;
300
+ /** Git commit hash for version correlation */
301
+ commit?: string;
302
+ }
303
+ /**
304
+ * Model pricing per 1M tokens
305
+ * Updated January 2026
306
+ */
307
+ interface ModelPricing {
308
+ inputPer1M: number;
309
+ outputPer1M: number;
310
+ cacheReadPer1M?: number;
311
+ cacheWritePer1M?: number;
312
+ thinkingPer1M?: number;
313
+ }
314
+ /**
315
+ * Pricing table for cost calculation
316
+ * Source: Official pricing pages as of January 2026
317
+ */
318
+ declare const MODEL_PRICING: Record<AIModel, ModelPricing>;
319
+ /**
320
+ * Calculate cost from token usage with caching support
321
+ */
322
+ declare function calculateCost(model: AIModel | string, inputTokens: number, outputTokens: number, options?: {
323
+ cacheReadTokens?: number;
324
+ cacheWriteTokens?: number;
325
+ thinkingTokens?: number;
326
+ }): number;
327
+ /**
328
+ * Estimate tokens from character count
329
+ * Rough approximation: ~4 chars per token for English
330
+ */
331
+ declare function estimateTokens(charCount: number): number;
332
+ /**
333
+ * Format duration in human-readable form
334
+ */
335
+ declare function formatDuration(seconds: number): string;
336
+ /**
337
+ * Format cost in USD
338
+ */
339
+ declare function formatCost(cost: number): string;
340
+
341
+ /**
342
+ * Client-side encryption for PII (Zero-Knowledge Architecture)
343
+ *
344
+ * All PII (emails, usernames, file paths) is encrypted on the client
345
+ * before being sent to Rulecatch API. We never see plaintext PII.
346
+ *
347
+ * The user's privacy key is derived from their password or a separate
348
+ * key they set during setup. Without this key, the data is unreadable.
349
+ */
350
+ interface EncryptedField {
351
+ /** Base64-encoded ciphertext */
352
+ ciphertext: string;
353
+ /** Base64-encoded initialization vector */
354
+ iv: string;
355
+ /** Base64-encoded authentication tag (GCM) */
356
+ tag: string;
357
+ }
358
+ interface PrivacyConfig {
359
+ /** User's privacy key (password-derived or standalone) */
360
+ privacyKey: string;
361
+ /** Salt for key derivation (stored with user account, not secret) */
362
+ salt: string;
363
+ }
364
+ /**
365
+ * Derive an encryption key from a password/passphrase
366
+ * Uses PBKDF2 with 100k iterations for brute-force resistance
367
+ */
368
+ declare function deriveKey(password: string, salt: string): Buffer;
369
+ /**
370
+ * Generate a random salt for new users
371
+ */
372
+ declare function generateSalt(): string;
373
+ /**
374
+ * Encrypt a PII field (email, username, file path, etc.)
375
+ * Returns ciphertext + IV + auth tag for storage
376
+ */
377
+ declare function encryptPII(plaintext: string, key: Buffer): EncryptedField;
378
+ /**
379
+ * Decrypt a PII field
380
+ * Used client-side in the dashboard to show actual values
381
+ */
382
+ declare function decryptPII(encrypted: EncryptedField, key: Buffer): string;
383
+ /**
384
+ * Create a one-way hash for indexing/grouping
385
+ * Cannot be reversed, but same input = same hash (for deduplication)
386
+ *
387
+ * We use a truncated hash (16 chars) to prevent rainbow table attacks
388
+ * while still allowing grouping by the same identifier.
389
+ */
390
+ declare function hashForIndex(plaintext: string, salt: string): string;
391
+ /**
392
+ * Encrypt all PII fields in an event payload
393
+ * Non-PII fields are passed through unchanged
394
+ */
395
+ declare function encryptEventPII(event: Record<string, unknown>, key: Buffer, salt: string): Record<string, unknown>;
396
+ /**
397
+ * Decrypt all PII fields in an event payload
398
+ * Used in the dashboard to display actual values
399
+ */
400
+ declare function decryptEventPII(event: Record<string, unknown>, key: Buffer): Record<string, unknown>;
401
+ /**
402
+ * Verify a privacy key is correct by attempting to decrypt a test value
403
+ */
404
+ declare function verifyPrivacyKey(testCiphertext: EncryptedField, expectedPlaintext: string, key: Buffer): boolean;
405
+
406
+ /**
407
+ * Git Context Collection
408
+ *
409
+ * Automatically collects git information from the current repository.
410
+ * This provides context about the development environment to track
411
+ * which project/branch/commit is being worked on.
412
+ */
413
+
414
+ /**
415
+ * Check if we're in a git repository
416
+ */
417
+ declare function isGitRepo(cwd?: string): boolean;
418
+ /**
419
+ * Get the root directory of the git repository
420
+ */
421
+ declare function getGitRoot(cwd?: string): string | null;
422
+ /**
423
+ * Collect git context from the current directory
424
+ */
425
+ declare function collectGitContext(cwd?: string): GitContext;
426
+ /**
427
+ * Watch for git changes (branch switches, commits, etc.)
428
+ * Returns a cleanup function to stop watching
429
+ */
430
+ declare function watchGitChanges(callback: (context: GitContext) => void, options?: {
431
+ cwd?: string;
432
+ pollInterval?: number;
433
+ }): () => void;
434
+ /**
435
+ * Get a summary string for the current git context
436
+ */
437
+ declare function getGitSummary(context: GitContext): string;
438
+
439
+ /**
440
+ * @rulecatch/ai-pooler - AI Development Analytics Pooler
441
+ *
442
+ * Production-grade tracking for AI-assisted development including:
443
+ * - Token usage with prompt caching and thinking tokens
444
+ * - Active time tracking (coding vs idle)
445
+ * - Per-file and per-language cost breakdown
446
+ * - Conversation turns and user interventions
447
+ * - Response latency metrics
448
+ */
449
+
450
+ /**
451
+ * Initialize the Rulecatch AI MCP server
452
+ */
453
+ declare function init(options: MCPConfig): void;
454
+ /**
455
+ * Start a new development session
456
+ */
457
+ declare function startSession(): string;
458
+ /**
459
+ * End the current session
460
+ */
461
+ declare function endSession(): SessionMetrics | null;
462
+ /**
463
+ * Track an AI request/response with full metrics
464
+ */
465
+ declare function trackAIRequest(params: {
466
+ model: AIModel | string;
467
+ inputTokens: number;
468
+ outputTokens: number;
469
+ cacheReadTokens?: number;
470
+ cacheWriteTokens?: number;
471
+ thinkingTokens?: number;
472
+ promptLength?: number;
473
+ responseLength?: number;
474
+ contextUsage?: number;
475
+ timeToFirstToken?: number;
476
+ totalResponseTime?: number;
477
+ filesContext?: string[];
478
+ language?: string;
479
+ taskContext?: string;
480
+ metadata?: Record<string, unknown>;
481
+ }): void;
482
+ /**
483
+ * Track a conversation turn (user message + AI response cycle)
484
+ */
485
+ declare function trackConversationTurn(params: {
486
+ userIntervention?: boolean;
487
+ taskContext?: string;
488
+ metadata?: Record<string, unknown>;
489
+ }): void;
490
+ /**
491
+ * Track a tool call with enhanced metrics
492
+ */
493
+ declare function trackToolCall(params: {
494
+ toolName: string;
495
+ success: boolean;
496
+ duration: number;
497
+ inputSize?: number;
498
+ outputSize?: number;
499
+ linesAdded?: number;
500
+ linesRemoved?: number;
501
+ filesModified?: string[];
502
+ language?: string;
503
+ fileOperation?: 'read' | 'write' | 'edit' | 'delete' | 'create';
504
+ retryAttempt?: number;
505
+ metadata?: Record<string, unknown>;
506
+ }): void;
507
+ /**
508
+ * Track file operation (read/write/edit)
509
+ */
510
+ declare function trackFileOperation(params: {
511
+ operation: 'read' | 'write' | 'edit' | 'delete' | 'create';
512
+ file: string;
513
+ linesAdded?: number;
514
+ linesRemoved?: number;
515
+ language?: string;
516
+ duration?: number;
517
+ }): void;
518
+ /**
519
+ * Track code acceptance/rejection with context
520
+ */
521
+ declare function trackCodeDecision(params: {
522
+ accepted: boolean;
523
+ linesAdded?: number;
524
+ linesRemoved?: number;
525
+ filesModified?: string[];
526
+ language?: string;
527
+ userIntervention?: boolean;
528
+ taskContext?: string;
529
+ }): void;
530
+ /**
531
+ * Track an error event
532
+ */
533
+ declare function trackError(params: {
534
+ message: string;
535
+ recovered?: boolean;
536
+ retryAttempt?: number;
537
+ toolName?: string;
538
+ metadata?: Record<string, unknown>;
539
+ }): void;
540
+ /**
541
+ * Track a rule violation (coding standard violation, pattern anti-pattern, etc.)
542
+ *
543
+ * Use this to track when AI-generated code violates established
544
+ * project rules like those in CLAUDE.md, eslint configs, or architectural patterns.
545
+ *
546
+ * @example
547
+ * trackRuleDeviation({
548
+ * ruleName: 'use-bulkwrite',
549
+ * ruleSource: 'CLAUDE.md',
550
+ * category: 'db_pattern',
551
+ * severity: 'warning',
552
+ * description: 'MongoDB writes should use bulkWrite instead of individual operations',
553
+ * violatingCode: 'await collection.updateOne(...)',
554
+ * suggestedFix: 'Use collection.bulkWrite([{ updateOne: {...} }])',
555
+ * file: 'src/api/ingest.ts',
556
+ * line: 238,
557
+ * corrected: true,
558
+ * confidence: 0.95,
559
+ * });
560
+ */
561
+ declare function trackRuleDeviation(params: {
562
+ /** Name/identifier of the rule that was violated */
563
+ ruleName: string;
564
+ /** Source of the rule (e.g., "CLAUDE.md", "eslint", "project-standards") */
565
+ ruleSource?: string;
566
+ /** Category of the rule violation */
567
+ category?: RuleViolationCategory;
568
+ /** Severity of the violation */
569
+ severity?: RuleViolationSeverity;
570
+ /** Description of what rule was violated */
571
+ description?: string;
572
+ /** The problematic code or pattern */
573
+ violatingCode?: string;
574
+ /** Suggested fix or correct pattern */
575
+ suggestedFix?: string;
576
+ /** File where the violation occurred */
577
+ file?: string;
578
+ /** Line number where violation occurred */
579
+ line?: number;
580
+ /** Whether the violation was auto-corrected */
581
+ corrected?: boolean;
582
+ /** Confidence score (0-1) that this is actually a violation */
583
+ confidence?: number;
584
+ /** Additional metadata */
585
+ metadata?: Record<string, unknown>;
586
+ }): void;
587
+ /**
588
+ * Track a generic event
589
+ */
590
+ declare function track(event: AIDevEvent): void;
591
+ /**
592
+ * Flush events to Rulecatch API
593
+ */
594
+ declare function flush(): Promise<void>;
595
+ /**
596
+ * Get current session metrics
597
+ */
598
+ declare function getSessionMetrics(): SessionMetrics | null;
599
+ /**
600
+ * Check if a session is active
601
+ */
602
+ declare function isSessionActive(): boolean;
603
+ /**
604
+ * Get current session ID
605
+ */
606
+ declare function getSessionId(): string | null;
607
+ /**
608
+ * Pause session (marks idle period)
609
+ */
610
+ declare function pauseSession(): void;
611
+ /**
612
+ * Resume session
613
+ */
614
+ declare function resumeSession(): void;
615
+ /**
616
+ * Get current git context
617
+ */
618
+ declare function getGitContext(): GitContext;
619
+ /**
620
+ * Manually refresh git context
621
+ */
622
+ declare function refreshGitContext(): GitContext;
623
+
624
+ export { MODEL_PRICING, calculateCost, collectGitContext, decryptEventPII, decryptPII, deriveKey, encryptEventPII, encryptPII, endSession, estimateTokens, flush, formatCost, formatDuration, generateSalt, getGitContext, getGitRoot, getGitSummary, getSessionId, getSessionMetrics, hashForIndex, init, isGitRepo, isSessionActive, pauseSession, refreshGitContext, resumeSession, startSession, track, trackAIRequest, trackCodeDecision, trackConversationTurn, trackError, trackFileOperation, trackRuleDeviation, trackToolCall, verifyPrivacyKey, watchGitChanges };
625
+ export type { AIDevEvent, AIEventType, AIModel, EncryptedField, GitContext, MCPConfig, ModelPricing, PrivacyConfig, RuleViolationCategory, RuleViolationSeverity, SessionMetrics };