create-kuckit-app 2.0.2 → 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.
Files changed (52) hide show
  1. package/README.md +24 -14
  2. package/package.json +1 -1
  3. package/templates/base/.claude/skills/beads/CLAUDE.md +87 -0
  4. package/templates/base/.claude/skills/beads/README.md +123 -0
  5. package/templates/base/.claude/skills/beads/SKILL.md +77 -715
  6. package/templates/base/.claude/skills/beads/adr/0001-bd-prime-as-source-of-truth.md +61 -0
  7. package/templates/base/.claude/skills/beads/resources/AGENTS.md +62 -0
  8. package/templates/base/.claude/skills/beads/resources/ASYNC_GATES.md +175 -0
  9. package/templates/base/.claude/skills/beads/resources/BOUNDARIES.md +520 -0
  10. package/templates/base/.claude/skills/beads/resources/CHEMISTRY_PATTERNS.md +197 -0
  11. package/templates/base/.claude/skills/beads/resources/CLI_REFERENCE.md +561 -0
  12. package/templates/base/.claude/skills/beads/resources/DEPENDENCIES.md +754 -0
  13. package/templates/base/.claude/skills/beads/resources/INTEGRATION_PATTERNS.md +438 -0
  14. package/templates/base/.claude/skills/beads/resources/ISSUE_CREATION.md +150 -0
  15. package/templates/base/.claude/skills/beads/resources/MOLECULES.md +370 -0
  16. package/templates/base/.claude/skills/beads/resources/PATTERNS.md +363 -0
  17. package/templates/base/.claude/skills/beads/resources/RESUMABILITY.md +239 -0
  18. package/templates/base/.claude/skills/beads/resources/STATIC_DATA.md +61 -0
  19. package/templates/base/.claude/skills/beads/resources/TROUBLESHOOTING.md +537 -0
  20. package/templates/base/.claude/skills/beads/resources/WORKFLOWS.md +638 -0
  21. package/templates/base/.claude/skills/beads/resources/WORKTREES.md +95 -0
  22. package/templates/base/.claude/skills/browser-skill/SKILL.md +72 -0
  23. package/templates/base/.claude/skills/knowledge/SKILL.md +155 -205
  24. package/templates/base/.claude/skills/knowledge/reference/doc-mapping.md +49 -0
  25. package/templates/base/.claude/skills/knowledge/reference/extraction-prompts.md +102 -0
  26. package/templates/base/.claude/skills/kuckit/SKILL.md +15 -9
  27. package/templates/base/.claude/skills/kuckit/references/MODULE-DEVELOPMENT.md +142 -0
  28. package/templates/base/.claude/skills/kuckit/references/PACKAGES.md +22 -17
  29. package/templates/base/.claude/skills/kuckit/references/PUBLISHING.md +92 -0
  30. package/templates/base/.claude/skills/module-testing/SKILL.md +1 -1
  31. package/templates/base/.claude/skills/planning/SKILL.md +26 -1
  32. package/templates/base/.env.example +1 -1
  33. package/templates/base/AGENTS.md +155 -418
  34. package/templates/base/apps/server/src/modules.ts +14 -1
  35. package/templates/base/apps/web/.env.example +1 -1
  36. package/templates/base/apps/web/src/routes/$.tsx +0 -1
  37. package/templates/base/apps/web/src/routes/dashboard.tsx +3 -1
  38. package/templates/base/docs/ARCHITECTURE.md +689 -0
  39. package/templates/base/docs/DEPENDENCY-INJECTION.md +871 -0
  40. package/templates/base/docs/DEPLOYMENT.md +573 -0
  41. package/templates/base/docs/INDEX.md +135 -0
  42. package/templates/base/docs/MIGRATION.md +989 -0
  43. package/templates/base/docs/MODULE_CSS.md +343 -0
  44. package/templates/base/docs/MODULE_TESTING.md +368 -0
  45. package/templates/base/docs/MULTI_AGENT_WORKFLOW.md +909 -0
  46. package/templates/base/docs/TESTING.md +579 -0
  47. package/templates/base/docs/TROUBLESHOOTING.md +360 -0
  48. package/templates/base/package.json +2 -0
  49. package/templates/base/packages/items-module/AGENTS.md +3 -1
  50. package/templates/base/packages/items-module/src/server/adapters/{item.drizzle.ts → item.repository.ts} +1 -13
  51. package/templates/base/packages/items-module/src/server/module.ts +2 -1
  52. package/templates/base/packages/items-module/src/server/schema/item.ts +13 -0
