create-kuckit-app 0.4.1 → 1.0.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.
- package/package.json +1 -1
- package/templates/base/.claude/{commands/file-beads.md → skills/file-beads/SKILL.md} +3 -3
- package/templates/base/.claude/{commands/review-beads.md → skills/review-beads/SKILL.md} +3 -3
- package/templates/base/apps/server/package.json +1 -1
- package/templates/base/apps/web/AGENTS.md +6 -7
- package/templates/base/apps/web/src/routes/$.tsx +1 -1
- package/templates/base/apps/web/src/routes/dashboard/$.tsx +1 -1
- package/templates/base/docker-compose.yml +1 -1
- package/templates/base/package.json +3 -0
- package/templates/base/apps/web/src/components/KuckitModuleRoute.tsx +0 -141
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
name: file-beads
|
|
3
|
+
description: File detailed Beads epics and issues from a plan. Use when converting plans, roadmaps, or feature specs into structured Beads issues with proper dependencies.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# File Beads Epics and Issues from Plan
|
|
@@ -9,7 +9,7 @@ You are tasked with converting a plan into a comprehensive set of Beads epics an
|
|
|
9
9
|
|
|
10
10
|
## Step 1: Understand the Plan
|
|
11
11
|
|
|
12
|
-
First, review the plan context provided
|
|
12
|
+
First, review the plan context provided by the user.
|
|
13
13
|
|
|
14
14
|
If no specific plan is provided, ask the user to share the plan or point to a planning document (check `history/` directory for recent plans).
|
|
15
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
name: review-beads
|
|
3
|
+
description: Review, proofread, and refine filed Beads epics and issues. Use when you need to polish issues for clarity, fix dependencies, or ensure workers have a smooth implementation experience.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Review and Refine Beads Issues
|
|
@@ -16,7 +16,7 @@ bd list --json
|
|
|
16
16
|
bd ready --json
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
If specific IDs were provided
|
|
19
|
+
If specific IDs were provided, focus on those. Otherwise, review all issues.
|
|
20
20
|
|
|
21
21
|
## Step 2: Systematic Review Checklist
|
|
22
22
|
|
|
@@ -8,13 +8,12 @@ React frontend using TanStack Router, TanStack Query, and Kuckit client modules.
|
|
|
8
8
|
|
|
9
9
|
## Key Files
|
|
10
10
|
|
|
11
|
-
| File
|
|
12
|
-
|
|
|
13
|
-
| `main.tsx`
|
|
14
|
-
| `modules.client.ts`
|
|
15
|
-
| `routes/`
|
|
16
|
-
| `routes/$.tsx`
|
|
17
|
-
| `components/KuckitModuleRoute.tsx` | Renders module-registered routes |
|
|
11
|
+
| File | Purpose |
|
|
12
|
+
| ------------------- | -------------------------------------------------- |
|
|
13
|
+
| `main.tsx` | App entry point (17 lines) |
|
|
14
|
+
| `modules.client.ts` | Client module registration |
|
|
15
|
+
| `routes/` | TanStack Router file-based routes |
|
|
16
|
+
| `routes/$.tsx` | Catch-all for module routes (uses @kuckit/app-web) |
|
|
18
17
|
|
|
19
18
|
## How It Works
|
|
20
19
|
|
|
@@ -34,8 +34,11 @@
|
|
|
34
34
|
"@kuckit/api": "^2.0.0",
|
|
35
35
|
"@kuckit/auth": "^2.0.0",
|
|
36
36
|
"@kuckit/db": "^2.0.0",
|
|
37
|
+
"@kuckit/domain": "^2.0.0",
|
|
38
|
+
"@kuckit/infrastructure": "^2.0.0",
|
|
37
39
|
"awilix": "^12.0.5",
|
|
38
40
|
"dotenv": "^17.0.0",
|
|
41
|
+
"drizzle-orm": "^0.44.0",
|
|
39
42
|
"zod": "^3.23.0"
|
|
40
43
|
},
|
|
41
44
|
"devDependencies": {
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { useRouterState, Link, useNavigate } from '@tanstack/react-router'
|
|
2
|
-
import { useKuckitWeb, useAuth } from '@kuckit/app-web'
|
|
3
|
-
import { useEffect, useState } from 'react'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Helper to determine if a route path is a root-level route (outside dashboard).
|
|
7
|
-
* Root routes start with '/' but NOT '/dashboard'.
|
|
8
|
-
*/
|
|
9
|
-
function isRootLevelRoute(path: string): boolean {
|
|
10
|
-
return path.startsWith('/') && !path.startsWith('/dashboard')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Dynamic route renderer for Kuckit module routes.
|
|
15
|
-
*
|
|
16
|
-
* This component looks up the current path in the RouteRegistry
|
|
17
|
-
* and renders the corresponding module component if found.
|
|
18
|
-
*
|
|
19
|
-
* Route resolution is context-aware:
|
|
20
|
-
* - When rendered under /dashboard/*: matches dashboard routes
|
|
21
|
-
* - When rendered at root level: matches root-level routes (paths starting with '/' but not '/dashboard/')
|
|
22
|
-
*
|
|
23
|
-
* For root routes with meta.requiresAuth: true, redirects to /login if not authenticated.
|
|
24
|
-
*/
|
|
25
|
-
export function KuckitModuleRoute() {
|
|
26
|
-
const { routeRegistry } = useKuckitWeb()
|
|
27
|
-
const authClient = useAuth()
|
|
28
|
-
const { location } = useRouterState()
|
|
29
|
-
const navigate = useNavigate()
|
|
30
|
-
const pathname = location.pathname
|
|
31
|
-
|
|
32
|
-
const [authChecked, setAuthChecked] = useState(false)
|
|
33
|
-
const [isAuthenticated, setIsAuthenticated] = useState(false)
|
|
34
|
-
|
|
35
|
-
// Determine if we're in dashboard context
|
|
36
|
-
const isDashboardContext = pathname.startsWith('/dashboard')
|
|
37
|
-
|
|
38
|
-
// Filter routes based on context
|
|
39
|
-
const contextRoutes = routeRegistry.getAll().filter((r) => {
|
|
40
|
-
const isRoot = isRootLevelRoute(r.path)
|
|
41
|
-
// In dashboard context: show non-root routes
|
|
42
|
-
// In root context: show root routes
|
|
43
|
-
return isDashboardContext ? !isRoot : isRoot
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
// For dashboard context, also try matching with /dashboard prefix stripped
|
|
47
|
-
const modulePathname = isDashboardContext ? pathname.replace('/dashboard', '') || '/' : pathname
|
|
48
|
-
|
|
49
|
-
// Match route path against pathname, supporting catch-all patterns like /docs/$
|
|
50
|
-
function matchRoute(routePath: string, pathname: string): boolean {
|
|
51
|
-
// Exact match
|
|
52
|
-
if (routePath === pathname) return true
|
|
53
|
-
|
|
54
|
-
// Catch-all pattern: /docs/$ matches /docs/anything/here
|
|
55
|
-
if (routePath.endsWith('/$')) {
|
|
56
|
-
const base = routePath.slice(0, -1) // Remove trailing $
|
|
57
|
-
return pathname.startsWith(base)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return false
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Find matching route - prefer exact matches over catch-all
|
|
64
|
-
const exactMatch = contextRoutes.find((r) => r.path === pathname)
|
|
65
|
-
const catchAllMatch = contextRoutes.find(
|
|
66
|
-
(r) => r.path.endsWith('/$') && matchRoute(r.path, pathname)
|
|
67
|
-
)
|
|
68
|
-
let routeDef = exactMatch || catchAllMatch
|
|
69
|
-
|
|
70
|
-
if (!routeDef && isDashboardContext) {
|
|
71
|
-
// For dashboard routes, also try matching stripped path
|
|
72
|
-
const exactDash = contextRoutes.find((r) => r.path === modulePathname)
|
|
73
|
-
const catchAllDash = contextRoutes.find(
|
|
74
|
-
(r) => r.path.endsWith('/$') && matchRoute(r.path, modulePathname)
|
|
75
|
-
)
|
|
76
|
-
routeDef = exactDash || catchAllDash
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Check auth for root routes with requiresAuth
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
async function checkAuth() {
|
|
82
|
-
if (!routeDef) {
|
|
83
|
-
setAuthChecked(true)
|
|
84
|
-
return
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Dashboard routes are already protected by the dashboard layout
|
|
88
|
-
if (isDashboardContext) {
|
|
89
|
-
setAuthChecked(true)
|
|
90
|
-
setIsAuthenticated(true)
|
|
91
|
-
return
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// For root routes, check if auth is required
|
|
95
|
-
if (routeDef.meta?.requiresAuth) {
|
|
96
|
-
const session = await authClient.getSession()
|
|
97
|
-
if (!session.data) {
|
|
98
|
-
// Redirect to login with return URL
|
|
99
|
-
navigate({
|
|
100
|
-
to: '/login',
|
|
101
|
-
search: { redirect: pathname },
|
|
102
|
-
})
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
setIsAuthenticated(true)
|
|
106
|
-
}
|
|
107
|
-
setAuthChecked(true)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
checkAuth()
|
|
111
|
-
}, [routeDef, isDashboardContext, pathname, navigate, authClient])
|
|
112
|
-
|
|
113
|
-
// Show loading while checking auth for protected root routes
|
|
114
|
-
if (!isDashboardContext && routeDef?.meta?.requiresAuth && !authChecked) {
|
|
115
|
-
return (
|
|
116
|
-
<div className="flex items-center justify-center min-h-screen">
|
|
117
|
-
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
|
|
118
|
-
</div>
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Protected root route - waiting for redirect
|
|
123
|
-
if (!isDashboardContext && routeDef?.meta?.requiresAuth && !isAuthenticated) {
|
|
124
|
-
return null
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (!routeDef) {
|
|
128
|
-
return (
|
|
129
|
-
<div className="flex flex-col items-center justify-center min-h-[50vh] gap-4">
|
|
130
|
-
<h1 className="text-2xl font-bold">Page Not Found</h1>
|
|
131
|
-
<p className="text-muted-foreground">The page "{pathname}" could not be found.</p>
|
|
132
|
-
<Link to="/" className="text-primary hover:underline">
|
|
133
|
-
Go Home
|
|
134
|
-
</Link>
|
|
135
|
-
</div>
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const Component = routeDef.component as React.ComponentType
|
|
140
|
-
return <Component />
|
|
141
|
-
}
|