create-kuckit-app 0.1.0 → 0.2.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 (92) hide show
  1. package/dist/bin.js +11 -5
  2. package/dist/{create-project-DTm05G7D.js → create-project-CP-h4Ygi.js} +7 -5
  3. package/dist/index.js +1 -1
  4. package/package.json +3 -2
  5. package/templates/base/.claude/CLAUDE.md +44 -0
  6. package/templates/base/.claude/agents/daidalos.md +76 -0
  7. package/templates/base/.claude/agents/episteme.md +79 -0
  8. package/templates/base/.claude/agents/librarian.md +132 -0
  9. package/templates/base/.claude/agents/oracle.md +210 -0
  10. package/templates/base/.claude/commands/create-plan.md +159 -0
  11. package/templates/base/.claude/commands/file-beads.md +98 -0
  12. package/templates/base/.claude/commands/review-beads.md +161 -0
  13. package/templates/base/.claude/settings.json +11 -0
  14. package/templates/base/.claude/skills/kuckit/SKILL.md +436 -0
  15. package/templates/base/.claude/skills/kuckit/references/ARCHITECTURE.md +388 -0
  16. package/templates/base/.claude/skills/kuckit/references/CLI-COMMANDS.md +365 -0
  17. package/templates/base/.claude/skills/kuckit/references/MODULE-DEVELOPMENT.md +581 -0
  18. package/templates/base/.claude/skills/kuckit/references/PACKAGES.md +112 -0
  19. package/templates/base/.claude/skills/kuckit/references/PUBLISHING.md +231 -0
  20. package/templates/base/.env.example +13 -0
  21. package/templates/base/.github/workflows/ci.yml +28 -0
  22. package/templates/base/.husky/pre-commit +1 -0
  23. package/templates/base/.prettierignore +5 -0
  24. package/templates/base/.prettierrc +8 -0
  25. package/templates/base/AGENTS.md +148 -0
  26. package/templates/base/apps/server/.env.example +18 -0
  27. package/templates/base/apps/server/AGENTS.md +37 -0
  28. package/templates/base/apps/server/package.json +13 -4
  29. package/templates/base/apps/server/src/app.ts +20 -0
  30. package/templates/base/apps/server/src/auth.ts +10 -0
  31. package/templates/base/apps/server/src/config/modules.ts +14 -6
  32. package/templates/base/apps/server/src/container.ts +81 -0
  33. package/templates/base/apps/server/src/health.ts +27 -0
  34. package/templates/base/apps/server/src/middleware/container.ts +41 -0
  35. package/templates/base/apps/server/src/rpc-router-registry.ts +26 -0
  36. package/templates/base/apps/server/src/rpc.ts +31 -0
  37. package/templates/base/apps/server/src/server.ts +39 -29
  38. package/templates/base/apps/web/.env.example +4 -0
  39. package/templates/base/apps/web/AGENTS.md +53 -0
  40. package/templates/base/apps/web/index.html +1 -1
  41. package/templates/base/apps/web/package.json +15 -3
  42. package/templates/base/apps/web/src/lib/kuckit-router.ts +42 -0
  43. package/templates/base/apps/web/src/main.tsx +26 -14
  44. package/templates/base/apps/web/src/providers/KuckitProvider.tsx +147 -0
  45. package/templates/base/apps/web/src/providers/ServicesProvider.tsx +47 -0
  46. package/templates/base/apps/web/src/routeTree.gen.ts +91 -0
  47. package/templates/base/apps/web/src/routes/__root.tsx +31 -0
  48. package/templates/base/apps/web/src/routes/index.tsx +46 -0
  49. package/templates/base/apps/web/src/routes/login.tsx +108 -0
  50. package/templates/base/apps/web/src/services/auth-client.ts +12 -0
  51. package/templates/base/apps/web/src/services/index.ts +3 -0
  52. package/templates/base/apps/web/src/services/rpc.ts +29 -0
  53. package/templates/base/apps/web/src/services/types.ts +14 -0
  54. package/templates/base/apps/web/vite.config.ts +2 -1
  55. package/templates/base/docker-compose.yml +23 -0
  56. package/templates/base/eslint.config.js +18 -0
  57. package/templates/base/package.json +32 -2
  58. package/templates/base/packages/api/AGENTS.md +27 -0
  59. package/templates/base/packages/api/package.json +35 -0
  60. package/templates/base/packages/api/src/context.ts +48 -0
  61. package/templates/base/packages/api/src/index.ts +22 -0
  62. package/templates/base/packages/api/tsconfig.json +8 -0
  63. package/templates/base/packages/auth/AGENTS.md +45 -0
  64. package/templates/base/packages/auth/package.json +27 -0
  65. package/templates/base/packages/auth/src/index.ts +22 -0
  66. package/templates/base/packages/auth/tsconfig.json +8 -0
  67. package/templates/base/packages/db/AGENTS.md +59 -0
  68. package/templates/base/packages/db/drizzle.config.ts +19 -0
  69. package/templates/base/packages/db/package.json +36 -0
  70. package/templates/base/packages/db/src/connection.ts +40 -0
  71. package/templates/base/packages/db/src/index.ts +4 -0
  72. package/templates/base/packages/db/src/migrations/0000_init.sql +54 -0
  73. package/templates/base/packages/db/src/migrations/meta/_journal.json +13 -0
  74. package/templates/base/packages/db/src/schema/auth.ts +51 -0
  75. package/templates/base/packages/db/tsconfig.json +8 -0
  76. package/templates/base/packages/items-module/AGENTS.md +112 -0
  77. package/templates/base/packages/items-module/package.json +32 -0
  78. package/templates/base/packages/items-module/src/adapters/item.drizzle.ts +66 -0
  79. package/templates/base/packages/items-module/src/api/items.router.ts +47 -0
  80. package/templates/base/packages/items-module/src/client-module.ts +39 -0
  81. package/templates/base/packages/items-module/src/domain/item.entity.ts +36 -0
  82. package/templates/base/packages/items-module/src/index.ts +15 -0
  83. package/templates/base/packages/items-module/src/module.ts +53 -0
  84. package/templates/base/packages/items-module/src/ports/item.repository.ts +13 -0
  85. package/templates/base/packages/items-module/src/ui/ItemsPage.tsx +162 -0
  86. package/templates/base/packages/items-module/src/usecases/create-item.ts +25 -0
  87. package/templates/base/packages/items-module/src/usecases/delete-item.ts +18 -0
  88. package/templates/base/packages/items-module/src/usecases/get-item.ts +19 -0
  89. package/templates/base/packages/items-module/src/usecases/list-items.ts +21 -0
  90. package/templates/base/packages/items-module/tsconfig.json +9 -0
  91. package/templates/base/turbo.json +13 -1
  92. package/templates/base/apps/web/src/App.tsx +0 -16