@@ -2,507 +2,244 @@
2
2
 
3
3
  > **Main Documentation**: [Kuckit SDK](https://github.com/draphonix/kuckit)
4
4
 
5
- ## Quick Start
5
+ ## Commands
6
6
 
7
7
  ```bash
8
- bun install # Install dependencies
9
- docker compose up -d # Start PostgreSQL
10
- bun run db:push # Sync schema to database (dev) or db:migrate (prod)
11
- bun run dev # Start dev servers (web + server)
12
- ```
13
-
14
- ## Project Structure
15
-
16
- ```
17
- __APP_NAME_KEBAB__/
18
- ├── apps/
19
- │ ├── server/ # Express + oRPC backend (port 3000)
20
- │ └── web/ # React + TanStack Router frontend (port 3001)
21
- ├── packages/
22
- │ └── items-module/ # Example Kuckit module (reference implementation)
23
- ├── .env.example # Environment template
24
- ├── docker-compose.yml # PostgreSQL container
25
- ├── drizzle.config.ts # Drizzle pointing to @kuckit/db + module schemas
26
- └── turbo.json # Turborepo configuration
27
- ```
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
- ```
8
+ # Development
9
+ bun run dev # Start web + server
10
+ bun run dev:server # Backend only (port 3000)
11
+ bun run dev:web # Frontend only (port 5173)
12
+ bun run check-types # Typecheck all packages
13
+ bun run build # Build all packages
76
14
 
77
- ### Web Bootstrap (`@kuckit/app-web`)
15
+ # Database
16
+ bun run db:push # Sync schema to database
17
+ bun run db:studio # Open Drizzle Studio
78
18
 
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_SERVER_URL,
87
- })
19
+ # Module management
20
+ bunx kuckit generate module <name> # Scaffold new module
21
+ bunx kuckit doctor # Validate setup
88
22
 
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
23
  ```
102
24
 
103
- **Access registries and auth via hooks:**
25
+ ## Architecture
104
26
 
105
- ```typescript
106
- import { useKuckitWeb, useAuth } from '@kuckit/app-web'
27
+ **Clean Architecture** with **Awilix DI** and **modular plugin system**.
107
28
 
108
- function MyComponent() {
109
- const { routeRegistry, navRegistry, slotRegistry } = useKuckitWeb()
110
- const authClient = useAuth()
111
- const { data: session } = authClient.useSession()
112
- }
113
- ```
114
-
115
- ## Module Development
116
-
117
- Kuckit uses a **module-based architecture** where each module contains its own Clean Architecture layers internally.
118
-
119
- ### Module Structure
120
-
121
- ```
122
- packages/your-module/
123
- ├── src/
124
- │ ├── domain/ # Entities with Zod schemas
125
- │ ├── ports/ # Repository interfaces
126
- │ ├── adapters/ # Drizzle implementations
127
- │ ├── usecases/ # Business logic
128
- │ ├── api/ # oRPC routers
129
- │ ├── ui/ # React components (optional)
130
- │ ├── module.ts # Server module definition
131
- │ └── client-module.ts # Client module definition
132
- ```
133
-
134
- ### Creating a New Module
135
-
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
29
+ | Layer | Packages | Purpose |
30
+ | -------------- | --------------------------------------------------------- | ---------------------------------- |
31
+ | Interface | `apps/web`, `apps/server` | React + Express entry points |
32
+ | Bootstrap | `@kuckit/app-server`, `@kuckit/app-web` | DI wiring, module loading |
33
+ | SDK | `@kuckit/sdk`, `@kuckit/sdk-react` | Module system, registries |
34
+ | Application | `packages/application`, `packages/api` | Use cases, oRPC procedures |
35
+ | Domain | `packages/domain`, `packages/contracts` | Entities, ports, DTOs |
36
+ | Infrastructure | `packages/infrastructure`, `packages/db`, `packages/auth` | Repositories, Drizzle, Better-Auth |
151
37
 
152
38
  ### Dependency Rules
153
39
 
154
- ```
155
- domain No dependencies (pure Zod schemas)
156
-
157
- ports Depends on domain only
158
-
159
- usecases Depends on ports and domain
160
-
161
- adapters → Implements ports, depends on domain
162
-
163
- api → Wires everything together
164
- ```
40
+ | Layer | CAN Import | CANNOT Import |
41
+ | ---------------- | ------------------------------ | ----------------------- |
42
+ | `domain` | (nothing) | everything else |
43
+ | `application` | domain | infrastructure, api, db |
44
+ | `infrastructure` | domain | application, api |
45
+ | `contracts` | zod | domain, application |
46
+ | `api` | domain, application, contracts | infrastructure, db |
165
47
 
166
- ## SDK Module System
48
+ ## Module Quick Reference
167
49
 
168
- > **SDK Documentation**: For comprehensive module patterns, see [@kuckit/sdk](https://github.com/draphonix/kuckit)
169
-
170
- ### Module Lifecycle
171
-
172
- Modules are loaded in a specific sequence:
173
-
174
- ```
175
- 1. createKuckitContainer()
176
- └─► Core services registered (logger, db, cache, eventBus)
177
-
178
- 2. loadKuckitModules({ modules: [...] })
179
- ├─► Phase 1: register() - DI bindings for all modules
180
- ├─► Phase 2: registerApi() - API registrations collected
181
- ├─► Phase 3: onApiRegistrations callback (wire routers HERE)
182
- ├─► Phase 4: onBootstrap() - Startup logic
183
- └─► Phase 5: onComplete callback
184
-
185
- 3. Application runs...
186
-
187
- 4. disposeContainer()
188
- └─► For each module: onShutdown()
50
+ ```bash
51
+ bunx kuckit generate module billing --org acme
189
52
  ```
190
53
 
191
- ### Core Services (CoreCradle)
192
-
193
- After container creation, these services are available via DI:
194
-
195
- | Token | Type | Lifetime | Description |
196
- | ------------------ | ------------------ | --------- | --------------------------- |
197
- | `config` | `CoreConfig` | Singleton | Application configuration |
198
- | `db` | Drizzle | Singleton | Database query builder |
199
- | `dbPool` | `Pool` | Singleton | PostgreSQL connection pool |
200
- | `logger` | `Logger` | Singleton | Structured logging |
201
- | `eventBus` | `EventBus` | Singleton | Pub/sub event system |
202
- | `clock` | `Clock` | Singleton | Time abstraction (testable) |
203
- | `cacheStore` | `CacheStore` | Singleton | Key-value cache |
204
- | `rateLimiterStore` | `RateLimiterStore` | Singleton | Rate limiting |
205
- | `auth` | Better-Auth | Singleton | Authentication utilities |
206
- | `requestId` | `string` | Scoped | Per-request unique ID |
207
- | `requestLogger` | `Logger` | Scoped | Logger with request context |
208
-
209
- ### Server Module Definition
54
+ **Server module** (`src/module.ts`):
210
55
 
211
56
  ```typescript
212
- import { defineKuckitModule, asClass, asFunction } from '@kuckit/sdk'
57
+ import { defineKuckitModule, asFunction } from '@kuckit/sdk'
213
58
 
214
59
  export const kuckitModule = defineKuckitModule({
215
- id: 'myapp.billing',
216
- displayName: 'Billing',
217
- version: '1.0.0',
218
- capabilities: ['nav.item', 'api.public'],
219
-
60
+ id: 'myorg.billing',
220
61
  register(ctx) {
221
- // Phase 1: Register DI bindings
222
62
  ctx.container.register({
223
- invoiceRepository: asClass(InvoiceRepository).scoped(),
224
- createInvoice: asFunction(makeCreateInvoiceUseCase).scoped(),
63
+ invoiceRepo: asFunction(({ db }) => makeInvoiceRepo(db)).scoped(),
225
64
  })
226
65
  },
227
-
228
66
  registerApi(ctx) {
229
- // Phase 2: Register API routes
230
- ctx.addApiRegistration({
231
- type: 'rpc-router',
232
- name: 'invoices',
233
- router: invoicesRouter,
234
- })
235
- },
236
-
237
- onBootstrap(ctx) {
238
- // Phase 4: Startup logic (cache warming, logging, etc.)
239
- ctx.container.resolve('logger').info('Billing module started')
240
- },
241
-
242
- onShutdown(ctx) {
243
- // Cleanup on shutdown
244
- ctx.container.resolve('logger').info('Billing module stopped')
67
+ ctx.addApiRegistration({ type: 'rpc-router', name: 'invoices', router: invoicesRouter })
245
68
  },
246
69
  })
247
70
  ```
248
71
 
249
- ### Client Module Definition
72
+ **Client module** (`src/client-module.ts`):
250
73
 
251
74
  ```typescript
252
75
  import { defineKuckitClientModule } from '@kuckit/sdk-react'
253
76
 
254
77
  export const kuckitClientModule = defineKuckitClientModule({
255
- id: 'myapp.billing',
256
- displayName: 'Billing',
257
- capabilities: ['nav.item', 'dashboard.widget'],
258
-
259
- routes: [
260
- {
261
- id: 'billing-invoices',
262
- path: '/billing/invoices',
263
- component: InvoicesPage,
264
- },
265
- ],
266
-
267
- navItems: [
268
- {
269
- id: 'billing-nav',
270
- label: 'Billing',
271
- href: '/billing/invoices',
272
- icon: CreditCard,
273
- order: 50,
274
- },
275
- ],
276
-
277
- slots: {
278
- 'dashboard.widgets': {
279
- component: BillingWidget,
280
- order: 10,
281
- },
282
- },
78
+ id: 'myorg.billing',
79
+ routes: [{ id: 'billing', path: '/billing', component: BillingPage }],
80
+ navItems: [{ id: 'billing-nav', label: 'Billing', href: '/billing', order: 50 }],
283
81
  })
284
82
  ```
285
83
 
286
- ### Module Capabilities
84
+ **Critical**: oRPC routers must be wired before `RPCHandler` is created. See [SDK docs](./packages/sdk/AGENTS.md).
287
85
 
288
- Modules can declare capabilities for discovery:
86
+ ## Coding Standards
289
87
 
290
- - `nav.item` - Provides navigation items
291
- - `settings.page` - Has settings page
292
- - `dashboard.widget` - Provides dashboard widgets
293
- - `api.webhook` - Exposes webhooks
294
- - `api.public` - Has public API endpoints
295
- - `slot.provider` - Provides slot components
88
+ - **TypeScript**: Strict mode, no `any`, explicit return types
89
+ - **Factory pattern**: Use `createX()` functions, not direct imports with side effects
90
+ - **DI lifetimes**: `singleton()` for shared, `scoped()` for per-request
91
+ - **Naming**: entities `invoice.ts`, ports `invoice-repository.ts`, use cases `create-invoice.ts`
296
92
 
297
- ### useRpc with TanStack Query
93
+ ## Issue Tracking (bd)
298
94
 
299
- Module components use the `useRpc` hook to access the API:
300
-
301
- ```typescript
302
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
303
- import { useRpc } from '@kuckit/sdk-react'
304
-
305
- interface ItemsRpc {
306
- items: {
307
- list: (input: Record<string, never>) => Promise<Item[]>
308
- create: (input: { name: string }) => Promise<Item>
309
- }
310
- }
311
-
312
- function ItemsPage() {
313
- const rpc = useRpc<ItemsRpc>()
314
- const queryClient = useQueryClient()
315
-
316
- const { data: items = [], isLoading } = useQuery({
317
- queryKey: ['items'],
318
- queryFn: () => rpc.items.list({}),
319
- })
320
-
321
- const createMutation = useMutation({
322
- mutationFn: (data: { name: string }) => rpc.items.create(data),
323
- onSuccess: () => queryClient.invalidateQueries({ queryKey: ['items'] }),
324
- })
325
-
326
- // ... component render
327
- }
328
- ```
329
-
330
- ### oRPC Router Wiring (Important)
331
-
332
- oRPC's `RPCHandler` captures the router object at construction time. Module routers must be wired **before** the handler is created:
333
-
334
- 1. Modules register routers via `registerApi()` hook
335
- 2. Server wires routers in `onApiRegistrations` into a **mutable router object**
336
- 3. `RPCHandler` is created **after** modules are loaded
337
-
338
- ```typescript
339
- // apps/server/src/rpc-router-registry.ts
340
- export const rootRpcRouter = { ...appRouter }
341
-
342
- export const wireModuleRpcRouters = (registrations: ApiRegistration[]) => {
343
- for (const reg of registrations) {
344
- if (reg.type === 'rpc-router') {
345
- rootRpcRouter[reg.name] = reg.router
346
- }
347
- }
348
- }
95
+ ```bash
96
+ bd ready # Show unblocked work
97
+ bd create "Title" -t feature -p 1 # Create issue
98
+ bd update bd-42 --status in_progress # Claim task
99
+ bd close bd-42 --reason "Done" # Complete
349
100
  ```
350
101
 
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
- ```
102
+ Types: `bug`, `feature`, `task`, `epic`, `chore` | Priorities: `0` (critical) → `4` (backlog)
364
103
 
365
- REST routers are mounted at `/api<prefix>` (e.g., `/api/ai/chat`). They receive:
104
+ ## AI Planning Documents
366
105
 
367
- - Per-request scoped container via `req.scope`
368
- - Session via `req.scope.cradle.session`
369
- - Full Express `Request` and `Response` objects
106
+ Store in `history/` directory, not repo root.
370
107
 
371
- ### Typing DI in Routers
108
+ ## AI Tool Preferences
372
109
 
373
- Use a module-local interface to type `context.di.cradle`:
110
+ **Codebase exploration** (prefer gkg MCP):
374
111
 
375
- ```typescript
376
- // In your module's router file
377
- interface BillingCradle {
378
- createInvoice: (input: CreateInvoiceInput) => Promise<Invoice>
379
- }
380
-
381
- export const invoicesRouter = {
382
- create: protectedProcedure.input(createInvoiceSchema).handler(async ({ input, context }) => {
383
- const { createInvoice } = context.di.cradle as BillingCradle
384
- return createInvoice(input)
385
- }),
386
- }
387
- ```
112
+ - `mcp__gkg__search_codebase_definitions` - Find functions, classes, interfaces by name
113
+ - `mcp__gkg__get_definition` - Jump to definition from a line of code
114
+ - `mcp__gkg__get_references` - Find all usages of a symbol
115
+ - `mcp__gkg__read_definitions` - Read multiple definition bodies efficiently
116
+ - `mcp__gkg__repo_map` - Get API-style map of directories
388
117
 
389
- ## Common Tasks
118
+ **Web/code search & documentation** (prefer Docker Toolkit MCP over built-in):
390
119
 
391
- ### Add a new API endpoint
120
+ - `mcp__MCP_DOCKER__web_search_exa` - Real-time web search with content scraping
121
+ - `mcp__MCP_DOCKER__resolve-library-id` - Resolve library name to Context7 ID (call first)
122
+ - `mcp__MCP_DOCKER__get-library-docs` - Fetch up-to-date library documentation from Context7
392
123
 
393
- 1. Define input/output schemas in `domain/`
394
- 2. Create use case in `usecases/`
395
- 3. Add to router in `api/`
124
+ **File editing** (prefer morph MCP):
396
125
 
397
- ### Add a new database table
126
+ - `mcp__morph_mcp__edit_file` - Fast, accurate edits using `// ... existing code ...` placeholders
127
+ - `mcp__morph_mcp__warpgrep_codebase_search` - **Prefer over built-in Grep** for semantic-aware, faster searches with better context
398
128
 
399
- 1. Define schema in your module's `adapters/` directory
400
- 2. Run `bun run db:generate`
401
- 3. Run `bun run db:migrate`
129
+ **Frontend UI** (use `frontend-design` skill + shadcn MCP - do NOT create custom UI components):
402
130
 
403
- ### Add authentication to an endpoint
131
+ - Load the `frontend-design` skill for distinctive, production-grade interfaces
132
+ - `mcp__shadcn__search_items_in_registries` - Find components by name
133
+ - `mcp__shadcn__view_items_in_registries` - View component details and files
134
+ - `mcp__shadcn__get_item_examples_from_registries` - Get usage examples/demos
135
+ - `mcp__shadcn__get_add_command_for_items` - Get CLI command to add components
404
136
 
405
- ```typescript
406
- import { protectedProcedure } from '@kuckit/api'
407
-
408
- export const myRouter = {
409
- protectedRoute: protectedProcedure.input(mySchema).handler(async ({ input, context }) => {
410
- const { user } = context // Authenticated user
411
- // ...
412
- }),
413
- }
414
- ```
137
+ <!-- MCP_AGENT_MAIL_AND_BEADS_SNIPPET_START -->
415
138
 
416
- ## Scripts
139
+ ## MCP Agent Mail: coordination for multi-agent workflows
417
140
 
418
- | Command | Description |
419
- | ---------------------- | -------------------------------------- |
420
- | `bun run dev` | Start all dev servers |
421
- | `bun run build` | Build all packages |
422
- | `bun run check-types` | Type check all packages |
423
- | `bun run lint` | Run ESLint on all packages |
424
- | `bun run lint:fix` | Fix ESLint issues automatically |
425
- | `bun run format` | Format code with Prettier |
426
- | `bun run format:check` | Check formatting without changes |
427
- | `bun run db:generate` | Generate migration from schema changes |
428
- | `bun run db:migrate` | Apply pending migrations |
429
- | `bun run db:studio` | Open Drizzle Studio |
141
+ What it is
430
142
 
431
- ## Code Quality
143
+ - A mail-like layer that lets coding agents coordinate asynchronously via MCP tools and resources.
144
+ - Provides identities, inbox/outbox, searchable threads, and advisory file reservations, with human-auditable artifacts in Git.
432
145
 
433
- This project includes pre-configured code quality tools:
146
+ Why it's useful
434
147
 
435
- - **ESLint** - TypeScript linting with recommended rules
436
- - **Prettier** - Code formatting
437
- - **Husky** - Git hooks for pre-commit checks
438
- - **lint-staged** - Run linters on staged files only
148
+ - Prevents agents from stepping on each other with explicit file reservations (leases) for files/globs.
149
+ - Keeps communication out of your token budget by storing messages in a per-project archive.
150
+ - Offers quick reads (`resource://inbox/...`, `resource://thread/...`) and macros that bundle common flows.
439
151
 
440
- Pre-commit hooks automatically run `lint-staged` which:
152
+ How to use effectively
441
153
 
442
- 1. Runs ESLint on staged `.ts/.tsx/.js/.jsx` files
443
- 2. Runs Prettier on all staged files
154
+ 1. Same repository
155
+ - Register an identity: call `ensure_project`, then `register_agent` using this repo's absolute path as `project_key`.
156
+ - Reserve files before you edit: `file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true)` to signal intent and avoid conflict.
157
+ - Communicate with threads: use `send_message(..., thread_id="FEAT-123")`; check inbox with `fetch_inbox` and acknowledge with `acknowledge_message`.
158
+ - Read fast: `resource://inbox/{Agent}?project=<abs-path>&limit=20` or `resource://thread/{id}?project=<abs-path>&include_bodies=true`.
159
+ - Tip: set `AGENT_NAME` in your environment so the pre-commit guard can block commits that conflict with others' active exclusive file reservations.
444
160
 
445
- To bypass hooks (not recommended): `git commit --no-verify`
161
+ 2. Across different repos in one project (e.g., Next.js frontend + FastAPI backend)
162
+ - 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/**`).
163
+ - 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.
446
164
 
447
- ## Environment Variables
165
+ Macros vs granular tools
448
166
 
449
- See `.env.example` for required variables:
167
+ - 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`.
168
+ - Use granular tools when you need control: `register_agent`, `file_reservation_paths`, `send_message`, `fetch_inbox`, `acknowledge_message`.
450
169
 
451
- - `DATABASE_URL` - PostgreSQL connection string
452
- - `BETTER_AUTH_SECRET` - Auth session secret
453
- - `BETTER_AUTH_URL` - Auth callback URL
454
- - `PORT` - Server port (default: 3000)
455
- - `VITE_SERVER_URL` - API URL for frontend
170
+ Common pitfalls
456
171
 
457
- ## Troubleshooting
172
+ - "from_agent not registered": always `register_agent` in the correct `project_key` first.
173
+ - "FILE_RESERVATION_CONFLICT": adjust patterns, wait for expiry, or use a non-exclusive reservation when appropriate.
174
+ - 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.
458
175
 
459
- ### 404 Errors on API Calls
176
+ ## Integrating with Beads (dependency-aware task planning)
460
177
 
461
- **Symptom**: `POST /rpc/items/list 404 (Not Found)` with multiple retries
178
+ 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)
462
179
 
463
- **Cause**: Server and client modules are out of sync. The client has a module registered but the server doesn't.
180
+ Recommended conventions
464
181
 
465
- **Fix**: Ensure both files register the same modules:
182
+ - **Single source of truth**: Use **Beads** for task status/priority/dependencies; use **Agent Mail** for conversation, decisions, and attachments (audit).
183
+ - **Shared identifiers**: Use the Beads issue id (e.g., `bd-123`) as the Mail `thread_id` and prefix message subjects with `[bd-123]`.
184
+ - **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.
466
185
 
467
- - `apps/server/src/config/modules.ts` - Server modules
468
- - `apps/web/src/modules.client.ts` - Client modules
186
+ Typical flow (agents)
469
187
 
470
- **Prevention**: Run `bunx kuckit doctor` to detect mismatches.
188
+ 1. **Pick ready work** (Beads)
189
+ - `bd ready --json` → choose one item (highest priority, no blockers)
190
+ 2. **Reserve edit surface** (Mail)
191
+ - `file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true, reason="bd-123")`
192
+ 3. **Announce start** (Mail)
193
+ - `send_message(..., thread_id="bd-123", subject="[bd-123] Start: <short title>", ack_required=true)`
194
+ 4. **Work and update**
195
+ - Reply in-thread with progress and attach artifacts/images; keep the discussion in one thread per issue id
196
+ 5. **Complete and release**
197
+ - `bd close bd-123 --reason "Completed"` (Beads is status authority)
198
+ - `release_file_reservations(project_key, agent_name, paths=["src/**"])`
199
+ - Final Mail reply: `[bd-123] Completed` with summary and links
471
200
 
472
- ### "Relation does not exist" Database Errors
201
+ Mapping cheat-sheet
473
202
 
474
- **Symptom**: `error: relation "items" does not exist`
203
+ - **Mail `thread_id`** `bd-###`
204
+ - **Mail subject**: `[bd-###] …`
205
+ - **File reservation `reason`**: `bd-###`
206
+ - **Commit messages (optional)**: include `bd-###` for traceability
475
207
 
476
- **Cause**: Module schema not registered in `drizzle.config.ts`.
208
+ Event mirroring (optional automation)
477
209
 
478
- **Fix**: Add the module's schema path to `drizzle.config.ts` (in project root):
210
+ - On `bd update --status blocked`, send a high-importance Mail message in thread `bd-###` describing the blocker.
211
+ - 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`.
479
212
 
480
- ```typescript
481
- schema: [
482
- './node_modules/@kuckit/db/dist/schema/auth.js',
483
- './packages/your-module/src/adapters',
484
- ],
485
- ```
213
+ Pitfalls to avoid
486
214
 
487
- Then run:
215
+ - Don't create or manage tasks in Mail; treat Beads as the single task queue.
216
+ - Always include `bd-###` in message `thread_id` to avoid ID drift across tools.
488
217
 
489
- ```bash
490
- bun run db:generate
491
- bun run db:migrate
492
- ```
218
+ <!-- MCP_AGENT_MAIL_AND_BEADS_SNIPPET_END -->
493
219
 
494
- ### Module Not Appearing in Navigation
220
+ ## Landing the Plane (Session Completion)
495
221
 
496
- **Symptom**: Module pages work but nav items don't show.
222
+ **When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
497
223
 
498
- **Cause**: Client module not registered or missing `navItems`.
224
+ **MANDATORY WORKFLOW:**
499
225
 
500
- **Fix**: Verify module is in `apps/web/src/modules.client.ts` and defines `navItems` in `defineKuckitClientModule()`.
226
+ 1. **File issues for remaining work** - Create issues for anything that needs follow-up
227
+ 2. **Run quality gates** (if code changed) - Tests, linters, builds
228
+ 3. **Update issue status** - Close finished work, update in-progress items
229
+ 4. **PUSH TO REMOTE** - This is MANDATORY:
230
+ ```bash
231
+ git pull --rebase
232
+ bd sync
233
+ git push
234
+ git status # MUST show "up to date with origin"
235
+ ```
236
+ 5. **Clean up** - Clear stashes, prune remote branches
237
+ 6. **Verify** - All changes committed AND pushed
238
+ 7. **Hand off** - Provide context for next session
501
239
 
502
- ## Related Documentation
240
+ **CRITICAL RULES:**
503
241
 
504
- - [Kuckit SDK](https://github.com/draphonix/kuckit)
505
- - [oRPC](https://orpc.dev)
506
- - [Better-Auth](https://better-auth.com)
507
- - [Drizzle ORM](https://orm.drizzle.team)
508
- - [TanStack Router](https://tanstack.com/router)
242
+ - Work is NOT complete until `git push` succeeds
243
+ - NEVER stop before pushing - that leaves work stranded locally
244
+ - NEVER say "ready to push when you are" - YOU must push
245
+ - If push fails, resolve and retry until it succeeds