@cogito.ai/cli 0.4.2 → 0.4.3

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 (101) hide show
  1. package/README.md +29 -22
  2. package/dist/index.js +9 -15
  3. package/dist/templates/web-nextjs/.github/copilot-instructions.md +5 -6
  4. package/dist/templates/web-nextjs/README.md +25 -24
  5. package/dist/templates/web-nextjs/apps/docs/.source/browser.ts +18 -8
  6. package/dist/templates/web-nextjs/apps/docs/.source/dynamic.ts +11 -5
  7. package/dist/templates/web-nextjs/apps/docs/.source/server.ts +37 -17
  8. package/dist/templates/web-nextjs/apps/docs/app/docs/[[...slug]]/page.tsx +1 -6
  9. package/dist/templates/web-nextjs/apps/docs/app/docs/layout.tsx +1 -4
  10. package/dist/templates/web-nextjs/apps/docs/app/llms-full.txt/route.ts +3 -1
  11. package/dist/templates/web-nextjs/apps/docs/next-env.d.ts +1 -1
  12. package/dist/templates/web-nextjs/apps/web/.github/copilot-instructions.md +53 -6
  13. package/dist/templates/web-nextjs/apps/web/.github/skills/impeccable/SKILL.md +55 -0
  14. package/dist/templates/web-nextjs/apps/web/DESIGN.md +65 -0
  15. package/dist/templates/web-nextjs/apps/web/messages/en.json +81 -5
  16. package/dist/templates/web-nextjs/apps/web/messages/zh.json +81 -5
  17. package/dist/templates/web-nextjs/apps/web/next.config.ts +3 -3
  18. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/forgot-password/page.tsx +174 -39
  19. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/login/page.tsx +13 -3
  20. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/reset-password/page.tsx +4 -1
  21. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/signup/page.tsx +18 -17
  22. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/dashboard/page.tsx +1 -5
  23. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/settings/layout.tsx +1 -5
  24. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/settings/profile/page.tsx +2 -8
  25. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/about/page.tsx +3 -6
  26. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/globals.css +17 -5
  27. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/help/page.tsx +1 -5
  28. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/layout.tsx +10 -8
  29. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/page.tsx +22 -6
  30. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/privacy/page.tsx +3 -6
  31. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/terms/page.tsx +1 -5
  32. package/dist/templates/web-nextjs/apps/web/src/app/auth/callback/route.ts +2 -3
  33. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/app-sidebar.tsx +13 -16
  34. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/chart-area-interactive.tsx +122 -146
  35. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/data-table.tsx +84 -149
  36. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-documents.tsx +7 -16
  37. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-main.tsx +4 -4
  38. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-secondary.tsx +4 -4
  39. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-user.tsx +12 -21
  40. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/page.tsx +10 -13
  41. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/section-cards.tsx +5 -9
  42. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/site-header.tsx +6 -7
  43. package/dist/templates/web-nextjs/apps/web/src/components/landing/features.tsx +63 -0
  44. package/dist/templates/web-nextjs/apps/web/src/components/landing/footer.tsx +48 -0
  45. package/dist/templates/web-nextjs/apps/web/src/components/landing/header.tsx +97 -0
  46. package/dist/templates/web-nextjs/apps/web/src/components/landing/hero.tsx +45 -0
  47. package/dist/templates/web-nextjs/apps/web/src/components/landing/how-it-works.tsx +35 -0
  48. package/dist/templates/web-nextjs/apps/web/src/components/landing/pricing-teaser.tsx +23 -0
  49. package/dist/templates/web-nextjs/apps/web/src/components/profile/profile-form.tsx +6 -4
  50. package/dist/templates/web-nextjs/apps/web/src/components/providers/theme-provider.tsx +16 -0
  51. package/dist/templates/web-nextjs/apps/web/src/components/ui/alert-dialog.tsx +32 -49
  52. package/dist/templates/web-nextjs/apps/web/src/components/ui/alert.tsx +16 -23
  53. package/dist/templates/web-nextjs/apps/web/src/components/ui/avatar.tsx +25 -38
  54. package/dist/templates/web-nextjs/apps/web/src/components/ui/badge.tsx +16 -18
  55. package/dist/templates/web-nextjs/apps/web/src/components/ui/breadcrumb.tsx +19 -26
  56. package/dist/templates/web-nextjs/apps/web/src/components/ui/button.tsx +23 -24
  57. package/dist/templates/web-nextjs/apps/web/src/components/ui/card.tsx +19 -36
  58. package/dist/templates/web-nextjs/apps/web/src/components/ui/chart.tsx +60 -94
  59. package/dist/templates/web-nextjs/apps/web/src/components/ui/checkbox.tsx +8 -11
  60. package/dist/templates/web-nextjs/apps/web/src/components/ui/collapsible.tsx +5 -17
  61. package/dist/templates/web-nextjs/apps/web/src/components/ui/command.tsx +25 -48
  62. package/dist/templates/web-nextjs/apps/web/src/components/ui/dialog.tsx +21 -35
  63. package/dist/templates/web-nextjs/apps/web/src/components/ui/drawer.tsx +24 -35
  64. package/dist/templates/web-nextjs/apps/web/src/components/ui/dropdown-menu.tsx +26 -55
  65. package/dist/templates/web-nextjs/apps/web/src/components/ui/field.tsx +62 -76
  66. package/dist/templates/web-nextjs/apps/web/src/components/ui/form.tsx +19 -34
  67. package/dist/templates/web-nextjs/apps/web/src/components/ui/input-otp.tsx +13 -20
  68. package/dist/templates/web-nextjs/apps/web/src/components/ui/input.tsx +6 -6
  69. package/dist/templates/web-nextjs/apps/web/src/components/ui/label.tsx +6 -6
  70. package/dist/templates/web-nextjs/apps/web/src/components/ui/pagination.tsx +21 -42
  71. package/dist/templates/web-nextjs/apps/web/src/components/ui/popover.tsx +16 -31
  72. package/dist/templates/web-nextjs/apps/web/src/components/ui/progress.tsx +5 -8
  73. package/dist/templates/web-nextjs/apps/web/src/components/ui/radio-group.tsx +8 -8
  74. package/dist/templates/web-nextjs/apps/web/src/components/ui/scroll-area.tsx +10 -12
  75. package/dist/templates/web-nextjs/apps/web/src/components/ui/select.tsx +26 -41
  76. package/dist/templates/web-nextjs/apps/web/src/components/ui/separator.tsx +7 -7
  77. package/dist/templates/web-nextjs/apps/web/src/components/ui/sheet.tsx +29 -38
  78. package/dist/templates/web-nextjs/apps/web/src/components/ui/sidebar.tsx +157 -189
  79. package/dist/templates/web-nextjs/apps/web/src/components/ui/skeleton.tsx +3 -3
  80. package/dist/templates/web-nextjs/apps/web/src/components/ui/slider.tsx +10 -15
  81. package/dist/templates/web-nextjs/apps/web/src/components/ui/sonner.tsx +13 -7
  82. package/dist/templates/web-nextjs/apps/web/src/components/ui/switch.tsx +9 -9
  83. package/dist/templates/web-nextjs/apps/web/src/components/ui/table.tsx +24 -48
  84. package/dist/templates/web-nextjs/apps/web/src/components/ui/tabs.tsx +21 -31
  85. package/dist/templates/web-nextjs/apps/web/src/components/ui/textarea.tsx +5 -5
  86. package/dist/templates/web-nextjs/apps/web/src/components/ui/theme-toggle.tsx +23 -0
  87. package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle-group.tsx +15 -16
  88. package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle.tsx +14 -15
  89. package/dist/templates/web-nextjs/apps/web/src/components/ui/tooltip.tsx +8 -12
  90. package/dist/templates/web-nextjs/apps/web/src/core/repositories/IAuthRepository.ts +2 -0
  91. package/dist/templates/web-nextjs/apps/web/src/core/types/auth.ts +1 -3
  92. package/dist/templates/web-nextjs/apps/web/src/features/auth/actions.ts +57 -1
  93. package/dist/templates/web-nextjs/apps/web/src/features/auth/index.ts +2 -0
  94. package/dist/templates/web-nextjs/apps/web/src/hooks/use-mobile.ts +4 -4
  95. package/dist/templates/web-nextjs/apps/web/src/i18n/config.ts +1 -1
  96. package/dist/templates/web-nextjs/apps/web/src/infra/db/SupabaseAuthRepository.ts +48 -4
  97. package/dist/templates/web-nextjs/apps/web/src/infra/db/client.ts +1 -4
  98. package/dist/templates/web-nextjs/apps/web/src/lib/utils.ts +2 -2
  99. package/dist/templates/web-nextjs/apps/web/src/lib/validations/auth.ts +13 -0
  100. package/dist/templates/web-nextjs/apps/web/src/styles/tokens.css +58 -0
  101. package/package.json +1 -1
