@coze-arch/cli 0.0.20 → 0.0.21-alpha.df4fd6

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 (26) hide show
  1. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +1 -13
  2. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +0 -12
  3. package/lib/__templates__/expo/client/components/Screen.tsx +5 -5
  4. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.types.ts +6 -6
  5. package/lib/__templates__/expo/client/heroui/components/toast/toast.tsx +2 -2
  6. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-augmented-ref.ts +2 -2
  7. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-controllable-state.ts +1 -1
  8. package/lib/__templates__/expo/client/package.json +1 -1
  9. package/lib/__templates__/expo/server/package.json +1 -1
  10. package/lib/__templates__/nextjs/scripts/dev.sh +4 -4
  11. package/lib/__templates__/nuxt-vue/scripts/dev.sh +4 -4
  12. package/lib/__templates__/pi-agent/package.json +1 -1
  13. package/lib/__templates__/pi-agent/tests/web-search.test.ts +2 -2
  14. package/lib/__templates__/taro/src/components/ui/collapsible.tsx +2 -2
  15. package/lib/__templates__/taro/src/components/ui/hover-card.tsx +10 -10
  16. package/lib/__templates__/taro/src/components/ui/input-otp.tsx +3 -2
  17. package/lib/__templates__/taro/src/components/ui/slider.tsx +4 -4
  18. package/lib/__templates__/taro/src/components/ui/tabs.tsx +2 -1
  19. package/lib/__templates__/taro/src/components/ui/toast.tsx +1 -1
  20. package/lib/__templates__/taro/src/components/ui/tooltip.tsx +10 -10
  21. package/lib/__templates__/taro/src/lib/measure.ts +1 -1
  22. package/lib/__templates__/templates.json +24 -24
  23. package/lib/__templates__/vite/scripts/dev.sh +4 -4
  24. package/lib/__templates__/vite/server/server.ts +1 -2
  25. package/lib/cli.js +823 -94
  26. package/package.json +10 -6
@@ -2,7 +2,6 @@
2
2
  if [ -z "${BASH_VERSION:-}" ]; then exec /usr/bin/env bash "$0" "$@"; fi
3
3
  set -euo pipefail
4
4
  ROOT_DIR="$(pwd)"
5
- PREVIEW_DIR="${COZE_PREVIEW_DIR:-/source/preview}"
6
5
 
7
6
  # ==================== 配置项 ====================
8
7
  SERVER_DIR="app"
