@cogito.ai/cli 0.4.1 → 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 (105) 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 +127 -1
  16. package/dist/templates/web-nextjs/apps/web/messages/zh.json +127 -1
  17. package/dist/templates/web-nextjs/apps/web/next-env.d.ts +1 -1
  18. package/dist/templates/web-nextjs/apps/web/next.config.ts +3 -3
  19. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/forgot-password/page.tsx +265 -0
  20. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/login/page.tsx +20 -4
  21. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/reset-password/page.tsx +115 -0
  22. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/signup/page.tsx +18 -17
  23. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/dashboard/page.tsx +1 -5
  24. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/settings/layout.tsx +5 -0
  25. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/settings/page.tsx +9 -0
  26. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/settings/profile/page.tsx +91 -0
  27. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/about/page.tsx +22 -0
  28. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/globals.css +17 -5
  29. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/help/page.tsx +21 -0
  30. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/layout.tsx +10 -8
  31. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/page.tsx +22 -6
  32. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/privacy/page.tsx +14 -15
  33. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/terms/page.tsx +1 -5
  34. package/dist/templates/web-nextjs/apps/web/src/app/auth/callback/route.ts +7 -2
  35. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/app-sidebar.tsx +37 -137
  36. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/chart-area-interactive.tsx +122 -146
  37. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/data-table.tsx +84 -149
  38. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-documents.tsx +7 -16
  39. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-main.tsx +4 -4
  40. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-secondary.tsx +4 -4
  41. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-user.tsx +17 -33
  42. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/page.tsx +10 -13
  43. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/section-cards.tsx +5 -9
  44. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/site-header.tsx +6 -7
  45. package/dist/templates/web-nextjs/apps/web/src/components/landing/features.tsx +63 -0
  46. package/dist/templates/web-nextjs/apps/web/src/components/landing/footer.tsx +48 -0
  47. package/dist/templates/web-nextjs/apps/web/src/components/landing/header.tsx +97 -0
  48. package/dist/templates/web-nextjs/apps/web/src/components/landing/hero.tsx +45 -0
  49. package/dist/templates/web-nextjs/apps/web/src/components/landing/how-it-works.tsx +35 -0
  50. package/dist/templates/web-nextjs/apps/web/src/components/landing/pricing-teaser.tsx +23 -0
  51. package/dist/templates/web-nextjs/apps/web/src/components/profile/profile-form.tsx +66 -0
  52. package/dist/templates/web-nextjs/apps/web/src/components/providers/theme-provider.tsx +16 -0
  53. package/dist/templates/web-nextjs/apps/web/src/components/ui/alert-dialog.tsx +32 -49
  54. package/dist/templates/web-nextjs/apps/web/src/components/ui/alert.tsx +16 -23
  55. package/dist/templates/web-nextjs/apps/web/src/components/ui/avatar.tsx +25 -38
  56. package/dist/templates/web-nextjs/apps/web/src/components/ui/badge.tsx +16 -18
  57. package/dist/templates/web-nextjs/apps/web/src/components/ui/breadcrumb.tsx +19 -26
  58. package/dist/templates/web-nextjs/apps/web/src/components/ui/button.tsx +23 -24
  59. package/dist/templates/web-nextjs/apps/web/src/components/ui/card.tsx +19 -36
  60. package/dist/templates/web-nextjs/apps/web/src/components/ui/chart.tsx +60 -94
  61. package/dist/templates/web-nextjs/apps/web/src/components/ui/checkbox.tsx +8 -11
  62. package/dist/templates/web-nextjs/apps/web/src/components/ui/collapsible.tsx +5 -17
  63. package/dist/templates/web-nextjs/apps/web/src/components/ui/command.tsx +25 -48
  64. package/dist/templates/web-nextjs/apps/web/src/components/ui/dialog.tsx +21 -35
  65. package/dist/templates/web-nextjs/apps/web/src/components/ui/drawer.tsx +24 -35
  66. package/dist/templates/web-nextjs/apps/web/src/components/ui/dropdown-menu.tsx +26 -55
  67. package/dist/templates/web-nextjs/apps/web/src/components/ui/field.tsx +62 -76
  68. package/dist/templates/web-nextjs/apps/web/src/components/ui/form.tsx +19 -34
  69. package/dist/templates/web-nextjs/apps/web/src/components/ui/input-otp.tsx +13 -20
  70. package/dist/templates/web-nextjs/apps/web/src/components/ui/input.tsx +6 -6
  71. package/dist/templates/web-nextjs/apps/web/src/components/ui/label.tsx +6 -6
  72. package/dist/templates/web-nextjs/apps/web/src/components/ui/pagination.tsx +21 -42
  73. package/dist/templates/web-nextjs/apps/web/src/components/ui/popover.tsx +16 -31
  74. package/dist/templates/web-nextjs/apps/web/src/components/ui/progress.tsx +5 -8
  75. package/dist/templates/web-nextjs/apps/web/src/components/ui/radio-group.tsx +8 -8
  76. package/dist/templates/web-nextjs/apps/web/src/components/ui/scroll-area.tsx +10 -12
  77. package/dist/templates/web-nextjs/apps/web/src/components/ui/select.tsx +26 -41
  78. package/dist/templates/web-nextjs/apps/web/src/components/ui/separator.tsx +7 -7
  79. package/dist/templates/web-nextjs/apps/web/src/components/ui/sheet.tsx +29 -38
  80. package/dist/templates/web-nextjs/apps/web/src/components/ui/sidebar.tsx +157 -189
  81. package/dist/templates/web-nextjs/apps/web/src/components/ui/skeleton.tsx +3 -3
  82. package/dist/templates/web-nextjs/apps/web/src/components/ui/slider.tsx +10 -15
  83. package/dist/templates/web-nextjs/apps/web/src/components/ui/sonner.tsx +13 -7
  84. package/dist/templates/web-nextjs/apps/web/src/components/ui/switch.tsx +9 -9
  85. package/dist/templates/web-nextjs/apps/web/src/components/ui/table.tsx +24 -48
  86. package/dist/templates/web-nextjs/apps/web/src/components/ui/tabs.tsx +21 -31
  87. package/dist/templates/web-nextjs/apps/web/src/components/ui/textarea.tsx +5 -5
  88. package/dist/templates/web-nextjs/apps/web/src/components/ui/theme-toggle.tsx +23 -0
  89. package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle-group.tsx +15 -16
  90. package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle.tsx +14 -15
  91. package/dist/templates/web-nextjs/apps/web/src/components/ui/tooltip.tsx +8 -12
  92. package/dist/templates/web-nextjs/apps/web/src/core/repositories/IAuthRepository.ts +5 -0
  93. package/dist/templates/web-nextjs/apps/web/src/core/types/auth.ts +1 -3
  94. package/dist/templates/web-nextjs/apps/web/src/features/auth/__contract__.ts +6 -0
  95. package/dist/templates/web-nextjs/apps/web/src/features/auth/actions.ts +126 -1
  96. package/dist/templates/web-nextjs/apps/web/src/features/auth/index.ts +12 -1
  97. package/dist/templates/web-nextjs/apps/web/src/features/auth/server.ts +3 -0
  98. package/dist/templates/web-nextjs/apps/web/src/hooks/use-mobile.ts +4 -4
  99. package/dist/templates/web-nextjs/apps/web/src/i18n/config.ts +1 -1
  100. package/dist/templates/web-nextjs/apps/web/src/infra/db/SupabaseAuthRepository.ts +73 -4
  101. package/dist/templates/web-nextjs/apps/web/src/infra/db/client.ts +1 -4
  102. package/dist/templates/web-nextjs/apps/web/src/lib/utils.ts +2 -2
  103. package/dist/templates/web-nextjs/apps/web/src/lib/validations/auth.ts +34 -0
  104. package/dist/templates/web-nextjs/apps/web/src/styles/tokens.css +58 -0
  105. 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 } 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__'
