@claudetools/tools 0.3.9 → 0.5.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.
- package/README.md +60 -4
- package/dist/cli.js +0 -0
- package/dist/codedna/generators/base.d.ts +41 -0
- package/dist/codedna/generators/base.js +102 -0
- package/dist/codedna/generators/express-api.d.ts +12 -0
- package/dist/codedna/generators/express-api.js +61 -0
- package/dist/codedna/index.d.ts +4 -0
- package/dist/codedna/index.js +7 -0
- package/dist/codedna/parser.d.ts +117 -0
- package/dist/codedna/parser.js +233 -0
- package/dist/codedna/registry.d.ts +60 -0
- package/dist/codedna/registry.js +217 -0
- package/dist/codedna/template-engine.d.ts +17 -0
- package/dist/codedna/template-engine.js +183 -0
- package/dist/codedna/types.d.ts +64 -0
- package/dist/codedna/types.js +4 -0
- package/dist/handlers/codedna-handlers.d.ts +122 -0
- package/dist/handlers/codedna-handlers.js +194 -0
- package/dist/handlers/tool-handlers.js +593 -14
- package/dist/helpers/api-client.d.ts +37 -0
- package/dist/helpers/api-client.js +70 -0
- package/dist/helpers/codedna-monitoring.d.ts +34 -0
- package/dist/helpers/codedna-monitoring.js +159 -0
- package/dist/helpers/error-tracking.d.ts +73 -0
- package/dist/helpers/error-tracking.js +164 -0
- package/dist/helpers/library-detection.d.ts +26 -0
- package/dist/helpers/library-detection.js +145 -0
- package/dist/helpers/tasks-retry.d.ts +49 -0
- package/dist/helpers/tasks-retry.js +168 -0
- package/dist/helpers/tasks.d.ts +24 -1
- package/dist/helpers/tasks.js +146 -50
- package/dist/helpers/usage-analytics.d.ts +91 -0
- package/dist/helpers/usage-analytics.js +256 -0
- package/dist/helpers/workers.d.ts +25 -0
- package/dist/helpers/workers.js +80 -0
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.js +16 -5
- package/dist/tools.js +314 -0
- package/docs/AUTO-REGISTRATION.md +353 -0
- package/docs/CLAUDE4_PROMPT_ANALYSIS.md +589 -0
- package/docs/ENTITY_DSL_REFERENCE.md +685 -0
- package/docs/MODERN_STACK_COMPLETE_GUIDE.md +706 -0
- package/docs/PROMPT_STANDARDIZATION_RESULTS.md +324 -0
- package/docs/PROMPT_TIER_TEMPLATES.md +787 -0
- package/docs/RESEARCH_METHODOLOGY_EXTRACTION.md +336 -0
- package/package.json +14 -3
- package/scripts/verify-prompt-compliance.sh +197 -0
|
@@ -48,3 +48,40 @@ export declare function injectContext(projectId: string, query: string, userId?:
|
|
|
48
48
|
reason?: string;
|
|
49
49
|
};
|
|
50
50
|
}>;
|
|
51
|
+
export interface CachedDoc {
|
|
52
|
+
library: string;
|
|
53
|
+
context7Id: string | null;
|
|
54
|
+
version: string | null;
|
|
55
|
+
fetchedAt: string;
|
|
56
|
+
size: number;
|
|
57
|
+
mode: 'code' | 'info';
|
|
58
|
+
content: string;
|
|
59
|
+
library_name?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface DocsCacheListResponse {
|
|
62
|
+
libraries: {
|
|
63
|
+
library_id: string;
|
|
64
|
+
library_name: string;
|
|
65
|
+
topics?: string[];
|
|
66
|
+
cached_at: string;
|
|
67
|
+
}[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* List all cached documentation libraries (global cache)
|
|
71
|
+
*/
|
|
72
|
+
export declare function listCachedDocs(_projectId?: string): Promise<DocsCacheListResponse>;
|
|
73
|
+
/**
|
|
74
|
+
* Get cached documentation for a specific library
|
|
75
|
+
*/
|
|
76
|
+
export declare function getCachedDocs(_projectId: string, // Unused - docs cache is global
|
|
77
|
+
libraryId: string, topic?: string): Promise<CachedDoc | null>;
|
|
78
|
+
/**
|
|
79
|
+
* Ensure documentation is cached (fetches from Context7 if needed)
|
|
80
|
+
*/
|
|
81
|
+
export declare function cacheDocs(_projectId: string, // Unused - docs cache is global
|
|
82
|
+
libraryId: string, libraryName: string, _content?: string, // Unused - backend fetches from Context7
|
|
83
|
+
topic?: string): Promise<{
|
|
84
|
+
success: boolean;
|
|
85
|
+
status?: string;
|
|
86
|
+
size?: number;
|
|
87
|
+
}>;
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
// API Client and Memory Operations
|
|
3
3
|
// =============================================================================
|
|
4
4
|
import { API_BASE_URL, DEFAULT_USER_ID } from './config.js';
|
|
5
|
+
import { getConfig } from './config-manager.js';
|
|
5
6
|
export async function apiRequest(endpoint, method = 'GET', body) {
|
|
7
|
+
const config = getConfig();
|
|
8
|
+
const apiKey = config.apiKey || process.env.CLAUDETOOLS_API_KEY || process.env.MEMORY_API_KEY;
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
throw new Error('No API key found. Set CLAUDETOOLS_API_KEY or MEMORY_API_KEY in environment or ~/.claudetools/config.json');
|
|
11
|
+
}
|
|
6
12
|
const url = `${API_BASE_URL}${endpoint}`;
|
|
7
13
|
const options = {
|
|
8
14
|
method,
|
|
9
15
|
headers: {
|
|
10
16
|
'Content-Type': 'application/json',
|
|
17
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
11
18
|
},
|
|
12
19
|
};
|
|
13
20
|
if (body) {
|
|
@@ -57,3 +64,66 @@ export async function injectContext(projectId, query, userId = DEFAULT_USER_ID)
|
|
|
57
64
|
});
|
|
58
65
|
return response.data;
|
|
59
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* List all cached documentation libraries (global cache)
|
|
69
|
+
*/
|
|
70
|
+
export async function listCachedDocs(_projectId // Unused - docs cache is global
|
|
71
|
+
) {
|
|
72
|
+
try {
|
|
73
|
+
const response = await apiRequest('/api/v1/docs');
|
|
74
|
+
// Transform to expected format
|
|
75
|
+
return {
|
|
76
|
+
libraries: response.data.libraries.map(lib => ({
|
|
77
|
+
library_id: lib.library,
|
|
78
|
+
library_name: lib.library,
|
|
79
|
+
cached_at: new Date().toISOString(), // Not provided by list endpoint
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return { libraries: [] };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get cached documentation for a specific library
|
|
89
|
+
*/
|
|
90
|
+
export async function getCachedDocs(_projectId, // Unused - docs cache is global
|
|
91
|
+
libraryId, topic) {
|
|
92
|
+
try {
|
|
93
|
+
const modeParam = topic ? `?mode=info` : '';
|
|
94
|
+
const response = await apiRequest(`/api/v1/docs/${encodeURIComponent(libraryId)}${modeParam}`);
|
|
95
|
+
if (!response.success || !response.data) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
// Add compatibility alias
|
|
99
|
+
return {
|
|
100
|
+
...response.data,
|
|
101
|
+
library_name: response.data.library,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Ensure documentation is cached (fetches from Context7 if needed)
|
|
110
|
+
*/
|
|
111
|
+
export async function cacheDocs(_projectId, // Unused - docs cache is global
|
|
112
|
+
libraryId, libraryName, _content, // Unused - backend fetches from Context7
|
|
113
|
+
topic) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await apiRequest('/api/v1/docs/ensure', 'POST', {
|
|
116
|
+
library: libraryName || libraryId,
|
|
117
|
+
mode: topic ? 'info' : 'code',
|
|
118
|
+
topic,
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
success: response.success,
|
|
122
|
+
status: response.data?.status,
|
|
123
|
+
size: response.data?.size,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return { success: false };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ErrorRateResult } from './error-tracking.js';
|
|
2
|
+
export interface DashboardMetrics {
|
|
3
|
+
timeRange: string;
|
|
4
|
+
errorMetrics: ErrorRateResult;
|
|
5
|
+
alerts: Alert[];
|
|
6
|
+
recommendations: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface Alert {
|
|
9
|
+
level: 'info' | 'warning' | 'critical';
|
|
10
|
+
message: string;
|
|
11
|
+
metric: string;
|
|
12
|
+
value: number;
|
|
13
|
+
threshold: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get dashboard metrics for a time range
|
|
17
|
+
*/
|
|
18
|
+
export declare function getDashboardMetrics(startTime: string, endTime: string): Promise<DashboardMetrics>;
|
|
19
|
+
/**
|
|
20
|
+
* Get error metrics for last 24 hours
|
|
21
|
+
*/
|
|
22
|
+
export declare function getLast24Hours(): Promise<DashboardMetrics>;
|
|
23
|
+
/**
|
|
24
|
+
* Get error metrics for last 7 days
|
|
25
|
+
*/
|
|
26
|
+
export declare function getLast7Days(): Promise<DashboardMetrics>;
|
|
27
|
+
/**
|
|
28
|
+
* Print dashboard to console
|
|
29
|
+
*/
|
|
30
|
+
export declare function printDashboard(metrics: DashboardMetrics): void;
|
|
31
|
+
/**
|
|
32
|
+
* CLI command: npm run codedna:monitor
|
|
33
|
+
*/
|
|
34
|
+
export declare function runMonitoring(): Promise<void>;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// CodeDNA Monitoring Dashboard
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Query functions for monitoring CodeDNA performance and error rates.
|
|
6
|
+
//
|
|
7
|
+
import { getErrorRate } from './error-tracking.js';
|
|
8
|
+
/**
|
|
9
|
+
* Get dashboard metrics for a time range
|
|
10
|
+
*/
|
|
11
|
+
export async function getDashboardMetrics(startTime, endTime) {
|
|
12
|
+
const errorMetrics = await getErrorRate({ startTime, endTime });
|
|
13
|
+
const alerts = [];
|
|
14
|
+
const recommendations = [];
|
|
15
|
+
// Check error rate threshold (>5% is warning, >10% is critical)
|
|
16
|
+
if (errorMetrics.errorRate > 10) {
|
|
17
|
+
alerts.push({
|
|
18
|
+
level: 'critical',
|
|
19
|
+
message: 'CodeDNA error rate exceeds 10%',
|
|
20
|
+
metric: 'error_rate',
|
|
21
|
+
value: errorMetrics.errorRate,
|
|
22
|
+
threshold: 10,
|
|
23
|
+
});
|
|
24
|
+
recommendations.push('Investigate template fetch errors and validation failures');
|
|
25
|
+
recommendations.push('Check Cloudflare Workers logs for registry issues');
|
|
26
|
+
}
|
|
27
|
+
else if (errorMetrics.errorRate > 5) {
|
|
28
|
+
alerts.push({
|
|
29
|
+
level: 'warning',
|
|
30
|
+
message: 'CodeDNA error rate exceeds 5%',
|
|
31
|
+
metric: 'error_rate',
|
|
32
|
+
value: errorMetrics.errorRate,
|
|
33
|
+
threshold: 5,
|
|
34
|
+
});
|
|
35
|
+
recommendations.push('Monitor error trends over next 24 hours');
|
|
36
|
+
}
|
|
37
|
+
// Check validation errors
|
|
38
|
+
const validationErrors = errorMetrics.errorsByType['validation_error'] || 0;
|
|
39
|
+
if (validationErrors > errorMetrics.totalErrors * 0.5) {
|
|
40
|
+
alerts.push({
|
|
41
|
+
level: 'info',
|
|
42
|
+
message: 'High percentage of validation errors (>50%)',
|
|
43
|
+
metric: 'validation_error_rate',
|
|
44
|
+
value: (validationErrors / errorMetrics.totalErrors) * 100,
|
|
45
|
+
threshold: 50,
|
|
46
|
+
});
|
|
47
|
+
recommendations.push('Review Entity DSL documentation with users');
|
|
48
|
+
recommendations.push('Consider adding Entity DSL syntax examples to error messages');
|
|
49
|
+
}
|
|
50
|
+
// Check template fetch errors
|
|
51
|
+
const templateErrors = errorMetrics.errorsByType['template_error'] || 0;
|
|
52
|
+
if (templateErrors > 3) {
|
|
53
|
+
alerts.push({
|
|
54
|
+
level: 'warning',
|
|
55
|
+
message: 'Multiple template fetch errors detected',
|
|
56
|
+
metric: 'template_errors',
|
|
57
|
+
value: templateErrors,
|
|
58
|
+
threshold: 3,
|
|
59
|
+
});
|
|
60
|
+
recommendations.push('Verify Cloudflare Workers deployment is healthy');
|
|
61
|
+
recommendations.push('Check R2 storage bucket access');
|
|
62
|
+
recommendations.push('Verify DOCS_CACHE KV namespace is operational');
|
|
63
|
+
}
|
|
64
|
+
// Check network errors
|
|
65
|
+
const networkErrors = errorMetrics.errorsByType['network_error'] || 0;
|
|
66
|
+
if (networkErrors > 2) {
|
|
67
|
+
alerts.push({
|
|
68
|
+
level: 'warning',
|
|
69
|
+
message: 'Network connectivity issues detected',
|
|
70
|
+
metric: 'network_errors',
|
|
71
|
+
value: networkErrors,
|
|
72
|
+
threshold: 2,
|
|
73
|
+
});
|
|
74
|
+
recommendations.push('Check api.claudetools.dev availability');
|
|
75
|
+
recommendations.push('Verify network connection and firewall rules');
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
timeRange: `${startTime} to ${endTime}`,
|
|
79
|
+
errorMetrics,
|
|
80
|
+
alerts,
|
|
81
|
+
recommendations,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get error metrics for last 24 hours
|
|
86
|
+
*/
|
|
87
|
+
export async function getLast24Hours() {
|
|
88
|
+
const endTime = new Date().toISOString();
|
|
89
|
+
const startTime = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
90
|
+
return getDashboardMetrics(startTime, endTime);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get error metrics for last 7 days
|
|
94
|
+
*/
|
|
95
|
+
export async function getLast7Days() {
|
|
96
|
+
const endTime = new Date().toISOString();
|
|
97
|
+
const startTime = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
98
|
+
return getDashboardMetrics(startTime, endTime);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Print dashboard to console
|
|
102
|
+
*/
|
|
103
|
+
export function printDashboard(metrics) {
|
|
104
|
+
console.log('\n=================================================');
|
|
105
|
+
console.log('CodeDNA Monitoring Dashboard');
|
|
106
|
+
console.log('=================================================\n');
|
|
107
|
+
console.log(`Time Range: ${metrics.timeRange}\n`);
|
|
108
|
+
console.log('Error Metrics:');
|
|
109
|
+
console.log(` Total Errors: ${metrics.errorMetrics.totalErrors}`);
|
|
110
|
+
console.log(` Error Rate: ${metrics.errorMetrics.errorRate.toFixed(2)}%\n`);
|
|
111
|
+
console.log('Errors by Type:');
|
|
112
|
+
Object.entries(metrics.errorMetrics.errorsByType).forEach(([type, count]) => {
|
|
113
|
+
console.log(` ${type}: ${count}`);
|
|
114
|
+
});
|
|
115
|
+
console.log();
|
|
116
|
+
console.log('Errors by Operation:');
|
|
117
|
+
Object.entries(metrics.errorMetrics.errorsByOperation).forEach(([op, count]) => {
|
|
118
|
+
console.log(` ${op}: ${count}`);
|
|
119
|
+
});
|
|
120
|
+
console.log();
|
|
121
|
+
if (metrics.alerts.length > 0) {
|
|
122
|
+
console.log('Alerts:');
|
|
123
|
+
metrics.alerts.forEach(alert => {
|
|
124
|
+
const emoji = alert.level === 'critical' ? '🔴' : alert.level === 'warning' ? '🟡' : 'ℹ️';
|
|
125
|
+
console.log(` ${emoji} [${alert.level.toUpperCase()}] ${alert.message}`);
|
|
126
|
+
console.log(` ${alert.metric}: ${alert.value} (threshold: ${alert.threshold})`);
|
|
127
|
+
});
|
|
128
|
+
console.log();
|
|
129
|
+
}
|
|
130
|
+
if (metrics.recommendations.length > 0) {
|
|
131
|
+
console.log('Recommendations:');
|
|
132
|
+
metrics.recommendations.forEach((rec, i) => {
|
|
133
|
+
console.log(` ${i + 1}. ${rec}`);
|
|
134
|
+
});
|
|
135
|
+
console.log();
|
|
136
|
+
}
|
|
137
|
+
if (metrics.errorMetrics.recentErrors.length > 0) {
|
|
138
|
+
console.log('Recent Errors (last 10):');
|
|
139
|
+
metrics.errorMetrics.recentErrors.forEach((error, i) => {
|
|
140
|
+
console.log(` ${i + 1}. [${error.timestamp}] ${error.operation}`);
|
|
141
|
+
console.log(` Type: ${error.errorType}`);
|
|
142
|
+
console.log(` Message: ${error.errorMessage}`);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
console.log('\n=================================================\n');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* CLI command: npm run codedna:monitor
|
|
149
|
+
*/
|
|
150
|
+
export async function runMonitoring() {
|
|
151
|
+
console.log('Fetching CodeDNA metrics for last 24 hours...\n');
|
|
152
|
+
const metrics = await getLast24Hours();
|
|
153
|
+
printDashboard(metrics);
|
|
154
|
+
// Exit with error code if critical alerts
|
|
155
|
+
const hasCritical = metrics.alerts.some(a => a.level === 'critical');
|
|
156
|
+
if (hasCritical) {
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export interface CodeDNAError {
|
|
2
|
+
timestamp: string;
|
|
3
|
+
operation: 'generate_api' | 'generate_frontend' | 'generate_component' | 'validate_spec' | 'list_generators' | 'template_fetch';
|
|
4
|
+
errorType: 'validation_error' | 'generation_error' | 'template_error' | 'network_error' | 'unknown_error';
|
|
5
|
+
errorMessage: string;
|
|
6
|
+
context: {
|
|
7
|
+
spec?: string;
|
|
8
|
+
framework?: string;
|
|
9
|
+
generatorId?: string;
|
|
10
|
+
templateFile?: string;
|
|
11
|
+
stackTrace?: string;
|
|
12
|
+
};
|
|
13
|
+
projectId?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class CodeDNAErrorTracker {
|
|
16
|
+
private static instance;
|
|
17
|
+
private constructor();
|
|
18
|
+
static getInstance(): CodeDNAErrorTracker;
|
|
19
|
+
/**
|
|
20
|
+
* Track a CodeDNA error
|
|
21
|
+
*/
|
|
22
|
+
trackError(error: Omit<CodeDNAError, 'timestamp'>): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Track validation error
|
|
25
|
+
*/
|
|
26
|
+
trackValidationError(spec: string, errors: string[], projectId?: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Track generation error
|
|
29
|
+
*/
|
|
30
|
+
trackGenerationError(framework: string, spec: string, error: Error, projectId?: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Track template fetch error
|
|
33
|
+
*/
|
|
34
|
+
trackTemplateFetchError(generatorId: string, templateFile: string, error: Error, projectId?: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Track network error
|
|
37
|
+
*/
|
|
38
|
+
trackNetworkError(operation: CodeDNAError['operation'], error: Error, projectId?: string): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare const errorTracker: CodeDNAErrorTracker;
|
|
41
|
+
/**
|
|
42
|
+
* Get error rate for monitoring dashboard
|
|
43
|
+
*/
|
|
44
|
+
export interface ErrorRateQuery {
|
|
45
|
+
startTime: string;
|
|
46
|
+
endTime: string;
|
|
47
|
+
operation?: CodeDNAError['operation'];
|
|
48
|
+
errorType?: CodeDNAError['errorType'];
|
|
49
|
+
}
|
|
50
|
+
export interface ErrorRateResult {
|
|
51
|
+
totalErrors: number;
|
|
52
|
+
errorsByType: Record<string, number>;
|
|
53
|
+
errorsByOperation: Record<string, number>;
|
|
54
|
+
errorRate: number;
|
|
55
|
+
recentErrors: CodeDNAError[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Query for error rate monitoring
|
|
59
|
+
*
|
|
60
|
+
* Example usage:
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const result = await getErrorRate({
|
|
63
|
+
* startTime: '2025-12-04T00:00:00Z',
|
|
64
|
+
* endTime: '2025-12-05T00:00:00Z',
|
|
65
|
+
* operation: 'generate_api'
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* if (result.errorRate > 5) {
|
|
69
|
+
* console.warn('CodeDNA error rate exceeds 5%:', result);
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function getErrorRate(query: ErrorRateQuery): Promise<ErrorRateResult>;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// CodeDNA Error Tracking
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Centralized error tracking for CodeDNA operations with memory storage
|
|
6
|
+
// and analytics queries.
|
|
7
|
+
//
|
|
8
|
+
import { storeFact, searchMemory } from './api-client.js';
|
|
9
|
+
import { DEFAULT_USER_ID, resolveProjectId } from './config.js';
|
|
10
|
+
export class CodeDNAErrorTracker {
|
|
11
|
+
static instance;
|
|
12
|
+
constructor() { }
|
|
13
|
+
static getInstance() {
|
|
14
|
+
if (!CodeDNAErrorTracker.instance) {
|
|
15
|
+
CodeDNAErrorTracker.instance = new CodeDNAErrorTracker();
|
|
16
|
+
}
|
|
17
|
+
return CodeDNAErrorTracker.instance;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Track a CodeDNA error
|
|
21
|
+
*/
|
|
22
|
+
async trackError(error) {
|
|
23
|
+
try {
|
|
24
|
+
const errorRecord = {
|
|
25
|
+
...error,
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
};
|
|
28
|
+
// Store error in memory system as a fact
|
|
29
|
+
const userId = DEFAULT_USER_ID;
|
|
30
|
+
const projectId = error.projectId || resolveProjectId();
|
|
31
|
+
await storeFact(projectId, 'CodeDNA', 'ERROR_OCCURRED', error.operation, JSON.stringify(errorRecord), userId);
|
|
32
|
+
// Log to console for immediate visibility
|
|
33
|
+
console.error('[CodeDNA Error]', {
|
|
34
|
+
operation: error.operation,
|
|
35
|
+
type: error.errorType,
|
|
36
|
+
message: error.errorMessage,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (trackingError) {
|
|
40
|
+
// Don't fail the operation if error tracking fails
|
|
41
|
+
console.error('[CodeDNA Error Tracking Failed]', trackingError);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Track validation error
|
|
46
|
+
*/
|
|
47
|
+
async trackValidationError(spec, errors, projectId) {
|
|
48
|
+
await this.trackError({
|
|
49
|
+
operation: 'validate_spec',
|
|
50
|
+
errorType: 'validation_error',
|
|
51
|
+
errorMessage: `Validation failed: ${errors.join(', ')}`,
|
|
52
|
+
context: {
|
|
53
|
+
spec,
|
|
54
|
+
},
|
|
55
|
+
projectId,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Track generation error
|
|
60
|
+
*/
|
|
61
|
+
async trackGenerationError(framework, spec, error, projectId) {
|
|
62
|
+
await this.trackError({
|
|
63
|
+
operation: 'generate_api',
|
|
64
|
+
errorType: 'generation_error',
|
|
65
|
+
errorMessage: error.message,
|
|
66
|
+
context: {
|
|
67
|
+
spec,
|
|
68
|
+
framework,
|
|
69
|
+
stackTrace: error.stack,
|
|
70
|
+
},
|
|
71
|
+
projectId,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Track template fetch error
|
|
76
|
+
*/
|
|
77
|
+
async trackTemplateFetchError(generatorId, templateFile, error, projectId) {
|
|
78
|
+
await this.trackError({
|
|
79
|
+
operation: 'template_fetch',
|
|
80
|
+
errorType: 'template_error',
|
|
81
|
+
errorMessage: error.message,
|
|
82
|
+
context: {
|
|
83
|
+
generatorId,
|
|
84
|
+
templateFile,
|
|
85
|
+
stackTrace: error.stack,
|
|
86
|
+
},
|
|
87
|
+
projectId,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Track network error
|
|
92
|
+
*/
|
|
93
|
+
async trackNetworkError(operation, error, projectId) {
|
|
94
|
+
await this.trackError({
|
|
95
|
+
operation,
|
|
96
|
+
errorType: 'network_error',
|
|
97
|
+
errorMessage: error.message,
|
|
98
|
+
context: {
|
|
99
|
+
stackTrace: error.stack,
|
|
100
|
+
},
|
|
101
|
+
projectId,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Export singleton instance
|
|
106
|
+
export const errorTracker = CodeDNAErrorTracker.getInstance();
|
|
107
|
+
/**
|
|
108
|
+
* Query for error rate monitoring
|
|
109
|
+
*
|
|
110
|
+
* Example usage:
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const result = await getErrorRate({
|
|
113
|
+
* startTime: '2025-12-04T00:00:00Z',
|
|
114
|
+
* endTime: '2025-12-05T00:00:00Z',
|
|
115
|
+
* operation: 'generate_api'
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* if (result.errorRate > 5) {
|
|
119
|
+
* console.warn('CodeDNA error rate exceeds 5%:', result);
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export async function getErrorRate(query) {
|
|
124
|
+
const userId = DEFAULT_USER_ID;
|
|
125
|
+
const projectId = resolveProjectId();
|
|
126
|
+
// Search for error facts
|
|
127
|
+
const searchQuery = `CodeDNA ERROR_OCCURRED ${query.operation || ''}`;
|
|
128
|
+
const result = await searchMemory(projectId, searchQuery, 100, userId);
|
|
129
|
+
// Parse error records from facts
|
|
130
|
+
const errors = result.relevant_facts
|
|
131
|
+
.map((fact) => {
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(fact.fact);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
.filter((e) => e !== null)
|
|
140
|
+
.filter((e) => {
|
|
141
|
+
const errorTime = new Date(e.timestamp).getTime();
|
|
142
|
+
const start = new Date(query.startTime).getTime();
|
|
143
|
+
const end = new Date(query.endTime).getTime();
|
|
144
|
+
return errorTime >= start && errorTime <= end;
|
|
145
|
+
})
|
|
146
|
+
.filter((e) => !query.operation || e.operation === query.operation)
|
|
147
|
+
.filter((e) => !query.errorType || e.errorType === query.errorType);
|
|
148
|
+
// Calculate error rate (errors per 100 operations - assuming 1:1 for now)
|
|
149
|
+
const errorRate = errors.length > 0 ? (errors.length / Math.max(errors.length, 1)) * 100 : 0;
|
|
150
|
+
// Group by type and operation
|
|
151
|
+
const errorsByType = {};
|
|
152
|
+
const errorsByOperation = {};
|
|
153
|
+
errors.forEach(error => {
|
|
154
|
+
errorsByType[error.errorType] = (errorsByType[error.errorType] || 0) + 1;
|
|
155
|
+
errorsByOperation[error.operation] = (errorsByOperation[error.operation] || 0) + 1;
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
totalErrors: errors.length,
|
|
159
|
+
errorsByType,
|
|
160
|
+
errorsByOperation,
|
|
161
|
+
errorRate,
|
|
162
|
+
recentErrors: errors.slice(0, 10), // Last 10 errors
|
|
163
|
+
};
|
|
164
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context7-compatible library ID mappings
|
|
3
|
+
* Maps canonical names to context7 library IDs
|
|
4
|
+
*/
|
|
5
|
+
export declare const CONTEXT7_LIBRARY_IDS: Record<string, string>;
|
|
6
|
+
export interface DetectedLibrary {
|
|
7
|
+
name: string;
|
|
8
|
+
context7Id?: string;
|
|
9
|
+
mentions: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect libraries mentioned in text
|
|
13
|
+
* @param text - Text to scan for library mentions
|
|
14
|
+
* @returns Array of detected libraries with mention counts
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectLibraries(text: string): DetectedLibrary[];
|
|
17
|
+
/**
|
|
18
|
+
* Detect libraries from goal and task descriptions
|
|
19
|
+
* @param goal - The epic/plan goal
|
|
20
|
+
* @param tasks - Array of task objects with title and description
|
|
21
|
+
* @returns Deduplicated list of detected libraries
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectLibrariesFromPlan(goal: string, tasks: {
|
|
24
|
+
title: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
}[]): DetectedLibrary[];
|