@@ -2,7 +2,14 @@
2
2
 
3
3
  import { redirect } from 'next/navigation'
4
4
  import { getAuthRepository } from '@/infra/providers'
5
- import { signInSchema, signUpSchema, forgotPasswordSchema, resetPasswordSchema, displayNameSchema } from '@/lib/validations/auth'
5
+ import {
6
+ signInSchema,
7
+ signUpSchema,
8
+ forgotPasswordSchema,
9
+ resetPasswordWithOTPSchema,
10
+ resetPasswordSchema,
11
+ displayNameSchema,
12
+ } from '@/lib/validations/auth'
6
13
  import type { ActionResult } from '@/core/types/auth'
7
14
  import { defaultLocale, isLocale } from '@/i18n/config'
8
15
  import type { SignUpSuccessData, OAuthData } from './__contract__'
@@ -153,3 +160,52 @@ export async function updateDisplayName(
153
160
 
154
161
  return { data: undefined as void, error: null }
155
162
  }
163
+
164
+ export async function sendPasswordResetOTP(
165
+ _prevState: ActionResult | null,
166
+ formData: FormData,
167
+ ): Promise<ActionResult<void>> {
168
+ const email = formData.get('email')
169
+ if (!email || typeof email !== 'string') {
170
+ return { data: null, error: '邮箱不能为空' }
171
+ }
172
+
173
+ const repo = getAuthRepository()
174
+ const result = await repo.sendPasswordResetOTP(email)
175
+
176
+ if (result.error) {
177
+ return { data: null, error: result.error }
178
+ }
179
+
180
+ return { data: undefined as void, error: null }
181
+ }
182
+
183
+ export async function resetPasswordWithOTP(
184
+ _prevState: ActionResult | null,
185
+ formData: FormData,
186
+ ): Promise<ActionResult<void>> {
187
+ const parsed = resetPasswordWithOTPSchema.safeParse({
188
+ email: formData.get('email'),
189
+ token: formData.get('token'),
190
+ password: formData.get('password'),
191
+ confirmPassword: formData.get('confirmPassword'),
192
+ })
193
+
194
+ if (!parsed.success) {
195
+ return { data: null, error: parsed.error.issues[0]?.message ?? '输入无效' }
196
+ }
197
+
198
+ const repo = getAuthRepository()
199
+ const result = await repo.verifyPasswordResetOTP(
200
+ parsed.data.email,
201
+ parsed.data.token,
202
+ parsed.data.password,
203
+ )
204
+
205
+ if (result.error) {
206
+ return { data: null, error: result.error }
207
+ }
208
+
209
+ const locale = normalizeLocale(formData.get('locale'))
210
+ redirect(`/${locale}/login`)
211
+ }
@@ -7,4 +7,6 @@ export {
7
7
  requestPasswordReset,
8
8
  resetPassword,
9
9
  updateDisplayName,
10
+ sendPasswordResetOTP,
11
+ resetPasswordWithOTP,
10
12
  } from './actions'
