@coze-arch/cli 0.0.9 → 0.0.10-alpha.acdcf1

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.
@@ -67,6 +67,10 @@ npm run lint:server
67
67
 
68
68
  默认为跟随系统,如果用户明确指定为“暗色”或“亮色”,需要修改 `client/components/ColorSchemeUpdater.tsx` 的 `DEFAULT_THEME` 变量为合适的值
69
69
 
70
+ ## 如何定制主题 design tokens
71
+
72
+ 当前项目的**设计系统**基于 tailwindcss 实现,核心入口文件为 `client/global.css`,如果需要定制主题,应该**阅读并修改 `client/global.css` 文件**
73
+
70
74
  ## 路由及 Tab Bar 实现规范
71
75
 
72
76
  ### 方案一:无 Tab Bar(Stack 导航)
@@ -82,17 +86,14 @@ client/app/
82
86
  ```
83
87
 
84
88
  **根布局配置** `client/app/_layout.tsx`:
85
- ```tsx
86
- import { Stack } from 'expo-router';
87
89
 
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
- }
90
+ 以下仅为代码片段供写法参考
91
+
92
+ ```tsx
93
+ <Stack screenOptions={{ headerShown: false }}>
94
+ <Stack.Screen name="index" />
95
+ <Stack.Screen name="detail" />
96
+ </Stack>
96
97
  ```
97
98
 
98
99
  **应用入口** `client/app/index.tsx`:
@@ -118,17 +119,14 @@ client/app/
118
119
  > **⚠️ [CRITICAL]**: `app/index.tsx` 优先级高于 `(tabs)/index.tsx`,会导致首页无 Tab Bar。**当有(tabs)/index.tsx时必须删除 `app/index.tsx`**。
119
120
 
120
121
  **根布局配置** `client/app/_layout.tsx`:
121
- ```tsx
122
- import { Stack } from 'expo-router';
123
122
 
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
- }
123
+ 以下仅为代码片段供写法参考
124
+
125
+ ```tsx
126
+ <Stack screenOptions={{ headerShown: false }}>
127
+ <Stack.Screen name="(tabs)" />
128
+ <Stack.Screen name="detail" />
129
+ </Stack>
132
130
  ```
133
131
 
134
132
  **应用入口** `client/app/(tabs)/index.tsx`:
@@ -162,18 +160,11 @@ export default function TabLayout() {
162
160
  backgroundColor: background,
163
161
  borderTopWidth: 1,
164
162
  borderTopColor: border,
165
- // 移动端:标准高度 50px + 底部安全区
166
- // Web端:固定60px,无需安全区
167
- height: Platform.OS === 'web' ? 60 : 50 + insets.bottom,
168
- // 移动端:内容区域底部 padding 防止内容被遮挡
169
- paddingBottom: Platform.OS === 'web' ? 0 : insets.bottom,
163
+ // 通过固定宽度 55 来修正 Web 上的表现
164
+ height: Platform.OS === 'web' ? 55 : 50 + insets.bottom,
170
165
  },
171
166
  tabBarActiveTintColor: accent,
172
167
  tabBarInactiveTintColor: muted,
173
- tabBarItemStyle: {
174
- // Web 端必须显式指定 item 高度,防止 Tab Bar 高度塌陷或图标显示异常
175
- height: Platform.OS === 'web' ? 60 : undefined,
176
- },
177
168
  }}
178
169
  >
179
170
  {/* name 必须与文件名完全一致 */}
@@ -214,6 +205,15 @@ export default function TabLayout() {
214
205
  export { default } from "@/screens/home";
215
206
  ```
216
207
 
208
+ ### 注意事项
209
+
210
+ 在改动 `client/app/_layout.tsx` 前,必须先阅读该文件,再进行修改操作
211
+
212
+ 以下是需要保留的重要逻辑
213
+
214
+ - 保留 global.css 引入(tailwindcss 生效的关键)
215
+ - 保留 Provider 的使用
216
+
217
217
  ## 依赖管理与模块导入规范
218
218
 
219
219
  ### 依赖安装
@@ -67,6 +67,10 @@ npm run lint:server
67
67
 
68
68
  默认为跟随系统,如果用户明确指定为“暗色”或“亮色”,需要修改 `client/components/ColorSchemeUpdater.tsx` 的 `DEFAULT_THEME` 变量为合适的值
69
69
 
70
+ ## 如何定制主题 design tokens
71
+
72
+ 当前项目的**设计系统**基于 tailwindcss 实现,核心入口文件为 `client/global.css`,如果需要定制主题,应该**阅读并修改 `client/global.css` 文件**
73
+
70
74
  ## 路由及 Tab Bar 实现规范
