@coze-arch/cli 0.0.9 → 0.0.10-alpha.98c617
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/lib/__templates__/expo/AGENTS.md +29 -29
- package/lib/__templates__/expo/README.md +29 -29
- package/lib/__templates__/expo/_npmrc +3 -0
- package/lib/__templates__/nextjs/_npmrc +3 -0
- package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
- package/lib/__templates__/nuxt-vue/_npmrc +3 -0
- package/lib/__templates__/taro/_npmrc +3 -0
- package/lib/__templates__/taro/eslint.config.mjs +51 -0
- package/lib/__templates__/taro/package.json +4 -4
- package/lib/__templates__/taro/project.config.json +1 -8
- package/lib/__templates__/vite/_npmrc +3 -0
- package/lib/cli.js +16 -4
- package/package.json +2 -1
|
@@ -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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
//
|
|
166
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
//
|
|
166
|
-
|
|
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
|
### 依赖安装
|
|
@@ -5,6 +5,11 @@ 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
|
+
},
|
|
12
|
+
},
|
|
8
13
|
// Override default ignores of eslint-config-next.
|
|
9
14
|
globalIgnores([
|
|
10
15
|
// Default ignores of eslint-config-next:
|
|
@@ -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
|
},
|
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.
|
|
2109
|
+
var version = "0.0.10-alpha.98c617";
|
|
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",
|
|
@@ -4696,6 +4697,7 @@ function createStringifyContext(doc, options) {
|
|
|
4696
4697
|
nullStr: 'null',
|
|
4697
4698
|
simpleKeys: false,
|
|
4698
4699
|
singleQuote: null,
|
|
4700
|
+
trailingComma: false,
|
|
4699
4701
|
trueStr: 'true',
|
|
4700
4702
|
verifyAliasOrder: true
|
|
4701
4703
|
}, doc.schema.toStringOptions, options);
|
|
@@ -5202,12 +5204,22 @@ function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
|
|
|
5202
5204
|
if (comment)
|
|
5203
5205
|
reqNewline = true;
|
|
5204
5206
|
let str = stringify(item, itemCtx, () => (comment = null));
|
|
5205
|
-
|
|
5207
|
+
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\n'));
|
|
5208
|
+
if (i < items.length - 1) {
|
|
5206
5209
|
str += ',';
|
|
5210
|
+
}
|
|
5211
|
+
else if (ctx.options.trailingComma) {
|
|
5212
|
+
if (ctx.options.lineWidth > 0) {
|
|
5213
|
+
reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +
|
|
5214
|
+
(str.length + 2) >
|
|
5215
|
+
ctx.options.lineWidth);
|
|
5216
|
+
}
|
|
5217
|
+
if (reqNewline) {
|
|
5218
|
+
str += ',';
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5207
5221
|
if (comment)
|
|
5208
5222
|
str += lineComment(str, itemIndent, commentString(comment));
|
|
5209
|
-
if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
|
|
5210
|
-
reqNewline = true;
|
|
5211
5223
|
lines.push(str);
|
|
5212
5224
|
linesAtValue = lines.length;
|
|
5213
5225
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coze-arch/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10-alpha.98c617",
|
|
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",
|