@@ -0,0 +1,162 @@
1
+ import { useState, useEffect } from 'react'
2
+
3
+ interface Item {
4
+ id: string
5
+ name: string
6
+ description?: string
7
+ createdAt: Date
8
+ updatedAt: Date
9
+ }
10
+
11
+ /**
12
+ * Items page component
13
+ * Demonstrates CRUD operations using the items module
14
+ */
15
+ export function ItemsPage() {
16
+ const [items, setItems] = useState<Item[]>([])
17
+ const [newItemName, setNewItemName] = useState('')
18
+ const [newItemDescription, setNewItemDescription] = useState('')
19
+ const [loading, setLoading] = useState(true)
20
+ const [error, setError] = useState<string | null>(null)
21
+
22
+ const apiUrl = import.meta.env.VITE_API_URL || 'http://localhost:3000'
23
+
24
+ // Fetch items on mount
25
+ useEffect(() => {
26
+ fetchItems()
27
+ }, [])
28
+
29
+ const fetchItems = async () => {
30
+ try {
31
+ setLoading(true)
32
+ const response = await fetch(`${apiUrl}/rpc/items.list`, {
33
+ method: 'POST',
34
+ headers: { 'Content-Type': 'application/json' },
35
+ credentials: 'include',
36
+ body: JSON.stringify({}),
37
+ })
38
+ if (response.ok) {
39
+ const data = await response.json()
40
+ setItems(data)
41
+ }
42
+ } catch {
43
+ setError('Failed to load items')
44
+ } finally {
45
+ setLoading(false)
46
+ }
47
+ }
48
+
49
+ const createItem = async (e: React.FormEvent) => {
50
+ e.preventDefault()
51
+ if (!newItemName.trim()) return
52
+
53
+ try {
54
+ const response = await fetch(`${apiUrl}/rpc/items.create`, {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/json' },
57
+ credentials: 'include',
58
+ body: JSON.stringify({
59
+ name: newItemName,
60
+ description: newItemDescription || undefined,
61
+ }),
62
+ })
63
+ if (response.ok) {
64
+ setNewItemName('')
65
+ setNewItemDescription('')
66
+ fetchItems()
67
+ }
68
+ } catch {
69
+ setError('Failed to create item')
70
+ }
71
+ }
72
+
73
+ const deleteItem = async (id: string) => {
74
+ try {
75
+ const response = await fetch(`${apiUrl}/rpc/items.delete`, {
76
+ method: 'POST',
77
+ headers: { 'Content-Type': 'application/json' },
78
+ credentials: 'include',
79
+ body: JSON.stringify({ id }),
80
+ })
81
+ if (response.ok) {
82
+ fetchItems()
83
+ }
84
+ } catch {
85
+ setError('Failed to delete item')
86
+ }
87
+ }
88
+
89
+ if (loading) {
90
+ return <div style={{ padding: '2rem' }}>Loading items...</div>
91
+ }
92
+
93
+ return (
94
+ <div style={{ padding: '2rem', fontFamily: 'system-ui', maxWidth: '600px', margin: '0 auto' }}>
95
+ <h1>Items</h1>
96
+
97
+ {error && (
98
+ <div style={{ color: 'red', marginBottom: '1rem' }}>
99
+ {error}
100
+ <button onClick={() => setError(null)} style={{ marginLeft: '1rem' }}>
101
+ Dismiss
102
+ </button>
103
+ </div>
104
+ )}
105
+
106
+ <form onSubmit={createItem} style={{ marginBottom: '2rem' }}>
107
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
108
+ <input
109
+ type="text"
110
+ placeholder="Item name"
111
+ value={newItemName}
112
+ onChange={(e) => setNewItemName(e.target.value)}
113
+ required
114
+ style={{ padding: '0.5rem', fontSize: '1rem' }}
115
+ />
116
+ <input
117
+ type="text"
118
+ placeholder="Description (optional)"
119
+ value={newItemDescription}
120
+ onChange={(e) => setNewItemDescription(e.target.value)}
121
+ style={{ padding: '0.5rem', fontSize: '1rem' }}
122
+ />
123
+ <button type="submit" style={{ padding: '0.5rem 1rem', cursor: 'pointer' }}>
124
+ Add Item
125
+ </button>
126
+ </div>
127
+ </form>
128
+
129
+ <ul style={{ listStyle: 'none', padding: 0 }}>
130
+ {items.map((item) => (
131
+ <li
132
+ key={item.id}
133
+ style={{
134
+ padding: '1rem',
135
+ border: '1px solid #ccc',
136
+ marginBottom: '0.5rem',
137
+ borderRadius: '4px',
138
+ display: 'flex',
139
+ justifyContent: 'space-between',
140
+ alignItems: 'center',
141
+ }}
142
+ >
143
+ <div>
144
+ <strong>{item.name}</strong>
145
+ {item.description && (
146
+ <p style={{ margin: '0.5rem 0 0 0', color: '#666' }}>{item.description}</p>
147
+ )}
148
+ </div>
149
+ <button
150
+ onClick={() => deleteItem(item.id)}
151
+ style={{ cursor: 'pointer', color: 'red', background: 'none', border: 'none' }}
152
+ >
153
+ Delete
154
+ </button>
155
+ </li>
156
+ ))}
157
+ </ul>
158
+
159
+ {items.length === 0 && <p>No items yet. Create one above!</p>}
160
+ </div>
161
+ )
162
+ }
@@ -0,0 +1,25 @@
1
+ import type { ItemRepository } from '../ports/item.repository'
2
+ import type { Item, CreateItemInput } from '../domain/item.entity'
3
+
4
+ export interface CreateItemUseCaseInput extends CreateItemInput {
5
+ userId: string
6
+ }
7
+
8
+ interface CreateItemDeps {
9
+ itemRepository: ItemRepository
10
+ }
11
+
12
+ /**
13
+ * Create item use case
14
+ */
15
+ export function makeCreateItem(deps: CreateItemDeps) {
16
+ return async (input: CreateItemUseCaseInput): Promise<Item> => {
17
+ const id = crypto.randomUUID()
18
+ return deps.itemRepository.create({
19
+ id,
20
+ name: input.name,
21
+ description: input.description,
22
+ userId: input.userId,
23
+ })
24
+ }
25
+ }
@@ -0,0 +1,18 @@
1
+ import type { ItemRepository } from '../ports/item.repository'
2
+
3
+ export interface DeleteItemInput {
4
+ id: string
5
+ }
6
+
7
+ interface DeleteItemDeps {
8
+ itemRepository: ItemRepository
9
+ }
10
+
11
+ /**
12
+ * Delete item use case
13
+ */
14
+ export function makeDeleteItem(deps: DeleteItemDeps) {
15
+ return async (input: DeleteItemInput): Promise<boolean> => {
16
+ return deps.itemRepository.delete(input.id)
17
+ }
18
+ }
@@ -0,0 +1,19 @@
1
+ import type { ItemRepository } from '../ports/item.repository'
2
+ import type { Item } from '../domain/item.entity'
3
+
4
+ export interface GetItemInput {
5
+ id: string
6
+ }
7
+
8
+ interface GetItemDeps {
9
+ itemRepository: ItemRepository
10
+ }
11
+
12
+ /**
13
+ * Get item use case
14
+ */
15
+ export function makeGetItem(deps: GetItemDeps) {
16
+ return async (input: GetItemInput): Promise<Item | null> => {
17
+ return deps.itemRepository.findById(input.id)
18
+ }
19
+ }
@@ -0,0 +1,21 @@
1
+ import type { ItemRepository } from '../ports/item.repository'
2
+ import type { Item } from '../domain/item.entity'
3
+
4
+ export interface ListItemsInput {
5
+ userId: string
6
+ }
7
+
8
+ export type ListItemsOutput = Item[]
9
+
10
+ interface ListItemsDeps {
11
+ itemRepository: ItemRepository
12
+ }
13
+
14
+ /**
15
+ * List items use case
16
+ */
17
+ export function makeListItems(deps: ListItemsDeps) {
18
+ return async (input: ListItemsInput): Promise<ListItemsOutput> => {
19
+ return deps.itemRepository.findByUserId(input.userId)
20
+ }
21
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src",
6
+ "jsx": "react-jsx"
7
+ },
8
+ "include": ["src/**/*"]
9
+ }
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "$schema": "https://turbo.build/schema.json",
3
+ "ui": "tui",
3
4
  "tasks": {
4
5
  "build": {
5
6
  "dependsOn": ["^build"],
7
+ "inputs": ["$TURBO_DEFAULT$", ".env*"],
6
8
  "outputs": ["dist/**"]
7
9
  },
8
10
  "dev": {
@@ -10,7 +12,17 @@
10
12
  "persistent": true
11
13
  },
12
14
  "check-types": {
13
- "dependsOn": ["^build"]
15
+ "dependsOn": ["^check-types"]
16
+ },
17
+ "db:generate": {
18
+ "cache": false
19
+ },
20
+ "db:migrate": {
21
+ "cache": false
22
+ },
23
+ "db:studio": {
24
+ "cache": false,
25
+ "persistent": true
14
26
  }
15
27
  }
16
28
  }
@@ -1,16 +0,0 @@
1
- export function App() {
2
- return (
3
- <div style={{ fontFamily: 'system-ui', padding: '2rem' }}>
4
- <h1>Welcome to __APP_NAME__</h1>
5
- <p>Your Kuckit application is ready!</p>
6
- <ul>
7
- <li>
8
- Server: <a href="http://localhost:3000/health">http://localhost:3000/health</a>
9
- </li>
10
- <li>
11
- Web: <a href="http://localhost:3001">http://localhost:3001</a>
12
- </li>
13
- </ul>
14
- </div>
15
- )
16
- }