@@ -17,11 +16,6 @@ check_command() {
17
16
 
18
17
  echo "==================== 开始构建 ===================="
19
18
 
20
- echo "检查根目录 pre_install.py"
21
- if [ -f "$PREVIEW_DIR/pre_install.py" ]; then
22
- echo "执行:python $PREVIEW_DIR/pre_install.py"
23
- python "$PREVIEW_DIR/pre_install.py" || echo "pre_install.py 执行失败"
24
- fi
25
19
 
26
20
  echo "开始执行构建脚本(build_dev.sh)..."
27
21
  echo "正在检查依赖命令是否存在..."
@@ -36,11 +30,5 @@ fi
36
30
  # 步骤 2.1/2.2:安装项目依赖
37
31
  pnpm install --registry=https://registry.npmmirror.com || echo "Expo 项目依赖安装失败(pnpm 执行出错)"
38
32
 
39
- echo "检查根目录 post_install.py"
40
- if [ -f "$PREVIEW_DIR/post_install.py" ]; then
41
- echo "执行:python $PREVIEW_DIR/post_install.py"
42
- python "$PREVIEW_DIR/post_install.py" || echo "post_install.py 执行失败"
43
- fi
44
-
45
33
  echo "==================== 依赖安装完成!====================\n"
46
- echo "下一步:执行 ./deploy_run.sh 启动服务"
34
+ echo "下一步:执行 ./dev_run.sh 启动服务"
@@ -1,5 +1,4 @@
1
1
  ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
2
- PREVIEW_DIR="${COZE_PREVIEW_DIR:-/source/preview}"
3
2
  LOG_DIR="${COZE_LOG_DIR:-$ROOT_DIR/logs}"
4
3
  LOG_CLIENT_FILE="$LOG_DIR/client.log"
5
4
  mkdir -p "$LOG_DIR"
@@ -148,17 +147,6 @@ detect_expo_fetch_failed() {
148
147
  # 关掉nginx进程
149
148
  ps -ef | grep nginx | grep -v grep | awk '{print $2}' | xargs -r kill -9
150
149
 
151
- echo "检查根目录 pre_install.py"
152
- if [ -f "$PREVIEW_DIR/pre_install.py" ]; then
153
- echo "执行:python $PREVIEW_DIR/pre_install.py"
154
- python "$PREVIEW_DIR/pre_install.py" || echo "pre_install.py 执行失败"
155
- fi
156
-
157
- echo "检查根目录 post_install.py"
158
- if [ -f "$PREVIEW_DIR/post_install.py" ]; then
159
- echo "执行:python $PREVIEW_DIR/post_install.py"
160
- python "$PREVIEW_DIR/post_install.py" || echo "post_install.py 执行失败"
161
- fi
162
150
 
163
151
  echo "==================== 开始启动 ===================="
164
152
  echo "开始执行服务启动脚本(start_dev.sh)..."
@@ -92,7 +92,7 @@ const KeyboardAwareScrollable = ({
92
92
  contentInsetBehaviorIOS,
93
93
  }: KeyboardAwareProps) => {
94
94
  // 获取原始组件的 props
95
- const childAttrs: any = (element as any).props || {};
95
+ const childAttrs = ((element as React.ReactElement).props ?? {}) as Record<string, unknown>;
96
96
  const originStyle = childAttrs['contentContainerStyle'];
97
97
  const styleArray = Array.isArray(originStyle) ? originStyle : originStyle ? [originStyle] : [];
98
98
  const merged = Object.assign({}, ...styleArray);
@@ -117,7 +117,7 @@ const KeyboardAwareScrollable = ({
117
117
  : {}),
118
118
  };
119
119
 
120
- const t = (element as any).type;
120
+ const t = (element as React.ReactElement).type;
121
121
 
122
122
  // 根据组件类型返回对应的 KeyboardAware 版本
123
123
  // 注意:不再使用 KeyboardAvoidingView,直接替换为增强版 ScrollView
@@ -171,7 +171,7 @@ const RawScreen = ({
171
171
  const props = element.props as Record<string, unknown> | undefined;
172
172
  // 仅识别“垂直”滚动容器;横向滚动不视为页面已处理垂直滚动
173
173
  // eslint-disable-next-line react/prop-types
174
- const isHorizontal = !!(props && (props as any).horizontal === true);
174
+ const isHorizontal = !!(props && props.horizontal === true);
175
175
  if ((t === ScrollView || t === FlatList || t === SectionList) && !isHorizontal) return true;
176
176
  const c: React.ReactNode | undefined = props && 'children' in props
177
177
  ? (props.children as React.ReactNode)
@@ -238,8 +238,8 @@ const RawScreen = ({
238
238
  const wrapScrollableWithKeyboardAvoid = (nodes: React.ReactNode): React.ReactNode => {
239
239
  const isVerticalScrollable = (el: React.ReactElement<any, any>): boolean => {
240
240
  const t = el.type;
241
- const elementProps = (el as any).props || {};
242
- const isHorizontal = !!(elementProps as any).horizontal;
241
+ const elementProps = ((el as React.ReactElement).props ?? {}) as Record<string, unknown>;
242
+ const isHorizontal = !!elementProps.horizontal;
243
243
  return (t === ScrollView || t === FlatList || t === SectionList) && !isHorizontal;
244
244
  };
245
245
 
@@ -1,5 +1,5 @@
1
1
  import type { ComponentType } from 'react';
2
- import type { ViewProps } from 'react-native';
2
+ import type { ViewProps, StyleProp, ViewStyle } from 'react-native';
3
3
  import type {
4
4
  AnimationRoot,
5
5
  AnimationValue,
@@ -32,11 +32,11 @@ export type ScrollShadowVisibility =
32
32
  | 'none';
33
33
 
34
34
  export interface LinearGradientProps {
35
- colors: any;
36
- locations?: any;
37
- start?: any;
38
- end?: any;
39
- style?: any;
35
+ colors: readonly string[];
36
+ locations?: readonly number[];
37
+ start?: { x: number; y: number };
38
+ end?: { x: number; y: number };
39
+ style?: StyleProp<ViewStyle>;
40
40
  }
41
41
 
42
42
  export type LinearGradientComponent = ComponentType<LinearGradientProps>;
@@ -1,4 +1,4 @@
1
- import { forwardRef, useMemo } from 'react';
1
+ import React, { forwardRef, useMemo } from 'react';
2
2
  import { View, Text as RNText } from 'react-native';
3
3
  import { GestureDetector } from 'react-native-gesture-handler';
4
4
  import Animated from 'react-native-reanimated';
@@ -339,7 +339,7 @@ const ToastClose = forwardRef<View, ToastCloseProps>((props, ref) => {
339
339
  * If hide and id are available from context, use them to hide the toast
340
340
  * Otherwise, use the provided onPress handler
341
341
  */
342
- const handlePress = (event: any) => {
342
+ const handlePress = (event: Parameters<NonNullable<React.ComponentProps<typeof Button>['onPress']>>[0]) => {
343
343
  if (hide && id) {
344
344
  hide(id);
345
345
  }
@@ -3,8 +3,8 @@ import { useImperativeHandle, useRef } from 'react';
3
3
 
4
4
  interface AugmentRefProps<T> {
5
5
  ref: React.Ref<T>;
6
- methods?: Record<string, (...args: any[]) => any>;
7
- deps?: any[];
6
+ methods?: Record<string, (...args: unknown[]) => unknown>;
7
+ deps?: unknown[];
8
8
  }
9
9
 
10
10
  export function useAugmentedRef<T>({
@@ -108,7 +108,7 @@ function useUncontrolledState<T>({
108
108
  * A custom hook that converts a callback to a ref to avoid triggering re-renders when passed as a
109
109
  * prop or avoid re-executing effects when passed as a dependency
110
110
  */
111
- function useCallbackRef<T extends (...args: any[]) => any>(
111
+ function useCallbackRef<T extends (...args: unknown[]) => unknown>(
112
112
  callback: T | undefined
113
113
  ): T {
114
114
  const callbackRef = useRef(callback);
@@ -24,7 +24,7 @@
24
24
  "@react-native-picker/picker": "2.11.1",
25
25
  "@react-navigation/bottom-tabs": "^7.2.0",
26
26
  "@react-navigation/native": "^7.0.14",
27
- "dayjs": "^1.11.19",
27
+ "dayjs": "^1.11.20",
28
28
  "expo": "54.0.33",
29
29
  "expo-auth-session": "~7.0.10",
30
30
  "expo-av": "~16.0.8",
@@ -13,7 +13,7 @@
13
13
  "@supabase/supabase-js": "2.95.3",
14
14
  "cors": "^2.8.5",
15
15
  "coze-coding-dev-sdk": "^0.7.16",
16
- "dayjs": "^1.11.19",
16
+ "dayjs": "^1.11.20",
17
17
  "dotenv": "^17.2.3",
18
18
  "drizzle-orm": "^0.45.1",
19
19
  "drizzle-zod": "^0.8.3",
@@ -9,7 +9,7 @@ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
9
  <% } else { %>
10
10
  PORT=<%= port %>
11
11
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
12
- DEPLOY_RUN_PORT=<%= port %>
12
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
13
13
  <% } %>
14
14
 
15
15
  cd "${COZE_WORKSPACE_PATH}"
@@ -32,8 +32,8 @@ kill_port_if_listening() {
32
32
  fi
33
33
  }
34
34
 
35
- echo "Clearing port ${PORT} before start."
35
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
36
  kill_port_if_listening
37
- echo "Starting HTTP service on port ${PORT} for dev..."
37
+ echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
38
38
 
39
- PORT=$PORT pnpm tsx watch src/server.ts
39
+ PORT=${DEPLOY_RUN_PORT} pnpm tsx watch src/server.ts
@@ -9,7 +9,7 @@ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
9
  <% } else { %>
10
10
  PORT=<%= port %>
11
11
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
12
- DEPLOY_RUN_PORT=<%= port %>
12
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
13
13
  <% } %>
14
14
 
15
15
  cd "${COZE_WORKSPACE_PATH}"
@@ -32,8 +32,8 @@ kill_port_if_listening() {
32
32
  fi
33
33
  }
34
34
 
35
- echo "Clearing port ${PORT} before start."
35
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
36
  kill_port_if_listening
37
- echo "Starting Nuxt dev server on port ${PORT}..."
37
+ echo "Starting Nuxt dev server on port ${DEPLOY_RUN_PORT}..."
38
38
 
39
- PORT=$PORT pnpm nuxt dev
39
+ PORT=${DEPLOY_RUN_PORT} pnpm nuxt dev
@@ -46,7 +46,7 @@
46
46
  "@types/node": "^24.3.0",
47
47
  "@types/react": "^18.3.12",
48
48
  "@types/react-dom": "^18.3.1",
49
- "@types/ws": "^8.5.10",
49
+ "@types/ws": "^8.18.1",
50
50
  "@vitejs/plugin-react": "^4.3.3",
51
51
  "autoprefixer": "^10.4.27",
52
52
  "postcss": "^8.5.9",
@@ -171,7 +171,7 @@ test("web-search: returns error content on search failure", async (t) => {
171
171
  });
172
172
 
173
173
  test("web-search: defaults count to 10 and type to web", async (t) => {
174
- const captured: any[] = [];
174
+ const captured: Array<{ query: string; count: number; needSummary?: boolean }> = [];
175
175
  t.mock.method(SearchClient.prototype, "webSearch", async (query: string, count: number, needSummary?: boolean) => {
176
176
  captured.push({ query, count, needSummary });
177
177
  return makeWebSearchResponse();
@@ -181,7 +181,7 @@ test("web-search: defaults count to 10 and type to web", async (t) => {
181
181
 
182
182
  assert.equal(captured[0].query, "hello");
183
183
  assert.equal(captured[0].count, 10);
184
- assert.equal((captured[0] as any).needSummary, undefined);
184
+ assert.equal(captured[0].needSummary, undefined);
185
185
  });
186
186
 
187
187
  test("web-search: details contain correct metadata", async (t) => {
@@ -46,11 +46,11 @@ const CollapsibleTrigger = React.forwardRef<
46
46
  <View
47
47
  ref={ref}
48
48
  className={className}
49
- onClick={(e: any) => {
49
+ onClick={(e) => {
50
50
  context?.onOpenChange(!context.open)
51
51
  onClick?.(e)
52
52
  }}
53
- {...(props as any)}
53
+ {...props}
54
54
  />
55
55
  )
56
56
  })
@@ -83,8 +83,8 @@ const HoverCard = ({
83
83
  const HoverCardTrigger = React.forwardRef<
84
84
  React.ElementRef<typeof View>,
85
85
  React.ComponentPropsWithoutRef<typeof View> & {
86
- onMouseEnter?: (e: any) => void
87
- onMouseLeave?: (e: any) => void
86
+ onMouseEnter?: (e: React.MouseEvent) => void
87
+ onMouseLeave?: (e: React.MouseEvent) => void
88
88
  }
89
89
  >(({ className, children, onClick, onMouseEnter, onMouseLeave, ...props }, ref) => {
90
90
  const context = React.useContext(HoverCardContext)
@@ -101,15 +101,15 @@ const HoverCardTrigger = React.forwardRef<
101
101
  }}
102
102
  {...(isH5()
103
103
  ? ({
104
- onMouseEnter: (e: any) => {
104
+ onMouseEnter: (e: React.MouseEvent) => {
105
105
  onMouseEnter?.(e)
106
106
  context?.setHoverPart?.("trigger", true)
107
107
  },
108
- onMouseLeave: (e: any) => {
108
+ onMouseLeave: (e: React.MouseEvent) => {
109
109
  onMouseLeave?.(e)
110
110
  context?.setHoverPart?.("trigger", false)
111
111
  },
112
- } as any)
112
+ } as React.ComponentPropsWithoutRef<typeof View>)
113
113
  : {})}
114
114
  >
115
115
  {children}
@@ -124,8 +124,8 @@ const HoverCardContent = React.forwardRef<
124
124
  align?: "start" | "center" | "end"
125
125
  side?: "top" | "bottom" | "left" | "right"
126
126
  sideOffset?: number
127
- onMouseEnter?: (e: any) => void
128
- onMouseLeave?: (e: any) => void
127
+ onMouseEnter?: (e: React.MouseEvent) => void
128
+ onMouseLeave?: (e: React.MouseEvent) => void
129
129
  }
130
130
  >(
131
131
  (
@@ -262,15 +262,15 @@ const HoverCardContent = React.forwardRef<
262
262
  style={contentStyle}
263
263
  {...(isH5()
264
264
  ? ({
265
- onMouseEnter: (e: any) => {
265
+ onMouseEnter: (e: React.MouseEvent) => {
266
266
  onMouseEnter?.(e)
267
267
  context?.setHoverPart?.("content", true)
268
268
  },
269
- onMouseLeave: (e: any) => {
269
+ onMouseLeave: (e: React.MouseEvent) => {
270
270
  onMouseLeave?.(e)
271
271
  context?.setHoverPart?.("content", false)
272
272
  },
273
- } as any)
273
+ } as React.ComponentPropsWithoutRef<typeof View>)
274
274
  : {})}
275
275
  />
276
276
  </Portal>
@@ -1,5 +1,6 @@
1
1
  import * as React from "react"
2
- import { View, Input } from "@tarojs/components"
2
+ import { View, Input, type BaseEventOrig } from "@tarojs/components"
3
+ import { type InputProps } from "@tarojs/components/types/Input"
3
4
  import { Dot } from "lucide-react-taro"
4
5
  import { cn } from "@/lib/utils"
5
6
 
@@ -27,7 +28,7 @@ const InputOTP = React.forwardRef<
27
28
  const [isFocused, setIsFocused] = React.useState(false)
28
29
  const value = valueProp !== undefined ? valueProp : valueState
29
30
 
30
- const handleChange = (e: any) => {
31
+ const handleChange = (e: BaseEventOrig<InputProps.inputValueEventDetail>) => {
31
32
  const newValue = e.detail.value
32
33
  if (newValue.length <= maxLength) {
33
34
  if (valueProp === undefined) {
@@ -1,6 +1,6 @@
1
1
  import * as React from "react"
2
2
  import { View } from "@tarojs/components"
3
- import Taro from "@tarojs/taro"
3
+ import Taro, { type ITouchEvent } from "@tarojs/taro"
4
4
 
5
5
  import { cn } from "@/lib/utils"
6
6
 
@@ -79,7 +79,7 @@ const Slider = React.forwardRef<
79
79
  }
80
80
  }
81
81
 
82
- const handleTouchStart = (e: any) => {
82
+ const handleTouchStart = (e: ITouchEvent) => {
83
83
  if (disabled) return
84
84
  setIsDragging(true)
85
85
  // Try to update rect on touch start in case of layout changes
@@ -135,7 +135,7 @@ const Slider = React.forwardRef<
135
135
  }
136
136
  }
137
137
 
138
- const handleTouchMove = (e: any) => {
138
+ const handleTouchMove = (e: ITouchEvent) => {
139
139
  if (disabled) return
140
140
  const touch = e.touches[0] || e.changedTouches[0]
141
141
  if (touch) {
@@ -143,7 +143,7 @@ const Slider = React.forwardRef<
143
143
  }
144
144
  }
145
145
 
146
- const handleTouchEnd = (e: any) => {
146
+ const handleTouchEnd = (e: ITouchEvent) => {
147
147
  if (disabled) return
148
148
  setIsDragging(false)
149
149
  const touch = e.touches[0] || e.changedTouches[0]
@@ -1,5 +1,6 @@
1
1
  import * as React from "react"
2
2
  import { View } from "@tarojs/components"
3
+ import { type ITouchEvent } from "@tarojs/taro"
3
4
  import { cn } from "@/lib/utils"
4
5
 
5
6
  const TabsContext = React.createContext<{
@@ -62,7 +63,7 @@ const TabsTrigger = React.forwardRef<
62
63
  const context = React.useContext(TabsContext)
63
64
  const isActive = context?.value === value
64
65
 
65
- const handleClick = (e: any) => {
66
+ const handleClick = (e: ITouchEvent) => {
66
67
  if (disabled) return
67
68
  context?.onValueChange?.(value)
68
69
  onClick?.(e)
@@ -119,7 +119,7 @@ const toast = Object.assign(toastFn, {
119
119
  data: {
120
120
  loading?: string | React.ReactNode
121
121
  success?: string | React.ReactNode | ((data: T) => React.ReactNode)
122
- error?: string | React.ReactNode | ((error: any) => React.ReactNode)
122
+ error?: string | React.ReactNode | ((error: unknown) => React.ReactNode)
123
123
  finally?: () => void
124
124
  } & ToastData
125
125
  ) => {
@@ -92,8 +92,8 @@ const Tooltip = ({
92
92
  const TooltipTrigger = React.forwardRef<
93
93
  React.ElementRef<typeof View>,
94
94
  React.ComponentPropsWithoutRef<typeof View> & {
95
- onMouseEnter?: (e: any) => void
96
- onMouseLeave?: (e: any) => void
95
+ onMouseEnter?: (e: React.MouseEvent) => void
96
+ onMouseLeave?: (e: React.MouseEvent) => void
97
97
  }
98
98
  >(
99
99
  (
@@ -113,15 +113,15 @@ const TooltipTrigger = React.forwardRef<
113
113
  }}
114
114
  {...(isH5()
115
115
  ? ({
116
- onMouseEnter: (e: any) => {
116
+ onMouseEnter: (e: React.MouseEvent) => {
117
117
  onMouseEnter?.(e)
118
118
  context?.setHoverPart?.("trigger", true)
119
119
  },
120
- onMouseLeave: (e: any) => {
120
+ onMouseLeave: (e: React.MouseEvent) => {
121
121
  onMouseLeave?.(e)
122
122
  context?.setHoverPart?.("trigger", false)
123
123
  },
124
- } as any)
124
+ } as React.ComponentPropsWithoutRef<typeof View>)
125
125
  : {})}
126
126
  {...props}
127
127
  >
@@ -142,8 +142,8 @@ const TooltipContent = React.forwardRef<
142
142
  collisionPadding?: number
143
143
  showArrow?: boolean
144
144
  arrowSize?: number
145
- onMouseEnter?: (e: any) => void
146
- onMouseLeave?: (e: any) => void
145
+ onMouseEnter?: (e: React.MouseEvent) => void
146
+ onMouseLeave?: (e: React.MouseEvent) => void
147
147
  }
148
148
  >(
149
149
  (
@@ -432,15 +432,15 @@ const TooltipContent = React.forwardRef<
432
432
  style={contentStyle}
433
433
  {...(isH5()
434
434
  ? ({
435
- onMouseEnter: (e: any) => {
435
+ onMouseEnter: (e: React.MouseEvent) => {
436
436
  onMouseEnter?.(e)
437
437
  context?.setHoverPart?.("content", true)
438
438
  },
439
- onMouseLeave: (e: any) => {
439
+ onMouseLeave: (e: React.MouseEvent) => {
440
440
  onMouseLeave?.(e)
441
441
  context?.setHoverPart?.("content", false)
442
442
  },
443
- } as any)
443
+ } as React.ComponentPropsWithoutRef<typeof View>)
444
444
  : {})}
445
445
  {...props}
446
446
  >
@@ -12,7 +12,7 @@ const toNumber = (v: unknown) => {
12
12
  return 0
13
13
  }
14
14
 
15
- const normalizeRect = (r: any): Rect | null => {
15
+ const normalizeRect = (r: Record<string, unknown> | null | undefined): Rect | null => {
16
16
  if (!r) return null
17
17
  return {
18
18
  left: toNumber(r.left),
@@ -94,6 +94,30 @@
94
94
  "additionalProperties": false
95
95
  }
96
96
  },
97
+ {
98
+ "name": "pi-agent",
99
+ "description": "Pi Agent:`coze init ${COZE_WORKSPACE_PATH} --template pi-agent`\n- 适用:基于 pi-agent-core 的 AI Agent 应用\n- 支持飞书、微信等多渠道接入\n- 内置 Dashboard 管理面板\n- 使用 TypeScript + Express + Vite",
100
+ "location": "./pi-agent",
101
+ "paramsSchema": {
102
+ "type": "object",
103
+ "properties": {
104
+ "port": {
105
+ "type": "number",
106
+ "default": 5000,
107
+ "minimum": 1024,
108
+ "maximum": 65535,
109
+ "description": "Dashboard server port"
110
+ },
111
+ "workspaceDir": {
112
+ "type": "string",
113
+ "default": "/workspace/workspace",
114
+ "description": "Workspace directory path"
115
+ }
116
+ },
117
+ "required": [],
118
+ "additionalProperties": false
119
+ }
120
+ },
97
121
  {
98
122
  "name": "taro",
99
123
  "description": "Taro(小程序 + H5):`coze init ${COZE_WORKSPACE_PATH} --template taro`\n- 适用:微信小程序、H5 跨端应用\n- 前后端分离架构:Taro 4 + NestJS\n- 支持微信小程序和 H5 双端构建\n- 使用 TailwindCSS + weapp-tailwindcss 实现跨端样式",
@@ -157,30 +181,6 @@
157
181
  "required": [],
158
182
  "additionalProperties": false
159
183
  }
160
- },
161
- {
162
- "name": "pi-agent",
163
- "description": "Pi Agent:`coze init ${COZE_WORKSPACE_PATH} --template pi-agent`\n- 适用:基于 pi-agent-core 的 AI Agent 应用\n- 支持飞书、微信等多渠道接入\n- 内置 Dashboard 管理面板\n- 使用 TypeScript + Express + Vite",
164
- "location": "./pi-agent",
165
- "paramsSchema": {
166
- "type": "object",
167
- "properties": {
168
- "port": {
169
- "type": "number",
170
- "default": 5000,
171
- "minimum": 1024,
172
- "maximum": 65535,
173
- "description": "Dashboard server port"
174
- },
175
- "workspaceDir": {
176
- "type": "string",
177
- "default": "/workspace/workspace",
178
- "description": "Workspace directory path"
179
- }
180
- },
181
- "required": [],
182
- "additionalProperties": false
183
- }
184
184
  }
185
185
  ]
186
186
  }
@@ -9,7 +9,7 @@ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
9
  <% } else { %>
10
10
  PORT=<%= port %>
11
11
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
12
- DEPLOY_RUN_PORT=<%= port %>
12
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
13
13
  <% } %>
14
14
 
15
15
  cd "${COZE_WORKSPACE_PATH}"
@@ -32,8 +32,8 @@ kill_port_if_listening() {
32
32
  fi
33
33
  }
34
34
 
35
- echo "Clearing port ${PORT} before start."
35
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
36
  kill_port_if_listening
37
- echo "Starting express + Vite dev server on port ${PORT}..."
37
+ echo "Starting express + Vite dev server on port ${DEPLOY_RUN_PORT}..."
38
38
 
39
- PORT=$PORT pnpm tsx watch server/server.ts
39
+ PORT=${DEPLOY_RUN_PORT} pnpm tsx watch server/server.ts
@@ -39,8 +39,7 @@ async function startServer(): Promise<Server> {
39
39
  // 全局错误处理
40
40
  app.use((err: Error, req: express.Request, res: express.Response) => {
41
41
  console.error('Server error:', err);
42
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
- const status = 'status' in err ? (err as any).status || 500 : 500;
42
+ const status = 'status' in err ? (err as { status?: number }).status ?? 500 : 500;
44
43
  res.status(status).json({
45
44
  error: err.message || 'Internal server error',
46
45
  });