create-kuckit-app 0.3.5 → 0.4.1
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/bin.js +1 -1
- package/dist/{create-project-CP-h4Ygi.js → create-project-CAsuZMK5.js} +7 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/base/.claude/CLAUDE.md +83 -0
- package/templates/base/.claude/skills/kuckit/SKILL.md +22 -2
- package/templates/base/.claude/skills/kuckit/references/MODULE-DEVELOPMENT.md +39 -28
- package/templates/base/.claude/skills/kuckit/references/PACKAGES.md +94 -74
- package/templates/base/AGENTS.md +130 -18
- package/templates/base/apps/server/AGENTS.md +44 -62
- package/templates/base/apps/server/package.json +5 -17
- package/templates/base/apps/server/src/config.ts +12 -0
- package/templates/base/apps/server/src/modules.ts +66 -0
- package/templates/base/apps/server/src/server.ts +4 -44
- package/templates/base/apps/web/AGENTS.md +63 -85
- package/templates/base/apps/web/package.json +7 -11
- package/templates/base/apps/web/src/components/KuckitModuleRoute.tsx +29 -7
- package/templates/base/apps/web/src/components/dashboard/dashboard-overview.tsx +2 -2
- package/templates/base/apps/web/src/components/dashboard/nav-user.tsx +2 -2
- package/templates/base/apps/web/src/main.tsx +12 -22
- package/templates/base/apps/web/src/modules.client.ts +43 -9
- package/templates/base/apps/web/src/routes/__root.tsx +1 -1
- package/templates/base/apps/web/src/routes/dashboard.tsx +1 -1
- package/templates/base/apps/web/src/routes/index.tsx +2 -2
- package/templates/base/apps/web/src/routes/login.tsx +2 -2
- package/templates/base/{packages/db/src/migrations → drizzle}/0000_init.sql +31 -36
- package/templates/base/{packages/db/src/migrations → drizzle}/meta/_journal.json +1 -1
- package/templates/base/drizzle.config.ts +34 -0
- package/templates/base/kuckit.config.ts +30 -0
- package/templates/base/package.json +14 -9
- package/templates/base/packages/items-module/AGENTS.md +83 -0
- package/templates/base/packages/items-module/package.json +7 -7
- package/templates/base/packages/items-module/src/api/items.router.ts +1 -1
- package/templates/base/apps/server/src/app.ts +0 -20
- package/templates/base/apps/server/src/auth.ts +0 -10
- package/templates/base/apps/server/src/config/modules.ts +0 -21
- package/templates/base/apps/server/src/container.ts +0 -81
- package/templates/base/apps/server/src/health.ts +0 -27
- package/templates/base/apps/server/src/middleware/container.ts +0 -41
- package/templates/base/apps/server/src/rpc-router-registry.ts +0 -26
- package/templates/base/apps/server/src/rpc.ts +0 -31
- package/templates/base/apps/web/src/providers/KuckitProvider.tsx +0 -123
- package/templates/base/apps/web/src/providers/ServicesProvider.tsx +0 -47
- package/templates/base/apps/web/src/services/auth-client.ts +0 -12
- package/templates/base/apps/web/src/services/index.ts +0 -3
- package/templates/base/apps/web/src/services/rpc.ts +0 -29
- package/templates/base/apps/web/src/services/types.ts +0 -14
- package/templates/base/packages/api/AGENTS.md +0 -66
- package/templates/base/packages/api/package.json +0 -35
- package/templates/base/packages/api/src/context.ts +0 -48
- package/templates/base/packages/api/src/index.ts +0 -22
- package/templates/base/packages/api/tsconfig.json +0 -8
- package/templates/base/packages/auth/AGENTS.md +0 -61
- package/templates/base/packages/auth/package.json +0 -27
- package/templates/base/packages/auth/src/index.ts +0 -22
- package/templates/base/packages/auth/tsconfig.json +0 -8
- package/templates/base/packages/db/AGENTS.md +0 -99
- package/templates/base/packages/db/drizzle.config.ts +0 -23
- package/templates/base/packages/db/package.json +0 -36
- package/templates/base/packages/db/src/connection.ts +0 -40
- package/templates/base/packages/db/src/index.ts +0 -4
- package/templates/base/packages/db/src/schema/auth.ts +0 -51
- package/templates/base/packages/db/tsconfig.json +0 -8
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as createProject } from "./create-project-
|
|
2
|
+
import { t as createProject } from "./create-project-CAsuZMK5.js";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -39,7 +39,8 @@ async function createProject(name, options) {
|
|
|
39
39
|
const replacements = {
|
|
40
40
|
__APP_NAME__: name,
|
|
41
41
|
__APP_NAME_LOWER__: name.toLowerCase(),
|
|
42
|
-
__APP_NAME_KEBAB__: name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()
|
|
42
|
+
__APP_NAME_KEBAB__: name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(),
|
|
43
|
+
__APP_TITLE__: name
|
|
43
44
|
};
|
|
44
45
|
console.log(" Copying template files...");
|
|
45
46
|
await copyDir(templateDir, targetDir, replacements);
|
|
@@ -73,6 +74,11 @@ Next steps:
|
|
|
73
74
|
bun run db:migrate # Run database migrations
|
|
74
75
|
bun run dev # Start development server
|
|
75
76
|
|
|
77
|
+
Deploy to GCP:
|
|
78
|
+
|
|
79
|
+
bun add -D @kuckit/infra-gcp
|
|
80
|
+
bunx kuckit infra up # One-command deploy
|
|
81
|
+
|
|
76
82
|
Inside that directory, you can run:
|
|
77
83
|
|
|
78
84
|
bun run dev Start the development server
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -42,3 +42,86 @@ This is a Kuckit application using Clean Architecture patterns.
|
|
|
42
42
|
- Adapters: `*.drizzle.ts`
|
|
43
43
|
- Routers: `*.router.ts`
|
|
44
44
|
- Use cases: verb-noun (e.g., `create-item.ts`, `list-items.ts`)
|
|
45
|
+
|
|
46
|
+
<!-- MCP_AGENT_MAIL_AND_BEADS_SNIPPET_START -->
|
|
47
|
+
|
|
48
|
+
## MCP Agent Mail: coordination for multi-agent workflows
|
|
49
|
+
|
|
50
|
+
What it is
|
|
51
|
+
|
|
52
|
+
- A mail-like layer that lets coding agents coordinate asynchronously via MCP tools and resources.
|
|
53
|
+
- Provides identities, inbox/outbox, searchable threads, and advisory file reservations, with human-auditable artifacts in Git.
|
|
54
|
+
|
|
55
|
+
Why it's useful
|
|
56
|
+
|
|
57
|
+
- Prevents agents from stepping on each other with explicit file reservations (leases) for files/globs.
|
|
58
|
+
- Keeps communication out of your token budget by storing messages in a per-project archive.
|
|
59
|
+
- Offers quick reads (`resource://inbox/...`, `resource://thread/...`) and macros that bundle common flows.
|
|
60
|
+
|
|
61
|
+
How to use effectively
|
|
62
|
+
|
|
63
|
+
1. Same repository
|
|
64
|
+
- Register an identity: call `ensure_project`, then `register_agent` using this repo's absolute path as `project_key`.
|
|
65
|
+
- Reserve files before you edit: `file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true)` to signal intent and avoid conflict.
|
|
66
|
+
- Communicate with threads: use `send_message(..., thread_id="FEAT-123")`; check inbox with `fetch_inbox` and acknowledge with `acknowledge_message`.
|
|
67
|
+
- Read fast: `resource://inbox/{Agent}?project=<abs-path>&limit=20` or `resource://thread/{id}?project=<abs-path>&include_bodies=true`.
|
|
68
|
+
- Tip: set `AGENT_NAME` in your environment so the pre-commit guard can block commits that conflict with others' active exclusive file reservations.
|
|
69
|
+
|
|
70
|
+
2. Across different repos in one project (e.g., Next.js frontend + FastAPI backend)
|
|
71
|
+
- Option A (single project bus): register both sides under the same `project_key` (shared key/path). Keep reservation patterns specific (e.g., `frontend/**` vs `backend/**`).
|
|
72
|
+
- Option B (separate projects): each repo has its own `project_key`; use `macro_contact_handshake` or `request_contact`/`respond_contact` to link agents, then message directly. Keep a shared `thread_id` (e.g., ticket key) across repos for clean summaries/audits.
|
|
73
|
+
|
|
74
|
+
Macros vs granular tools
|
|
75
|
+
|
|
76
|
+
- Prefer macros when you want speed or are on a smaller model: `macro_start_session`, `macro_prepare_thread`, `macro_file_reservation_cycle`, `macro_contact_handshake`.
|
|
77
|
+
- Use granular tools when you need control: `register_agent`, `file_reservation_paths`, `send_message`, `fetch_inbox`, `acknowledge_message`.
|
|
78
|
+
|
|
79
|
+
Common pitfalls
|
|
80
|
+
|
|
81
|
+
- "from_agent not registered": always `register_agent` in the correct `project_key` first.
|
|
82
|
+
- "FILE_RESERVATION_CONFLICT": adjust patterns, wait for expiry, or use a non-exclusive reservation when appropriate.
|
|
83
|
+
- Auth errors: if JWT+JWKS is enabled, include a bearer token with a `kid` that matches server JWKS; static bearer is used only when JWT is disabled.
|
|
84
|
+
|
|
85
|
+
## Integrating with Beads (dependency-aware task planning)
|
|
86
|
+
|
|
87
|
+
Beads provides a lightweight, dependency-aware issue database and a CLI (`bd`) for selecting "ready work," setting priorities, and tracking status. It complements MCP Agent Mail's messaging, audit trail, and file-reservation signals. Project: [steveyegge/beads](https://github.com/steveyegge/beads)
|
|
88
|
+
|
|
89
|
+
Recommended conventions
|
|
90
|
+
|
|
91
|
+
- **Single source of truth**: Use **Beads** for task status/priority/dependencies; use **Agent Mail** for conversation, decisions, and attachments (audit).
|
|
92
|
+
- **Shared identifiers**: Use the Beads issue id (e.g., `bd-123`) as the Mail `thread_id` and prefix message subjects with `[bd-123]`.
|
|
93
|
+
- **Reservations**: When starting a `bd-###` task, call `file_reservation_paths(...)` for the affected paths; include the issue id in the `reason` and release on completion.
|
|
94
|
+
|
|
95
|
+
Typical flow (agents)
|
|
96
|
+
|
|
97
|
+
1. **Pick ready work** (Beads)
|
|
98
|
+
- `bd ready --json` → choose one item (highest priority, no blockers)
|
|
99
|
+
2. **Reserve edit surface** (Mail)
|
|
100
|
+
- `file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true, reason="bd-123")`
|
|
101
|
+
3. **Announce start** (Mail)
|
|
102
|
+
- `send_message(..., thread_id="bd-123", subject="[bd-123] Start: <short title>", ack_required=true)`
|
|
103
|
+
4. **Work and update**
|
|
104
|
+
- Reply in-thread with progress and attach artifacts/images; keep the discussion in one thread per issue id
|
|
105
|
+
5. **Complete and release**
|
|
106
|
+
- `bd close bd-123 --reason "Completed"` (Beads is status authority)
|
|
107
|
+
- `release_file_reservations(project_key, agent_name, paths=["src/**"])`
|
|
108
|
+
- Final Mail reply: `[bd-123] Completed` with summary and links
|
|
109
|
+
|
|
110
|
+
Mapping cheat-sheet
|
|
111
|
+
|
|
112
|
+
- **Mail `thread_id`** ↔ `bd-###`
|
|
113
|
+
- **Mail subject**: `[bd-###] …`
|
|
114
|
+
- **File reservation `reason`**: `bd-###`
|
|
115
|
+
- **Commit messages (optional)**: include `bd-###` for traceability
|
|
116
|
+
|
|
117
|
+
Event mirroring (optional automation)
|
|
118
|
+
|
|
119
|
+
- On `bd update --status blocked`, send a high-importance Mail message in thread `bd-###` describing the blocker.
|
|
120
|
+
- On Mail "ACK overdue" for a critical decision, add a Beads label (e.g., `needs-ack`) or bump priority to surface it in `bd ready`.
|
|
121
|
+
|
|
122
|
+
Pitfalls to avoid
|
|
123
|
+
|
|
124
|
+
- Don't create or manage tasks in Mail; treat Beads as the single task queue.
|
|
125
|
+
- Always include `bd-###` in message `thread_id` to avoid ID drift across tools.
|
|
126
|
+
|
|
127
|
+
<!-- MCP_AGENT_MAIL_AND_BEADS_SNIPPET_END -->
|
|
@@ -193,14 +193,34 @@ export const kuckitClientModule = defineKuckitClientModule({
|
|
|
193
193
|
|
|
194
194
|
### Module package.json Metadata
|
|
195
195
|
|
|
196
|
+
Modules depend on `@kuckit/*` npm packages:
|
|
197
|
+
|
|
196
198
|
```json
|
|
197
199
|
{
|
|
198
200
|
"name": "@acme/billing-module",
|
|
201
|
+
"version": "0.1.0",
|
|
202
|
+
"type": "module",
|
|
203
|
+
"exports": {
|
|
204
|
+
".": "./src/index.ts",
|
|
205
|
+
"./client": "./src/client-module.ts"
|
|
206
|
+
},
|
|
207
|
+
"peerDependencies": {
|
|
208
|
+
"@kuckit/sdk": "^1.0.0",
|
|
209
|
+
"@kuckit/sdk-react": "^1.0.0",
|
|
210
|
+
"typescript": "^5"
|
|
211
|
+
},
|
|
212
|
+
"dependencies": {
|
|
213
|
+
"@kuckit/api": "^1.0.0",
|
|
214
|
+
"@orpc/server": "^1.10.0",
|
|
215
|
+
"@orpc/zod": "^1.10.0",
|
|
216
|
+
"drizzle-orm": "^0.44.0",
|
|
217
|
+
"zod": "^3.23.0",
|
|
218
|
+
"react": "^19.0.0"
|
|
219
|
+
},
|
|
199
220
|
"kuckit": {
|
|
200
221
|
"id": "acme.billing",
|
|
201
222
|
"server": "./dist/module.js",
|
|
202
|
-
"client": "./dist/client
|
|
203
|
-
"schema": "./src/server/schema/index.ts"
|
|
223
|
+
"client": "./dist/client-module.js"
|
|
204
224
|
}
|
|
205
225
|
}
|
|
206
226
|
```
|
|
@@ -6,50 +6,61 @@ Complete guide for developing Kuckit modules.
|
|
|
6
6
|
|
|
7
7
|
### Generated Module Layout
|
|
8
8
|
|
|
9
|
+
Modules follow Clean Architecture internally with all layers self-contained:
|
|
10
|
+
|
|
9
11
|
```
|
|
10
12
|
packages/billing-module/
|
|
11
13
|
├── src/
|
|
12
|
-
│ ├──
|
|
13
|
-
│
|
|
14
|
-
│ ├──
|
|
15
|
-
│ │
|
|
16
|
-
│
|
|
17
|
-
│ └──
|
|
18
|
-
│
|
|
19
|
-
│
|
|
20
|
-
│
|
|
21
|
-
│
|
|
22
|
-
│
|
|
23
|
-
│
|
|
24
|
-
|
|
14
|
+
│ ├── domain/
|
|
15
|
+
│ │ └── billing.entity.ts # Zod schema for entity
|
|
16
|
+
│ ├── ports/
|
|
17
|
+
│ │ └── billing.repository.ts # Repository interface
|
|
18
|
+
│ ├── adapters/
|
|
19
|
+
│ │ └── billing.drizzle.ts # Drizzle implementation
|
|
20
|
+
│ ├── usecases/
|
|
21
|
+
│ │ ├── list-billings.ts
|
|
22
|
+
│ │ ├── get-billing.ts
|
|
23
|
+
│ │ ├── create-billing.ts
|
|
24
|
+
│ │ └── delete-billing.ts
|
|
25
|
+
│ ├── api/
|
|
26
|
+
│ │ └── billings.router.ts # oRPC router
|
|
27
|
+
│ ├── ui/
|
|
28
|
+
│ │ └── BillingsPage.tsx # React component
|
|
29
|
+
│ ├── module.ts # Server module
|
|
30
|
+
│ ├── client-module.ts # Client module
|
|
31
|
+
│ └── index.ts
|
|
32
|
+
├── package.json # Uses @kuckit/* from npm
|
|
25
33
|
└── tsconfig.json
|
|
26
34
|
```
|
|
27
35
|
|
|
28
36
|
### package.json Metadata
|
|
29
37
|
|
|
38
|
+
Modules depend on `@kuckit/*` npm packages:
|
|
39
|
+
|
|
30
40
|
```json
|
|
31
41
|
{
|
|
32
42
|
"name": "@acme/billing-module",
|
|
33
43
|
"version": "1.0.0",
|
|
34
44
|
"type": "module",
|
|
35
|
-
"kuckit": {
|
|
36
|
-
"id": "acme.billing",
|
|
37
|
-
"server": "./dist/module.js",
|
|
38
|
-
"client": "./dist/client/module.js",
|
|
39
|
-
"schema": "./src/server/schema/index.ts"
|
|
40
|
-
},
|
|
41
45
|
"exports": {
|
|
42
|
-
".":
|
|
43
|
-
|
|
44
|
-
"types": "./dist/index.d.ts"
|
|
45
|
-
},
|
|
46
|
-
"./client": {
|
|
47
|
-
"import": "./dist/client/index.js",
|
|
48
|
-
"types": "./dist/client/index.d.ts"
|
|
49
|
-
}
|
|
46
|
+
".": "./src/index.ts",
|
|
47
|
+
"./client": "./src/client-module.ts"
|
|
50
48
|
},
|
|
51
49
|
"peerDependencies": {
|
|
52
|
-
"@kuckit/sdk": "
|
|
50
|
+
"@kuckit/sdk": "^1.0.0",
|
|
51
|
+
"@kuckit/sdk-react": "^1.0.0",
|
|
52
|
+
"typescript": "^5"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@kuckit/api": "^1.0.0",
|
|
56
|
+
"@orpc/server": "^1.10.0",
|
|
57
|
+
"drizzle-orm": "^0.44.0",
|
|
58
|
+
"zod": "^3.23.0"
|
|
59
|
+
},
|
|
60
|
+
"kuckit": {
|
|
61
|
+
"id": "acme.billing",
|
|
62
|
+
"server": "./dist/module.js",
|
|
63
|
+
"client": "./dist/client-module.js"
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
```
|
|
@@ -1,67 +1,82 @@
|
|
|
1
1
|
# Kuckit Package Reference
|
|
2
2
|
|
|
3
|
-
Quick reference for all packages
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
3
|
+
Quick reference for all `@kuckit/*` packages from npm.
|
|
4
|
+
|
|
5
|
+
## Framework Packages
|
|
6
|
+
|
|
7
|
+
These are installed from npm as dependencies, not copied into your project:
|
|
8
|
+
|
|
9
|
+
| Package | Description |
|
|
10
|
+
| ------------------- | ------------------------------------------------------ |
|
|
11
|
+
| `@kuckit/sdk` | Server-side module system, DI container, core services |
|
|
12
|
+
| `@kuckit/sdk-react` | Client-side module system, hooks, providers |
|
|
13
|
+
| `@kuckit/api` | oRPC procedures (publicProcedure, protectedProcedure) |
|
|
14
|
+
| `@kuckit/db` | Drizzle ORM utilities and connection |
|
|
15
|
+
| `@kuckit/auth` | Better-Auth configuration |
|
|
16
|
+
| `@kuckit/domain` | Base types, Logger, Clock interfaces |
|
|
17
|
+
| `@kuckit/contracts` | Shared DTOs and Zod schemas |
|
|
18
|
+
|
|
19
|
+
## Your Project Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
your-app/
|
|
23
|
+
├── apps/
|
|
24
|
+
│ ├── server/ # Express bootstrap (imports @kuckit/* from npm)
|
|
25
|
+
│ └── web/ # React bootstrap (imports @kuckit/* from npm)
|
|
26
|
+
├── packages/
|
|
27
|
+
│ └── your-module/ # Your modules with Clean Architecture
|
|
28
|
+
├── node_modules/
|
|
29
|
+
│ └── @kuckit/ # Framework packages from npm
|
|
30
|
+
├── package.json # Lists @kuckit/* deps
|
|
31
|
+
└── drizzle.config.ts # Points to @kuckit/db + module schemas
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Key Files Per Framework Package
|
|
26
35
|
|
|
27
36
|
### @kuckit/sdk
|
|
28
37
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `src/config/loader.ts` | Configuration loading |
|
|
38
|
-
| `src/schema/registry.ts` | Schema registry |
|
|
39
|
-
|
|
40
|
-
### @kuckit/cli
|
|
41
|
-
|
|
42
|
-
| File | Purpose |
|
|
43
|
-
| --------------------------------- | ------------------------------ |
|
|
44
|
-
| `src/bin.ts` | CLI entry point (Commander.js) |
|
|
45
|
-
| `src/commands/generate-module.ts` | Module scaffolding |
|
|
46
|
-
| `src/commands/add-module.ts` | Module installation |
|
|
47
|
-
| `src/commands/discover-module.ts` | Module discovery |
|
|
48
|
-
| `src/commands/doctor.ts` | Project validation |
|
|
49
|
-
| `src/commands/auth.ts` | Authentication commands |
|
|
50
|
-
| `src/commands/db.ts` | Database commands |
|
|
51
|
-
| `src/commands/infra/*.ts` | Infrastructure commands |
|
|
52
|
-
| `src/lib/credentials.ts` | Token storage |
|
|
53
|
-
| `src/lib/sdk-loader.ts` | Dynamic SDK loading |
|
|
38
|
+
| Export | Purpose |
|
|
39
|
+
| ----------------------- | ------------------------ |
|
|
40
|
+
| `createKuckitContainer` | DI container creation |
|
|
41
|
+
| `loadKuckitModules` | Module loading |
|
|
42
|
+
| `defineKuckitModule` | Server module definition |
|
|
43
|
+
| `disposeContainer` | Container cleanup |
|
|
44
|
+
| `asClass`, `asFunction` | DI registration helpers |
|
|
45
|
+
| `asValue` | DI value registration |
|
|
54
46
|
|
|
55
47
|
### @kuckit/sdk-react
|
|
56
48
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
|
|
49
|
+
| Export | Purpose |
|
|
50
|
+
| -------------------------- | ------------------------ |
|
|
51
|
+
| `defineKuckitClientModule` | Client module definition |
|
|
52
|
+
| `loadKuckitClientModules` | Client module loading |
|
|
53
|
+
| `KuckitNavProvider` | Navigation provider |
|
|
54
|
+
| `useKuckitNav` | Navigation hook |
|
|
55
|
+
| `useRpc` | RPC client hook |
|
|
56
|
+
|
|
57
|
+
### @kuckit/api
|
|
58
|
+
|
|
59
|
+
| Export | Purpose |
|
|
60
|
+
| -------------------- | ----------------------- |
|
|
61
|
+
| `publicProcedure` | Public oRPC procedure |
|
|
62
|
+
| `protectedProcedure` | Auth-required procedure |
|
|
63
|
+
| `createContext` | oRPC context factory |
|
|
64
|
+
| `appRouter` | Base app router |
|
|
65
|
+
|
|
66
|
+
### @kuckit/db
|
|
67
|
+
|
|
68
|
+
| Export | Purpose |
|
|
69
|
+
| ------------ | -------------------------- |
|
|
70
|
+
| `createDb` | Drizzle instance factory |
|
|
71
|
+
| `createPool` | PostgreSQL pool factory |
|
|
72
|
+
| `authSchema` | Better-Auth schema exports |
|
|
73
|
+
|
|
74
|
+
### @kuckit/auth
|
|
75
|
+
|
|
76
|
+
| Export | Purpose |
|
|
77
|
+
| ------------ | --------------------- |
|
|
78
|
+
| `auth` | Better-Auth instance |
|
|
79
|
+
| `authClient` | Client auth utilities |
|
|
65
80
|
|
|
66
81
|
## Import Patterns
|
|
67
82
|
|
|
@@ -83,30 +98,35 @@ import {
|
|
|
83
98
|
loadKuckitClientModules,
|
|
84
99
|
KuckitNavProvider,
|
|
85
100
|
useKuckitNav,
|
|
101
|
+
useRpc,
|
|
86
102
|
} from '@kuckit/sdk-react'
|
|
87
103
|
|
|
88
|
-
//
|
|
89
|
-
import {
|
|
104
|
+
// API imports (for modules)
|
|
105
|
+
import { protectedProcedure, publicProcedure } from '@kuckit/api'
|
|
90
106
|
|
|
91
|
-
//
|
|
92
|
-
import {
|
|
93
|
-
|
|
94
|
-
// Contracts imports
|
|
95
|
-
import { CreateUserInput, UserDTO, createUserSchema } from '@kuckit/contracts'
|
|
107
|
+
// Database imports
|
|
108
|
+
import { createDb, createPool } from '@kuckit/db/connection'
|
|
96
109
|
```
|
|
97
110
|
|
|
98
111
|
## Package Dependencies
|
|
99
112
|
|
|
100
113
|
### What Each Package Can Import
|
|
101
114
|
|
|
102
|
-
| Package
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
|
115
|
+
| Package | Allowed Imports |
|
|
116
|
+
| ------------ | ------------------------------- |
|
|
117
|
+
| Your modules | @kuckit/\* packages, zod |
|
|
118
|
+
| apps/server | @kuckit/\*, your modules |
|
|
119
|
+
| apps/web | @kuckit/sdk-react, your modules |
|
|
120
|
+
|
|
121
|
+
### Module Internal Layers
|
|
122
|
+
|
|
123
|
+
Within your modules, follow Clean Architecture:
|
|
124
|
+
|
|
125
|
+
| Layer | Can Import |
|
|
126
|
+
| -------- | ----------------------------- |
|
|
127
|
+
| domain | (none - pure Zod schemas) |
|
|
128
|
+
| ports | domain |
|
|
129
|
+
| usecases | domain, ports |
|
|
130
|
+
| adapters | domain, drizzle-orm |
|
|
131
|
+
| api | domain, usecases, @kuckit/api |
|
|
132
|
+
| ui | @kuckit/sdk-react, react |
|
package/templates/base/AGENTS.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# AGENTS.md - **APP_NAME**
|
|
2
2
|
|
|
3
|
+
> **Main Documentation**: [Kuckit SDK](https://github.com/draphonix/kuckit)
|
|
4
|
+
|
|
3
5
|
## Quick Start
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
8
|
bun install # Install dependencies
|
|
7
9
|
docker compose up -d # Start PostgreSQL
|
|
8
|
-
bun run db:
|
|
10
|
+
bun run db:push # Sync schema to database (dev) or db:migrate (prod)
|
|
9
11
|
bun run dev # Start dev servers (web + server)
|
|
10
12
|
```
|
|
11
13
|
|
|
@@ -17,15 +19,99 @@ __APP_NAME_KEBAB__/
|
|
|
17
19
|
│ ├── server/ # Express + oRPC backend (port 3000)
|
|
18
20
|
│ └── web/ # React + TanStack Router frontend (port 3001)
|
|
19
21
|
├── packages/
|
|
20
|
-
│ ├── api/ # Shared API context and types
|
|
21
|
-
│ ├── auth/ # Better-Auth configuration
|
|
22
|
-
│ ├── db/ # Drizzle ORM, migrations, schema
|
|
23
22
|
│ └── items-module/ # Example Kuckit module (reference implementation)
|
|
24
23
|
├── .env.example # Environment template
|
|
25
24
|
├── docker-compose.yml # PostgreSQL container
|
|
25
|
+
├── drizzle.config.ts # Drizzle pointing to @kuckit/db + module schemas
|
|
26
26
|
└── turbo.json # Turborepo configuration
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
**Note:** Core packages (`api`, `auth`, `db`, `domain`, `contracts`) are installed from npm as `@kuckit/*` dependencies, not copied into your project.
|
|
30
|
+
|
|
31
|
+
## Bootstrap Architecture
|
|
32
|
+
|
|
33
|
+
Kuckit uses **bootstrap packages** to minimize boilerplate in your apps:
|
|
34
|
+
|
|
35
|
+
### Server Bootstrap (`@kuckit/app-server`)
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// apps/server/src/server.ts
|
|
39
|
+
import 'dotenv/config'
|
|
40
|
+
import { runKuckitServer } from '@kuckit/app-server'
|
|
41
|
+
import { loadConfig } from './config/server'
|
|
42
|
+
import { getModuleSpecs } from './config/modules'
|
|
43
|
+
|
|
44
|
+
runKuckitServer({
|
|
45
|
+
loadConfig,
|
|
46
|
+
getModuleSpecs,
|
|
47
|
+
}).catch((error) => {
|
|
48
|
+
console.error('Failed to start server:', error)
|
|
49
|
+
process.exit(1)
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**What `runKuckitServer` handles automatically:**
|
|
54
|
+
|
|
55
|
+
- Express app creation with CORS, JSON parsing
|
|
56
|
+
- DI container setup with per-request scoping
|
|
57
|
+
- Module loading and API route wiring
|
|
58
|
+
- Auth, health, metrics endpoints
|
|
59
|
+
- Graceful shutdown
|
|
60
|
+
|
|
61
|
+
**Customization via hooks:**
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
runKuckitServer({
|
|
65
|
+
loadConfig,
|
|
66
|
+
getModuleSpecs,
|
|
67
|
+
hooks: {
|
|
68
|
+
onAppCreated: (app) => app.use(helmet()),
|
|
69
|
+
onContainerReady: (container) => {
|
|
70
|
+
/* warm caches */
|
|
71
|
+
},
|
|
72
|
+
onServerReady: (port) => console.log(`Listening on ${port}`),
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Web Bootstrap (`@kuckit/app-web`)
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// apps/web/src/main.tsx
|
|
81
|
+
import { createKuckitWebProvider } from '@kuckit/app-web'
|
|
82
|
+
import { createAuthClient } from 'better-auth/react'
|
|
83
|
+
import config from '../kuckit.config'
|
|
84
|
+
|
|
85
|
+
const authClient = createAuthClient({
|
|
86
|
+
baseURL: import.meta.env.VITE_API_URL,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const KuckitProvider = createKuckitWebProvider({
|
|
90
|
+
config,
|
|
91
|
+
authClient,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
95
|
+
<StrictMode>
|
|
96
|
+
<KuckitProvider>
|
|
97
|
+
<App />
|
|
98
|
+
</KuckitProvider>
|
|
99
|
+
</StrictMode>
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Access registries and auth via hooks:**
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { useKuckitWeb, useAuth } from '@kuckit/app-web'
|
|
107
|
+
|
|
108
|
+
function MyComponent() {
|
|
109
|
+
const { routeRegistry, navRegistry, slotRegistry } = useKuckitWeb()
|
|
110
|
+
const authClient = useAuth()
|
|
111
|
+
const { data: session } = authClient.useSession()
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
29
115
|
## Module Development
|
|
30
116
|
|
|
31
117
|
Kuckit uses a **module-based architecture** where each module contains its own Clean Architecture layers internally.
|
|
@@ -47,15 +133,21 @@ packages/your-module/
|
|
|
47
133
|
|
|
48
134
|
### Creating a New Module
|
|
49
135
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
136
|
+
```bash
|
|
137
|
+
bunx kuckit generate module your-module
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This scaffolds a full Clean Architecture module. Then:
|
|
141
|
+
|
|
142
|
+
1. Implement your domain entities in `domain/`
|
|
143
|
+
2. Define repository interfaces in `ports/`
|
|
144
|
+
3. Implement adapters in `adapters/`
|
|
145
|
+
4. Create use cases in `usecases/`
|
|
146
|
+
5. Expose API in `api/` via oRPC router
|
|
147
|
+
6. Register module in `apps/server/src/config/modules.ts`
|
|
148
|
+
7. Add client module to `apps/web/src/modules.client.ts`
|
|
149
|
+
8. Add schema path to `drizzle.config.ts` in project root
|
|
150
|
+
9. Run `bun run db:push` to create the table
|
|
59
151
|
|
|
60
152
|
### Dependency Rules
|
|
61
153
|
|
|
@@ -256,6 +348,26 @@ export const wireModuleRpcRouters = (registrations: ApiRegistration[]) => {
|
|
|
256
348
|
}
|
|
257
349
|
```
|
|
258
350
|
|
|
351
|
+
### REST Router Pattern
|
|
352
|
+
|
|
353
|
+
For modules that need direct Express response access (e.g., AI streaming with `pipeUIMessageStreamToResponse`), use REST routers instead of oRPC:
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
// In your module's registerApi()
|
|
357
|
+
ctx.addApiRegistration({
|
|
358
|
+
type: 'rest-router',
|
|
359
|
+
name: 'ai',
|
|
360
|
+
router: createAiRouter(),
|
|
361
|
+
prefix: '/ai', // Optional, defaults to /<name>
|
|
362
|
+
})
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
REST routers are mounted at `/api<prefix>` (e.g., `/api/ai/chat`). They receive:
|
|
366
|
+
|
|
367
|
+
- Per-request scoped container via `req.scope`
|
|
368
|
+
- Session via `req.scope.cradle.session`
|
|
369
|
+
- Full Express `Request` and `Response` objects
|
|
370
|
+
|
|
259
371
|
### Typing DI in Routers
|
|
260
372
|
|
|
261
373
|
Use a module-local interface to type `context.di.cradle`:
|
|
@@ -284,14 +396,14 @@ export const invoicesRouter = {
|
|
|
284
396
|
|
|
285
397
|
### Add a new database table
|
|
286
398
|
|
|
287
|
-
1. Define schema in your module's `adapters/`
|
|
399
|
+
1. Define schema in your module's `adapters/` directory
|
|
288
400
|
2. Run `bun run db:generate`
|
|
289
401
|
3. Run `bun run db:migrate`
|
|
290
402
|
|
|
291
403
|
### Add authentication to an endpoint
|
|
292
404
|
|
|
293
405
|
```typescript
|
|
294
|
-
import { protectedProcedure } from '@
|
|
406
|
+
import { protectedProcedure } from '@kuckit/api'
|
|
295
407
|
|
|
296
408
|
export const myRouter = {
|
|
297
409
|
protectedRoute: protectedProcedure.input(mySchema).handler(async ({ input, context }) => {
|
|
@@ -363,12 +475,12 @@ See `.env.example` for required variables:
|
|
|
363
475
|
|
|
364
476
|
**Cause**: Module schema not registered in `drizzle.config.ts`.
|
|
365
477
|
|
|
366
|
-
**Fix**: Add the module's schema path to `
|
|
478
|
+
**Fix**: Add the module's schema path to `drizzle.config.ts` (in project root):
|
|
367
479
|
|
|
368
480
|
```typescript
|
|
369
481
|
schema: [
|
|
370
|
-
|
|
371
|
-
|
|
482
|
+
'./node_modules/@kuckit/db/dist/schema/auth.js',
|
|
483
|
+
'./packages/your-module/src/adapters',
|
|
372
484
|
],
|
|
373
485
|
```
|
|
374
486
|
|