@coze-arch/cli 0.0.7 → 0.0.8-alpha.9a0dda

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 (36) hide show
  1. package/lib/__templates__/expo/AGENTS.md +194 -17
  2. package/lib/__templates__/expo/README.md +194 -17
  3. package/lib/__templates__/expo/client/app/+not-found.tsx +4 -19
  4. package/lib/__templates__/expo/client/app/_layout.tsx +16 -22
  5. package/lib/__templates__/expo/client/components/ColorSchemeUpdater.tsx +43 -0
  6. package/lib/__templates__/expo/client/components/Provider.tsx +18 -0
  7. package/lib/__templates__/expo/client/components/Screen.tsx +1 -1
  8. package/lib/__templates__/expo/client/eslint.config.mjs +1 -0
  9. package/lib/__templates__/expo/client/global.css +267 -0
  10. package/lib/__templates__/expo/client/metro.config.js +8 -1
  11. package/lib/__templates__/expo/client/package.json +5 -2
  12. package/lib/__templates__/expo/client/screens/demo/index.tsx +7 -13
  13. package/lib/__templates__/expo/client/scripts/formatter.mjs +78 -0
  14. package/lib/__templates__/expo/client/scripts/reporter.mjs +1358 -0
  15. package/lib/__templates__/expo/client/scripts/stylish-formatter.mjs +153 -0
  16. package/lib/__templates__/expo/client/scripts/text-table.mjs +68 -0
  17. package/lib/__templates__/expo/client/uniwind-types.d.ts +10 -0
  18. package/lib/__templates__/expo/package.json +4 -1
  19. package/lib/__templates__/expo/pnpm-lock.yaml +510 -51
  20. package/lib/__templates__/expo/server/package.json +2 -1
  21. package/lib/__templates__/nextjs/scripts/build.sh +2 -2
  22. package/lib/__templates__/nextjs/scripts/dev.sh +1 -1
  23. package/lib/__templates__/nuxt-vue/nuxt.config.ts +13 -0
  24. package/lib/__templates__/nuxt-vue/scripts/build.sh +1 -1
  25. package/lib/__templates__/nuxt-vue/scripts/dev.sh +1 -1
  26. package/lib/__templates__/taro/eslint.config.mjs +132 -123
  27. package/lib/__templates__/vite/scripts/build.sh +2 -2
  28. package/lib/__templates__/vite/scripts/dev.sh +1 -1
  29. package/lib/cli.js +4236 -488
  30. package/package.json +3 -1
  31. package/lib/__templates__/expo/client/components/ThemedText.tsx +0 -33
  32. package/lib/__templates__/expo/client/components/ThemedView.tsx +0 -37
  33. package/lib/__templates__/expo/client/constants/theme.ts +0 -177
  34. package/lib/__templates__/expo/client/hooks/useColorScheme.tsx +0 -48
  35. package/lib/__templates__/expo/client/hooks/useTheme.ts +0 -33
  36. package/lib/__templates__/expo/client/screens/demo/styles.ts +0 -28
@@ -7,33 +7,214 @@
7
7
  - Expo 代码在 client 目录,Express.js 代码在 server 目录
8
8
  - 本模板默认无 Tab Bar,可按需改造
9
9
 
10
- 目录结构说明
11
-
12
- ├── server/ # 服务端代码根目录 (Express.js)
13
- | ├── src/
14
- │ │ └── index.ts # Express 入口文件
15
- | └── package.json # 服务端 package.json
16
10
  ├── client/ # React Native 前端代码
17
11
  │ ├── app/ # Expo Router 路由目录(仅路由配置)
18
12
  │ │ ├── _layout.tsx # 根布局文件(必需,务必阅读)
19
- │ │ ├── home.tsx # 首页
20
- │ │ └── index.tsx # re-export home.tsx
13
+ │ │ └── index.tsx # 首页
21
14
  │ ├── screens/ # 页面实现目录(与 app/ 路由对应)
22
- │ │ └── demo/ # demo 示例页面
23
- │ │ ├── index.tsx # 页面组件实现
24
- │ │ └── styles.ts # 页面样式
15
+ │ │ └── demo/ # 示例页面
16
+ │ │ └── index.tsx
25
17
  │ ├── components/ # 可复用组件
