@claudetools/tools 0.3.9 → 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.
- 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 +80 -0
- package/dist/codedna/parser.js +176 -0
- package/dist/codedna/registry.d.ts +60 -0
- package/dist/codedna/registry.js +214 -0
- package/dist/codedna/template-engine.d.ts +17 -0
- package/dist/codedna/template-engine.js +149 -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 +167 -0
- package/dist/handlers/tool-handlers.js +593 -14
- package/dist/helpers/api-client.d.ts +37 -0
- package/dist/helpers/api-client.js +63 -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/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/package.json +3 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Template Registry Client
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// HTTP client for Cloudflare Workers template registry with local caching
|
|
6
|
+
// and fallback to bundled templates on network failure.
|
|
7
|
+
//
|
|
8
|
+
import fs from 'fs/promises';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
export class TemplateRegistry {
|
|
13
|
+
baseUrl;
|
|
14
|
+
cacheDir;
|
|
15
|
+
useCache;
|
|
16
|
+
constructor(baseUrl = 'https://templates.claudetools.com', useCache = true) {
|
|
17
|
+
this.baseUrl = baseUrl;
|
|
18
|
+
this.cacheDir = path.join(__dirname, '../../templates');
|
|
19
|
+
this.useCache = useCache;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* List all available generators
|
|
23
|
+
*/
|
|
24
|
+
async listGenerators() {
|
|
25
|
+
try {
|
|
26
|
+
const response = await fetch(`${this.baseUrl}/registry`, {
|
|
27
|
+
signal: AbortSignal.timeout(5000), // 5 second timeout
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`Registry fetch failed: ${response.statusText}`);
|
|
31
|
+
}
|
|
32
|
+
const data = await response.json();
|
|
33
|
+
return data.generators;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.warn('Failed to fetch from registry, using local fallback:', error);
|
|
37
|
+
return this.getLocalGenerators();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get metadata for specific generator
|
|
42
|
+
*/
|
|
43
|
+
async getGeneratorMetadata(generatorId) {
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(`${this.baseUrl}/metadata/${generatorId}`, {
|
|
46
|
+
signal: AbortSignal.timeout(5000),
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Metadata fetch failed: ${response.statusText}`);
|
|
50
|
+
}
|
|
51
|
+
return await response.json();
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.warn('Failed to fetch metadata from registry, using local fallback:', error);
|
|
55
|
+
return this.getLocalMetadata(generatorId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get template file content
|
|
60
|
+
*/
|
|
61
|
+
async getTemplate(generatorId, templateFile) {
|
|
62
|
+
// Check cache first
|
|
63
|
+
if (this.useCache) {
|
|
64
|
+
const cached = await this.getCachedTemplate(generatorId, templateFile);
|
|
65
|
+
if (cached)
|
|
66
|
+
return cached;
|
|
67
|
+
}
|
|
68
|
+
// Fetch from registry
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(`${this.baseUrl}/templates/${generatorId}/${templateFile}`, {
|
|
71
|
+
signal: AbortSignal.timeout(10000), // 10 second timeout for templates
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
throw new Error(`Template fetch failed: ${response.statusText}`);
|
|
75
|
+
}
|
|
76
|
+
const content = await response.text();
|
|
77
|
+
// Cache it
|
|
78
|
+
if (this.useCache) {
|
|
79
|
+
await this.cacheTemplate(generatorId, templateFile, content);
|
|
80
|
+
}
|
|
81
|
+
return content;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
console.warn('Failed to fetch template from registry, using local fallback:', error);
|
|
85
|
+
return this.getLocalTemplate(generatorId, templateFile);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get multiple templates at once
|
|
90
|
+
*/
|
|
91
|
+
async getTemplates(generatorId, templateFiles) {
|
|
92
|
+
const results = {};
|
|
93
|
+
await Promise.all(templateFiles.map(async (file) => {
|
|
94
|
+
results[file] = await this.getTemplate(generatorId, file);
|
|
95
|
+
}));
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if template is cached locally
|
|
100
|
+
*/
|
|
101
|
+
async getCachedTemplate(generatorId, templateFile) {
|
|
102
|
+
try {
|
|
103
|
+
const cachePath = path.join(this.cacheDir, generatorId, templateFile);
|
|
104
|
+
return await fs.readFile(cachePath, 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Cache template locally
|
|
112
|
+
*/
|
|
113
|
+
async cacheTemplate(generatorId, templateFile, content) {
|
|
114
|
+
try {
|
|
115
|
+
const cachePath = path.join(this.cacheDir, generatorId, templateFile);
|
|
116
|
+
await fs.mkdir(path.dirname(cachePath), { recursive: true });
|
|
117
|
+
await fs.writeFile(cachePath, content, 'utf-8');
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.warn('Failed to cache template:', error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get local generators (fallback)
|
|
125
|
+
*/
|
|
126
|
+
async getLocalGenerators() {
|
|
127
|
+
// Return hardcoded list of bundled generators
|
|
128
|
+
return [
|
|
129
|
+
{
|
|
130
|
+
id: 'express-api',
|
|
131
|
+
name: 'Express REST API',
|
|
132
|
+
framework: 'express',
|
|
133
|
+
description: 'Generate TypeScript Express API with CRUD operations',
|
|
134
|
+
features: ['auth', 'validation', 'tests'],
|
|
135
|
+
databases: ['postgresql', 'mysql', 'mongodb'],
|
|
136
|
+
version: '1.0.0',
|
|
137
|
+
templates: [
|
|
138
|
+
'controller.ts.j2',
|
|
139
|
+
'model.ts.j2',
|
|
140
|
+
'route.ts.j2',
|
|
141
|
+
'middleware.ts.j2',
|
|
142
|
+
'validator.ts.j2',
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get local metadata (fallback)
|
|
149
|
+
*/
|
|
150
|
+
async getLocalMetadata(generatorId) {
|
|
151
|
+
const generators = await this.getLocalGenerators();
|
|
152
|
+
const generator = generators.find(g => g.id === generatorId);
|
|
153
|
+
if (!generator) {
|
|
154
|
+
throw new Error(`Generator not found: ${generatorId}`);
|
|
155
|
+
}
|
|
156
|
+
return generator;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get local template (fallback)
|
|
160
|
+
*/
|
|
161
|
+
async getLocalTemplate(generatorId, templateFile) {
|
|
162
|
+
// Try to load from local bundled templates
|
|
163
|
+
const localPath = path.join(__dirname, '../../../cloudflare/templates', generatorId, templateFile);
|
|
164
|
+
try {
|
|
165
|
+
return await fs.readFile(localPath, 'utf-8');
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
throw new Error(`Template not found: ${generatorId}/${templateFile}. Registry unavailable and local fallback missing.`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Clear local cache
|
|
173
|
+
*/
|
|
174
|
+
async clearCache() {
|
|
175
|
+
try {
|
|
176
|
+
await fs.rm(this.cacheDir, { recursive: true, force: true });
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
console.warn('Failed to clear cache:', error);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get cache statistics
|
|
184
|
+
*/
|
|
185
|
+
async getCacheStats() {
|
|
186
|
+
try {
|
|
187
|
+
const entries = await fs.readdir(this.cacheDir, { withFileTypes: true });
|
|
188
|
+
const generators = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
189
|
+
let totalFiles = 0;
|
|
190
|
+
let totalSize = 0;
|
|
191
|
+
for (const gen of generators) {
|
|
192
|
+
const genPath = path.join(this.cacheDir, gen);
|
|
193
|
+
const files = await fs.readdir(genPath);
|
|
194
|
+
totalFiles += files.length;
|
|
195
|
+
for (const file of files) {
|
|
196
|
+
const stats = await fs.stat(path.join(genPath, file));
|
|
197
|
+
totalSize += stats.size;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
cachedGenerators: generators,
|
|
202
|
+
totalFiles,
|
|
203
|
+
totalSize,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
return {
|
|
208
|
+
cachedGenerators: [],
|
|
209
|
+
totalFiles: 0,
|
|
210
|
+
totalSize: 0,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EntitySpec } from './parser.js';
|
|
2
|
+
export declare class TemplateEngine {
|
|
3
|
+
private env;
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Render template string with context
|
|
7
|
+
*/
|
|
8
|
+
render(template: string, context: any): string;
|
|
9
|
+
/**
|
|
10
|
+
* Add custom filters for code generation
|
|
11
|
+
*/
|
|
12
|
+
private addFilters;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Helper to build template context from EntitySpec
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildContext(entity: EntitySpec, options?: any): any;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Template Engine with Custom Filters
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Jinja2-style template engine using nunjucks with custom filters for
|
|
6
|
+
// code generation (plural, camelCase, TypeScript types, SQL types, etc.)
|
|
7
|
+
//
|
|
8
|
+
import nunjucks from 'nunjucks';
|
|
9
|
+
export class TemplateEngine {
|
|
10
|
+
env;
|
|
11
|
+
constructor() {
|
|
12
|
+
// Configure nunjucks
|
|
13
|
+
this.env = new nunjucks.Environment(null, {
|
|
14
|
+
autoescape: false,
|
|
15
|
+
trimBlocks: true,
|
|
16
|
+
lstripBlocks: true,
|
|
17
|
+
});
|
|
18
|
+
// Add custom filters
|
|
19
|
+
this.addFilters();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Render template string with context
|
|
23
|
+
*/
|
|
24
|
+
render(template, context) {
|
|
25
|
+
return this.env.renderString(template, context);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Add custom filters for code generation
|
|
29
|
+
*/
|
|
30
|
+
addFilters() {
|
|
31
|
+
// Pluralize: User → Users
|
|
32
|
+
this.env.addFilter('plural', (str) => {
|
|
33
|
+
if (str.endsWith('y'))
|
|
34
|
+
return str.slice(0, -1) + 'ies';
|
|
35
|
+
if (str.endsWith('s'))
|
|
36
|
+
return str + 'es';
|
|
37
|
+
return str + 's';
|
|
38
|
+
});
|
|
39
|
+
// Lowercase: User → user
|
|
40
|
+
this.env.addFilter('lower', (str) => {
|
|
41
|
+
return str.toLowerCase();
|
|
42
|
+
});
|
|
43
|
+
// Uppercase: user → USER
|
|
44
|
+
this.env.addFilter('upper', (str) => {
|
|
45
|
+
return str.toUpperCase();
|
|
46
|
+
});
|
|
47
|
+
// camelCase: user_name → userName
|
|
48
|
+
this.env.addFilter('camel', (str) => {
|
|
49
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
50
|
+
});
|
|
51
|
+
// PascalCase: user_name → UserName
|
|
52
|
+
this.env.addFilter('pascal', (str) => {
|
|
53
|
+
const camel = str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
54
|
+
return camel.charAt(0).toUpperCase() + camel.slice(1);
|
|
55
|
+
});
|
|
56
|
+
// snake_case: userName → user_name
|
|
57
|
+
this.env.addFilter('snake', (str) => {
|
|
58
|
+
return str.replace(/[A-Z]/g, letter => '_' + letter.toLowerCase());
|
|
59
|
+
});
|
|
60
|
+
// kebab-case: userName → user-name
|
|
61
|
+
this.env.addFilter('kebab', (str) => {
|
|
62
|
+
return str.replace(/[A-Z]/g, letter => '-' + letter.toLowerCase());
|
|
63
|
+
});
|
|
64
|
+
// Check if array includes value
|
|
65
|
+
this.env.addFilter('includes', (arr, val) => {
|
|
66
|
+
return Array.isArray(arr) && arr.includes(val);
|
|
67
|
+
});
|
|
68
|
+
// Get TypeScript type for field
|
|
69
|
+
this.env.addFilter('tsType', (field) => {
|
|
70
|
+
if (field.type.kind === 'primitive') {
|
|
71
|
+
const typeMap = {
|
|
72
|
+
string: 'string',
|
|
73
|
+
integer: 'number',
|
|
74
|
+
decimal: 'number',
|
|
75
|
+
boolean: 'boolean',
|
|
76
|
+
datetime: 'Date',
|
|
77
|
+
};
|
|
78
|
+
return typeMap[field.type.value];
|
|
79
|
+
}
|
|
80
|
+
if (field.type.kind === 'reference') {
|
|
81
|
+
return field.type.entity;
|
|
82
|
+
}
|
|
83
|
+
if (field.type.kind === 'enum') {
|
|
84
|
+
return field.type.values.map(v => `'${v}'`).join(' | ');
|
|
85
|
+
}
|
|
86
|
+
return 'any';
|
|
87
|
+
});
|
|
88
|
+
// Get SQL type for field
|
|
89
|
+
this.env.addFilter('sqlType', (field) => {
|
|
90
|
+
if (field.type.kind === 'primitive') {
|
|
91
|
+
const typeMap = {
|
|
92
|
+
string: 'VARCHAR(255)',
|
|
93
|
+
integer: 'INTEGER',
|
|
94
|
+
decimal: 'DECIMAL(10,2)',
|
|
95
|
+
boolean: 'BOOLEAN',
|
|
96
|
+
datetime: 'TIMESTAMP',
|
|
97
|
+
};
|
|
98
|
+
return typeMap[field.type.value];
|
|
99
|
+
}
|
|
100
|
+
if (field.type.kind === 'reference') {
|
|
101
|
+
return 'INTEGER'; // Foreign key
|
|
102
|
+
}
|
|
103
|
+
if (field.type.kind === 'enum') {
|
|
104
|
+
return `ENUM(${field.type.values.map(v => `'${v}'`).join(',')})`;
|
|
105
|
+
}
|
|
106
|
+
return 'TEXT';
|
|
107
|
+
});
|
|
108
|
+
// Check if field has specific constraint
|
|
109
|
+
this.env.addFilter('hasConstraint', (field, constraintKind) => {
|
|
110
|
+
return field.constraints.some(c => c.kind === constraintKind);
|
|
111
|
+
});
|
|
112
|
+
// Get constraint value (for min, max, default)
|
|
113
|
+
this.env.addFilter('getConstraint', (field, constraintKind) => {
|
|
114
|
+
const constraint = field.constraints.find(c => c.kind === constraintKind);
|
|
115
|
+
if (!constraint)
|
|
116
|
+
return null;
|
|
117
|
+
if ('value' in constraint)
|
|
118
|
+
return constraint.value;
|
|
119
|
+
return true;
|
|
120
|
+
});
|
|
121
|
+
// Join array with custom separator
|
|
122
|
+
this.env.addFilter('joinWith', (arr, separator) => {
|
|
123
|
+
return arr.join(separator);
|
|
124
|
+
});
|
|
125
|
+
// First letter uppercase
|
|
126
|
+
this.env.addFilter('capitalize', (str) => {
|
|
127
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
128
|
+
});
|
|
129
|
+
// Indent lines
|
|
130
|
+
this.env.addFilter('indent', (str, spaces = 2) => {
|
|
131
|
+
const indent = ' '.repeat(spaces);
|
|
132
|
+
return str.split('\n').map(line => indent + line).join('\n');
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Helper to build template context from EntitySpec
|
|
138
|
+
*/
|
|
139
|
+
export function buildContext(entity, options = {}) {
|
|
140
|
+
return {
|
|
141
|
+
entity,
|
|
142
|
+
options,
|
|
143
|
+
// Helper data
|
|
144
|
+
hasRequiredFields: entity.fields.some(f => f.constraints.some(c => c.kind === 'required')),
|
|
145
|
+
hasUniqueFields: entity.fields.some(f => f.constraints.some(c => c.kind === 'unique')),
|
|
146
|
+
hasHashedFields: entity.fields.some(f => f.constraints.some(c => c.kind === 'hashed')),
|
|
147
|
+
hasReferences: entity.fields.some(f => f.type.kind === 'reference'),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { EntitySpec } from './parser.js';
|
|
2
|
+
/**
|
|
3
|
+
* Options for API generation
|
|
4
|
+
*/
|
|
5
|
+
export interface GenerateApiOptions {
|
|
6
|
+
auth?: boolean;
|
|
7
|
+
validation?: boolean;
|
|
8
|
+
tests?: boolean;
|
|
9
|
+
database?: 'postgresql' | 'mysql' | 'mongodb';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Options for frontend generation
|
|
13
|
+
*/
|
|
14
|
+
export interface GenerateFrontendOptions {
|
|
15
|
+
ui?: 'shadcn' | 'mui' | 'chakra';
|
|
16
|
+
forms?: boolean;
|
|
17
|
+
tables?: boolean;
|
|
18
|
+
routing?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Options for component generation
|
|
22
|
+
*/
|
|
23
|
+
export interface GenerateComponentOptions {
|
|
24
|
+
ui?: 'shadcn' | 'mui' | 'chakra';
|
|
25
|
+
validation?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generated code result
|
|
29
|
+
*/
|
|
30
|
+
export interface GenerationResult {
|
|
31
|
+
files: Record<string, string>;
|
|
32
|
+
metadata: GenerationMetadata;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Metadata about generated code
|
|
36
|
+
*/
|
|
37
|
+
export interface GenerationMetadata {
|
|
38
|
+
generator: string;
|
|
39
|
+
framework: string;
|
|
40
|
+
entities: string[];
|
|
41
|
+
filesGenerated: number;
|
|
42
|
+
linesOfCode: number;
|
|
43
|
+
estimatedTokensSaved: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generator metadata from registry
|
|
47
|
+
*/
|
|
48
|
+
export interface GeneratorMetadata {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
framework: string;
|
|
52
|
+
description: string;
|
|
53
|
+
features: string[];
|
|
54
|
+
databases?: string[];
|
|
55
|
+
version: string;
|
|
56
|
+
templates: string[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Template context for rendering
|
|
60
|
+
*/
|
|
61
|
+
export interface TemplateContext {
|
|
62
|
+
entity: EntitySpec;
|
|
63
|
+
options: any;
|
|
64
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handle codedna_generate_api tool call
|
|
3
|
+
*/
|
|
4
|
+
export declare function handleGenerateApi(args: any): Promise<{
|
|
5
|
+
error: string;
|
|
6
|
+
details: string[] | undefined;
|
|
7
|
+
message?: undefined;
|
|
8
|
+
supported?: undefined;
|
|
9
|
+
success?: undefined;
|
|
10
|
+
files?: undefined;
|
|
11
|
+
metadata?: undefined;
|
|
12
|
+
tokenSavings?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
error: string;
|
|
15
|
+
message: string;
|
|
16
|
+
details?: undefined;
|
|
17
|
+
supported?: undefined;
|
|
18
|
+
success?: undefined;
|
|
19
|
+
files?: undefined;
|
|
20
|
+
metadata?: undefined;
|
|
21
|
+
tokenSavings?: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
error: string;
|
|
24
|
+
supported: string[];
|
|
25
|
+
details?: undefined;
|
|
26
|
+
message?: undefined;
|
|
27
|
+
success?: undefined;
|
|
28
|
+
files?: undefined;
|
|
29
|
+
metadata?: undefined;
|
|
30
|
+
tokenSavings?: undefined;
|
|
31
|
+
} | {
|
|
32
|
+
success: boolean;
|
|
33
|
+
files: Record<string, string>;
|
|
34
|
+
metadata: import("../codedna/types.js").GenerationMetadata;
|
|
35
|
+
tokenSavings: {
|
|
36
|
+
traditional: number;
|
|
37
|
+
codedna: number;
|
|
38
|
+
saved: number;
|
|
39
|
+
percentSaved: string;
|
|
40
|
+
};
|
|
41
|
+
error?: undefined;
|
|
42
|
+
details?: undefined;
|
|
43
|
+
message?: undefined;
|
|
44
|
+
supported?: undefined;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Handle codedna_generate_frontend tool call
|
|
48
|
+
*/
|
|
49
|
+
export declare function handleGenerateFrontend(args: any): Promise<{
|
|
50
|
+
error: string;
|
|
51
|
+
details: string[] | undefined;
|
|
52
|
+
message?: undefined;
|
|
53
|
+
frameworks?: undefined;
|
|
54
|
+
status?: undefined;
|
|
55
|
+
} | {
|
|
56
|
+
error: string;
|
|
57
|
+
message: string;
|
|
58
|
+
frameworks: string[];
|
|
59
|
+
status: string;
|
|
60
|
+
details?: undefined;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Handle codedna_generate_component tool call
|
|
64
|
+
*/
|
|
65
|
+
export declare function handleGenerateComponent(args: any): Promise<{
|
|
66
|
+
error: string;
|
|
67
|
+
details: string[] | undefined;
|
|
68
|
+
message?: undefined;
|
|
69
|
+
types?: undefined;
|
|
70
|
+
frameworks?: undefined;
|
|
71
|
+
status?: undefined;
|
|
72
|
+
} | {
|
|
73
|
+
error: string;
|
|
74
|
+
message: string;
|
|
75
|
+
types: string[];
|
|
76
|
+
frameworks: string[];
|
|
77
|
+
status: string;
|
|
78
|
+
details?: undefined;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Handle codedna_list_generators tool call
|
|
82
|
+
*/
|
|
83
|
+
export declare function handleListGenerators(): Promise<{
|
|
84
|
+
generators: import("../codedna/types.js").GeneratorMetadata[];
|
|
85
|
+
summary: {
|
|
86
|
+
total: number;
|
|
87
|
+
byFramework: any;
|
|
88
|
+
};
|
|
89
|
+
error?: undefined;
|
|
90
|
+
message?: undefined;
|
|
91
|
+
} | {
|
|
92
|
+
error: string;
|
|
93
|
+
message: string;
|
|
94
|
+
generators?: undefined;
|
|
95
|
+
summary?: undefined;
|
|
96
|
+
}>;
|
|
97
|
+
/**
|
|
98
|
+
* Handle codedna_validate_spec tool call
|
|
99
|
+
*/
|
|
100
|
+
export declare function handleValidateSpec(args: any): Promise<{
|
|
101
|
+
valid: boolean;
|
|
102
|
+
entity: {
|
|
103
|
+
name: string;
|
|
104
|
+
fields: {
|
|
105
|
+
name: string;
|
|
106
|
+
type: import("../codedna/parser.js").FieldType;
|
|
107
|
+
constraints: ("default" | "min" | "max" | "required" | "unique" | "hashed" | "index")[];
|
|
108
|
+
}[];
|
|
109
|
+
};
|
|
110
|
+
summary: {
|
|
111
|
+
totalFields: number;
|
|
112
|
+
hasReferences: boolean;
|
|
113
|
+
hasEnums: boolean;
|
|
114
|
+
hasConstraints: boolean;
|
|
115
|
+
};
|
|
116
|
+
errors?: undefined;
|
|
117
|
+
} | {
|
|
118
|
+
valid: boolean;
|
|
119
|
+
errors: string[] | undefined;
|
|
120
|
+
entity?: undefined;
|
|
121
|
+
summary?: undefined;
|
|
122
|
+
}>;
|