@@ -84,3 +91,121 @@ export async function signInWithGithubForLocale(
84
91
  return { data: null, error: msg }
85
92
  }
86
93
  }
94
+
95
+ export async function requestPasswordReset(
96
+ _prevState: ActionResult | null,
97
+ formData: FormData,
98
+ ): Promise<ActionResult<void>> {
99
+ const parsed = forgotPasswordSchema.safeParse({
100
+ email: formData.get('email'),
101
+ })
102
+
103
+ if (!parsed.success) {
104
+ return { data: null, error: parsed.error.issues[0]?.message ?? '输入无效' }
105
+ }
106
+
107
+ const repo = getAuthRepository()
108
+ const appUrl = process.env.NEXT_PUBLIC_APP_URL ?? 'http://localhost:3000'
109
+ const locale = normalizeLocale(formData.get('locale'))
110
+ const redirectTo = `${appUrl}/auth/callback?next=/${locale}/reset-password`
111
+
112
+ // Always return success to prevent email enumeration
113
+ await repo.requestPasswordReset(parsed.data.email, redirectTo)
114
+
115
+ return { data: undefined as void, error: null }
116
+ }
117
+
118
+ export async function resetPassword(
119
+ _prevState: ActionResult | null,
120
+ formData: FormData,
121
+ ): Promise<ActionResult<void>> {
122
+ const parsed = resetPasswordSchema.safeParse({
123
+ password: formData.get('password'),
124
+ confirmPassword: formData.get('confirmPassword'),
125
+ })
126
+
127
+ if (!parsed.success) {
128
+ return { data: null, error: parsed.error.issues[0]?.message ?? '输入无效' }
129
+ }
130
+
131
+ const repo = getAuthRepository()
132
+ const result = await repo.resetPassword(parsed.data.password)
133
+
134
+ if (result.error) {
135
+ return { data: null, error: result.error }
136
+ }
137
+
138
+ const locale = normalizeLocale(formData.get('locale'))
139
+ redirect(`/${locale}/login`)
140
+ }
141
+
142
+ export async function updateDisplayName(
143
+ _prevState: ActionResult | null,
144
+ formData: FormData,
145
+ ): Promise<ActionResult<void>> {
146
+ const parsed = displayNameSchema.safeParse({
147
+ name: formData.get('name'),
148
+ })
149
+
150
+ if (!parsed.success) {
151
+ return { data: null, error: parsed.error.issues[0]?.message ?? '输入无效' }
152
+ }
153
+
154
+ const repo = getAuthRepository()
155
+ const result = await repo.updateDisplayName(parsed.data.name)
156
+
157
+ if (result.error) {
158
+ return { data: null, error: result.error }
159
+ }
160
+
161
+ return { data: undefined as void, error: null }
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
+ }
@@ -1 +1,12 @@
1
- export { signIn, signUp, signOut, signInWithGithub, signInWithGithubForLocale } from './actions'
1
+ export {
2
+ signIn,
3
+ signUp,
4
+ signOut,
5
+ signInWithGithub,
6
+ signInWithGithubForLocale,
7
+ requestPasswordReset,
8
+ resetPassword,
9
+ updateDisplayName,
10
+ sendPasswordResetOTP,
11
+ resetPasswordWithOTP,
12
+ } from './actions'
@@ -1,9 +1,12 @@
1
1
  import { cache } from 'react'