26
18
  │ │ └── Screen.tsx # 页面容器组件(必用)
27
19
  │ ├── hooks/ # 自定义 Hooks
28
20
  │ ├── contexts/ # React Context 代码
29
- │ ├── constants/ # 常量定义(如主题配置)
30
21
  │ ├── utils/ # 工具函数
31
22
  │ ├── assets/ # 静态资源
32
23
  | └── package.json # Expo 应用 package.json
24
+ ├── server/ # 服务端代码根目录 (Express.js)
25
+ | ├── src/
26
+ │ │ └── index.ts # 服务端入口文件
27
+ | └── package.json # 服务端 package.json
33
28
  ├── package.json
34
29
  ├── .cozeproj # 预置脚手架脚本(禁止修改)
35
30
  └── .coze # 配置文件(禁止修改)
36
31
 
32
+ ## 样式方案
33
+
34
+ 基于 tailwindcss 进行样式开发(底层基于 Uniwind)
35
+
36
+ 写法示例:
37
+
38
+ ```tsx
39
+ <View className="flex-1 bg-white dark:bg-gray-900 p-4"></View>
40
+ ```
41
+
42
+ ```tsx
43
+ <Text
44
+ className="text-lg font-bold text-gray-900 dark:text-white"
45
+ selectionColorClassName="accent-blue-500"
46
+ >
47
+ Hello World
48
+ </Text>
49
+ ```
50
+
51
+ Uniwind 官方文档:https://docs.uniwind.dev/llms.txt
52
+
53
+ ## 如何进行静态校验(TSC + ESLint)
54
+
55
+ ```bash
56
+ # 对 client 和 server 目录同时进行校验
57
+ npm run lint
58
+
59
+ # 对 client 目录进行校验
60
+ npm run lint:client
61
+
62
+ # 对 server 目录进行校验
63
+ npm run lint:server
64
+ ```
65
+
66
+ ## 如何修改主题模式(跟随系统、固定暗色、固定亮色)
67
+
68
+ 默认为跟随系统,如果用户明确指定为“暗色”或“亮色”,需要修改 `client/components/ColorSchemeUpdater.tsx` 的 `DEFAULT_THEME` 变量为合适的值
69
+
70
+ ## 路由及 Tab Bar 实现规范
71
+
72
+ ### 方案一:无 Tab Bar(Stack 导航)
73
+
74
+ 适用于线性流程应用,采用简化的目录结构:
75
+
76
+ ```
77
+ client/app/
78
+ ├── _layout.tsx # 根布局(Stack 导航配置)
79
+ ├── index.tsx # 应用入口
80
+ ├── detail.tsx # 详情页(通过 params 传递数据)
81
+ └── +not-found.tsx # 404 页面
82
+ ```
83
+
84
+ **根布局配置** `client/app/_layout.tsx`:
85
+ ```tsx
86
+ import { Stack } from 'expo-router';
87
+
88
+ export default function RootLayout() {
89
+ return (
90
+ <Stack screenOptions={{ headerShown: false }}>
91
+ <Stack.Screen name="index" />
92
+ <Stack.Screen name="detail" />
93
+ </Stack>
94
+ );
95
+ }
96
+ ```
97
+
98
+ **应用入口** `client/app/index.tsx`:
99
+ ```tsx
100
+ export { default } from "@/screens/home";
101
+ ```
102
+ > **禁止事项**:无 Tab Bar 场景下,不得创建 `(tabs)` 目录。
103
+
104
+ ### 方案二:有 Tab Bar(Tabs 导航)
105
+
106
+ 采用路由分组实现底部导航栏:
107
+ ```
108
+ client/app/
109
+ ├── _layout.tsx # 根布局
110
+ ├── (tabs)/
111
+ │ ├── _layout.tsx # Tab 导航配置
112
+ │ ├── index.tsx # 默认 Tab(必须存在)
113
+ │ ├── discover.tsx # 发现页
114
+ │ └── profile.tsx # 个人中心
115
+ ├── detail.tsx # Tab 外的独立页面(通过 params 传递数据)
116
+ └── +not-found.tsx
117
+ ```
118
+ > **⚠️ [CRITICAL]**: `app/index.tsx` 优先级高于 `(tabs)/index.tsx`,会导致首页无 Tab Bar。**当有(tabs)/index.tsx时必须删除 `app/index.tsx`**。
119
+
120
+ **根布局配置** `client/app/_layout.tsx`:
121
+ ```tsx
122
+ import { Stack } from 'expo-router';
123
+
124
+ export default function RootLayout() {
125
+ return (
126
+ <Stack screenOptions={{ headerShown: false }}>
127
+ <Stack.Screen name="(tabs)" />
128
+ <Stack.Screen name="detail" />
129
+ </Stack>
130
+ );
131
+ }
132
+ ```
133
+
134
+ **应用入口** `client/app/(tabs)/index.tsx`:
135
+ ```tsx
136
+ export { default } from "@/screens/home";
137
+ ```
138
+
139
+ **Tab 布局配置** `client/app/(tabs)/_layout.tsx`:
140
+
141
+ ```tsx
142
+ import { Tabs } from 'expo-router';
143
+ import { Platform } from 'react-native';
144
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
145
+ import { FontAwesome6 } from '@expo/vector-icons';
146
+ import { useCSSVariable } from 'uniwind';
147
+
148
+ export default function TabLayout() {
149
+ const insets = useSafeAreaInsets();
150
+ const [
151
+ background,
152
+ muted,
153
+ accent,
154
+ ] = useCSSVariable([
155
+ '--color-background',
156
+ '--color-muted',
157
+ '--color-accent',
158
+ ]);
159
+
160
+ return (
161
+ <Tabs
162
+ screenOptions={{
163
+ headerShown: false,
164
+ tabBarStyle: {
165
+ backgroundColor: background,
166
+ // 移动端:标准高度 50px + 底部安全区
167
+ // Web端:固定60px,无需安全区
168
+ height: Platform.OS === 'web' ? 60 : 50 + insets.bottom,
169
+ // 移动端:内容区域底部 padding 防止内容被遮挡
170
+ paddingBottom: Platform.OS === 'web' ? 0 : insets.bottom,
171
+ },
172
+ tabBarActiveTintColor: accent,
173
+ tabBarInactiveTintColor: muted,
174
+ tabBarItemStyle: {
175
+ // **Web 兼容性强制规范**:Web 端必须显式指定 item 高度,防止 Tab Bar 高度塌陷或图标显示异常
176
+ height: Platform.OS === 'web' ? 60 : undefined,
177
+ },
178
+ }}
179
+ >
180
+ {/* name 必须与文件名完全一致 */}
181
+ <Tabs.Screen
182
+ name="index"
183
+ options={{
184
+ title: '首页',
185
+ tabBarIcon: ({ color }) => (
186
+ <FontAwesome6 name="house" size={20} color={color} />
187
+ ),
188
+ }}
189
+ />
190
+ <Tabs.Screen
191
+ name="discover"
192
+ options={{
193
+ title: '发现',
194
+ tabBarIcon: ({ color }) => (
195
+ <FontAwesome6 name="compass" size={20} color={color} />
196
+ ),
197
+ }}
198
+ />
199
+ <Tabs.Screen
200
+ name="profile"
201
+ options={{
202
+ title: '我的',
203
+ tabBarIcon: ({ color }) => (
204
+ <FontAwesome6 name="user" size={20} color={color} />
205
+ ),
206
+ }}
207
+ />
208
+ </Tabs>
209
+ );
210
+ }
211
+ ```
212
+
213
+ **Tab 页面文件** `client/app/(tabs)/index.tsx`:
214
+ ```tsx
215
+ export { default } from "@/screens/home";
216
+ ```
217
+
37
218
  ## 依赖管理与模块导入规范
