archetype-engine 2.0.1 → 2.1.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/src/cli.js +6 -0
- package/dist/src/init/templates.d.ts +2 -0
- package/dist/src/init/templates.d.ts.map +1 -1
- package/dist/src/init/templates.js +418 -0
- package/dist/src/mcp-server.d.ts +15 -0
- package/dist/src/mcp-server.d.ts.map +1 -0
- package/dist/src/mcp-server.js +271 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts +3 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts.map +1 -1
- package/dist/src/templates/nextjs-drizzle-trpc/generators/index.js +7 -1
- package/dist/src/templates/nextjs-drizzle-trpc/generators/openapi.d.ts +26 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/openapi.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/openapi.js +690 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/seed.d.ts +27 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/seed.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/seed.js +407 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/test.d.ts +27 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/test.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/test.js +520 -0
- package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts +5 -1
- package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts.map +1 -1
- package/dist/src/templates/nextjs-drizzle-trpc/index.js +11 -1
- package/package.json +3 -2
package/dist/src/cli.js
CHANGED
|
@@ -507,6 +507,11 @@ async function main() {
|
|
|
507
507
|
// Run the TUI init flow
|
|
508
508
|
await (0, init_1.init)({ yes: yesFlag, headless: headlessFlag });
|
|
509
509
|
}
|
|
510
|
+
else if (command === 'mcp') {
|
|
511
|
+
// Run MCP server
|
|
512
|
+
const { runMCPServer } = await Promise.resolve().then(() => __importStar(require('./mcp-server')));
|
|
513
|
+
await runMCPServer();
|
|
514
|
+
}
|
|
510
515
|
else {
|
|
511
516
|
console.log('Usage:');
|
|
512
517
|
console.log(' archetype init - Interactive setup with prompts');
|
|
@@ -515,6 +520,7 @@ async function main() {
|
|
|
515
520
|
console.log(' archetype generate [config] - Generate code from entities');
|
|
516
521
|
console.log(' archetype validate [config] - Validate manifest without generating');
|
|
517
522
|
console.log(' archetype view [config] - View ERD diagram in browser');
|
|
523
|
+
console.log(' archetype mcp - Start MCP server (for Claude Desktop/Code)');
|
|
518
524
|
console.log('');
|
|
519
525
|
console.log('Flags:');
|
|
520
526
|
console.log(' --json - Output as JSON (for AI agents)');
|
|
@@ -12,6 +12,8 @@ export declare function getAuthTemplate(config: InitConfig): string;
|
|
|
12
12
|
export declare function getAuthRouteTemplate(): string;
|
|
13
13
|
export declare function getEnvExampleTemplate(config: InitConfig): string;
|
|
14
14
|
export declare function getGitignoreTemplate(): string;
|
|
15
|
+
export declare function getClaudeMdTemplate(): string;
|
|
16
|
+
export declare function getCursorRulesTemplate(): string;
|
|
15
17
|
export interface TemplateFile {
|
|
16
18
|
path: string;
|
|
17
19
|
content: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/init/templates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAI9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA2G5D;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAe9C;AAGD,wBAAgB,wBAAwB,IAAI,MAAM,CAejD;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CA2B5D;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAyGhE;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAyB7C;AAGD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAgC9D;AAGD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAsBvE;AAGD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA6E1D;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAkChE;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C;AAGD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/init/templates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAI9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA2G5D;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAe9C;AAGD,wBAAgB,wBAAwB,IAAI,MAAM,CAejD;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CA2B5D;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAyGhE;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAyB7C;AAGD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAgC9D;AAGD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAsBvE;AAGD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA6E1D;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAkChE;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C;AAGD,wBAAgB,mBAAmB,IAAI,MAAM,CAgN5C;AAGD,wBAAgB,sBAAsB,IAAI,MAAM,CAyM/C;AAGD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAsFnG;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAahF"}
|
|
@@ -14,6 +14,8 @@ exports.getAuthTemplate = getAuthTemplate;
|
|
|
14
14
|
exports.getAuthRouteTemplate = getAuthRouteTemplate;
|
|
15
15
|
exports.getEnvExampleTemplate = getEnvExampleTemplate;
|
|
16
16
|
exports.getGitignoreTemplate = getGitignoreTemplate;
|
|
17
|
+
exports.getClaudeMdTemplate = getClaudeMdTemplate;
|
|
18
|
+
exports.getCursorRulesTemplate = getCursorRulesTemplate;
|
|
17
19
|
exports.getAllTemplateFiles = getAllTemplateFiles;
|
|
18
20
|
exports.getPackageJsonScripts = getPackageJsonScripts;
|
|
19
21
|
const entity_templates_1 = require("./entity-templates");
|
|
@@ -512,6 +514,419 @@ dist/
|
|
|
512
514
|
.turbo
|
|
513
515
|
`;
|
|
514
516
|
}
|
|
517
|
+
// CLAUDE.md - Rules for Claude Code in user projects
|
|
518
|
+
function getClaudeMdTemplate() {
|
|
519
|
+
return `# Archetype Engine Project - Rules for Claude Code
|
|
520
|
+
|
|
521
|
+
## Overview
|
|
522
|
+
This is an **Archetype Engine** project. Archetype generates backend code (Drizzle schemas, tRPC routers, Zod validation, React hooks) from entity definitions.
|
|
523
|
+
|
|
524
|
+
**CRITICAL:** Code in \`generated/\` is auto-generated and **MUST NOT** be edited manually.
|
|
525
|
+
|
|
526
|
+
## 🚫 NEVER Edit These Directories
|
|
527
|
+
|
|
528
|
+
- \`generated/db/\` - Database schemas (regenerated on each \`archetype generate\`)
|
|
529
|
+
- \`generated/trpc/\` - tRPC routers (regenerated)
|
|
530
|
+
- \`generated/schemas/\` - Zod validation schemas (regenerated)
|
|
531
|
+
- \`generated/hooks/use*.ts\` - React hooks (regenerated)
|
|
532
|
+
- \`generated/erd.md\` - ERD diagram (regenerated)
|
|
533
|
+
|
|
534
|
+
**Why?** These files are overwritten every time \`npm run archetype:generate\` runs.
|
|
535
|
+
|
|
536
|
+
## ✅ ALWAYS Edit These Instead
|
|
537
|
+
|
|
538
|
+
- \`archetype/entities/\` - Entity definitions (source of truth)
|
|
539
|
+
- \`archetype.config.ts\` - Archetype configuration
|
|
540
|
+
- \`manifest.json\` - Alternative to entity files (JSON format)
|
|
541
|
+
- \`src/app/\`, \`src/components/\` - Next.js UI code
|
|
542
|
+
- \`generated/hooks/{entity}.ts\` - Hook implementations (if hooks enabled)
|
|
543
|
+
|
|
544
|
+
## Correct Workflow
|
|
545
|
+
|
|
546
|
+
### When User Asks to Add/Modify Entities
|
|
547
|
+
|
|
548
|
+
**Option 1: JSON Manifest (Recommended - Faster)**
|
|
549
|
+
|
|
550
|
+
\`\`\`bash
|
|
551
|
+
# 1. Create/update manifest.json
|
|
552
|
+
cat > manifest.json << 'EOF'
|
|
553
|
+
{
|
|
554
|
+
"entities": [
|
|
555
|
+
{
|
|
556
|
+
"name": "Product",
|
|
557
|
+
"fields": {
|
|
558
|
+
"name": { "type": "text", "required": true, "min": 1, "max": 200 },
|
|
559
|
+
"price": { "type": "number", "required": true, "min": 0 },
|
|
560
|
+
"stock": { "type": "number", "required": true, "integer": true, "min": 0 }
|
|
561
|
+
},
|
|
562
|
+
"behaviors": {
|
|
563
|
+
"timestamps": true
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
],
|
|
567
|
+
"database": { "type": "sqlite", "file": "./app.db" }
|
|
568
|
+
}
|
|
569
|
+
EOF
|
|
570
|
+
|
|
571
|
+
# 2. Generate code
|
|
572
|
+
npx archetype generate manifest.json
|
|
573
|
+
|
|
574
|
+
# 3. Push to database
|
|
575
|
+
npx drizzle-kit push
|
|
576
|
+
\`\`\`
|
|
577
|
+
|
|
578
|
+
**Option 2: TypeScript Entity Files (For Incremental Changes)**
|
|
579
|
+
|
|
580
|
+
\`\`\`typescript
|
|
581
|
+
// Edit: archetype/entities/product.ts
|
|
582
|
+
import { defineEntity, text, number } from 'archetype-engine'
|
|
583
|
+
|
|
584
|
+
export const Product = defineEntity('Product', {
|
|
585
|
+
fields: {
|
|
586
|
+
name: text().required().min(1).max(200),
|
|
587
|
+
price: number().required().positive(),
|
|
588
|
+
stock: number().required().integer().min(0),
|
|
589
|
+
},
|
|
590
|
+
behaviors: {
|
|
591
|
+
timestamps: true,
|
|
592
|
+
},
|
|
593
|
+
})
|
|
594
|
+
\`\`\`
|
|
595
|
+
|
|
596
|
+
\`\`\`bash
|
|
597
|
+
# Generate code
|
|
598
|
+
npm run archetype:generate
|
|
599
|
+
|
|
600
|
+
# Push to database
|
|
601
|
+
npm run db:push
|
|
602
|
+
\`\`\`
|
|
603
|
+
|
|
604
|
+
### When to Use Each Method
|
|
605
|
+
|
|
606
|
+
| User Request | Use |
|
|
607
|
+
|-------------|-----|
|
|
608
|
+
| "Create a blog with users and posts" | JSON manifest |
|
|
609
|
+
| "Build an e-commerce app" | JSON manifest |
|
|
610
|
+
| "Add a comment entity" | JSON manifest or entity file |
|
|
611
|
+
| "Add a field to User" | Edit entity file |
|
|
612
|
+
| "Change email to unique" | Edit entity file |
|
|
613
|
+
|
|
614
|
+
## Available Commands
|
|
615
|
+
|
|
616
|
+
\`\`\`bash
|
|
617
|
+
npm run archetype:generate # Generate code from entities
|
|
618
|
+
npm run archetype:view # View ERD in browser
|
|
619
|
+
npm run db:push # Push schema to database
|
|
620
|
+
npm run db:studio # Open Drizzle Studio
|
|
621
|
+
npx archetype validate manifest.json --json # Validate manifest
|
|
622
|
+
\`\`\`
|
|
623
|
+
|
|
624
|
+
## Examples
|
|
625
|
+
|
|
626
|
+
### ❌ WRONG: Editing Generated Code
|
|
627
|
+
|
|
628
|
+
\`\`\`typescript
|
|
629
|
+
// File: generated/trpc/routers/product.ts
|
|
630
|
+
// DON'T DO THIS - will be overwritten!
|
|
631
|
+
export const productRouter = router({
|
|
632
|
+
list: publicProcedure.query(async ({ ctx }) => {
|
|
633
|
+
// Adding custom logic here ❌
|
|
634
|
+
const products = await ctx.db.query.products.findMany()
|
|
635
|
+
return products.filter(p => p.stock > 0) // ❌ WRONG
|
|
636
|
+
})
|
|
637
|
+
})
|
|
638
|
+
\`\`\`
|
|
639
|
+
|
|
640
|
+
### ✅ CORRECT: Using Hooks for Business Logic
|
|
641
|
+
|
|
642
|
+
If the entity has \`hooks: true\`, edit the hook implementation:
|
|
643
|
+
|
|
644
|
+
\`\`\`typescript
|
|
645
|
+
// File: generated/hooks/product.ts (editable!)
|
|
646
|
+
export const productHooks: ProductHooks = {
|
|
647
|
+
async beforeCreate(input, ctx) {
|
|
648
|
+
// Validate stock is positive
|
|
649
|
+
if (input.stock < 0) {
|
|
650
|
+
throw new Error('Stock cannot be negative')
|
|
651
|
+
}
|
|
652
|
+
return input
|
|
653
|
+
},
|
|
654
|
+
|
|
655
|
+
async afterCreate(record, ctx) {
|
|
656
|
+
// Send notification
|
|
657
|
+
await notifyLowStock(record)
|
|
658
|
+
},
|
|
659
|
+
}
|
|
660
|
+
\`\`\`
|
|
661
|
+
|
|
662
|
+
### ✅ CORRECT: Modifying Entity Definition
|
|
663
|
+
|
|
664
|
+
\`\`\`typescript
|
|
665
|
+
// File: archetype/entities/product.ts
|
|
666
|
+
import { defineEntity, text, number, boolean } from 'archetype-engine'
|
|
667
|
+
|
|
668
|
+
export const Product = defineEntity('Product', {
|
|
669
|
+
fields: {
|
|
670
|
+
name: text().required().min(1).max(200),
|
|
671
|
+
price: number().required().positive(),
|
|
672
|
+
stock: number().required().integer().min(0),
|
|
673
|
+
// Add new field ✅
|
|
674
|
+
inStock: boolean().default(true),
|
|
675
|
+
},
|
|
676
|
+
behaviors: {
|
|
677
|
+
timestamps: true,
|
|
678
|
+
},
|
|
679
|
+
})
|
|
680
|
+
\`\`\`
|
|
681
|
+
|
|
682
|
+
Then run:
|
|
683
|
+
\`\`\`bash
|
|
684
|
+
npm run archetype:generate && npm run db:push
|
|
685
|
+
\`\`\`
|
|
686
|
+
|
|
687
|
+
## Field Types Reference
|
|
688
|
+
|
|
689
|
+
- \`text()\` - String with \`.email()\`, \`.url()\`, \`.regex()\`, \`.min()\`, \`.max()\`, \`.oneOf()\`
|
|
690
|
+
- \`number()\` - Numeric with \`.integer()\`, \`.positive()\`, \`.min()\`, \`.max()\`
|
|
691
|
+
- \`boolean()\` - Boolean with \`.default()\`
|
|
692
|
+
- \`date()\` - Date/timestamp with \`.default('now')\`
|
|
693
|
+
|
|
694
|
+
All fields: \`.required()\`, \`.optional()\`, \`.unique()\`, \`.default()\`, \`.label()\`
|
|
695
|
+
|
|
696
|
+
## Relations
|
|
697
|
+
|
|
698
|
+
- \`hasOne('Entity')\` - One-to-one
|
|
699
|
+
- \`hasMany('Entity')\` - One-to-many
|
|
700
|
+
- \`belongsToMany('Entity')\` - Many-to-many
|
|
701
|
+
- \`belongsToMany('Entity').through({ fields: {...} })\` - Many-to-many with pivot data
|
|
702
|
+
|
|
703
|
+
## Questions to Ask Before Making Changes
|
|
704
|
+
|
|
705
|
+
1. **Am I editing \`generated/\`?** → STOP. Edit entity definition instead.
|
|
706
|
+
2. **Am I adding business logic?** → Use hooks system, not generated routers.
|
|
707
|
+
3. **Am I creating a new entity?** → Use manifest.json or create entity file.
|
|
708
|
+
4. **Am I modifying UI?** → That's fine, UI code is not Archetype-managed.
|
|
709
|
+
|
|
710
|
+
## Technology Stack
|
|
711
|
+
|
|
712
|
+
- **ORM**: Drizzle (schemas in \`generated/db/\`)
|
|
713
|
+
- **API**: tRPC (routers in \`generated/trpc/\`)
|
|
714
|
+
- **Validation**: Zod (schemas in \`generated/schemas/\`)
|
|
715
|
+
- **Frontend**: React hooks (in \`generated/hooks/\`)
|
|
716
|
+
- **Auth**: NextAuth v5 (if enabled)
|
|
717
|
+
|
|
718
|
+
## Summary
|
|
719
|
+
|
|
720
|
+
1. **Source of truth**: Entity definitions in \`archetype/entities/\` or \`manifest.json\`
|
|
721
|
+
2. **Generated code**: Read-only, never edit directly
|
|
722
|
+
3. **Workflow**: Edit entities → Generate → Push to DB
|
|
723
|
+
4. **Business logic**: Use hooks, not router edits
|
|
724
|
+
5. **Prefer JSON manifests** for new entities (faster, simpler)
|
|
725
|
+
`;
|
|
726
|
+
}
|
|
727
|
+
// .cursorrules - AI assistant rules for Archetype projects
|
|
728
|
+
function getCursorRulesTemplate() {
|
|
729
|
+
return `# Archetype Engine - AI Assistant Rules
|
|
730
|
+
|
|
731
|
+
## Overview
|
|
732
|
+
This project uses **Archetype Engine** to generate backend code from entity definitions.
|
|
733
|
+
You are working in a project that follows the Archetype workflow.
|
|
734
|
+
|
|
735
|
+
## Critical Rules
|
|
736
|
+
|
|
737
|
+
### 🚫 NEVER Edit Generated Code
|
|
738
|
+
- **NEVER** modify files in \`generated/\` directory
|
|
739
|
+
- **NEVER** edit \`generated/db/schema.ts\`, \`generated/trpc/routers/\`, or \`generated/hooks/\`
|
|
740
|
+
- Generated code is **read-only** - it gets overwritten on next generation
|
|
741
|
+
|
|
742
|
+
### ✅ Always Edit Source Files Instead
|
|
743
|
+
- To change database schema: Edit \`archetype/entities/*.ts\`
|
|
744
|
+
- To add/modify fields: Edit entity definitions
|
|
745
|
+
- To change relations: Edit entity relations
|
|
746
|
+
- To add validation: Edit field validators in entities
|
|
747
|
+
|
|
748
|
+
## Correct Workflow
|
|
749
|
+
|
|
750
|
+
### Adding/Modifying Entities
|
|
751
|
+
|
|
752
|
+
**Option 1: TypeScript Files (Incremental Changes)**
|
|
753
|
+
\`\`\`typescript
|
|
754
|
+
// Edit: archetype/entities/user.ts
|
|
755
|
+
import { defineEntity, text, number } from 'archetype-engine'
|
|
756
|
+
|
|
757
|
+
export const User = defineEntity('User', {
|
|
758
|
+
fields: {
|
|
759
|
+
email: text().required().unique().email(),
|
|
760
|
+
name: text().required().min(2),
|
|
761
|
+
age: number().optional().min(0),
|
|
762
|
+
},
|
|
763
|
+
})
|
|
764
|
+
\`\`\`
|
|
765
|
+
|
|
766
|
+
**Option 2: JSON Manifest (Full App Setup)**
|
|
767
|
+
\`\`\`json
|
|
768
|
+
// Edit: manifest.json
|
|
769
|
+
{
|
|
770
|
+
"entities": [
|
|
771
|
+
{
|
|
772
|
+
"name": "User",
|
|
773
|
+
"fields": {
|
|
774
|
+
"email": { "type": "text", "email": true, "required": true, "unique": true },
|
|
775
|
+
"name": { "type": "text", "required": true, "min": 2 }
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
],
|
|
779
|
+
"database": { "type": "sqlite", "file": "./app.db" }
|
|
780
|
+
}
|
|
781
|
+
\`\`\`
|
|
782
|
+
|
|
783
|
+
### After Editing Entities
|
|
784
|
+
1. Run: \`npm run archetype:generate\` (or \`npx archetype generate\`)
|
|
785
|
+
2. Review changes in \`generated/\`
|
|
786
|
+
3. Run: \`npm run db:push\` to update database schema
|
|
787
|
+
|
|
788
|
+
### User-Editable Directories
|
|
789
|
+
- \`archetype/entities/\` - Entity definitions ✅
|
|
790
|
+
- \`archetype.config.ts\` - Configuration ✅
|
|
791
|
+
- \`src/app/\` - Next.js pages and components ✅
|
|
792
|
+
- \`src/components/\` - React components ✅
|
|
793
|
+
- \`src/lib/\` - Utility functions ✅
|
|
794
|
+
- \`generated/hooks/{entity}.ts\` - Hook implementations (if hooks enabled) ✅
|
|
795
|
+
- \`drizzle.config.ts\` - Drizzle configuration ✅
|
|
796
|
+
|
|
797
|
+
### Read-Only Directories
|
|
798
|
+
- \`generated/db/\` - Generated database schemas ❌
|
|
799
|
+
- \`generated/trpc/\` - Generated tRPC routers ❌
|
|
800
|
+
- \`generated/schemas/\` - Generated Zod schemas ❌
|
|
801
|
+
- \`generated/hooks/use{Entity}.ts\` - Generated React hooks ❌
|
|
802
|
+
- \`generated/erd.md\` - Generated ERD diagram ❌
|
|
803
|
+
|
|
804
|
+
## Common Tasks
|
|
805
|
+
|
|
806
|
+
### Add a New Field
|
|
807
|
+
1. Edit the entity file in \`archetype/entities/{entity}.ts\`
|
|
808
|
+
2. Add the field using field builders: \`text()\`, \`number()\`, \`boolean()\`, \`date()\`
|
|
809
|
+
3. Run \`npm run archetype:generate\`
|
|
810
|
+
4. Run \`npm run db:push\`
|
|
811
|
+
|
|
812
|
+
### Add a Relation
|
|
813
|
+
1. Edit entity file: add to \`relations\` object
|
|
814
|
+
2. Use: \`hasOne('Entity')\`, \`hasMany('Entity')\`, or \`belongsToMany('Entity')\`
|
|
815
|
+
3. Run \`npm run archetype:generate\`
|
|
816
|
+
4. Run \`npm run db:push\`
|
|
817
|
+
|
|
818
|
+
### Enable Authentication
|
|
819
|
+
1. Edit \`archetype.config.ts\`:
|
|
820
|
+
\`\`\`typescript
|
|
821
|
+
auth: {
|
|
822
|
+
enabled: true,
|
|
823
|
+
providers: ['credentials', 'google'],
|
|
824
|
+
}
|
|
825
|
+
\`\`\`
|
|
826
|
+
2. Run \`npm run archetype:generate\`
|
|
827
|
+
3. Configure env vars in \`.env.local\`
|
|
828
|
+
|
|
829
|
+
### Add CRUD Hooks (Business Logic)
|
|
830
|
+
1. Edit entity: \`hooks: true\` or \`hooks: { beforeCreate: true, afterCreate: true }\`
|
|
831
|
+
2. Run \`npm run archetype:generate\`
|
|
832
|
+
3. Edit \`generated/hooks/{entity}.ts\` to implement logic
|
|
833
|
+
|
|
834
|
+
## Technology Stack
|
|
835
|
+
- **Database ORM**: Drizzle (generated schemas in \`generated/db/\`)
|
|
836
|
+
- **API Layer**: tRPC (generated routers in \`generated/trpc/\`)
|
|
837
|
+
- **Validation**: Zod (generated schemas in \`generated/schemas/\`)
|
|
838
|
+
- **React Hooks**: TanStack Query + tRPC hooks (generated in \`generated/hooks/\`)
|
|
839
|
+
- **Auth**: NextAuth v5 (if enabled)
|
|
840
|
+
|
|
841
|
+
## File References
|
|
842
|
+
When discussing code, use \`file:line\` format: \`archetype/entities/user.ts:12\`
|
|
843
|
+
|
|
844
|
+
## When User Asks to "Add Backend" or "Create API"
|
|
845
|
+
1. **Ask which approach they prefer**:
|
|
846
|
+
- Quick setup: Create \`manifest.json\` + run \`npx archetype generate manifest.json\`
|
|
847
|
+
- Incremental: Create/edit entity files in \`archetype/entities/\`
|
|
848
|
+
|
|
849
|
+
2. **For new projects**: Recommend \`manifest.json\` (faster, simpler)
|
|
850
|
+
3. **For existing projects**: Edit entity files directly
|
|
851
|
+
|
|
852
|
+
## Commands Reference
|
|
853
|
+
\`\`\`bash
|
|
854
|
+
# Generate code from entities
|
|
855
|
+
npm run archetype:generate
|
|
856
|
+
|
|
857
|
+
# View ERD diagram
|
|
858
|
+
npm run archetype:view
|
|
859
|
+
|
|
860
|
+
# Push schema to database (full mode)
|
|
861
|
+
npm run db:push
|
|
862
|
+
|
|
863
|
+
# Open Drizzle Studio (full mode)
|
|
864
|
+
npm run db:studio
|
|
865
|
+
|
|
866
|
+
# Validate manifest
|
|
867
|
+
npx archetype validate manifest.json --json
|
|
868
|
+
\`\`\`
|
|
869
|
+
|
|
870
|
+
## Examples
|
|
871
|
+
|
|
872
|
+
### ❌ Wrong: Editing Generated Code
|
|
873
|
+
\`\`\`typescript
|
|
874
|
+
// DON'T DO THIS - will be overwritten
|
|
875
|
+
// File: generated/trpc/routers/user.ts
|
|
876
|
+
export const userRouter = router({
|
|
877
|
+
list: publicProcedure.query(async () => {
|
|
878
|
+
// Adding custom logic here - WRONG!
|
|
879
|
+
})
|
|
880
|
+
})
|
|
881
|
+
\`\`\`
|
|
882
|
+
|
|
883
|
+
### ✅ Correct: Using Hooks for Business Logic
|
|
884
|
+
\`\`\`typescript
|
|
885
|
+
// DO THIS - edit hook implementation
|
|
886
|
+
// File: generated/hooks/user.ts
|
|
887
|
+
export const userHooks: UserHooks = {
|
|
888
|
+
async beforeCreate(input, ctx) {
|
|
889
|
+
// Custom validation
|
|
890
|
+
if (input.email.includes('spam')) {
|
|
891
|
+
throw new Error('Invalid email')
|
|
892
|
+
}
|
|
893
|
+
return input
|
|
894
|
+
},
|
|
895
|
+
async afterCreate(record, ctx) {
|
|
896
|
+
// Send welcome email
|
|
897
|
+
await sendWelcomeEmail(record.email)
|
|
898
|
+
},
|
|
899
|
+
}
|
|
900
|
+
\`\`\`
|
|
901
|
+
|
|
902
|
+
### ✅ Correct: Modifying Entity Definition
|
|
903
|
+
\`\`\`typescript
|
|
904
|
+
// DO THIS - edit source entity
|
|
905
|
+
// File: archetype/entities/user.ts
|
|
906
|
+
import { defineEntity, text } from 'archetype-engine'
|
|
907
|
+
|
|
908
|
+
export const User = defineEntity('User', {
|
|
909
|
+
fields: {
|
|
910
|
+
email: text().required().unique().email(),
|
|
911
|
+
// Add new field here
|
|
912
|
+
phone: text().optional().regex(/^\\+?[1-9]\\d{1,14}$/),
|
|
913
|
+
},
|
|
914
|
+
})
|
|
915
|
+
\`\`\`
|
|
916
|
+
|
|
917
|
+
## Questions to Ask Before Acting
|
|
918
|
+
1. Is this modifying generated code? → Edit entity definition instead
|
|
919
|
+
2. Is this business logic? → Use hooks system
|
|
920
|
+
3. Is this a new entity? → Create in \`archetype/entities/\` or update \`manifest.json\`
|
|
921
|
+
4. Is this UI/frontend? → Edit normally (not Archetype-managed)
|
|
922
|
+
|
|
923
|
+
## Summary
|
|
924
|
+
- **Source of truth**: Entity definitions in \`archetype/entities/\` or \`manifest.json\`
|
|
925
|
+
- **Generated code**: Read-only, regenerated on every \`archetype generate\`
|
|
926
|
+
- **Workflow**: Edit entities → Generate → Push to DB → Develop frontend
|
|
927
|
+
- **Business logic**: Use hooks system, not direct router edits
|
|
928
|
+
`;
|
|
929
|
+
}
|
|
515
930
|
function getAllTemplateFiles(config, structure) {
|
|
516
931
|
const prefix = structure.useSrcDir ? 'src/' : '';
|
|
517
932
|
const files = [
|
|
@@ -519,6 +934,9 @@ function getAllTemplateFiles(config, structure) {
|
|
|
519
934
|
{ path: 'archetype.config.ts', content: getConfigTemplate(config) },
|
|
520
935
|
// Gitignore - always needed
|
|
521
936
|
{ path: '.gitignore', content: getGitignoreTemplate() },
|
|
937
|
+
// AI assistant guidance files
|
|
938
|
+
{ path: 'CLAUDE.md', content: getClaudeMdTemplate() }, // For Claude Code
|
|
939
|
+
{ path: '.cursorrules', content: getCursorRulesTemplate() }, // For Cursor/Windsurf
|
|
522
940
|
];
|
|
523
941
|
if (config.mode === 'headless') {
|
|
524
942
|
// Headless mode: tRPC but no database
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for Archetype Engine
|
|
4
|
+
*
|
|
5
|
+
* Provides tools for Claude Desktop, Claude Code, Cursor, and other MCP clients
|
|
6
|
+
* to generate backends from entity descriptions.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx archetype-engine mcp
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Main MCP server loop
|
|
13
|
+
*/
|
|
14
|
+
export declare function runMCPServer(): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/mcp-server.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AA8MH;;GAEG;AACH,wBAAsB,YAAY,kBAqEjC"}
|