71
75
 
72
76
  ### 方案一:无 Tab Bar(Stack 导航)
@@ -82,17 +86,14 @@ client/app/
82
86
  ```
83
87
 
84
88
  **根布局配置** `client/app/_layout.tsx`:
85
- ```tsx
86
- import { Stack } from 'expo-router';
87
89
 
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
- }
90
+ 以下仅为代码片段供写法参考
91
+
92
+ ```tsx
93
+ <Stack screenOptions={{ headerShown: false }}>
94
+ <Stack.Screen name="index" />
95
+ <Stack.Screen name="detail" />
96
+ </Stack>
96
97
  ```
97
98
 
98
99
  **应用入口** `client/app/index.tsx`:
@@ -118,17 +119,14 @@ client/app/
118
119
  > **⚠️ [CRITICAL]**: `app/index.tsx` 优先级高于 `(tabs)/index.tsx`,会导致首页无 Tab Bar。**当有(tabs)/index.tsx时必须删除 `app/index.tsx`**。
119
120
 
120
121
  **根布局配置** `client/app/_layout.tsx`:
121
- ```tsx
122
- import { Stack } from 'expo-router';
123
122
 
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
- }
123
+ 以下仅为代码片段供写法参考
124
+
125
+ ```tsx
126
+ <Stack screenOptions={{ headerShown: false }}>
127
+ <Stack.Screen name="(tabs)" />
128
+ <Stack.Screen name="detail" />
129
+ </Stack>
132
130
  ```
133
131
 
134
132
  **应用入口** `client/app/(tabs)/index.tsx`:
@@ -162,18 +160,11 @@ export default function TabLayout() {
162
160
  backgroundColor: background,
163
161
  borderTopWidth: 1,
164
162
  borderTopColor: border,
165
- // 移动端:标准高度 50px + 底部安全区
166
- // Web端:固定60px,无需安全区
167
- height: Platform.OS === 'web' ? 60 : 50 + insets.bottom,
168
- // 移动端:内容区域底部 padding 防止内容被遮挡
169
- paddingBottom: Platform.OS === 'web' ? 0 : insets.bottom,
163
+ // 通过固定宽度 55 来修正 Web 上的表现
164
+ height: Platform.OS === 'web' ? 55 : 50 + insets.bottom,
170
165
  },
171
166
  tabBarActiveTintColor: accent,
172
167
  tabBarInactiveTintColor: muted,
173
- tabBarItemStyle: {
174
- // Web 端必须显式指定 item 高度,防止 Tab Bar 高度塌陷或图标显示异常
175
- height: Platform.OS === 'web' ? 60 : undefined,
176
- },
177
168
  }}
178
169
  >
179
170
  {/* name 必须与文件名完全一致 */}
@@ -214,6 +205,15 @@ export default function TabLayout() {
214
205
  export { default } from "@/screens/home";
215
206
  ```
216
207
 
208
+ ### 注意事项
209
+
210
+ 在改动 `client/app/_layout.tsx` 前,必须先阅读该文件,再进行修改操作
211
+
212
+ 以下是需要保留的重要逻辑
213
+
214
+ - 保留 global.css 引入(tailwindcss 生效的关键)
215
+ - 保留 Provider 的使用
216
+
217
217
  ## 依赖管理与模块导入规范
218
218
 
219
219
  ### 依赖安装
@@ -19,3 +19,6 @@ prefer-frozen-lockfile=true
19
19
 
20
20
  # semver 选择最高版本
21
21
  resolution-mode=highest
22
+
23
+ # 不提示 npm 更新
24
+ update-notifier=false
@@ -42,9 +42,13 @@
42
42
 
43
43
  ## 开发规范
44
44
 
45
- - **项目理解加速**:初始可以依赖项目下`package.json`文件理解项目类型,如果没有或无法理解退化成阅读其他文件。
46
- - **Hydration 错误预防**:严禁在 JSX 渲染逻辑中直接使用 typeof window、Date.now()、Math.random() 等动态数据。必须使用 'use client' 并配合 useEffect + useState 确保动态内容仅在客户端挂载后渲染;同时严禁非法 HTML 嵌套(如 <p> 嵌套 <div>)。
45
+ ### Hydration 问题防范
47
46
 