38
219
 
39
220
  ### 依赖安装
@@ -70,8 +251,4 @@ import { Screen } from '../../../components/Screen';
70
251
 
71
252
  ## 本地开发
72
253
 
73
- 运行 coze dev 可以同时启动前端和后端服务,如果端口已占用,该命令会先杀掉占用端口的进程再启动,也可以用来重启前端和后端服务
74
-
75
- ```bash
76
- coze dev
77
- ```
254
+ `coze dev`:用来首次启动前后端服务,也可以用来重启前后端服务(该命令会先尝试杀掉占用端口的进程,再启动服务)
@@ -7,33 +7,214 @@
7
7
  - Expo 代码在 client 目录,Express.js 代码在 server 目录
8
8
  - 本模板默认无 Tab Bar,可按需改造
9
9
 
10
- 目录结构说明
11
-
12
- ├── server/ # 服务端代码根目录 (Express.js)
13
- | ├── src/
14
- │ │ └── index.ts # Express 入口文件
15
- | └── package.json # 服务端 package.json
16
10
  ├── client/ # React Native 前端代码
17
11
  │ ├── app/ # Expo Router 路由目录(仅路由配置)
18
12
  │ │ ├── _layout.tsx # 根布局文件(必需,务必阅读)
19
- │ │ ├── home.tsx # 首页
20
- │ │ └── index.tsx # re-export home.tsx
13
+ │ │ └── index.tsx # 首页
21
14
  │ ├── screens/ # 页面实现目录(与 app/ 路由对应)