@@ -1,6 +1,6 @@
1
- "use client"
1
+ 'use client'
2
2
 
3
- import * as React from "react"
3
+ import * as React from 'react'
4
4
 
5
5
  const MOBILE_BREAKPOINT = 768
6
6
 
@@ -12,9 +12,9 @@ export function useIsMobile() {
12
12
  const onChange = () => {
13
13
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
14
14
  }
15
- mql.addEventListener("change", onChange)
15
+ mql.addEventListener('change', onChange)
16
16
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
17
- return () => mql.removeEventListener("change", onChange)
17
+ return () => mql.removeEventListener('change', onChange)
18
18
  }, [])
19
19
 
20
20
  return !!isMobile
@@ -9,4 +9,4 @@ export const defaultLocale: AppLocale =
9
9
 
10
10
  export function isLocale(value: string): value is AppLocale {
11
11
  return locales.includes(value as AppLocale)
12
- }
12
+ }
@@ -20,9 +20,7 @@ export class SupabaseAuthRepository implements IAuthRepository {
20
20
  const supabase = await getServerClient()
21
21
  const { data, error } = await supabase.auth.signUp({ email, password })
22
22
  if (error) {
23
- const msg = error.message.toLowerCase().includes('already')
24
- ? '该邮箱已被注册'
25
- : error.message
23
+ const msg = error.message.toLowerCase().includes('already') ? '该邮箱已被注册' : error.message
26
24
  return { user: null, error: msg }
27
25
  }
28
26
  const u = data.user
@@ -39,7 +37,9 @@ export class SupabaseAuthRepository implements IAuthRepository {
39
37
 
40
38
  async getSession(): Promise<AuthUser | null> {
41
39
  const supabase = await getServerClient()
42
- const { data: { user } } = await supabase.auth.getUser()
40
+ const {
41
+ data: { user },
42
+ } = await supabase.auth.getUser()
43
43
  if (!user) return null
44
44
  return { id: user.id, email: user.email ?? '', createdAt: user.created_at }
45
45
  }
@@ -85,4 +85,48 @@ export class SupabaseAuthRepository implements IAuthRepository {
85
85
  }
86
86
  return { user: null, error: null }
87
87
  }
88
+
89
+ async sendPasswordResetOTP(email: string): Promise<AuthResult> {
90
+ const supabase = await getServerClient()
91
+ const { error } = await supabase.auth.signInWithOtp({
92
+ email,
93
+ options: {
94
+ shouldCreateUser: false, // Don't create user if not exists
95
+ },
96
+ })
97
+ if (error) {
98
+ return { user: null, error: error.message }
99
+ }
100
+ return { user: null, error: null }
101
+ }
102
+
103
+ async verifyPasswordResetOTP(
104
+ email: string,
105
+ token: string,
106
+ newPassword: string,
107
+ ): Promise<AuthResult> {
108
+ const supabase = await getServerClient()
109
+ const { data, error } = await supabase.auth.verifyOtp({
110
+ email,
111
+ token,
112
+ type: 'email',
113
+ })
114
+ if (error) {
115
+ return { user: null, error: error.message }
116
+ }
117
+
118
+ // After verifying OTP, update the password
119
+ const { error: updateError } = await supabase.auth.updateUser({
120
+ password: newPassword,
121
+ })
122
+ if (updateError) {
123
+ return { user: null, error: updateError.message }
124
+ }
125
+
126
+ const u = data.user
127
+ return {
128
+ user: u ? { id: u.id, email: u.email ?? '', createdAt: u.created_at } : null,
129
+ error: null,
130
+ }
131
+ }
88
132
  }
