@smicolon/ai-kit 0.3.2 → 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/README.md +73 -40
- package/dist/index.js +312 -127
- package/package.json +5 -5
- package/.claude-plugin/marketplace.json +0 -369
- package/packs/architect/CHANGELOG.md +0 -17
- package/packs/architect/README.md +0 -58
- package/packs/architect/agents/system-architect.md +0 -768
- package/packs/architect/commands/diagram-create.md +0 -300
- package/packs/better-auth/.mcp.json +0 -14
- package/packs/better-auth/CHANGELOG.md +0 -26
- package/packs/better-auth/README.md +0 -125
- package/packs/better-auth/agents/auth-architect.md +0 -278
- package/packs/better-auth/commands/auth-provider-add.md +0 -265
- package/packs/better-auth/commands/auth-setup.md +0 -298
- package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
- package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
- package/packs/dev-loop/CHANGELOG.md +0 -69
- package/packs/dev-loop/README.md +0 -155
- package/packs/dev-loop/commands/cancel-dev.md +0 -21
- package/packs/dev-loop/commands/dev-loop.md +0 -72
- package/packs/dev-loop/commands/dev-plan.md +0 -351
- package/packs/dev-loop/hooks/hooks.json +0 -15
- package/packs/dev-loop/hooks/stop-hook.sh +0 -178
- package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
- package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
- package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
- package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
- package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
- package/packs/django/CHANGELOG.md +0 -39
- package/packs/django/README.md +0 -92
- package/packs/django/agents/django-architect.md +0 -182
- package/packs/django/agents/django-builder.md +0 -250
- package/packs/django/agents/django-feature-based.md +0 -420
- package/packs/django/agents/django-reviewer.md +0 -253
- package/packs/django/agents/django-tester.md +0 -230
- package/packs/django/commands/api-endpoint.md +0 -285
- package/packs/django/commands/model-create.md +0 -178
- package/packs/django/commands/test-generate.md +0 -325
- package/packs/django/rules/migrations.md +0 -138
- package/packs/django/rules/models.md +0 -167
- package/packs/django/rules/serializers.md +0 -126
- package/packs/django/rules/services.md +0 -131
- package/packs/django/rules/tests.md +0 -140
- package/packs/django/rules/views.md +0 -102
- package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
- package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
- package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
- package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
- package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
- package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
- package/packs/django/skills/security-first-validator/SKILL.md +0 -435
- package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
- package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
- package/packs/failure-log/CHANGELOG.md +0 -20
- package/packs/failure-log/README.md +0 -168
- package/packs/failure-log/commands/failure-add.md +0 -106
- package/packs/failure-log/commands/failure-list.md +0 -89
- package/packs/failure-log/hooks/hooks.json +0 -16
- package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
- package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
- package/packs/flutter/CHANGELOG.md +0 -19
- package/packs/flutter/README.md +0 -170
- package/packs/flutter/agents/flutter-architect.md +0 -166
- package/packs/flutter/agents/flutter-builder.md +0 -303
- package/packs/flutter/agents/release-manager.md +0 -355
- package/packs/flutter/commands/fastlane-setup.md +0 -188
- package/packs/flutter/commands/flutter-build.md +0 -90
- package/packs/flutter/commands/flutter-deploy.md +0 -133
- package/packs/flutter/commands/flutter-test.md +0 -117
- package/packs/flutter/commands/signing-setup.md +0 -209
- package/packs/flutter/hooks/hooks.json +0 -17
- package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
- package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
- package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
- package/packs/hono/CHANGELOG.md +0 -19
- package/packs/hono/README.md +0 -143
- package/packs/hono/agents/hono-architect.md +0 -240
- package/packs/hono/agents/hono-builder.md +0 -285
- package/packs/hono/agents/hono-reviewer.md +0 -279
- package/packs/hono/agents/hono-tester.md +0 -346
- package/packs/hono/commands/middleware-create.md +0 -223
- package/packs/hono/commands/project-init.md +0 -306
- package/packs/hono/commands/route-create.md +0 -153
- package/packs/hono/commands/rpc-client.md +0 -263
- package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
- package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
- package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
- package/packs/hono/skills/zod-validation/SKILL.md +0 -332
- package/packs/nestjs/CHANGELOG.md +0 -29
- package/packs/nestjs/README.md +0 -75
- package/packs/nestjs/agents/nestjs-architect.md +0 -402
- package/packs/nestjs/agents/nestjs-builder.md +0 -301
- package/packs/nestjs/agents/nestjs-tester.md +0 -437
- package/packs/nestjs/commands/module-create.md +0 -369
- package/packs/nestjs/rules/controllers.md +0 -92
- package/packs/nestjs/rules/dto.md +0 -124
- package/packs/nestjs/rules/entities.md +0 -102
- package/packs/nestjs/rules/services.md +0 -106
- package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
- package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
- package/packs/nextjs/CHANGELOG.md +0 -36
- package/packs/nextjs/README.md +0 -76
- package/packs/nextjs/agents/frontend-tester.md +0 -680
- package/packs/nextjs/agents/frontend-visual.md +0 -820
- package/packs/nextjs/agents/nextjs-architect.md +0 -331
- package/packs/nextjs/agents/nextjs-modular.md +0 -433
- package/packs/nextjs/commands/component-create.md +0 -398
- package/packs/nextjs/rules/api-routes.md +0 -129
- package/packs/nextjs/rules/components.md +0 -106
- package/packs/nextjs/rules/hooks.md +0 -132
- package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
- package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
- package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
- package/packs/nuxtjs/CHANGELOG.md +0 -30
- package/packs/nuxtjs/README.md +0 -56
- package/packs/nuxtjs/agents/frontend-tester.md +0 -680
- package/packs/nuxtjs/agents/frontend-visual.md +0 -820
- package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
- package/packs/nuxtjs/commands/component-create.md +0 -223
- package/packs/nuxtjs/rules/components.md +0 -101
- package/packs/nuxtjs/rules/composables.md +0 -118
- package/packs/nuxtjs/rules/server-routes.md +0 -127
- package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
- package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
- package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
- package/packs/onboard/CHANGELOG.md +0 -22
- package/packs/onboard/README.md +0 -103
- package/packs/onboard/agents/onboard-guide.md +0 -118
- package/packs/onboard/commands/onboard.md +0 -313
- package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
- package/packs/tanstack-router/CHANGELOG.md +0 -30
- package/packs/tanstack-router/README.md +0 -113
- package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
- package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
- package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
- package/packs/tanstack-router/commands/form-create.md +0 -313
- package/packs/tanstack-router/commands/query-create.md +0 -263
- package/packs/tanstack-router/commands/route-create.md +0 -190
- package/packs/tanstack-router/commands/table-create.md +0 -413
- package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
- package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
- package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
- package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
- package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
- package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
- package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
- package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
- package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
- package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
- package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
- package/packs/worktree/CHANGELOG.md +0 -45
- package/packs/worktree/README.md +0 -219
- package/packs/worktree/commands/wt.md +0 -93
- package/packs/worktree/scripts/wt.sh +0 -957
- package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
|
@@ -1,455 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Better Auth Patterns
|
|
3
|
-
description: >-
|
|
4
|
-
Auto-enforce Better Auth implementation patterns. Activates when setting up
|
|
5
|
-
authentication, configuring providers, creating auth forms, or implementing
|
|
6
|
-
session management in React applications.
|
|
7
|
-
version: 1.0.0
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Better Auth Patterns
|
|
11
|
-
|
|
12
|
-
This skill enforces Better Auth best practices for authentication in React applications.
|
|
13
|
-
|
|
14
|
-
## Server Configuration
|
|
15
|
-
|
|
16
|
-
### Basic Setup
|
|
17
|
-
```typescript
|
|
18
|
-
// lib/auth.ts
|
|
19
|
-
import { betterAuth } from 'better-auth'
|
|
20
|
-
import { prismaAdapter } from 'better-auth/adapters/prisma'
|
|
21
|
-
import { prisma } from './prisma'
|
|
22
|
-
|
|
23
|
-
export const auth = betterAuth({
|
|
24
|
-
database: prismaAdapter(prisma, {
|
|
25
|
-
provider: 'postgresql',
|
|
26
|
-
}),
|
|
27
|
-
|
|
28
|
-
emailAndPassword: {
|
|
29
|
-
enabled: true,
|
|
30
|
-
requireEmailVerification: true,
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
session: {
|
|
34
|
-
expiresIn: 60 * 60 * 24 * 7, // 7 days
|
|
35
|
-
updateAge: 60 * 60 * 24, // Extend daily
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
export type Auth = typeof auth
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Social Providers
|
|
43
|
-
```typescript
|
|
44
|
-
import { betterAuth } from 'better-auth'
|
|
45
|
-
|
|
46
|
-
export const auth = betterAuth({
|
|
47
|
-
// ... database config
|
|
48
|
-
|
|
49
|
-
socialProviders: {
|
|
50
|
-
google: {
|
|
51
|
-
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
52
|
-
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
53
|
-
scopes: ['email', 'profile'],
|
|
54
|
-
},
|
|
55
|
-
github: {
|
|
56
|
-
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
57
|
-
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
58
|
-
scopes: ['user:email'],
|
|
59
|
-
},
|
|
60
|
-
discord: {
|
|
61
|
-
clientId: process.env.DISCORD_CLIENT_ID!,
|
|
62
|
-
clientSecret: process.env.DISCORD_CLIENT_SECRET!,
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Two-Factor Authentication
|
|
69
|
-
```typescript
|
|
70
|
-
import { twoFactor } from 'better-auth/plugins/two-factor'
|
|
71
|
-
|
|
72
|
-
export const auth = betterAuth({
|
|
73
|
-
// ... base config
|
|
74
|
-
|
|
75
|
-
plugins: [
|
|
76
|
-
twoFactor({
|
|
77
|
-
issuer: 'MyApp',
|
|
78
|
-
totpWindow: 1,
|
|
79
|
-
backupCodes: {
|
|
80
|
-
enabled: true,
|
|
81
|
-
count: 10,
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
],
|
|
85
|
-
})
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Passkeys (WebAuthn)
|
|
89
|
-
```typescript
|
|
90
|
-
import { passkey } from 'better-auth/plugins/passkey'
|
|
91
|
-
|
|
92
|
-
export const auth = betterAuth({
|
|
93
|
-
// ... base config
|
|
94
|
-
|
|
95
|
-
plugins: [
|
|
96
|
-
passkey({
|
|
97
|
-
rpId: 'myapp.com',
|
|
98
|
-
rpName: 'My App',
|
|
99
|
-
origin: 'https://myapp.com',
|
|
100
|
-
attestation: 'none',
|
|
101
|
-
authenticatorSelection: {
|
|
102
|
-
authenticatorAttachment: 'platform',
|
|
103
|
-
userVerification: 'preferred',
|
|
104
|
-
residentKey: 'preferred',
|
|
105
|
-
},
|
|
106
|
-
}),
|
|
107
|
-
],
|
|
108
|
-
})
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Client Setup
|
|
112
|
-
|
|
113
|
-
### Create Auth Client
|
|
114
|
-
```typescript
|
|
115
|
-
// auth/client.ts
|
|
116
|
-
import { createAuthClient } from 'better-auth/react'
|
|
117
|
-
import type { Auth } from '@/lib/auth'
|
|
118
|
-
|
|
119
|
-
export const authClient = createAuthClient<Auth>({
|
|
120
|
-
baseURL: import.meta.env.VITE_API_URL,
|
|
121
|
-
// Optional: Custom fetch for headers
|
|
122
|
-
fetch: async (url, options) => {
|
|
123
|
-
return fetch(url, {
|
|
124
|
-
...options,
|
|
125
|
-
credentials: 'include',
|
|
126
|
-
})
|
|
127
|
-
},
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
// Export typed methods
|
|
131
|
-
export const {
|
|
132
|
-
signIn,
|
|
133
|
-
signUp,
|
|
134
|
-
signOut,
|
|
135
|
-
useSession,
|
|
136
|
-
getSession,
|
|
137
|
-
resetPassword,
|
|
138
|
-
verifyEmail,
|
|
139
|
-
// Social
|
|
140
|
-
signInWithGoogle,
|
|
141
|
-
signInWithGithub,
|
|
142
|
-
// 2FA
|
|
143
|
-
enable2FA,
|
|
144
|
-
disable2FA,
|
|
145
|
-
verify2FA,
|
|
146
|
-
// Passkeys
|
|
147
|
-
registerPasskey,
|
|
148
|
-
signInWithPasskey,
|
|
149
|
-
} = authClient
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Session Hook
|
|
153
|
-
```typescript
|
|
154
|
-
// auth/hooks.ts
|
|
155
|
-
import { useSession } from './client'
|
|
156
|
-
|
|
157
|
-
export function useAuth() {
|
|
158
|
-
const { data: session, isPending, error } = useSession()
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
user: session?.user ?? null,
|
|
162
|
-
session: session?.session ?? null,
|
|
163
|
-
isAuthenticated: !!session?.user,
|
|
164
|
-
isLoading: isPending,
|
|
165
|
-
error,
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function useRequireAuth() {
|
|
170
|
-
const auth = useAuth()
|
|
171
|
-
const navigate = useNavigate()
|
|
172
|
-
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
if (!auth.isLoading && !auth.isAuthenticated) {
|
|
175
|
-
navigate({ to: '/login' })
|
|
176
|
-
}
|
|
177
|
-
}, [auth.isLoading, auth.isAuthenticated])
|
|
178
|
-
|
|
179
|
-
return auth
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Auth Components
|
|
184
|
-
|
|
185
|
-
### Login Form
|
|
186
|
-
```typescript
|
|
187
|
-
import { useForm } from '@tanstack/react-form'
|
|
188
|
-
import { zodValidator } from '@tanstack/zod-form-adapter'
|
|
189
|
-
import { signIn } from '@/auth/client'
|
|
190
|
-
import { z } from 'zod'
|
|
191
|
-
|
|
192
|
-
const loginSchema = z.object({
|
|
193
|
-
email: z.string().email(),
|
|
194
|
-
password: z.string().min(1, 'Password is required'),
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
export function LoginForm() {
|
|
198
|
-
const [error, setError] = useState<string | null>(null)
|
|
199
|
-
const navigate = useNavigate()
|
|
200
|
-
|
|
201
|
-
const form = useForm({
|
|
202
|
-
defaultValues: { email: '', password: '' },
|
|
203
|
-
validatorAdapter: zodValidator(),
|
|
204
|
-
validators: { onChange: loginSchema },
|
|
205
|
-
onSubmit: async ({ value }) => {
|
|
206
|
-
setError(null)
|
|
207
|
-
const result = await signIn.email(value)
|
|
208
|
-
|
|
209
|
-
if (result.error) {
|
|
210
|
-
setError(result.error.message)
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
navigate({ to: '/dashboard' })
|
|
215
|
-
},
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
return (
|
|
219
|
-
<form onSubmit={(e) => { e.preventDefault(); form.handleSubmit() }}>
|
|
220
|
-
{error && <div className="error">{error}</div>}
|
|
221
|
-
|
|
222
|
-
<form.Field
|
|
223
|
-
name="email"
|
|
224
|
-
children={(field) => (/* email input */)}
|
|
225
|
-
/>
|
|
226
|
-
|
|
227
|
-
<form.Field
|
|
228
|
-
name="password"
|
|
229
|
-
children={(field) => (/* password input */)}
|
|
230
|
-
/>
|
|
231
|
-
|
|
232
|
-
<form.Subscribe
|
|
233
|
-
selector={(state) => state.isSubmitting}
|
|
234
|
-
children={(isSubmitting) => (
|
|
235
|
-
<button type="submit" disabled={isSubmitting}>
|
|
236
|
-
{isSubmitting ? 'Signing in...' : 'Sign In'}
|
|
237
|
-
</button>
|
|
238
|
-
)}
|
|
239
|
-
/>
|
|
240
|
-
</form>
|
|
241
|
-
)
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Social Login Buttons
|
|
246
|
-
```typescript
|
|
247
|
-
import { signInWithGoogle, signInWithGithub } from '@/auth/client'
|
|
248
|
-
|
|
249
|
-
export function SocialLoginButtons() {
|
|
250
|
-
const handleGoogleLogin = async () => {
|
|
251
|
-
await signInWithGoogle({
|
|
252
|
-
callbackURL: '/dashboard',
|
|
253
|
-
})
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const handleGithubLogin = async () => {
|
|
257
|
-
await signInWithGithub({
|
|
258
|
-
callbackURL: '/dashboard',
|
|
259
|
-
})
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return (
|
|
263
|
-
<div className="flex flex-col gap-2">
|
|
264
|
-
<button onClick={handleGoogleLogin} className="btn-social">
|
|
265
|
-
<GoogleIcon /> Continue with Google
|
|
266
|
-
</button>
|
|
267
|
-
<button onClick={handleGithubLogin} className="btn-social">
|
|
268
|
-
<GithubIcon /> Continue with GitHub
|
|
269
|
-
</button>
|
|
270
|
-
</div>
|
|
271
|
-
)
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### 2FA Setup
|
|
276
|
-
```typescript
|
|
277
|
-
import { enable2FA, verify2FA } from '@/auth/client'
|
|
278
|
-
import { useState } from 'react'
|
|
279
|
-
|
|
280
|
-
export function TwoFactorSetup() {
|
|
281
|
-
const [qrCode, setQrCode] = useState<string | null>(null)
|
|
282
|
-
const [secret, setSecret] = useState<string | null>(null)
|
|
283
|
-
const [code, setCode] = useState('')
|
|
284
|
-
const [backupCodes, setBackupCodes] = useState<string[]>([])
|
|
285
|
-
|
|
286
|
-
const handleEnable = async () => {
|
|
287
|
-
const result = await enable2FA()
|
|
288
|
-
if (result.data) {
|
|
289
|
-
setQrCode(result.data.qrCode)
|
|
290
|
-
setSecret(result.data.secret)
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const handleVerify = async () => {
|
|
295
|
-
const result = await verify2FA({ code })
|
|
296
|
-
if (result.data) {
|
|
297
|
-
setBackupCodes(result.data.backupCodes)
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (backupCodes.length > 0) {
|
|
302
|
-
return (
|
|
303
|
-
<div>
|
|
304
|
-
<h3>Save your backup codes</h3>
|
|
305
|
-
<ul>
|
|
306
|
-
{backupCodes.map((code, i) => (
|
|
307
|
-
<li key={i}>{code}</li>
|
|
308
|
-
))}
|
|
309
|
-
</ul>
|
|
310
|
-
</div>
|
|
311
|
-
)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (qrCode) {
|
|
315
|
-
return (
|
|
316
|
-
<div>
|
|
317
|
-
<img src={qrCode} alt="2FA QR Code" />
|
|
318
|
-
<p>Secret: {secret}</p>
|
|
319
|
-
<input
|
|
320
|
-
value={code}
|
|
321
|
-
onChange={(e) => setCode(e.target.value)}
|
|
322
|
-
placeholder="Enter 6-digit code"
|
|
323
|
-
/>
|
|
324
|
-
<button onClick={handleVerify}>Verify</button>
|
|
325
|
-
</div>
|
|
326
|
-
)
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return (
|
|
330
|
-
<button onClick={handleEnable}>Enable 2FA</button>
|
|
331
|
-
)
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
### Passkey Registration
|
|
336
|
-
```typescript
|
|
337
|
-
import { registerPasskey, signInWithPasskey } from '@/auth/client'
|
|
338
|
-
|
|
339
|
-
export function PasskeyManager() {
|
|
340
|
-
const [error, setError] = useState<string | null>(null)
|
|
341
|
-
|
|
342
|
-
const handleRegister = async () => {
|
|
343
|
-
setError(null)
|
|
344
|
-
const result = await registerPasskey({
|
|
345
|
-
name: 'My Device',
|
|
346
|
-
})
|
|
347
|
-
|
|
348
|
-
if (result.error) {
|
|
349
|
-
setError(result.error.message)
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const handleSignIn = async () => {
|
|
354
|
-
setError(null)
|
|
355
|
-
const result = await signInWithPasskey()
|
|
356
|
-
|
|
357
|
-
if (result.error) {
|
|
358
|
-
setError(result.error.message)
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
return (
|
|
363
|
-
<div>
|
|
364
|
-
{error && <div className="error">{error}</div>}
|
|
365
|
-
<button onClick={handleRegister}>Register Passkey</button>
|
|
366
|
-
<button onClick={handleSignIn}>Sign in with Passkey</button>
|
|
367
|
-
</div>
|
|
368
|
-
)
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
## Router Integration
|
|
373
|
-
|
|
374
|
-
### Root Route with Session
|
|
375
|
-
```typescript
|
|
376
|
-
// routes/__root.tsx
|
|
377
|
-
import { createRootRouteWithContext } from '@tanstack/react-router'
|
|
378
|
-
import { getSession } from '@/auth/client'
|
|
379
|
-
|
|
380
|
-
export const Route = createRootRouteWithContext<RouterContext>()({
|
|
381
|
-
beforeLoad: async () => {
|
|
382
|
-
const session = await getSession()
|
|
383
|
-
return { session: session?.data ?? null }
|
|
384
|
-
},
|
|
385
|
-
})
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### Protected Route Layout
|
|
389
|
-
```typescript
|
|
390
|
-
// routes/_auth.tsx
|
|
391
|
-
import { createFileRoute, redirect } from '@tanstack/react-router'
|
|
392
|
-
|
|
393
|
-
export const Route = createFileRoute('/_auth')({
|
|
394
|
-
beforeLoad: async ({ context, location }) => {
|
|
395
|
-
if (!context.session) {
|
|
396
|
-
throw redirect({
|
|
397
|
-
to: '/login',
|
|
398
|
-
search: { redirect: location.pathname },
|
|
399
|
-
})
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
})
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### Guest-Only Routes
|
|
406
|
-
```typescript
|
|
407
|
-
// routes/_guest.tsx
|
|
408
|
-
import { createFileRoute, redirect } from '@tanstack/react-router'
|
|
409
|
-
|
|
410
|
-
export const Route = createFileRoute('/_guest')({
|
|
411
|
-
beforeLoad: async ({ context }) => {
|
|
412
|
-
if (context.session) {
|
|
413
|
-
throw redirect({ to: '/dashboard' })
|
|
414
|
-
}
|
|
415
|
-
},
|
|
416
|
-
})
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
## Conventions
|
|
420
|
-
|
|
421
|
-
1. **Server config in lib/** - Keep auth config at `lib/auth.ts`
|
|
422
|
-
2. **Client in auth/** - Export typed client from `auth/client.ts`
|
|
423
|
-
3. **Route protection** - Use pathless layouts (`_auth.tsx`)
|
|
424
|
-
4. **Session in context** - Load session in `__root.tsx`
|
|
425
|
-
5. **Error handling** - Always check `result.error`
|
|
426
|
-
6. **Type safety** - Use `Auth` type from server config
|
|
427
|
-
|
|
428
|
-
## Anti-Patterns
|
|
429
|
-
|
|
430
|
-
```typescript
|
|
431
|
-
// ❌ WRONG: Untyped client
|
|
432
|
-
const authClient = createAuthClient({})
|
|
433
|
-
|
|
434
|
-
// ✅ CORRECT: Typed client
|
|
435
|
-
const authClient = createAuthClient<Auth>({})
|
|
436
|
-
|
|
437
|
-
// ❌ WRONG: No error handling
|
|
438
|
-
const result = await signIn.email(data)
|
|
439
|
-
navigate('/dashboard')
|
|
440
|
-
|
|
441
|
-
// ✅ CORRECT: Check for errors
|
|
442
|
-
const result = await signIn.email(data)
|
|
443
|
-
if (result.error) {
|
|
444
|
-
setError(result.error.message)
|
|
445
|
-
return
|
|
446
|
-
}
|
|
447
|
-
navigate('/dashboard')
|
|
448
|
-
|
|
449
|
-
// ❌ WRONG: Client-side session check only
|
|
450
|
-
if (localStorage.getItem('session')) { ... }
|
|
451
|
-
|
|
452
|
-
// ✅ CORRECT: Server-validated session
|
|
453
|
-
const { data: session } = useSession()
|
|
454
|
-
if (session) { ... }
|
|
455
|
-
```
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to the smi-dev-loop plugin will be documented in this file.
|
|
4
|
-
|
|
5
|
-
## [Unreleased]
|
|
6
|
-
|
|
7
|
-
### Changed
|
|
8
|
-
- Renamed from `smi-dev-loop` to `dev-loop` as part of ai-kit migration
|
|
9
|
-
- Moved from `plugins/smi-dev-loop/` to `packs/dev-loop/`
|
|
10
|
-
|
|
11
|
-
## [1.2.1] - 2026-01-02
|
|
12
|
-
|
|
13
|
-
### Fixed
|
|
14
|
-
- Rewrite stop hook based on official Ralph Wiggum pattern
|
|
15
|
-
- Fix infinite loop bug when agent responds with natural language completion
|
|
16
|
-
- Add comprehensive error handling with clear user messages
|
|
17
|
-
- Use `systemMessage` field for iteration status
|
|
18
|
-
- Add anti-gaming instruction ("do not lie to exit!")
|
|
19
|
-
- Atomic file updates with PID suffix
|
|
20
|
-
|
|
21
|
-
### Changed
|
|
22
|
-
- Setup script now matches Ralph Wiggum quality with better argument parsing
|
|
23
|
-
- Multi-word prompts work without quotes
|
|
24
|
-
- Added `-h|--help` with full documentation
|
|
25
|
-
- Defaults remain: 50 iterations, "DONE" promise
|
|
26
|
-
|
|
27
|
-
## [1.2.0] - 2026-01-02
|
|
28
|
-
|
|
29
|
-
### Added
|
|
30
|
-
- Quality checklist enforcement for plan generation
|
|
31
|
-
- Required file tables: "Files to Modify" and "New Files to Create"
|
|
32
|
-
- Code snippets in implementation phases
|
|
33
|
-
- Acceptance criteria section with Given/When/Then format
|
|
34
|
-
- Framework-specific stuck handling (not generic)
|
|
35
|
-
- `references/good-example.md` - High-quality Flutter migration example
|
|
36
|
-
- Anti-patterns documentation to avoid vague plans
|
|
37
|
-
- **17+ framework auto-detection**: Flutter, React Native, Django, FastAPI, Flask, NestJS, Next.js, Nuxt.js, Hono, Express, TanStack, Go, Rust, Rails, Laravel
|
|
38
|
-
- **Custom framework support**: `--test-cmd` and `--lint-cmd` flags for any stack
|
|
39
|
-
- Test patterns for Go, Rust, Rails, Laravel, FastAPI, Hono, Flutter
|
|
40
|
-
|
|
41
|
-
### Changed
|
|
42
|
-
- Enhanced `dev-plan.md` command with deep codebase analysis step
|
|
43
|
-
- Improved `plan-template.md` with all required sections
|
|
44
|
-
- Updated `SKILL.md` with specificity requirements
|
|
45
|
-
- Tasks now require file paths and implementation details
|
|
46
|
-
- Framework detection now works with any tech stack
|
|
47
|
-
- **Package manager auto-detection**: bun (default) > pnpm > yarn > npm based on lockfile
|
|
48
|
-
|
|
49
|
-
### Fixed
|
|
50
|
-
- Plans now consistently include measurable success criteria
|
|
51
|
-
- Self-correction rules are phase-specific instead of generic
|
|
52
|
-
|
|
53
|
-
## [1.1.0] - 2025-01-02
|
|
54
|
-
|
|
55
|
-
### Added
|
|
56
|
-
- `/dev-plan` command for TDD planning phase
|
|
57
|
-
- `tdd-planner` skill for structured development plans
|
|
58
|
-
|
|
59
|
-
### Fixed
|
|
60
|
-
- Stop hook transcript parsing
|
|
61
|
-
- Progress tracking improvements
|
|
62
|
-
|
|
63
|
-
## [1.0.0] - 2024-12-15
|
|
64
|
-
|
|
65
|
-
### Added
|
|
66
|
-
- Initial stable release
|
|
67
|
-
- 3 commands: dev-loop, dev-plan, cancel-dev
|
|
68
|
-
- Autonomous development loop with Red-Green-Refactor
|
|
69
|
-
- Stop hook for continuation logic
|
package/packs/dev-loop/README.md
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
# dev-loop
|
|
2
|
-
|
|
3
|
-
Autonomous TDD development loops with planning phase and iterative coding.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
This plugin provides a "dev loop" mechanism that keeps Claude working on a task until completion. Based on the Ralph Wiggum pattern, it uses a Stop hook to intercept Claude's exit and re-feed the original prompt.
|
|
8
|
-
|
|
9
|
-
**New in v1.1**: Planning phase with `/dev-plan` for structured TDD workflows.
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
/plugin install dev-loop
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Recommended Workflow
|
|
18
|
-
|
|
19
|
-
For best results, use the planning phase first:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
# 1. Generate structured TDD plan
|
|
23
|
-
/dev-plan "Build user authentication with JWT"
|
|
24
|
-
|
|
25
|
-
# 2. Review and edit .claude/dev-plan.local.md if needed
|
|
26
|
-
|
|
27
|
-
# 3. Execute with structured plan
|
|
28
|
-
/dev-loop --from-plan
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Commands
|
|
32
|
-
|
|
33
|
-
### /dev-plan
|
|
34
|
-
|
|
35
|
-
Generate a structured TDD plan for dev-loop execution:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# Basic usage - auto-detects framework
|
|
39
|
-
/dev-plan "Build user authentication with JWT"
|
|
40
|
-
|
|
41
|
-
# With explicit framework
|
|
42
|
-
/dev-plan "Build API endpoints" --framework django
|
|
43
|
-
|
|
44
|
-
# With interactive questions
|
|
45
|
-
/dev-plan "Implement payment system" --interactive
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Creates `.claude/dev-plan.local.md` with:
|
|
49
|
-
- TDD phases (Red-Green-Refactor)
|
|
50
|
-
- Clear verification commands
|
|
51
|
-
- Self-correction rules
|
|
52
|
-
- Stuck handling
|
|
53
|
-
|
|
54
|
-
### /dev-loop
|
|
55
|
-
|
|
56
|
-
Start a development loop:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
# Recommended: Use with plan
|
|
60
|
-
/dev-loop --from-plan
|
|
61
|
-
|
|
62
|
-
# Simple usage - just provide your prompt
|
|
63
|
-
/dev-loop "Build a user authentication system with login and logout"
|
|
64
|
-
|
|
65
|
-
# With custom max iterations (default: 50)
|
|
66
|
-
/dev-loop "Refactor the database layer" --max-iterations 30
|
|
67
|
-
|
|
68
|
-
# With custom completion promise (default: DONE)
|
|
69
|
-
/dev-loop "Fix all TypeScript errors" --promise "ALL_FIXED"
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### /cancel-dev
|
|
73
|
-
|
|
74
|
-
Cancel an active loop:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
/cancel-dev
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## How It Works
|
|
81
|
-
|
|
82
|
-
1. **Start**: `/dev-loop "Your prompt"` creates a state file at `.claude/dev-loop.local.md`
|
|
83
|
-
2. **Work**: Claude works on your task iteratively
|
|
84
|
-
3. **Continue**: When Claude tries to stop, the Stop hook checks if `<promise>DONE</promise>` was output
|
|
85
|
-
4. **Complete**: If the promise is found, the loop ends. Otherwise, the prompt is re-fed.
|
|
86
|
-
5. **Safety**: After 50 iterations (configurable), the loop stops automatically.
|
|
87
|
-
|
|
88
|
-
## State File
|
|
89
|
-
|
|
90
|
-
The loop state is stored in `.claude/dev-loop.local.md`:
|
|
91
|
-
|
|
92
|
-
```yaml
|
|
93
|
-
---
|
|
94
|
-
active: true
|
|
95
|
-
iteration: 1
|
|
96
|
-
max_iterations: 50
|
|
97
|
-
completion_promise: "DONE"
|
|
98
|
-
started_at: "2026-01-01T00:00:00Z"
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
Your prompt text here
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Completion
|
|
105
|
-
|
|
106
|
-
To end the loop, output the completion promise:
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
<promise>DONE</promise>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Or with a custom promise:
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
<promise>YOUR_CUSTOM_PROMISE</promise>
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Use Cases
|
|
119
|
-
|
|
120
|
-
- **TDD Development**: Use `/dev-plan` for structured Red-Green-Refactor phases
|
|
121
|
-
- **Bug Fixing**: Keep working until the bug is resolved
|
|
122
|
-
- **Refactoring**: Iteratively improve code structure
|
|
123
|
-
- **Feature Building**: Build complex features step by step with planning
|
|
124
|
-
- **Code Review Fixes**: Address all review comments
|
|
125
|
-
|
|
126
|
-
## TDD Planner Skill
|
|
127
|
-
|
|
128
|
-
The `tdd-planner` skill auto-activates when you ask to:
|
|
129
|
-
- "Plan a feature"
|
|
130
|
-
- "Prepare for dev loop"
|
|
131
|
-
- "Break down this task"
|
|
132
|
-
- "Structure TDD approach"
|
|
133
|
-
|
|
134
|
-
It generates structured prompts with:
|
|
135
|
-
- Clear success criteria
|
|
136
|
-
- TDD phases (Red → Green → Refactor)
|
|
137
|
-
- Verification commands
|
|
138
|
-
- Self-correction rules
|
|
139
|
-
|
|
140
|
-
## Combining with Framework Plugins
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
# Install loop + Django conventions
|
|
144
|
-
/plugin install dev-loop django
|
|
145
|
-
|
|
146
|
-
# Now use both
|
|
147
|
-
/dev-loop "Build a REST API for user management following Django conventions"
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Technical Details
|
|
151
|
-
|
|
152
|
-
- **Hook Type**: Stop hook with bash command
|
|
153
|
-
- **State File**: `.claude/dev-loop.local.md` (gitignored)
|
|
154
|
-
- **Default Iterations**: 50
|
|
155
|
-
- **Default Promise**: "DONE"
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: cancel-dev
|
|
3
|
-
description: "Cancel active dev loop"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
```!
|
|
7
|
-
if [ -f ".claude/dev-loop.local.md" ]; then
|
|
8
|
-
rm ".claude/dev-loop.local.md"
|
|
9
|
-
echo "Dev loop cancelled."
|
|
10
|
-
else
|
|
11
|
-
echo "No active dev loop to cancel."
|
|
12
|
-
fi
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
# Dev Loop Cancelled
|
|
16
|
-
|
|
17
|
-
The dev loop has been cancelled. You can start a new loop with:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
/dev-loop "Your prompt here"
|
|
21
|
-
```
|