22
- │ │ └── demo/ # demo 示例页面
23
- │ │ ├── index.tsx # 页面组件实现
24
- │ │ └── styles.ts # 页面样式
15
+ │ │ └── demo/ # 示例页面
16
+ │ │ └── index.tsx
25
17
  │ ├── components/ # 可复用组件
26
18
  │ │ └── Screen.tsx # 页面容器组件(必用)
27
19
  │ ├── hooks/ # 自定义 Hooks
28
20
  │ ├── contexts/ # React Context 代码
29
- │ ├── constants/ # 常量定义(如主题配置)
30
21
  │ ├── utils/ # 工具函数
31
22
  │ ├── assets/ # 静态资源
32
23
  | └── package.json # Expo 应用 package.json
24
+ ├── server/ # 服务端代码根目录 (Express.js)
25
+ | ├── src/
26
+ │ │ └── index.ts # 服务端入口文件
27
+ | └── package.json # 服务端 package.json
33
28
  ├── package.json
34
29
  ├── .cozeproj # 预置脚手架脚本(禁止修改)
35
30
  └── .coze # 配置文件(禁止修改)
36
31
 
32
+ ## 样式方案
33
+
34
+ 基于 tailwindcss 进行样式开发(底层基于 Uniwind)
35
+
36
+ 写法示例:
37
+
38
+ ```tsx
39
+ <View className="flex-1 bg-white dark:bg-gray-900 p-4"></View>
40
+ ```
41
+
42
+ ```tsx
43
+ <Text
44
+ className="text-lg font-bold text-gray-900 dark:text-white"
45
+ selectionColorClassName="accent-blue-500"
46
+ >
47
+ Hello World
48
+ </Text>
49
+ ```
50
+
51
+ Uniwind 官方文档:https://docs.uniwind.dev/llms.txt
52
+
53
+ ## 如何进行静态校验(TSC + ESLint)
54
+
55
+ ```bash
56
+ # 对 client 和 server 目录同时进行校验
57
+ npm run lint
58
+
59
+ # 对 client 目录进行校验
60
+ npm run lint:client
61
+
62
+ # 对 server 目录进行校验
63
+ npm run lint:server
64
+ ```
65
+
66
+ ## 如何修改主题模式(跟随系统、固定暗色、固定亮色)
67
+
68
+ 默认为跟随系统,如果用户明确指定为“暗色”或“亮色”,需要修改 `client/components/ColorSchemeUpdater.tsx` 的 `DEFAULT_THEME` 变量为合适的值
69
+
70
+ ## 路由及 Tab Bar 实现规范
71
+
72
+ ### 方案一:无 Tab Bar(Stack 导航)
73
+
74
+ 适用于线性流程应用,采用简化的目录结构:
75
+
76
+ ```
77
+ client/app/
78
+ ├── _layout.tsx # 根布局(Stack 导航配置)
79
+ ├── index.tsx # 应用入口
80
+ ├── detail.tsx # 详情页(通过 params 传递数据)
81
+ └── +not-found.tsx # 404 页面
82
+ ```
83
+
84
+ **根布局配置** `client/app/_layout.tsx`:
85
+ ```tsx
86
+ import { Stack } from 'expo-router';
87
+
88
+ export default function RootLayout() {
89
+ return (
90
+ <Stack screenOptions={{ headerShown: false }}>
91
+ <Stack.Screen name="index" />
92
+ <Stack.Screen name="detail" />
93
+ </Stack>
94
+ );
95
+ }
96
+ ```
97
+
98
+ **应用入口** `client/app/index.tsx`:
99
+ ```tsx
100
+ export { default } from "@/screens/home";
101
+ ```
102
+ > **禁止事项**:无 Tab Bar 场景下,不得创建 `(tabs)` 目录。
103
+
104
+ ### 方案二:有 Tab Bar(Tabs 导航)
105
+
106
+ 采用路由分组实现底部导航栏:
107
+ ```
108
+ client/app/
109
+ ├── _layout.tsx # 根布局
110
+ ├── (tabs)/
111
+ │ ├── _layout.tsx # Tab 导航配置
112
+ │ ├── index.tsx # 默认 Tab(必须存在)
113
+ │ ├── discover.tsx # 发现页
114
+ │ └── profile.tsx # 个人中心
115
+ ├── detail.tsx # Tab 外的独立页面(通过 params 传递数据)
116
+ └── +not-found.tsx
117
+ ```
118
+ > **⚠️ [CRITICAL]**: `app/index.tsx` 优先级高于 `(tabs)/index.tsx`,会导致首页无 Tab Bar。**当有(tabs)/index.tsx时必须删除 `app/index.tsx`**。
119
+
120
+ **根布局配置** `client/app/_layout.tsx`:
121
+ ```tsx
122
+ import { Stack } from 'expo-router';
123
+
124
+ export default function RootLayout() {
125
+ return (
126
+ <Stack screenOptions={{ headerShown: false }}>
127
+ <Stack.Screen name="(tabs)" />
128
+ <Stack.Screen name="detail" />
129
+ </Stack>
130
+ );
131
+ }
132
+ ```
133
+
134
+ **应用入口** `client/app/(tabs)/index.tsx`:
135
+ ```tsx
136
+ export { default } from "@/screens/home";
137
+ ```
138
+
139
+ **Tab 布局配置** `client/app/(tabs)/_layout.tsx`:
140
+
141
+ ```tsx
142
+ import { Tabs } from 'expo-router';
143
+ import { Platform } from 'react-native';
144
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
145
+ import { FontAwesome6 } from '@expo/vector-icons';
146
+ import { useCSSVariable } from 'uniwind';
147
+
148
+ export default function TabLayout() {
149
+ const insets = useSafeAreaInsets();
150
+ const [
151
+ background,
152
+ muted,
153
+ accent,
154
+ ] = useCSSVariable([
155
+ '--color-background',
156
+ '--color-muted',
157
+ '--color-accent',
158
+ ]);
159
+
160
+ return (
161
+ <Tabs
162
+ screenOptions={{
163
+ headerShown: false,
164
+ tabBarStyle: {
165
+ backgroundColor: background,
166
+ // 移动端:标准高度 50px + 底部安全区
167
+ // Web端:固定60px,无需安全区
168
+ height: Platform.OS === 'web' ? 60 : 50 + insets.bottom,
169
+ // 移动端:内容区域底部 padding 防止内容被遮挡
170
+ paddingBottom: Platform.OS === 'web' ? 0 : insets.bottom,
171
+ },
172
+ tabBarActiveTintColor: accent,
173
+ tabBarInactiveTintColor: muted,
174
+ tabBarItemStyle: {
175
+ // **Web 兼容性强制规范**:Web 端必须显式指定 item 高度,防止 Tab Bar 高度塌陷或图标显示异常
176
+ height: Platform.OS === 'web' ? 60 : undefined,
177
+ },
178
+ }}
179
+ >
180
+ {/* name 必须与文件名完全一致 */}
181
+ <Tabs.Screen
182
+ name="index"
183
+ options={{
184
+ title: '首页',
185
+ tabBarIcon: ({ color }) => (
186
+ <FontAwesome6 name="house" size={20} color={color} />
187
+ ),
188
+ }}
189
+ />
190
+ <Tabs.Screen
191
+ name="discover"
192
+ options={{
193
+ title: '发现',
194
+ tabBarIcon: ({ color }) => (
195
+ <FontAwesome6 name="compass" size={20} color={color} />
196
+ ),
197
+ }}
198
+ />
199
+ <Tabs.Screen
200
+ name="profile"
201
+ options={{
202
+ title: '我的',
203
+ tabBarIcon: ({ color }) => (
204
+ <FontAwesome6 name="user" size={20} color={color} />
205
+ ),
206
+ }}
207
+ />
208
+ </Tabs>
209
+ );
210
+ }
211
+ ```
212
+
213
+ **Tab 页面文件** `client/app/(tabs)/index.tsx`:
214
+ ```tsx
215
+ export { default } from "@/screens/home";
216
+ ```
217
+
37
218
  ## 依赖管理与模块导入规范