@@ -66,10 +66,7 @@ export function getBrowserClient() {
66
66
  * await supabase.auth.getUser() // refreshes session token
67
67
  * ```
68
68
  */
69
- export function createMiddlewareClient(
70
- request: NextRequest,
71
- response: NextResponse,
72
- ) {
69
+ export function createMiddlewareClient(request: NextRequest, response: NextResponse) {
73
70
  const supabase = createServerClient(
74
71
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
75
72
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
@@ -1,5 +1,5 @@
1
- import { clsx, type ClassValue } from "clsx"
2
- import { twMerge } from "tailwind-merge"
1
+ import { clsx, type ClassValue } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
3
 
4
4
  export function cn(...inputs: ClassValue[]) {
5
5
  return twMerge(clsx(inputs))
@@ -20,6 +20,18 @@ export const forgotPasswordSchema = z.object({
20
20
  email: z.string().email('请输入有效邮箱'),
21
21
  })
22
22
 
23
+ export const resetPasswordWithOTPSchema = z
24
+ .object({
25
+ email: z.string().email('请输入有效邮箱'),
26
+ token: z.string().min(6, '验证码至少 6 位'),
27
+ password: z.string().min(8, '密码至少 8 位'),
28
+ confirmPassword: z.string(),
29
+ })
30
+ .refine((data) => data.password === data.confirmPassword, {
31
+ message: '两次密码不一致',
32
+ path: ['confirmPassword'],
33
+ })
34
+
23
35
  export const resetPasswordSchema = z
24
36
  .object({
25
37
  password: z.string().min(8, '密码至少 8 位'),
@@ -37,5 +49,6 @@ export const displayNameSchema = z.object({
37
49
  export type SignInInput = z.infer<typeof signInSchema>
38
50
  export type SignUpInput = z.infer<typeof signUpSchema>
39
51
  export type ForgotPasswordInput = z.infer<typeof forgotPasswordSchema>
52
+ export type ResetPasswordWithOTPInput = z.infer<typeof resetPasswordWithOTPSchema>
40
53
  export type ResetPasswordInput = z.infer<typeof resetPasswordSchema>
41
54
  export type DisplayNameInput = z.infer<typeof displayNameSchema>
@@ -0,0 +1,58 @@
1
+ @layer base {
2
+ :root {
3
+ /* Brand tokens — downstream projects override these three variables to change the theme color */
4
+ --color-brand-h: 262;
5
+ --color-brand-c: 0.26;
6
+ --color-brand-l: 0.56;
7
+
8
+ /* Semantic color tokens */
9
+ --color-primary: oklch(var(--color-brand-l) var(--color-brand-c) var(--color-brand-h));
10
+ --color-primary-foreground: oklch(0.98 0 0);
11
+
12
+ /* Neutral surface tokens (with subtle hue, not pure gray) */
13
+ --color-surface: oklch(0.985 0.003 262);
14
+ --color-surface-elevated: oklch(1 0 0);
15
+ --color-muted: oklch(0.94 0.004 262);
16
+ --color-muted-foreground: oklch(0.52 0.012 262);
17
+ --color-border: oklch(0.88 0.006 262);
18
+
19
+ /* Spacing tokens (4px baseline) */
20
+ --space-1: 4px;
21
+ --space-2: 8px;
22
+ --space-3: 12px;
23
+ --space-4: 16px;
24
+ --space-5: 20px;
25
+ --space-6: 24px;
26
+ --space-8: 32px;
27
+ --space-10: 40px;
28
+ --space-12: 48px;
29
+ --space-16: 64px;
30
+ --space-20: 80px;
31
+ --space-24: 96px;
32
+ --space-section: clamp(64px, 10vw, 120px);
33
+
34
+ /* Font tokens */
35
+ --font-heading: var(--font-geist, 'Geist', system-ui, sans-serif);
36
+ --font-body: var(--font-geist, 'Geist', system-ui, sans-serif);
37
+
38
+ /* Text size tokens */
39
+ --text-xs: 0.75rem;
40
+ --text-sm: 0.875rem;
41
+ --text-base: 1rem;
42
+ --text-lg: 1.125rem;
43
+ --text-xl: 1.25rem;
44
+ --text-2xl: 1.5rem;
45
+ --text-3xl: 1.875rem;
46
+ --text-4xl: 2.25rem;
47
+ --text-5xl: 3rem;
48
+ }
49
+
50
+ .dark {
51
+ /* Dark mode semantic tokens */
52
+ --color-surface: oklch(0.13 0.008 262);
53
+ --color-surface-elevated: oklch(0.18 0.007 262);
54
+ --color-muted: oklch(0.22 0.007 262);
55
+ --color-muted-foreground: oklch(0.62 0.010 262);
56
+ --color-border: oklch(0.28 0.008 262);
57
+ }
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cogito.ai/cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "description": "AgentDock CLI – scaffold projects for humans and AI agents",
6
6
  "publishConfig": {