2
+ // eslint-disable-next-line no-restricted-imports -- Infrastructure helper for reading current session; returns raw Supabase user with metadata
2
3
  import { getServerClient } from '@/infra/db/client'
3
4
 
4
5
  /**
5
6
  * Returns the current authenticated user for the active request.
6
7
  * Wrapped in React cache() so repeated reads in one request are deduplicated.
8
+ * Note: This is an infrastructure helper that returns the raw Supabase user
9
+ * object (including user_metadata) for use in Server Components.
7
10
  */
8
11
  export const getCurrentUser = cache(async () => {
9
12
  const supabase = await getServerClient()
@@ -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
  }
@@ -60,4 +60,73 @@ export class SupabaseAuthRepository implements IAuthRepository {
60
60
  }
61
61
  return { url: data.url }
62
62
  }
63
+
64
+ async updateDisplayName(name: string): Promise<AuthResult> {
65
+ const supabase = await getServerClient()
66
+ const { error } = await supabase.auth.updateUser({
67
+ data: { display_name: name },
68
+ })
69
+ if (error) {
70
+ return { user: null, error: error.message }
71
+ }
72
+ return { user: null, error: null }
73
+ }
74
+
75
+ async requestPasswordReset(email: string, redirectTo: string): Promise<void> {
76
+ const supabase = await getServerClient()
77
+ await supabase.auth.resetPasswordForEmail(email, { redirectTo })
78
+ }
79
+
80
+ async resetPassword(password: string): Promise<AuthResult> {
81
+ const supabase = await getServerClient()
82
+ const { error } = await supabase.auth.updateUser({ password })
83
+ if (error) {
84
+ return { user: null, error: error.message }
85
+ }
86
+ return { user: null, error: null }
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
+ }
63
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))
@@ -16,5 +16,39 @@ export const signUpSchema = z
16
16
  path: ['confirmPassword'],
17
17
  })
18
18
 
19
+ export const forgotPasswordSchema = z.object({
20
+ email: z.string().email('请输入有效邮箱'),
21
+ })
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
+
35
+ export const resetPasswordSchema = z
36
+ .object({
37
+ password: z.string().min(8, '密码至少 8 位'),
38
+ confirmPassword: z.string(),
39
+ })
40
+ .refine((data) => data.password === data.confirmPassword, {
41
+ message: '两次密码不一致',
42
+ path: ['confirmPassword'],
43
+ })
44
+
45
+ export const displayNameSchema = z.object({
46
+ name: z.string().min(1, '显示名不能为空').max(50, '显示名最多 50 字符'),
47
+ })
48
+
19
49
  export type SignInInput = z.infer<typeof signInSchema>
20
50
  export type SignUpInput = z.infer<typeof signUpSchema>
51
+ export type ForgotPasswordInput = z.infer<typeof forgotPasswordSchema>
52
+ export type ResetPasswordWithOTPInput = z.infer<typeof resetPasswordWithOTPSchema>
53
+ export type ResetPasswordInput = z.infer<typeof resetPasswordSchema>
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.1",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "description": "AgentDock CLI – scaffold projects for humans and AI agents",
6
6
  "publishConfig": {