38
219
 
39
220
  ### 依赖安装
@@ -70,8 +251,4 @@ import { Screen } from '../../../components/Screen';
70
251
 
71
252
  ## 本地开发
72
253
 
73
- 运行 coze dev 可以同时启动前端和后端服务,如果端口已占用,该命令会先杀掉占用端口的进程再启动,也可以用来重启前端和后端服务
74
-
75
- ```bash
76
- coze dev
77
- ```
254
+ `coze dev`:用来首次启动前后端服务,也可以用来重启前后端服务(该命令会先尝试杀掉占用端口的进程,再启动服务)
@@ -1,30 +1,15 @@
1
- import { View, Text, StyleSheet } from 'react-native';
1
+ import { View, Text } from 'react-native';
2
2
  import { Link } from 'expo-router';
3
- import { useTheme } from '@/hooks/useTheme';
4
- import { Spacing } from '@/constants/theme';
5
3
 
6
4
  export default function NotFoundScreen() {
7
- const { theme } = useTheme();
8
-
9
5
  return (
10
- <View style={[styles.container, { backgroundColor: theme.backgroundRoot }]}>
11
- <Text>
6
+ <View className="flex-1 justify-center items-center bg-background">
7
+ <Text className="text-foreground">
12
8
  页面不存在
13
9
  </Text>
14
- <Link href="/" style={[styles.gohome]}>
10
+ <Link href="/" className="text-accent mt-6">
15
11
  返回首页
16
12
  </Link>
17
13
  </View>
18
14
  );
19
15
  }