47
+ 1. 严禁在 JSX 渲染逻辑中直接使用 typeof window、Date.now()、Math.random() 等动态数据。**必须使用 'use client' 并配合 useEffect + useState 确保动态内容仅在客户端挂载后渲染**;同时严禁非法 HTML 嵌套(如 <p> 嵌套 <div>)。
48
+ 2. **禁止使用 head 标签**,优先使用 metadata,详见文档:https://nextjs.org/docs/app/api-reference/functions/generate-metadata
49
+ 1. 三方 CSS、字体等资源在 `globals.css` 中顶部通过 `@import` 引入
50
+ 2. preload, preconnect, dns-prefetch 通过 ReactDOM 的 preload、preconnect、dns-prefetch 方法引入
51
+ 3. json-ld 可阅读 https://nextjs.org/docs/app/guides/json-ld
48
52
 
49
53
  ## UI 设计与组件规范 (UI & Styling Standards)
50
54
 
@@ -21,3 +21,6 @@ prefer-frozen-lockfile=true
21
21
 
22
22
  # 如果 lockfile 存在但过期,更新而不是失败
23
23
  resolution-mode=highest
24
+
25
+ # 不提示 npm 更新
26
+ update-notifier=false
@@ -5,6 +5,12 @@ import { defineConfig, globalIgnores } from 'eslint/config';
5
5
  const eslintConfig = defineConfig([
6
6
  ...nextVitals,
7
7
  ...nextTs,
8
+ {
9
+ rules: {
10
+ 'react-hooks/set-state-in-effect': 'off',
11
+ '@next/next/no-head-element': 'error',
12
+ },
13
+ },
8
14
  // Override default ignores of eslint-config-next.
9
15
  globalIgnores([
10
16
  // Default ignores of eslint-config-next:
@@ -21,3 +21,6 @@ prefer-frozen-lockfile=true
21
21
 
22
22
  # 如果 lockfile 存在但过期,更新而不是失败
23
23
  resolution-mode=highest
24
+
25
+ # 不提示 npm 更新
26
+ update-notifier=false
@@ -16,3 +16,6 @@ lockfile=true
16
16
  prefer-frozen-lockfile=true
17
17
 
18
18
  resolution-mode=highest
19
+
20
+ # 不提示 npm 更新
21
+ update-notifier=false
@@ -9,6 +9,40 @@ const compat = new FlatCompat({
9
9
  baseDirectory: __dirname,
10
10
  });
11
11
 
12
+ const REMOTE_CSS_IMPORT_PATTERN =
13
+ /@import\s+(?:url\(\s*['"]?((?:https?:)?\/\/[^'")\s]+)['"]?\s*\)|['"]((?:https?:)?\/\/[^'"\s]+)['"])/g;
14
+
15
+ const cssImportGuardPlugin = {
16
+ processors: {
17
+ css: {
18
+ preprocess(text) {
19
+ const lines = text.split('\n');
20
+ const virtualLines = lines.map(line => {
21
+ const matches = [...line.matchAll(REMOTE_CSS_IMPORT_PATTERN)];
22
+
23
+ if (matches.length === 0) {
24
+ return '';
25
+ }
26
+
27
+ return matches
28
+ .map(match => {
29
+ const url = match[1] ?? match[2];
30
+
31
+ return `__cssExternalImport(${JSON.stringify(url)});`;
32
+ })
33
+ .join(' ');
34
+ });
35
+
36
+ return [virtualLines.join('\n')];
37
+ },
38
+ postprocess(messages) {
39
+ return messages.flat();
40
+ },
41
+ supportsAutofix: false,
42
+ },
43
+ },
44
+ };
45
+
12
46
  const baseRestrictedSyntaxRules = [
13
47
  {
14
48
  selector: "MemberExpression[object.name='process'][property.name='env']",
@@ -72,6 +106,12 @@ const baseRestrictedSyntaxRules = [
72
106
  ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/\\[[^\\]]*&[^\\]]*~[^\\]]*\\]/], TemplateElement[value.raw=/\\[[^\\]]*&[^\\]]*~[^\\]]*\\]/])",
73
107
  message: '微信小程序兼容性:WXSS 不支持 ~(会导致预览上传失败)。',
74
108
  },
109
+ {
110
+ selector:
111
+ "CallExpression[callee.name='__cssExternalImport'] > Literal[value=/^(?:https?:)?\\/\\//]",
112
+ message:
113
+ '微信小程序兼容性:禁止在 CSS/WXSS 中使用远程 @import(如 Google Fonts)。请改为本地静态资源或删除该导入。',
114
+ },
75
115
  {
76
116
  selector:
77
117
  "JSXAttribute[name.name='color'][value.type='Literal'][value.value='currentColor'], JSXAttribute[name.name='color'] > JSXExpressionContainer > Literal[value='currentColor']",
@@ -173,6 +213,17 @@ export default [
173
213
  ],
174
214
  },
