@claudetools/tools 0.9.0 → 0.9.2
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/cli.js +9 -1
- package/dist/codedna/__tests__/examples/mongoose-example.d.ts +6 -0
- package/dist/codedna/__tests__/examples/mongoose-example.js +163 -0
- package/dist/codedna/__tests__/fixtures/typeorm-production-test.d.ts +1 -0
- package/dist/codedna/__tests__/fixtures/typeorm-production-test.js +231 -0
- package/dist/codedna/__tests__/fixtures/typeorm-test.d.ts +1 -0
- package/dist/codedna/__tests__/fixtures/typeorm-test.js +124 -0
- package/dist/codedna/__tests__/laravel-output-review.d.ts +1 -0
- package/dist/codedna/__tests__/laravel-output-review.js +249 -0
- package/dist/codedna/__tests__/mongoose-output-test.d.ts +1 -0
- package/dist/codedna/__tests__/mongoose-output-test.js +178 -0
- package/dist/codedna/examples/radix-example.d.ts +2 -0
- package/dist/codedna/examples/radix-example.js +259 -0
- package/dist/codedna/index.d.ts +5 -3
- package/dist/codedna/index.js +6 -3
- package/dist/codedna/kappa-ast.d.ts +143 -5
- package/dist/codedna/kappa-drizzle-generator.js +8 -5
- package/dist/codedna/kappa-gofiber-generator.d.ts +65 -0
- package/dist/codedna/kappa-gofiber-generator.js +587 -0
- package/dist/codedna/kappa-laravel-generator.d.ts +68 -0
- package/dist/codedna/kappa-laravel-generator.js +741 -0
- package/dist/codedna/kappa-lexer.d.ts +44 -0
- package/dist/codedna/kappa-lexer.js +124 -0
- package/dist/codedna/kappa-mantine-generator.d.ts +65 -0
- package/dist/codedna/kappa-mantine-generator.js +518 -0
- package/dist/codedna/kappa-mongoose-generator.d.ts +44 -0
- package/dist/codedna/kappa-mongoose-generator.js +442 -0
- package/dist/codedna/kappa-parser.d.ts +43 -1
- package/dist/codedna/kappa-parser.js +601 -0
- package/dist/codedna/kappa-radix-generator.d.ts +61 -0
- package/dist/codedna/kappa-radix-generator.js +566 -0
- package/dist/codedna/kappa-typeorm-generator.d.ts +59 -0
- package/dist/codedna/kappa-typeorm-generator.js +723 -0
- package/dist/codedna/kappa-vitest-generator.d.ts +85 -0
- package/dist/codedna/kappa-vitest-generator.js +739 -0
- package/dist/codedna/parser.js +26 -1
- package/dist/codegen/cloud-client.d.ts +160 -0
- package/dist/codegen/cloud-client.js +195 -0
- package/dist/codegen/codegen-tool.d.ts +35 -0
- package/dist/codegen/codegen-tool.js +312 -0
- package/dist/codegen/field-inference.d.ts +24 -0
- package/dist/codegen/field-inference.js +101 -0
- package/dist/codegen/form-parser.d.ts +13 -0
- package/dist/codegen/form-parser.js +186 -0
- package/dist/codegen/index.d.ts +2 -0
- package/dist/codegen/index.js +4 -0
- package/dist/codegen/natural-parser.d.ts +50 -0
- package/dist/codegen/natural-parser.js +769 -0
- package/dist/handlers/codedna-handlers.d.ts +1 -1
- package/dist/handlers/codegen-handlers.d.ts +20 -0
- package/dist/handlers/codegen-handlers.js +60 -0
- package/dist/handlers/kappa-handlers.d.ts +97 -0
- package/dist/handlers/kappa-handlers.js +408 -0
- package/dist/handlers/tool-handlers.js +124 -221
- package/dist/helpers/api-client.js +48 -3
- package/dist/helpers/compact-formatter.d.ts +9 -2
- package/dist/helpers/compact-formatter.js +26 -2
- package/dist/helpers/config.d.ts +7 -2
- package/dist/helpers/config.js +25 -10
- package/dist/helpers/session-validation.d.ts +1 -1
- package/dist/helpers/session-validation.js +2 -4
- package/dist/helpers/tasks.d.ts +21 -0
- package/dist/helpers/tasks.js +52 -0
- package/dist/helpers/workers.d.ts +1 -1
- package/dist/helpers/workers.js +19 -19
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +228 -3
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.js +37 -152
- package/dist/templates/orchestrator-prompt.d.ts +2 -2
- package/dist/templates/orchestrator-prompt.js +31 -38
- package/dist/templates/self-critique.d.ts +50 -0
- package/dist/templates/self-critique.js +209 -0
- package/dist/templates/worker-prompt.d.ts +3 -3
- package/dist/templates/worker-prompt.js +18 -18
- package/dist/tools.js +77 -413
- package/docs/codedna/generator-testing-summary.md +205 -0
- package/docs/codedna/radix-ui-generator.md +478 -0
- package/docs/kappa-gofiber-generator.md +274 -0
- package/docs/kappa-laravel-fixes.md +172 -0
- package/docs/kappa-mongoose-generator.md +322 -0
- package/docs/kappa-vitest-generator.md +337 -0
- package/package.json +1 -1
- package/dist/context/deduplication.test.d.ts +0 -6
- package/dist/context/deduplication.test.js +0 -84
|
@@ -186,7 +186,7 @@ export declare function handleListGenerators(args?: {
|
|
|
186
186
|
byFramework: Record<string, number>;
|
|
187
187
|
byDomain: Record<string, number> | undefined;
|
|
188
188
|
availableUiLibraries: string[];
|
|
189
|
-
filteredByDomain?: "api" | "
|
|
189
|
+
filteredByDomain?: "api" | "component" | "frontend" | undefined;
|
|
190
190
|
total: number;
|
|
191
191
|
};
|
|
192
192
|
usage: {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handle the unified codegen tool
|
|
3
|
+
*/
|
|
4
|
+
export declare function handleCodegen(args: Record<string, unknown>): Promise<{
|
|
5
|
+
success: boolean;
|
|
6
|
+
files?: Array<{
|
|
7
|
+
path: string;
|
|
8
|
+
content: string;
|
|
9
|
+
description: string;
|
|
10
|
+
}>;
|
|
11
|
+
entities?: string[];
|
|
12
|
+
summary?: string;
|
|
13
|
+
error?: string;
|
|
14
|
+
errors?: string[];
|
|
15
|
+
stack?: {
|
|
16
|
+
orm: string;
|
|
17
|
+
api: string;
|
|
18
|
+
db: string;
|
|
19
|
+
};
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Unified Codegen Handler
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// ONE tool to replace 20+ broken CodeDNA/Kappa tools.
|
|
6
|
+
// Natural language in → generated code out.
|
|
7
|
+
//
|
|
8
|
+
import { codegen, detectStack } from '../codegen/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Handle the unified codegen tool
|
|
11
|
+
*/
|
|
12
|
+
export async function handleCodegen(args) {
|
|
13
|
+
const describe = args.describe;
|
|
14
|
+
if (!describe || typeof describe !== 'string') {
|
|
15
|
+
return {
|
|
16
|
+
success: false,
|
|
17
|
+
error: 'Missing required "describe" parameter. Describe what you want to generate, e.g., "User with email, password, role (admin/user)"',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// Build input
|
|
21
|
+
const input = {
|
|
22
|
+
describe,
|
|
23
|
+
};
|
|
24
|
+
// Optional stack override
|
|
25
|
+
if (args.stack && typeof args.stack === 'object') {
|
|
26
|
+
input.stack = args.stack;
|
|
27
|
+
}
|
|
28
|
+
// Optional generate filter
|
|
29
|
+
if (args.generate && Array.isArray(args.generate)) {
|
|
30
|
+
input.generate = args.generate;
|
|
31
|
+
}
|
|
32
|
+
// Optional package.json for stack detection
|
|
33
|
+
let packageJson;
|
|
34
|
+
if (args.package_json && typeof args.package_json === 'object') {
|
|
35
|
+
packageJson = args.package_json;
|
|
36
|
+
}
|
|
37
|
+
// Run codegen
|
|
38
|
+
const result = codegen(input, packageJson);
|
|
39
|
+
if (!result.success) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: result.summary,
|
|
43
|
+
errors: result.errors,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Detect stack for response
|
|
47
|
+
const detected = detectStack(packageJson);
|
|
48
|
+
const stack = {
|
|
49
|
+
orm: input.stack?.orm || detected.orm || 'drizzle',
|
|
50
|
+
api: input.stack?.api || detected.api || 'hono',
|
|
51
|
+
db: input.stack?.db || detected.db || 'sqlite',
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
success: true,
|
|
55
|
+
files: result.files,
|
|
56
|
+
entities: result.entities,
|
|
57
|
+
summary: result.summary,
|
|
58
|
+
stack,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -114,3 +114,100 @@ export declare function handleKappaGenerateAll(args: {
|
|
|
114
114
|
typescript?: boolean;
|
|
115
115
|
};
|
|
116
116
|
}): Promise<KappaGenerateResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Handle kappa_generate_mongoose tool call
|
|
119
|
+
* Generates MongoDB/Mongoose models from Kappa entity definitions
|
|
120
|
+
*/
|
|
121
|
+
export declare function handleKappaGenerateMongoose(args: {
|
|
122
|
+
spec: string;
|
|
123
|
+
options?: {
|
|
124
|
+
provenance?: boolean;
|
|
125
|
+
typescript?: boolean;
|
|
126
|
+
separateTypes?: boolean;
|
|
127
|
+
};
|
|
128
|
+
}): Promise<KappaGenerateResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Handle kappa_generate_typeorm tool call
|
|
131
|
+
* Generates TypeORM entities from Kappa entity definitions
|
|
132
|
+
*/
|
|
133
|
+
export declare function handleKappaGenerateTypeorm(args: {
|
|
134
|
+
spec: string;
|
|
135
|
+
dialect?: 'postgres' | 'mysql' | 'sqlite';
|
|
136
|
+
options?: {
|
|
137
|
+
provenance?: boolean;
|
|
138
|
+
migrations?: boolean;
|
|
139
|
+
repositories?: boolean;
|
|
140
|
+
};
|
|
141
|
+
}): Promise<KappaGenerateResult>;
|
|
142
|
+
/**
|
|
143
|
+
* Handle kappa_generate_tests tool call
|
|
144
|
+
* Generates Vitest/Jest test suites from Kappa specifications
|
|
145
|
+
*/
|
|
146
|
+
export declare function handleKappaGenerateTests(args: {
|
|
147
|
+
spec: string;
|
|
148
|
+
framework?: 'vitest' | 'jest';
|
|
149
|
+
testType?: 'unit' | 'integration' | 'e2e';
|
|
150
|
+
options?: {
|
|
151
|
+
provenance?: boolean;
|
|
152
|
+
factories?: boolean;
|
|
153
|
+
mocks?: boolean;
|
|
154
|
+
coverage?: boolean;
|
|
155
|
+
};
|
|
156
|
+
}): Promise<KappaGenerateResult>;
|
|
157
|
+
/**
|
|
158
|
+
* Handle kappa_generate_radix tool call
|
|
159
|
+
* Generates Radix UI components from Kappa component blocks
|
|
160
|
+
*/
|
|
161
|
+
export declare function handleKappaGenerateRadix(args: {
|
|
162
|
+
spec: string;
|
|
163
|
+
options?: {
|
|
164
|
+
provenance?: boolean;
|
|
165
|
+
typescript?: boolean;
|
|
166
|
+
forwardRef?: boolean;
|
|
167
|
+
tailwind?: boolean;
|
|
168
|
+
};
|
|
169
|
+
}): Promise<KappaGenerateResult>;
|
|
170
|
+
/**
|
|
171
|
+
* Handle kappa_generate_mantine tool call
|
|
172
|
+
* Generates Mantine UI components from Kappa specifications
|
|
173
|
+
*/
|
|
174
|
+
export declare function handleKappaGenerateMantine(args: {
|
|
175
|
+
spec: string;
|
|
176
|
+
options?: {
|
|
177
|
+
provenance?: boolean;
|
|
178
|
+
typescript?: boolean;
|
|
179
|
+
notifications?: boolean;
|
|
180
|
+
modals?: boolean;
|
|
181
|
+
};
|
|
182
|
+
}): Promise<KappaGenerateResult>;
|
|
183
|
+
/**
|
|
184
|
+
* Handle kappa_generate_gofiber tool call
|
|
185
|
+
* Generates Go code with Fiber framework from Kappa specifications
|
|
186
|
+
*/
|
|
187
|
+
export declare function handleKappaGenerateGoFiber(args: {
|
|
188
|
+
spec: string;
|
|
189
|
+
options?: {
|
|
190
|
+
packageName?: string;
|
|
191
|
+
provenance?: boolean;
|
|
192
|
+
gorm?: boolean;
|
|
193
|
+
validation?: boolean;
|
|
194
|
+
basePath?: string;
|
|
195
|
+
modulePath?: string;
|
|
196
|
+
};
|
|
197
|
+
}): Promise<KappaGenerateResult>;
|
|
198
|
+
/**
|
|
199
|
+
* Handle kappa_generate_laravel tool call
|
|
200
|
+
* Generates Laravel code from Kappa specifications
|
|
201
|
+
*/
|
|
202
|
+
export declare function handleKappaGenerateLaravel(args: {
|
|
203
|
+
spec: string;
|
|
204
|
+
options?: {
|
|
205
|
+
modelNamespace?: string;
|
|
206
|
+
controllerNamespace?: string;
|
|
207
|
+
provenance?: boolean;
|
|
208
|
+
migrations?: boolean;
|
|
209
|
+
formRequests?: boolean;
|
|
210
|
+
apiResources?: boolean;
|
|
211
|
+
basePath?: string;
|
|
212
|
+
};
|
|
213
|
+
}): Promise<KappaGenerateResult>;
|
|
@@ -463,3 +463,411 @@ export async function handleKappaGenerateAll(args) {
|
|
|
463
463
|
};
|
|
464
464
|
}
|
|
465
465
|
}
|
|
466
|
+
// =============================================================================
|
|
467
|
+
// Phase 1: Extended ORM Generators
|
|
468
|
+
// =============================================================================
|
|
469
|
+
/**
|
|
470
|
+
* Handle kappa_generate_mongoose tool call
|
|
471
|
+
* Generates MongoDB/Mongoose models from Kappa entity definitions
|
|
472
|
+
*/
|
|
473
|
+
export async function handleKappaGenerateMongoose(args) {
|
|
474
|
+
const { spec, options = {} } = args;
|
|
475
|
+
try {
|
|
476
|
+
const ast = parseKappaToAST(spec);
|
|
477
|
+
if (!ast) {
|
|
478
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
479
|
+
}
|
|
480
|
+
if (!ast.entities || ast.entities.length === 0) {
|
|
481
|
+
return { success: false, errors: ['No entity blocks found in specification'] };
|
|
482
|
+
}
|
|
483
|
+
// Import generator dynamically to avoid circular dependencies
|
|
484
|
+
const { generateMongooseSchema } = await import('../codedna/kappa-mongoose-generator.js');
|
|
485
|
+
const result = generateMongooseSchema(ast.entities, {
|
|
486
|
+
provenance: options.provenance ?? true,
|
|
487
|
+
typescript: options.typescript ?? true,
|
|
488
|
+
separateTypes: options.separateTypes ?? true,
|
|
489
|
+
});
|
|
490
|
+
const files = [
|
|
491
|
+
{ path: 'models/schemas.ts', content: result.schema },
|
|
492
|
+
];
|
|
493
|
+
if (result.types) {
|
|
494
|
+
files.push({ path: 'models/types.ts', content: result.types });
|
|
495
|
+
}
|
|
496
|
+
const totalLines = files.reduce((sum, f) => sum + f.content.split('\n').length, 0);
|
|
497
|
+
return {
|
|
498
|
+
success: true,
|
|
499
|
+
files,
|
|
500
|
+
metadata: {
|
|
501
|
+
filesGenerated: files.length,
|
|
502
|
+
linesOfCode: totalLines,
|
|
503
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
504
|
+
},
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
return {
|
|
509
|
+
success: false,
|
|
510
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Handle kappa_generate_typeorm tool call
|
|
516
|
+
* Generates TypeORM entities from Kappa entity definitions
|
|
517
|
+
*/
|
|
518
|
+
export async function handleKappaGenerateTypeorm(args) {
|
|
519
|
+
const { spec, dialect = 'postgres', options = {} } = args;
|
|
520
|
+
try {
|
|
521
|
+
const ast = parseKappaToAST(spec);
|
|
522
|
+
if (!ast) {
|
|
523
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
524
|
+
}
|
|
525
|
+
if (!ast.entities || ast.entities.length === 0) {
|
|
526
|
+
return { success: false, errors: ['No entity blocks found in specification'] };
|
|
527
|
+
}
|
|
528
|
+
// Import generator dynamically
|
|
529
|
+
const { generateTypeORMEntities } = await import('../codedna/kappa-typeorm-generator.js');
|
|
530
|
+
const result = generateTypeORMEntities(ast.entities, {
|
|
531
|
+
dialect,
|
|
532
|
+
provenance: options.provenance ?? true,
|
|
533
|
+
migrations: options.migrations ?? false,
|
|
534
|
+
repositories: options.repositories ?? false,
|
|
535
|
+
});
|
|
536
|
+
const files = [];
|
|
537
|
+
// Convert entities record to file array
|
|
538
|
+
for (const [entityName, content] of Object.entries(result.entities)) {
|
|
539
|
+
files.push({
|
|
540
|
+
path: `src/entities/${entityName}.ts`,
|
|
541
|
+
content,
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
// Add data source
|
|
545
|
+
files.push({
|
|
546
|
+
path: 'src/data-source.ts',
|
|
547
|
+
content: result.dataSource,
|
|
548
|
+
});
|
|
549
|
+
// Add repositories if enabled
|
|
550
|
+
if (result.repositories) {
|
|
551
|
+
for (const [repoName, content] of Object.entries(result.repositories)) {
|
|
552
|
+
files.push({
|
|
553
|
+
path: `src/repositories/${repoName}.ts`,
|
|
554
|
+
content,
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
// Add migration if enabled
|
|
559
|
+
if (result.migration) {
|
|
560
|
+
const timestamp = Date.now();
|
|
561
|
+
files.push({
|
|
562
|
+
path: `src/migrations/${timestamp}-CreateInitialSchema.ts`,
|
|
563
|
+
content: result.migration,
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
const totalLines = files.reduce((sum, f) => sum + f.content.split('\n').length, 0);
|
|
567
|
+
return {
|
|
568
|
+
success: true,
|
|
569
|
+
files,
|
|
570
|
+
metadata: {
|
|
571
|
+
filesGenerated: files.length,
|
|
572
|
+
linesOfCode: totalLines,
|
|
573
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
574
|
+
},
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
catch (error) {
|
|
578
|
+
return {
|
|
579
|
+
success: false,
|
|
580
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
// =============================================================================
|
|
585
|
+
// Phase 1: Testing Generator
|
|
586
|
+
// =============================================================================
|
|
587
|
+
/**
|
|
588
|
+
* Handle kappa_generate_tests tool call
|
|
589
|
+
* Generates Vitest/Jest test suites from Kappa specifications
|
|
590
|
+
*/
|
|
591
|
+
export async function handleKappaGenerateTests(args) {
|
|
592
|
+
const { spec, framework = 'vitest', testType = 'unit', options = {} } = args;
|
|
593
|
+
try {
|
|
594
|
+
const ast = parseKappaToAST(spec);
|
|
595
|
+
if (!ast) {
|
|
596
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
597
|
+
}
|
|
598
|
+
if (!ast.entities || ast.entities.length === 0) {
|
|
599
|
+
return { success: false, errors: ['No entity blocks found in specification'] };
|
|
600
|
+
}
|
|
601
|
+
// Import generator dynamically
|
|
602
|
+
const { generateTests } = await import('../codedna/kappa-vitest-generator.js');
|
|
603
|
+
const result = generateTests(ast.entities, ast.apis, {
|
|
604
|
+
testType,
|
|
605
|
+
provenance: options.provenance ?? true,
|
|
606
|
+
factories: options.factories ?? true,
|
|
607
|
+
mocks: options.mocks ?? true,
|
|
608
|
+
});
|
|
609
|
+
const files = result.testFiles.map((t) => ({
|
|
610
|
+
path: t.path,
|
|
611
|
+
content: t.content,
|
|
612
|
+
}));
|
|
613
|
+
if (result.factories) {
|
|
614
|
+
files.push({ path: '__tests__/factories.ts', content: result.factories });
|
|
615
|
+
}
|
|
616
|
+
if (result.mocks) {
|
|
617
|
+
files.push({ path: '__tests__/mocks.ts', content: result.mocks });
|
|
618
|
+
}
|
|
619
|
+
const totalLines = files.reduce((sum, f) => sum + f.content.split('\n').length, 0);
|
|
620
|
+
return {
|
|
621
|
+
success: true,
|
|
622
|
+
files,
|
|
623
|
+
metadata: {
|
|
624
|
+
filesGenerated: files.length,
|
|
625
|
+
linesOfCode: totalLines,
|
|
626
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
catch (error) {
|
|
631
|
+
return {
|
|
632
|
+
success: false,
|
|
633
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
// =============================================================================
|
|
638
|
+
// Phase 1: UI Library Generators
|
|
639
|
+
// =============================================================================
|
|
640
|
+
/**
|
|
641
|
+
* Handle kappa_generate_radix tool call
|
|
642
|
+
* Generates Radix UI components from Kappa component blocks
|
|
643
|
+
*/
|
|
644
|
+
export async function handleKappaGenerateRadix(args) {
|
|
645
|
+
const { spec, options = {} } = args;
|
|
646
|
+
try {
|
|
647
|
+
const ast = parseKappaToAST(spec);
|
|
648
|
+
if (!ast) {
|
|
649
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
650
|
+
}
|
|
651
|
+
if (!ast.components || ast.components.length === 0) {
|
|
652
|
+
return { success: false, errors: ['No component blocks found in specification'] };
|
|
653
|
+
}
|
|
654
|
+
// Import generator dynamically
|
|
655
|
+
const { generateRadixComponents } = await import('../codedna/kappa-radix-generator.js');
|
|
656
|
+
const result = generateRadixComponents(ast.components, {
|
|
657
|
+
provenance: options.provenance ?? true,
|
|
658
|
+
typescript: options.typescript ?? true,
|
|
659
|
+
});
|
|
660
|
+
const files = result.components.map((c) => ({
|
|
661
|
+
path: c.path,
|
|
662
|
+
content: c.content,
|
|
663
|
+
}));
|
|
664
|
+
const totalLines = files.reduce((sum, f) => sum + f.content.split('\n').length, 0);
|
|
665
|
+
return {
|
|
666
|
+
success: true,
|
|
667
|
+
files,
|
|
668
|
+
metadata: {
|
|
669
|
+
filesGenerated: files.length,
|
|
670
|
+
linesOfCode: totalLines,
|
|
671
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
672
|
+
},
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
catch (error) {
|
|
676
|
+
return {
|
|
677
|
+
success: false,
|
|
678
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Handle kappa_generate_mantine tool call
|
|
684
|
+
* Generates Mantine UI components from Kappa specifications
|
|
685
|
+
*/
|
|
686
|
+
export async function handleKappaGenerateMantine(args) {
|
|
687
|
+
const { spec, options = {} } = args;
|
|
688
|
+
try {
|
|
689
|
+
const ast = parseKappaToAST(spec);
|
|
690
|
+
if (!ast) {
|
|
691
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
692
|
+
}
|
|
693
|
+
if ((!ast.components || ast.components.length === 0) && (!ast.forms || ast.forms.length === 0)) {
|
|
694
|
+
return { success: false, errors: ['No component or form blocks found in specification'] };
|
|
695
|
+
}
|
|
696
|
+
// Import generators dynamically
|
|
697
|
+
const { generateMantineComponents, generateMantineForms } = await import('../codedna/kappa-mantine-generator.js');
|
|
698
|
+
const generatorOptions = {
|
|
699
|
+
provenance: options.provenance ?? true,
|
|
700
|
+
typescript: options.typescript ?? true,
|
|
701
|
+
};
|
|
702
|
+
const componentResult = generateMantineComponents(ast.components || [], generatorOptions);
|
|
703
|
+
const formResult = generateMantineForms(ast.forms || [], generatorOptions);
|
|
704
|
+
const files = [
|
|
705
|
+
...componentResult.files.map((c) => ({ path: c.path, content: c.content })),
|
|
706
|
+
...formResult.files.map((f) => ({ path: f.path, content: f.content })),
|
|
707
|
+
];
|
|
708
|
+
const totalLines = files.reduce((sum, f) => sum + f.content.split('\n').length, 0);
|
|
709
|
+
return {
|
|
710
|
+
success: true,
|
|
711
|
+
files,
|
|
712
|
+
metadata: {
|
|
713
|
+
filesGenerated: files.length,
|
|
714
|
+
linesOfCode: totalLines,
|
|
715
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
716
|
+
},
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
catch (error) {
|
|
720
|
+
return {
|
|
721
|
+
success: false,
|
|
722
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
// =============================================================================
|
|
727
|
+
// Go/Fiber Generation Handler
|
|
728
|
+
// =============================================================================
|
|
729
|
+
/**
|
|
730
|
+
* Handle kappa_generate_gofiber tool call
|
|
731
|
+
* Generates Go code with Fiber framework from Kappa specifications
|
|
732
|
+
*/
|
|
733
|
+
export async function handleKappaGenerateGoFiber(args) {
|
|
734
|
+
const { spec, options = {} } = args;
|
|
735
|
+
try {
|
|
736
|
+
const ast = parseKappaToAST(spec);
|
|
737
|
+
if (!ast) {
|
|
738
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
739
|
+
}
|
|
740
|
+
if (ast.apis.length === 0 && ast.entities.length === 0) {
|
|
741
|
+
return { success: false, errors: ['No API or entity blocks found in specification'] };
|
|
742
|
+
}
|
|
743
|
+
// Import generator dynamically
|
|
744
|
+
const { KappaGoFiberGenerator } = await import('../codedna/kappa-gofiber-generator.js');
|
|
745
|
+
const generator = new KappaGoFiberGenerator({
|
|
746
|
+
packageName: options.packageName ?? 'main',
|
|
747
|
+
provenance: options.provenance ?? true,
|
|
748
|
+
gorm: options.gorm ?? true,
|
|
749
|
+
validation: options.validation ?? true,
|
|
750
|
+
basePath: options.basePath ?? '/api',
|
|
751
|
+
modulePath: options.modulePath ?? 'app',
|
|
752
|
+
});
|
|
753
|
+
const result = generator.generateAll(ast.apis, ast.entities);
|
|
754
|
+
const files = [];
|
|
755
|
+
let totalLines = 0;
|
|
756
|
+
if (result.routes) {
|
|
757
|
+
files.push({ path: 'routes.go', content: result.routes });
|
|
758
|
+
totalLines += result.routes.split('\n').length;
|
|
759
|
+
}
|
|
760
|
+
if (result.handlers) {
|
|
761
|
+
files.push({ path: 'handlers.go', content: result.handlers });
|
|
762
|
+
totalLines += result.handlers.split('\n').length;
|
|
763
|
+
}
|
|
764
|
+
if (result.models) {
|
|
765
|
+
files.push({ path: 'models.go', content: result.models });
|
|
766
|
+
totalLines += result.models.split('\n').length;
|
|
767
|
+
}
|
|
768
|
+
if (result.types) {
|
|
769
|
+
files.push({ path: 'types.go', content: result.types });
|
|
770
|
+
totalLines += result.types.split('\n').length;
|
|
771
|
+
}
|
|
772
|
+
return {
|
|
773
|
+
success: true,
|
|
774
|
+
files,
|
|
775
|
+
metadata: {
|
|
776
|
+
filesGenerated: files.length,
|
|
777
|
+
linesOfCode: totalLines,
|
|
778
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
779
|
+
},
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
catch (error) {
|
|
783
|
+
return {
|
|
784
|
+
success: false,
|
|
785
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// =============================================================================
|
|
790
|
+
// PHP/Laravel Generation Handler
|
|
791
|
+
// =============================================================================
|
|
792
|
+
/**
|
|
793
|
+
* Handle kappa_generate_laravel tool call
|
|
794
|
+
* Generates Laravel code from Kappa specifications
|
|
795
|
+
*/
|
|
796
|
+
export async function handleKappaGenerateLaravel(args) {
|
|
797
|
+
const { spec, options = {} } = args;
|
|
798
|
+
try {
|
|
799
|
+
const ast = parseKappaToAST(spec);
|
|
800
|
+
if (!ast) {
|
|
801
|
+
return { success: false, errors: ['Failed to parse Kappa specification'] };
|
|
802
|
+
}
|
|
803
|
+
if (ast.apis.length === 0 && ast.entities.length === 0) {
|
|
804
|
+
return { success: false, errors: ['No API or entity blocks found in specification'] };
|
|
805
|
+
}
|
|
806
|
+
// Import generator dynamically
|
|
807
|
+
const { KappaLaravelGenerator } = await import('../codedna/kappa-laravel-generator.js');
|
|
808
|
+
const generator = new KappaLaravelGenerator({
|
|
809
|
+
modelNamespace: options.modelNamespace ?? 'App\\Models',
|
|
810
|
+
controllerNamespace: options.controllerNamespace ?? 'App\\Http\\Controllers',
|
|
811
|
+
provenance: options.provenance ?? true,
|
|
812
|
+
migrations: options.migrations ?? true,
|
|
813
|
+
formRequests: options.formRequests ?? true,
|
|
814
|
+
apiResources: options.apiResources ?? true,
|
|
815
|
+
basePath: options.basePath ?? '/api',
|
|
816
|
+
});
|
|
817
|
+
const result = generator.generateAll(ast.apis, ast.entities);
|
|
818
|
+
const files = [];
|
|
819
|
+
let totalLines = 0;
|
|
820
|
+
// Add routes
|
|
821
|
+
if (result.routes) {
|
|
822
|
+
files.push({ path: 'routes/api.php', content: result.routes });
|
|
823
|
+
totalLines += result.routes.split('\n').length;
|
|
824
|
+
}
|
|
825
|
+
// Add controllers
|
|
826
|
+
for (const [name, content] of Object.entries(result.controllers)) {
|
|
827
|
+
files.push({ path: `app/Http/Controllers/${name}.php`, content });
|
|
828
|
+
totalLines += content.split('\n').length;
|
|
829
|
+
}
|
|
830
|
+
// Add models
|
|
831
|
+
for (const [name, content] of Object.entries(result.models)) {
|
|
832
|
+
files.push({ path: `app/Models/${name}.php`, content });
|
|
833
|
+
totalLines += content.split('\n').length;
|
|
834
|
+
}
|
|
835
|
+
// Add migrations
|
|
836
|
+
if (result.migrations) {
|
|
837
|
+
for (const [name, content] of Object.entries(result.migrations)) {
|
|
838
|
+
const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14);
|
|
839
|
+
files.push({ path: `database/migrations/${timestamp}_${name}.php`, content });
|
|
840
|
+
totalLines += content.split('\n').length;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
// Add form requests
|
|
844
|
+
if (result.formRequests) {
|
|
845
|
+
for (const [name, content] of Object.entries(result.formRequests)) {
|
|
846
|
+
files.push({ path: `app/Http/Requests/${name}.php`, content });
|
|
847
|
+
totalLines += content.split('\n').length;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
// Add resources
|
|
851
|
+
if (result.resources) {
|
|
852
|
+
for (const [name, content] of Object.entries(result.resources)) {
|
|
853
|
+
files.push({ path: `app/Http/Resources/${name}.php`, content });
|
|
854
|
+
totalLines += content.split('\n').length;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return {
|
|
858
|
+
success: true,
|
|
859
|
+
files,
|
|
860
|
+
metadata: {
|
|
861
|
+
filesGenerated: files.length,
|
|
862
|
+
linesOfCode: totalLines,
|
|
863
|
+
estimatedTokensSaved: totalLines * 25 - 200,
|
|
864
|
+
},
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
catch (error) {
|
|
868
|
+
return {
|
|
869
|
+
success: false,
|
|
870
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
}
|