create-mantiq 0.7.2 → 0.7.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mantiq",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "description": "Scaffold a new MantiqJS application",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,83 @@
1
+ ---
2
+ description: MantiqJS framework conventions — loaded every session
3
+ ---
4
+
5
+ # MantiqJS Conventions
6
+
7
+ This is a MantiqJS project — a full-stack TypeScript web framework for Bun.
8
+
9
+ ## Critical Rules
10
+
11
+ 1. **Always use `override`** — `noImplicitOverride` is enabled. Every method that overrides a base class member MUST use the `override` keyword.
12
+
13
+ 2. **Use `make:*` generators** — never manually create models, controllers, migrations, etc. Run `bun mantiq make:model Post --migration` instead.
14
+
15
+ 3. **ESM only** — use `import`, never `require()`. Use `.ts` extensions in relative imports.
16
+
17
+ 4. **Bun runtime** — use `bun test`, `bun run`, Bun APIs. Not Node.js, not jest, not vitest.
18
+
19
+ 5. **Named exports** — controllers, models, middleware use named exports. Only migrations and seeders use `export default class`.
20
+
21
+ ## Base Class Signatures
22
+
23
+ These are the most common mistakes. Get these right:
24
+
25
+ ```
26
+ Factory.definition(index: number, fake: Faker) — NOT (faker)
27
+ Middleware.handle(request, next) — next() takes NO arguments
28
+ Controller methods return Promise<Response> — use MantiqResponse.json()
29
+ Command.handle(args: ParsedArgs): Promise<number> — return 0 for success
30
+ FormRequest.rules(): Record<string, string> — rule strings like 'required|email'
31
+ ```
32
+
33
+ ## File Placement
34
+
35
+ ```
36
+ Controllers → app/Http/Controllers/<Name>Controller.ts
37
+ Models → app/Models/<Name>.ts
38
+ Middleware → app/Http/Middleware/<Name>Middleware.ts
39
+ Form Requests → app/Http/Requests/<Action><Name>Request.ts
40
+ Providers → app/Providers/<Name>ServiceProvider.ts
41
+ Commands → app/Console/Commands/<Name>Command.ts
42
+ Migrations → database/migrations/<timestamp>_<name>.ts
43
+ Factories → database/factories/<Name>Factory.ts
44
+ Seeders → database/seeders/<Name>Seeder.ts
45
+ Feature tests → tests/feature/<name>.test.ts
46
+ Unit tests → tests/unit/<name>.test.ts
47
+ Config → config/<name>.ts
48
+ Routes → routes/web.ts, routes/api.ts
49
+ ```
50
+
51
+ ## Imports
52
+
53
+ ```typescript
54
+ import type { MantiqRequest } from '@mantiq/core'
55
+ import { MantiqResponse } from '@mantiq/core'
56
+ import { Model } from '@mantiq/database'
57
+ import { Migration } from '@mantiq/database'
58
+ import type { SchemaBuilder } from '@mantiq/database'
59
+ import { Factory } from '@mantiq/database'
60
+ import type { Faker } from '@mantiq/database'
61
+ import { FormRequest } from '@mantiq/validation'
62
+ import { Command } from '@mantiq/cli'
63
+ import type { ParsedArgs } from '@mantiq/cli'
64
+ import { ServiceProvider } from '@mantiq/core'
65
+ import type { Middleware, NextFunction } from '@mantiq/core'
66
+ import { CacheManager } from '@mantiq/core'
67
+ import { cache, config, env } from '@mantiq/core'
68
+ import { TestCase } from '@mantiq/testing'
69
+ ```
70
+
71
+ ## Common Commands
72
+
73
+ ```bash
74
+ bun mantiq make:model <Name> [--migration] [--factory] [--seed]
75
+ bun mantiq make:controller <Name>
76
+ bun mantiq make:middleware <Name>
77
+ bun mantiq make:request <Name>
78
+ bun mantiq migrate
79
+ bun mantiq migrate:fresh
80
+ bun mantiq route:list
81
+ bun mantiq serve
82
+ bun test tests/
83
+ ```
@@ -0,0 +1,112 @@
1
+ ---
2
+ description: MantiqJS code patterns — routing, responses, validation, testing
3
+ ---
4
+
5
+ # Code Patterns
6
+
7
+ ## Routing
8
+
9
+ Route files export a default function:
10
+
11
+ ```typescript
12
+ import type { Router } from '@mantiq/core'
13
+
14
+ export default function (router: Router) {
15
+ router.get('/posts', [PostController, 'index'])
16
+ router.post('/posts', [PostController, 'store'])
17
+ router.get('/posts/:id', [PostController, 'show']).whereNumber('id')
18
+
19
+ router.group({ prefix: '/admin', middleware: ['auth'] }, (r) => {
20
+ r.resource('/users', UserController)
21
+ })
22
+ }
23
+ ```
24
+
25
+ ## Responses
26
+
27
+ ```typescript
28
+ return MantiqResponse.json({ data: users }) // 200
29
+ return MantiqResponse.json({ data: post }, 201) // 201 Created
30
+ return MantiqResponse.noContent() // 204
31
+ return MantiqResponse.redirect('/login') // 302
32
+ ```
33
+
34
+ ## Validation Rules
35
+
36
+ ```typescript
37
+ override rules(): Record<string, string> {
38
+ return {
39
+ name: 'required|string|max:255',
40
+ email: 'required|email|unique:users,email',
41
+ password: 'required|min:8|confirmed',
42
+ age: 'integer|min:18|max:120',
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## Service Container
48
+
49
+ Use class keys, NOT strings:
50
+
51
+ ```typescript
52
+ import { CacheManager } from '@mantiq/core'
53
+
54
+ app.make(CacheManager) // correct — use the class itself as key
55
+ app.make('cache') // WRONG — string keys will throw
56
+ ```
57
+
58
+ Helper functions are available for common services:
59
+
60
+ ```typescript
61
+ import { cache, config, env } from '@mantiq/core'
62
+
63
+ await cache().get('key') // CacheManager
64
+ config('database.connection') // ConfigRepository
65
+ env('APP_KEY') // environment variable
66
+ ```
67
+
68
+ ## Config Files
69
+
70
+ ```typescript
71
+ import { env } from '@mantiq/core'
72
+
73
+ export default {
74
+ name: env('APP_NAME', 'MantiqJS'),
75
+ debug: env('APP_DEBUG', false),
76
+ }
77
+ ```
78
+
79
+ ## Testing
80
+
81
+ ```typescript
82
+ import { describe, test, expect } from 'bun:test'
83
+ import { TestCase } from '@mantiq/testing'
84
+
85
+ const t = new TestCase()
86
+ t.refreshDatabase = true
87
+ t.setup()
88
+
89
+ describe('Posts', () => {
90
+ test('can list posts', async () => {
91
+ await t.client.initSession()
92
+ const res = await t.client.get('/api/posts')
93
+ res.assertOk()
94
+ })
95
+ })
96
+ ```
97
+
98
+ - Call `t.client.initSession()` before POST/PUT/DELETE (gets CSRF token)
99
+ - Assertions: `assertOk()`, `assertCreated()`, `assertStatus(n)`, `assertJsonPath()`
100
+ - Database: `assertDatabaseHas('table', { key: 'value' })`
101
+
102
+ ## Don'ts
103
+
104
+ - Don't use `(faker)` for Factory.definition — it's `(index: number, fake: Faker)`
105
+ - Don't pass arguments to `next()` in middleware — NextFunction takes none
106
+ - Don't use string keys with container — use class keys
107
+ - Don't use `require()` — ESM only
108
+ - Don't use `fs.writeFileSync()` — use `Bun.write()`
109
+ - Don't put controllers in `app/Controllers/` — they go in `app/Http/Controllers/`
110
+ - Don't default export controllers or models — use named exports
111
+ - Don't manually create migration files — use `bun mantiq make:migration`
112
+ - Don't use jest or vitest — use `bun:test`
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: api
3
+ description: Add a new API endpoint with controller, validation, and tests
4
+ user_invocable: true
5
+ ---
6
+
7
+ # Add API Endpoint
8
+
9
+ Create a new API endpoint with proper controller, validation, and tests.
10
+
11
+ ## Arguments
12
+
13
+ `<method> <path> [description]` — e.g., `POST /api/orders "Create a new order"`
14
+
15
+ ## Process
16
+
17
+ ### 1. Determine the Controller
18
+
19
+ - If a matching controller exists (e.g., `OrderController` for `/api/orders`), add the method there
20
+ - Otherwise, generate one: `bun mantiq make:controller <Name>Controller`
21
+
22
+ ### 2. Add Controller Method
23
+
24
+ ```typescript
25
+ async methodName(request: MantiqRequest): Promise<Response> {
26
+ // Validate if needed
27
+ // Business logic
28
+ return MantiqResponse.json({ data: result })
29
+ }
30
+ ```
31
+
32
+ - Import `MantiqRequest` as type, `MantiqResponse` as value from `@mantiq/core`
33
+ - Use appropriate status codes: 200 (get/update), 201 (create), 204 (delete)
34
+ - For validation, create a FormRequest: `bun mantiq make:request <Name>Request`
35
+
36
+ ### 3. Add Route
37
+
38
+ Edit `routes/api.ts`:
39
+
40
+ ```typescript
41
+ router.get('/api/endpoint', [Controller, 'method'])
42
+ // Or with middleware:
43
+ router.post('/api/endpoint', [Controller, 'method']).middleware('auth')
44
+ ```
45
+
46
+ - API routes should be prefixed with `/api/`
47
+ - Protected endpoints need `auth` middleware
48
+ - Use parameter constraints: `.whereNumber('id')`, `.whereAlpha('slug')`
49
+
50
+ ### 4. Add Validation (if mutating)
51
+
52
+ For POST/PUT/PATCH endpoints, generate and fill a FormRequest:
53
+
54
+ ```bash
55
+ bun mantiq make:request <Name>Request
56
+ ```
57
+
58
+ ```typescript
59
+ override rules(): Record<string, string> {
60
+ return {
61
+ field: 'required|string|max:255',
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### 5. Add Tests
67
+
68
+ Create or update a test file in `tests/feature/`:
69
+
70
+ ```typescript
71
+ import { describe, test, expect } from 'bun:test'
72
+ import { TestCase } from '@mantiq/testing'
73
+
74
+ const t = new TestCase()
75
+ t.setup()
76
+
77
+ describe('Endpoint', () => {
78
+ test('returns expected response', async () => {
79
+ await t.client.initSession()
80
+ const res = await t.client.get('/api/endpoint')
81
+ res.assertOk()
82
+ })
83
+ })
84
+ ```
85
+
86
+ ### 6. Verify
87
+
88
+ ```bash
89
+ bun mantiq route:list
90
+ bun test tests/feature/<name>.test.ts
91
+ ```
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: crud
3
+ description: Generate a complete CRUD — model, migration, controller, routes, form requests, factory, seeder, tests
4
+ user_invocable: true
5
+ ---
6
+
7
+ # Full CRUD Generator
8
+
9
+ Generate all files needed for a complete resource CRUD.
10
+
11
+ ## Arguments
12
+
13
+ `<ModelName>` — e.g., `Post`, `Article`, `Product`
14
+
15
+ Optionally include fields: `Post title:string body:text published:boolean`
16
+
17
+ ## Process
18
+
19
+ ### 1. Generate Files Using CLI
20
+
21
+ Run these commands in order:
22
+
23
+ ```bash
24
+ bun mantiq make:model <Name> --migration --factory
25
+ bun mantiq make:controller <Name>Controller --resource
26
+ bun mantiq make:request Store<Name>Request
27
+ bun mantiq make:request Update<Name>Request
28
+ bun mantiq make:seeder <Name>Seeder
29
+ bun mantiq make:test <Name>
30
+ ```
31
+
32
+ ### 2. Fill in the Migration
33
+
34
+ Edit the generated migration file in `database/migrations/`. Add columns based on the provided fields (or sensible defaults):
35
+
36
+ ```typescript
37
+ override async up(schema: SchemaBuilder): Promise<void> {
38
+ await schema.create('<table_name>', (t) => {
39
+ t.id()
40
+ // Add columns here based on the provided fields
41
+ t.timestamps()
42
+ })
43
+ }
44
+ ```
45
+
46
+ - Use `snake_case` plural for table names (`blog_posts`, not `BlogPosts`)
47
+ - Always include `t.id()` and `t.timestamps()`
48
+ - Add `t.softDeletes()` if the model should support soft deletion
49
+
50
+ ### 3. Fill in the Model
51
+
52
+ Edit `app/Models/<Name>.ts`:
53
+
54
+ ```typescript
55
+ import { Model } from '@mantiq/database'
56
+
57
+ export class Post extends Model {
58
+ static override table = 'posts'
59
+ static override fillable = ['title', 'body', 'published']
60
+ static override casts = { published: 'boolean' }
61
+ }
62
+ ```
63
+
64
+ ### 4. Fill in the Controller
65
+
66
+ Edit `app/Http/Controllers/<Name>Controller.ts` with full CRUD methods:
67
+ - `index` — list with pagination (`Model.paginate(page, perPage)`)
68
+ - `store` — create (validate with `Store<Name>Request`, return 201)
69
+ - `show` — find by ID (return 404 if not found)
70
+ - `update` — update (validate with `Update<Name>Request`)
71
+ - `destroy` — delete (return 204)
72
+
73
+ Use `MantiqResponse.json()` for all responses.
74
+
75
+ ### 5. Fill in Form Requests
76
+
77
+ `Store<Name>Request` — all required fields:
78
+ ```typescript
79
+ override rules(): Record<string, string> {
80
+ return { title: 'required|string|max:255', body: 'required' }
81
+ }
82
+ ```
83
+
84
+ `Update<Name>Request` — same fields but optional where appropriate.
85
+
86
+ ### 6. Add Routes
87
+
88
+ Add to `routes/api.ts`:
89
+ ```typescript
90
+ router.group({ prefix: '/api', middleware: ['auth'] }, (r) => {
91
+ r.resource('/<plural_name>', <Name>Controller)
92
+ })
93
+ ```
94
+
95
+ Or for web routes with pages, add to `routes/web.ts`.
96
+
97
+ ### 7. Fill in Factory
98
+
99
+ Edit `database/factories/<Name>Factory.ts`:
100
+ ```typescript
101
+ override definition(index: number, fake: Faker): Record<string, any> {
102
+ return {
103
+ title: fake.sentence(),
104
+ body: fake.paragraph(),
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### 8. Fill in Seeder
110
+
111
+ Edit `database/seeders/<Name>Seeder.ts` to use the factory:
112
+ ```typescript
113
+ override async run(): Promise<void> {
114
+ await new <Name>Factory().count(10).create()
115
+ }
116
+ ```
117
+
118
+ ### 9. Fill in Tests
119
+
120
+ Edit `tests/feature/<name>.test.ts` with CRUD tests:
121
+ - Can list resources
122
+ - Can create with valid data
123
+ - Cannot create with invalid data (422)
124
+ - Can update
125
+ - Can delete
126
+ - Unauthenticated requests return 401
127
+
128
+ ### 10. Run Migration
129
+
130
+ ```bash
131
+ bun mantiq migrate
132
+ ```
133
+
134
+ ### 11. Report
135
+
136
+ Show a summary of all generated files and their locations.
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: debug
3
+ description: Framework-aware debugging — check routes, middleware, config, database, logs
4
+ user_invocable: true
5
+ ---
6
+
7
+ # Debug Helper
8
+
9
+ Systematically diagnose issues in the MantiqJS application.
10
+
11
+ ## Arguments
12
+
13
+ - No args: run full diagnostic
14
+ - `routes`: check route registration
15
+ - `db`: check database connection and migrations
16
+ - `config`: check configuration
17
+
18
+ ## Step 1: Environment Check
19
+
20
+ ```bash
21
+ cat .env | grep -E "APP_ENV|APP_DEBUG|APP_KEY|DB_CONNECTION|SESSION_DRIVER"
22
+ ```
23
+
24
+ Verify:
25
+ - `APP_KEY` is set (not empty)
26
+ - `APP_DEBUG=true` for development
27
+ - `DB_CONNECTION` matches available driver
28
+
29
+ ## Step 2: Route Check
30
+
31
+ ```bash
32
+ bun mantiq route:list
33
+ ```
34
+
35
+ - Verify the route in question is registered
36
+ - Check middleware is correct (auth on protected routes, guest on login/register)
37
+ - Check HTTP method matches (GET vs POST)
38
+
39
+ ## Step 3: Database Check
40
+
41
+ ```bash
42
+ bun mantiq migrate:status
43
+ ```
44
+
45
+ - Are all migrations ran?
46
+ - If "pending", run `bun mantiq migrate`
47
+ - Check if the SQLite file exists: `ls -la database/database.sqlite`
48
+
49
+ ## Step 4: Config Check
50
+
51
+ Read the relevant config file in `config/`:
52
+ - `config/app.ts` — app name, key, debug
53
+ - `config/database.ts` — connection settings
54
+ - `config/auth.ts` — guards, providers
55
+ - `config/session.ts` — driver, lifetime, cookie name
56
+
57
+ ## Step 5: Server Boot Check
58
+
59
+ ```bash
60
+ bun run index.ts &
61
+ sleep 2
62
+ curl -s http://localhost:3000/ -w "\nHTTP %{http_code}"
63
+ curl -s http://localhost:3000/api/ping -w "\nHTTP %{http_code}"
64
+ kill %1
65
+ ```
66
+
67
+ Check for boot errors, port conflicts, 500 errors.
68
+
69
+ ## Report
70
+
71
+ Summarize: what's working, what's broken, suggested fix with exact commands.
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: page
3
+ description: Add a new frontend page with routing and navigation
4
+ user_invocable: true
5
+ ---
6
+
7
+ # Add Page
8
+
9
+ Add a new frontend page with backend route and controller wiring.
10
+
11
+ ## Arguments
12
+
13
+ `<PageName> [path]` — e.g., `Settings /settings`, `About /about`
14
+
15
+ ## Process
16
+
17
+ ### 1. Create the Controller Method
18
+
19
+ Add a method to an existing controller or create a new one:
20
+
21
+ ```bash
22
+ bun mantiq make:controller <Name>Controller
23
+ ```
24
+
25
+ The controller method should return page data as JSON with `_page`:
26
+
27
+ ```typescript
28
+ async settings(request: MantiqRequest): Promise<Response> {
29
+ return MantiqResponse.json({
30
+ _page: 'Settings',
31
+ _url: '/settings',
32
+ // page-specific data here
33
+ })
34
+ }
35
+ ```
36
+
37
+ ### 2. Add the Route
38
+
39
+ Edit `routes/web.ts`:
40
+
41
+ ```typescript
42
+ router.get('/settings', [SettingsController, 'settings']).middleware('auth')
43
+ ```
44
+
45
+ ### 3. Create the Page Component
46
+
47
+ Create the page file based on the project's frontend kit:
48
+
49
+ **React** → `src/pages/Settings.tsx`:
50
+ ```tsx
51
+ interface SettingsProps {
52
+ navigate: (href: string) => void
53
+ [key: string]: any
54
+ }
55
+
56
+ export default function Settings({ navigate }: SettingsProps) {
57
+ return (
58
+ <div>
59
+ <h1>Settings</h1>
60
+ </div>
61
+ )
62
+ }
63
+ ```
64
+
65
+ **Vue** → `src/pages/Settings.vue`
66
+ **Svelte** → `src/pages/Settings.svelte`
67
+
68
+ ### 4. Register the Page
69
+
70
+ Add the page to the page registry in the entry file:
71
+
72
+ **React** → `src/main.tsx`:
73
+ ```typescript
74
+ import Settings from './pages/Settings.tsx'
75
+ // Add to pages object:
76
+ const pages = { ..., Settings }
77
+ ```
78
+
79
+ ### 5. Add to SPA Router
80
+
81
+ If the app uses client-side navigation, add the path to the SPA routes array in `src/App.tsx`:
82
+ ```typescript
83
+ const spaRoutes = [..., '/settings']
84
+ ```
85
+
86
+ ### 6. Verify
87
+
88
+ ```bash
89
+ bun mantiq route:list
90
+ ```
91
+
92
+ Start the server and navigate to the new page.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: test
3
+ description: Run tests, typecheck, and report results
4
+ user_invocable: true
5
+ ---
6
+
7
+ # Test Runner
8
+
9
+ Run the project test suite and report results clearly.
10
+
11
+ ## Arguments
12
+
13
+ - No args: run all (typecheck + tests)
14
+ - `unit`: run only unit tests
15
+ - `feature`: run only feature tests
16
+ - `typecheck`: run only typecheck
17
+ - `<file>`: run a specific test file
18
+
19
+ ## Step 1: TypeScript Typecheck
20
+
21
+ ```bash
22
+ npx tsc --noEmit
23
+ ```
24
+
25
+ Report any type errors with file:line.
26
+
27
+ ## Step 2: Tests
28
+
29
+ ```bash
30
+ bun test tests/
31
+ ```
32
+
33
+ Or for specific suites:
34
+ ```bash
35
+ bun test tests/unit/
36
+ bun test tests/feature/
37
+ bun test tests/feature/auth.test.ts
38
+ ```
39
+
40
+ ## Summary
41
+
42
+ Report a table:
43
+
44
+ | Check | Result |
45
+ |-------|--------|
46
+ | Typecheck | pass/fail (N errors) |
47
+ | Unit tests | N pass, N fail |
48
+ | Feature tests | N pass, N fail |
49
+
50
+ If all pass, say "All green." If any failures, list them with file:line and error message.
package/src/templates.ts CHANGED
@@ -47,6 +47,7 @@ export function getTemplates(ctx: TemplateContext): Record<string, string> {
47
47
  }
48
48
 
49
49
  const baseDevDeps: Record<string, string> = {
50
+ '@mantiq/agent-rules': '^0.7.0',
50
51
  '@mantiq/testing': '^0.7.0',
51
52
  'bun-types': 'latest',
52
53
  'typescript': '^5.7.0',
@@ -1,7 +1,7 @@
1
1
  import { defineConfig } from 'vite'
2
2
  import react from '@vitejs/plugin-react'
3
3
  import tailwindcss from '@tailwindcss/vite'
4
- import { mantiq } from '@mantiq/vite'
4
+ import { mantiq } from '@mantiq/vite/plugin'
5
5
  import path from 'path'
6
6
  import { writeFileSync, unlinkSync } from 'node:fs'
7
7