175
215
  },
216
+ {
217
+ files: ['src/**/*.css'],
218
+ plugins: {
219
+ local: cssImportGuardPlugin,
220
+ },
221
+ processor: 'local/css',
222
+ rules: {
223
+ 'no-undef': 'off',
224
+ 'no-restricted-syntax': ['error', ...baseRestrictedSyntaxRules],
225
+ },
226
+ },
176
227
  {
177
228
  files: ['src/pages/**/*.tsx'],
178
229
  rules: {
@@ -17,9 +17,9 @@
17
17
  "preinstall": "npx only-allow pnpm",
18
18
  "postinstall": "weapp-tw patch",
19
19
  "kill:all": "pkill -9 -f 'concurrently' 2>/dev/null || true; pkill -9 -f 'nest start' 2>/dev/null || true; pkill -9 -f 'taro build' 2>/dev/null || true; pkill -9 -f 'node.*dev' 2>/dev/null || true; echo 'All dev processes cleaned'",
20
- "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
21
- "lint:build": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --max-warnings=0",
22
- "lint:fix": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
20
+ "lint": "eslint \"src/**/*.{js,jsx,ts,tsx,css}\"",
21
+ "lint:build": "eslint \"src/**/*.{js,jsx,ts,tsx,css}\" --max-warnings=0",
22
+ "lint:fix": "eslint \"src/**/*.{js,jsx,ts,tsx,css}\" --fix",
23
23
  "new": "taro new",
24
24
  "preview:tt": "taro build --type tt --preview",
25
25
  "preview:weapp": "taro build --type weapp --preview",
@@ -27,7 +27,7 @@
27
27
  "validate": "pnpm exec concurrently --kill-others-on-fail --kill-signal SIGKILL -n lint,tsc -c red,blue \"pnpm lint:build\" \"pnpm tsc\""
28
28
  },
29
29
  "lint-staged": {
30
- "src/**/*.{js,jsx,ts,tsx}": [
30
+ "src/**/*.{js,jsx,ts,tsx,css}": [
31
31
  "eslint"
32
32
  ]
33
33
  },
@@ -12,12 +12,5 @@
12
12
  "minified": false
13
13
  },
14
14
  "compileType": "miniprogram",
15
- "packOptions": {
16
- "ignore": [
17
- {
18
- "type": "folder",
19
- "value": "assets"
20
- }
21
- ]
22
- }
15
+ "packOptions": {"ignore": [{"type": "folder","value": "./assets"}]}
23
16
  }
@@ -21,3 +21,6 @@ prefer-frozen-lockfile=true
21
21
 
22
22
  # 如果 lockfile 存在但过期,更新而不是失败
23
23
  resolution-mode=highest
24
+
25
+ # 不提示 npm 更新
26
+ update-notifier=false
package/lib/cli.js CHANGED
@@ -2106,7 +2106,7 @@ const EventBuilder = {
2106
2106
  };
2107
2107
 
2108
2108
  var name = "@coze-arch/cli";
2109
- var version = "0.0.9";
2109
+ var version = "0.0.10-alpha.acdcf1";
2110
2110
  var description = "coze coding devtools cli";
2111
2111
  var license = "MIT";
2112
2112
  var author = "fanwenjie.fe@bytedance.com";
@@ -2166,6 +2166,7 @@ var devDependencies = {
2166
2166
  "@coze-coding/lambda": "workspace:*",
2167
2167
  "@inquirer/prompts": "^3.2.0",
2168
2168
  "@playwright/test": "~1.55.0",
2169
+ "@slardar/rd-cli": "^0.10.3",
2169
2170
  "@types/debug": "^4.1.12",
2170
2171
  "@types/ejs": "^3.1.5",
2171
2172
  "@types/iarna__toml": "^2.0.5",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-arch/cli",
3
- "version": "0.0.9",
3
+ "version": "0.0.10-alpha.acdcf1",
4
4
  "private": false,
5
5
  "description": "coze coding devtools cli",
6
6
  "license": "MIT",
@@ -60,6 +60,7 @@
60
60
  "@coze-coding/lambda": "workspace:*",
61
61
  "@inquirer/prompts": "^3.2.0",
62
62
  "@playwright/test": "~1.55.0",
63
+ "@slardar/rd-cli": "^0.10.3",
63
64
  "@types/debug": "^4.1.12",
64
65
  "@types/ejs": "^3.1.5",
65
66
  "@types/iarna__toml": "^2.0.5",