20
-
21
- const styles = StyleSheet.create({
22
- container: {
23
- flex: 1,
24
- justifyContent: 'center',
25
- alignItems: 'center',
26
- },
27
- gohome: {
28
- marginTop: Spacing['2xl'],
29
- },
30
- });
@@ -1,11 +1,10 @@
1
- import { useEffect } from 'react';
2
- import { GestureHandlerRootView } from 'react-native-gesture-handler';
3
1
  import { Stack } from 'expo-router';
4
2
  import { StatusBar } from 'expo-status-bar';
5
3
  import { LogBox } from 'react-native';
6
4
  import Toast from 'react-native-toast-message';
7
- import { AuthProvider } from "@/contexts/AuthContext";
8
- import { ColorSchemeProvider } from '@/hooks/useColorScheme';
5
+ import { Provider } from '@/components/Provider';
6
+
7
+ import '../global.css';
9
8
 
10
9
  LogBox.ignoreLogs([
11
10
  "TurboModuleRegistry.getEnforcing(...): 'RNMapsAirModule' could not be found",
@@ -14,23 +13,18 @@ LogBox.ignoreLogs([
14
13
 
15
14
  export default function RootLayout() {
16
15
  return (
17
- <AuthProvider>
18
- <ColorSchemeProvider>
19
- <GestureHandlerRootView style={{ flex: 1 }}>
20
- <StatusBar style="dark"></StatusBar>
21
- <Stack screenOptions={{
22
- // 设置所有页面的切换动画为从右侧滑入,适用于iOS 和 Android
23
- animation: 'slide_from_right',
24
- gestureEnabled: true,
25
- gestureDirection: 'horizontal',
26
- // 隐藏自带的头部
27
- headerShown: false
28
- }}>
29
- <Stack.Screen name="index" options={{ title: "" }} />
30
- </Stack>
31
- <Toast />
32
- </GestureHandlerRootView>
33
- </ColorSchemeProvider>
34
- </AuthProvider>
16
+ <Provider>
17
+ <Stack
18
+ screenOptions={{
19
+ animation: 'slide_from_right',
20
+ gestureEnabled: true,
21
+ gestureDirection: 'horizontal',
22
+ headerShown: false
23
+ }}
24
+ >
25
+ <Stack.Screen name="index" options={{ title: "" }} />
26
+ </Stack>
27
+ <Toast />
28
+ </Provider>
35
29
  );
36
30
  }
@@ -0,0 +1,43 @@
1
+ import { Fragment, useEffect } from 'react';
2
+ import { ColorSchemeName, Platform } from 'react-native';
3
+ import { Uniwind } from 'uniwind'
4
+
5
+ // system: 跟随系统变化
6
+ // light: 固定为 light 主题
7
+ // dark: 固定为 dark 主题
8
+ const DEFAULT_THEME: 'system' | 'light' | 'dark' = 'system'
9
+
10
+ const WebOnlyColorSchemeUpdater = function ({ children }: { children?: ReactNode }) {
11
+ useEffect(() => {
12
+ Uniwind.setTheme(DEFAULT_THEME);
13
+ }, []);
14
+
15
+ useEffect(() => {
16
+ function handleMessage(e: MessageEvent<{ event: string; colorScheme: ColorSchemeName; } | undefined>) {
17
+ if (e.data?.event === 'coze.workbench.colorScheme') {
18
+ const cs = e.data.colorScheme;
19
+ if (typeof cs === 'string') {
20
+ Uniwind.setTheme(cs);
21
+ }
22
+ }
23
+ }
24
+
25
+ if (Platform.OS === 'web') {
26
+ window.addEventListener('message', handleMessage, false);
27
+ }
28
+
29
+ return () => {
30
+ if (Platform.OS === 'web') {
31
+ window.removeEventListener('message', handleMessage, false);
32
+ }
33
+ }
34
+ }, []);
35
+
36
+ return <Fragment>
37
+ {children}
38
+ </Fragment>
39
+ };
40
+
41
+ export {
42
+ WebOnlyColorSchemeUpdater,
43
+ }
@@ -0,0 +1,18 @@
1
+ import { AuthProvider } from '@/contexts/AuthContext';
2
+ import { type ReactNode } from 'react';
3
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
4
+ import { WebOnlyColorSchemeUpdater } from './ColorSchemeUpdater';
5
+
6
+ function Provider({ children }: { children: ReactNode }) {
7
+ return <WebOnlyColorSchemeUpdater>
8
+ <AuthProvider>
9
+ <GestureHandlerRootView style={{ flex: 1 }}>
10
+ {children}
11
+ </GestureHandlerRootView>
12
+ </AuthProvider>
13
+ </WebOnlyColorSchemeUpdater>
14
+ }
15
+
16
+ export {
17
+ Provider,
18
+ }
@@ -142,7 +142,7 @@ const KeyboardAwareScrollable = ({
142
142
 
143
143
  export const Screen = ({
144
144
  children,
145
- backgroundColor = '#fff',
145
+ backgroundColor = 'var(--background)',
146
146
  statusBarStyle = 'dark',
147
147
  statusBarColor = 'transparent',
148
148
  safeAreaEdges = ['top', 'left', 'right', 'bottom'],
@@ -23,6 +23,7 @@ export default [
23
23
  '**/*.d.ts',
24
24
  'eslint.config.*',
25
25
  'metro.config.*',
26
+ './scripts/**',
26
27
  ],
27
28
  },
28
29
  regexp.configs["flat/recommended"],