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 +1 -1
- package/skeleton/.claude/rules/conventions.md +83 -0
- package/skeleton/.claude/rules/patterns.md +112 -0
- package/skeleton/.claude/skills/api.md +91 -0
- package/skeleton/.claude/skills/crud.md +136 -0
- package/skeleton/.claude/skills/debug.md +71 -0
- package/skeleton/.claude/skills/page.md +92 -0
- package/skeleton/.claude/skills/test.md +50 -0
- package/src/templates.ts +1 -0
- package/stubs/react/vite.config.ts.stub +1 -1
package/package.json
CHANGED
|
@@ -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
|
@@ -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
|
|