@coze-arch/cli 0.1.5 → 0.1.8-alpha.4500b5
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/docs/deploy.md +12 -1
- package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +3 -3
- package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +11 -3
- package/lib/__templates__/expo/.cozeproj/scripts/prepare-node-modules.sh +212 -0
- package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +3 -3
- package/lib/__templates__/expo/client/components/Screen.tsx +65 -25
- package/lib/__templates__/expo/client/heroui/components/toast/toast.tsx +6 -2
- package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-controllable-state.ts +1 -1
- package/lib/__templates__/expo/pnpm-lock.yaml +5 -5
- package/lib/__templates__/expo/server/package.json +1 -1
- package/lib/__templates__/native-static/.coze +2 -2
- package/lib/__templates__/nextjs/eslint.config.mjs +11 -5
- package/lib/__templates__/nextjs/next.config.ts +10 -0
- package/lib/__templates__/nextjs/package.json +3 -6
- package/lib/__templates__/nextjs/pnpm-lock.yaml +19 -950
- package/lib/__templates__/nextjs/scripts/build.ps1 +1 -1
- package/lib/__templates__/nextjs/scripts/build.sh +2 -2
- package/lib/__templates__/nextjs/scripts/dev.ps1 +2 -2
- package/lib/__templates__/nextjs/scripts/dev.sh +86 -10
- package/lib/__templates__/nextjs/scripts/prepare-node-modules.sh +212 -0
- package/lib/__templates__/nextjs/scripts/prepare.sh +1 -4
- package/lib/__templates__/nextjs/src/app/layout.tsx +0 -4
- package/lib/__templates__/nextjs/src/server.ts +1 -1
- package/lib/__templates__/nextjs/template.config.js +1 -1
- package/lib/__templates__/nuxt-vue/package.json +1 -1
- package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +5 -5
- package/lib/__templates__/nuxt-vue/scripts/build.sh +1 -1
- package/lib/__templates__/nuxt-vue/scripts/dev.sh +11 -3
- package/lib/__templates__/nuxt-vue/scripts/prepare-node-modules.sh +212 -0
- package/lib/__templates__/nuxt-vue/scripts/prepare.sh +1 -4
- package/lib/__templates__/pi-agent/package.json +1 -1
- package/lib/__templates__/pi-agent/pnpm-lock.yaml +5 -5
- package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +5 -1
- package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +4 -0
- package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +3 -0
- package/lib/__templates__/taro/.cozeproj/scripts/dev_run.ps1 +4 -2
- package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +29 -7
- package/lib/__templates__/taro/.cozeproj/scripts/init_env.sh +4 -0
- package/lib/__templates__/taro/.cozeproj/scripts/pack.ps1 +3 -1
- package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +8 -0
- package/lib/__templates__/taro/.cozeproj/scripts/prepare-node-modules.sh +212 -0
- package/lib/__templates__/taro/.cozeproj/scripts/validate.ps1 +3 -1
- package/lib/__templates__/taro/.cozeproj/scripts/validate.sh +4 -0
- package/lib/__templates__/taro/_gitignore +1 -0
- package/lib/__templates__/taro/pnpm-lock.yaml +5 -5
- package/lib/__templates__/taro/server/package.json +1 -1
- package/lib/__templates__/vite/package.json +1 -1
- package/lib/__templates__/vite/pnpm-lock.yaml +5 -5
- package/lib/__templates__/vite/scripts/build.sh +1 -1
- package/lib/__templates__/vite/scripts/dev.ps1 +2 -2
- package/lib/__templates__/vite/scripts/dev.sh +11 -3
- package/lib/__templates__/vite/scripts/prepare-node-modules.sh +212 -0
- package/lib/__templates__/vite/scripts/prepare.sh +1 -4
- package/lib/__templates__/vite/template.config.js +1 -1
- package/lib/cli.js +147 -16
- package/package.json +2 -2
- package/lib/__templates__/nextjs/.babelrc +0 -15
package/docs/deploy.md
CHANGED
|
@@ -57,7 +57,7 @@ coze-dev deploy app rename <name> --app-id <app_id> --yes
|
|
|
57
57
|
coze-dev deploy app delete --app-id <app_id> --yes
|
|
58
58
|
coze-dev deploy app analytics|metrics --app-id <app_id> [--time-range <range>]
|
|
59
59
|
coze-dev deploy app usage --app-id <app_id> --bill-month <YYYY-MM>
|
|
60
|
-
coze-dev deploy [--lane <ppe_lane>] [--source-root <directory>] [--app-id <app_id>] [--application-type <type>] [--name <name>] [--connector-id <id>]
|
|
60
|
+
coze-dev deploy [--lane <ppe_lane>] [--source-root <directory>] [--app-id <app_id>] [--application-type <type>] [--name <name>] [--deploy-config <json>] [--connector-id <id>]
|
|
61
61
|
coze-dev deploy status|list|online|rollback-check|cancel|rollback|stop|resume|pause
|
|
62
62
|
coze-dev deploy logs|log-count|count|build-log|config
|
|
63
63
|
coze-dev deploy domain list [--unit-type dev|prod]
|
|
@@ -76,6 +76,17 @@ coze-dev deploy mini-program status|bind|submit-code|unbind|auth|preview
|
|
|
76
76
|
Application;类型不一致时创建新 Application、覆盖 `app_id` 并提示。也可用 `--project-id`
|
|
77
77
|
或 `--app-id` 显式指定已有资源,显式指定时不会额外创建 Project。
|
|
78
78
|
|
|
79
|
+
部署预检默认返回服务端给出的 `deploy_config`。需要调整部署规格时,传入包含完整四个字段的
|
|
80
|
+
`--deploy-config` JSON;预检会返回覆盖后的最终配置,确认部署时必须原样复用该参数:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
coze-dev deploy --source-root . \
|
|
84
|
+
--deploy-config '{"cpu":4,"memory_mb":8192,"max_instance":2,"max_concurrency":100}'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
CPU 与内存必须使用固定组合:`1/2048`、`4/8192`、`8/16384`、`16/32768`;
|
|
88
|
+
`max_instance` 为 1–100,`max_concurrency` 为 10–1000。四个值均为整数。
|
|
89
|
+
|
|
79
90
|
首次部署的应用名称可通过 `--name` 指定;显式参数优先于 `.coze` 的
|
|
80
91
|
`[project].name`。Pages 部署没有 `.coze` 时,CLI 会先生成最小配置再写入绑定。
|
|
81
92
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
if [ -z "${BASH_VERSION:-}" ]; then exec /usr/bin/env bash "$0" "$@"; fi
|
|
3
3
|
set -euo pipefail
|
|
4
|
-
ROOT_DIR="$(pwd)"
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
5
5
|
PREVIEW_DIR="/source/preview"
|
|
6
6
|
SOURCE_DIR="/source"
|
|
7
7
|
|
|
@@ -34,8 +34,8 @@ echo "==================== 安装项目依赖 ===================="
|
|
|
34
34
|
if [ ! -f "package.json" ]; then
|
|
35
35
|
echo "项目目录下无 package.json,不是合法的 Node.js 项目"
|
|
36
36
|
fi
|
|
37
|
-
# 步骤 2.1/2.2
|
|
38
|
-
|
|
37
|
+
# 步骤 2.1/2.2:通过受管入口安装项目依赖
|
|
38
|
+
bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --registry=https://registry.npmmirror.com
|
|
39
39
|
|
|
40
40
|
echo "检查根目录 post_install.py"
|
|
41
41
|
if [ -f "$PREVIEW_DIR/post_install.py" ]; then
|
|
@@ -123,11 +123,15 @@ wait_port_connectable() {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
# detached 出去的进程没人负责回收,超过这个时长就自己退出,避免端口与内存长期泄露。
|
|
126
|
-
MAX_RUNTIME_SECONDS=
|
|
126
|
+
MAX_RUNTIME_SECONDS=3600
|
|
127
|
+
|
|
128
|
+
timeout_watchdog_enabled() {
|
|
129
|
+
[[ -z "${COZE_EVAL:-}" && -z "${COZE_PROJECT_TYPE:-}" ]]
|
|
130
|
+
}
|
|
127
131
|
|
|
128
132
|
# 真正被 detach 的是这层 bash wrapper:它是进程组 leader,组内 watchdog 到点回收整组
|
|
129
133
|
# (wrapper -> pnpm -> expo/node);被包的进程自己先退出时也顺手清空进程组,不留残余。
|
|
130
|
-
RUN_WITH_TIMEOUT='
|
|
134
|
+
RUN_WITH_TIMEOUT="$(declare -f timeout_watchdog_enabled)"'
|
|
131
135
|
timeout_seconds=$1
|
|
132
136
|
shift
|
|
133
137
|
|
|
@@ -135,6 +139,7 @@ shift
|
|
|
135
139
|
child_pid=$!
|
|
136
140
|
|
|
137
141
|
# 先忽略 TERM,才能在向整组发 TERM(自己也在组里)之后存活下来补一发 KILL。
|
|
142
|
+
if timeout_watchdog_enabled; then
|
|
138
143
|
( trap "" TERM
|
|
139
144
|
sleep "${timeout_seconds}"
|
|
140
145
|
echo "[dev] 后台进程运行超过 ${timeout_seconds}s,回收进程组 $$。"
|
|
@@ -142,6 +147,7 @@ child_pid=$!
|
|
|
142
147
|
sleep 5
|
|
143
148
|
kill -KILL -- "-$$" 2>/dev/null || true
|
|
144
149
|
) &
|
|
150
|
+
fi
|
|
145
151
|
|
|
146
152
|
wait "${child_pid}"
|
|
147
153
|
kill -KILL -- "-$$" 2>/dev/null || true
|
|
@@ -290,7 +296,9 @@ if [ -z "${EXPO_PID}" ]; then
|
|
|
290
296
|
fi
|
|
291
297
|
|
|
292
298
|
echo "所有服务已启动。Server PID: ${SERVER_PID}, Expo PID: ${EXPO_PID}"
|
|
293
|
-
|
|
299
|
+
if timeout_watchdog_enabled; then
|
|
300
|
+
echo "两个服务均在 ${MAX_RUNTIME_SECONDS}s 后自动退出。"
|
|
301
|
+
fi
|
|
294
302
|
|
|
295
303
|
echo "检查 Server 服务端口:$SERVER_HOST:$SERVER_PORT"
|
|
296
304
|
if wait_port_connectable "$SERVER_HOST" "$SERVER_PORT" 10 2; then
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install dependencies on local disk and expose them to the source tree by symlink.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
6
|
+
if [ "$(basename "$(dirname "$SCRIPT_DIR")")" = ".cozeproj" ]; then
|
|
7
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd -P)"
|
|
8
|
+
else
|
|
9
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
command -v pnpm >/dev/null 2>&1 || {
|
|
13
|
+
echo "[node_modules] pnpm is required" >&2
|
|
14
|
+
exit 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
DRIVE_ROOT="${COZE_DRIVE_ROOT:-/Coze/Drive}"
|
|
18
|
+
if [ -d "$DRIVE_ROOT" ]; then
|
|
19
|
+
DRIVE_ROOT="$(cd "$DRIVE_ROOT" && pwd -P)"
|
|
20
|
+
else
|
|
21
|
+
DRIVE_ROOT="${DRIVE_ROOT%/}"
|
|
22
|
+
fi
|
|
23
|
+
case "$PROJECT_ROOT" in
|
|
24
|
+
"$DRIVE_ROOT"|"$DRIVE_ROOT"/*) ;;
|
|
25
|
+
*)
|
|
26
|
+
(cd "$PROJECT_ROOT" && pnpm install "$@")
|
|
27
|
+
exit 0
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
NM_ROOT="/tmp/nm"
|
|
32
|
+
PROJECT_ID="$(basename "$PROJECT_ROOT")-$(printf '%s' "$PROJECT_ROOT" | cksum | awk '{print $1}')"
|
|
33
|
+
mkdir -p "$NM_ROOT"
|
|
34
|
+
WORK_DIR="$NM_ROOT/$PROJECT_ID"
|
|
35
|
+
case "$WORK_DIR" in
|
|
36
|
+
"$DRIVE_ROOT"|"$DRIVE_ROOT"/*)
|
|
37
|
+
echo "[node_modules] local dependency directory must not be on Coze Drive: $WORK_DIR" >&2
|
|
38
|
+
exit 1
|
|
39
|
+
;;
|
|
40
|
+
esac
|
|
41
|
+
|
|
42
|
+
LOCK_DIR="$NM_ROOT/$PROJECT_ID.lock"
|
|
43
|
+
LOCK_TIMEOUT_SECONDS="${COZE_NODE_MODULES_LOCK_TIMEOUT_SECONDS:-120}"
|
|
44
|
+
case "$LOCK_TIMEOUT_SECONDS" in
|
|
45
|
+
''|*[!0-9]*|0)
|
|
46
|
+
echo "[node_modules] COZE_NODE_MODULES_LOCK_TIMEOUT_SECONDS must be a positive integer" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
lock_owner_is_alive() {
|
|
52
|
+
local owner_pid=""
|
|
53
|
+
[ -f "$LOCK_DIR/pid" ] || return 1
|
|
54
|
+
IFS= read -r owner_pid < "$LOCK_DIR/pid" || return 1
|
|
55
|
+
case "$owner_pid" in
|
|
56
|
+
''|*[!0-9]*) return 1 ;;
|
|
57
|
+
esac
|
|
58
|
+
kill -0 "$owner_pid" 2>/dev/null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
release_lock() {
|
|
62
|
+
local owner_pid=""
|
|
63
|
+
[ -f "$LOCK_DIR/pid" ] || return 0
|
|
64
|
+
IFS= read -r owner_pid < "$LOCK_DIR/pid" || true
|
|
65
|
+
if [ "$owner_pid" = "$$" ]; then
|
|
66
|
+
rm -f "$LOCK_DIR/pid"
|
|
67
|
+
rmdir "$LOCK_DIR" 2>/dev/null || true
|
|
68
|
+
fi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
lock_started_at="$(date +%s)"
|
|
72
|
+
missing_owner_checks=0
|
|
73
|
+
while ! mkdir "$LOCK_DIR" 2>/dev/null; do
|
|
74
|
+
if lock_owner_is_alive; then
|
|
75
|
+
missing_owner_checks=0
|
|
76
|
+
else
|
|
77
|
+
missing_owner_checks=$((missing_owner_checks + 1))
|
|
78
|
+
if [ "$missing_owner_checks" -ge 2 ]; then
|
|
79
|
+
stale_lock_dir="$LOCK_DIR.stale.$$"
|
|
80
|
+
if mv "$LOCK_DIR" "$stale_lock_dir" 2>/dev/null; then
|
|
81
|
+
echo "[node_modules] Recovering stale dependency preparation lock."
|
|
82
|
+
rm -rf "$stale_lock_dir"
|
|
83
|
+
fi
|
|
84
|
+
missing_owner_checks=0
|
|
85
|
+
continue
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
lock_now="$(date +%s)"
|
|
90
|
+
if [ $((lock_now - lock_started_at)) -ge "$LOCK_TIMEOUT_SECONDS" ]; then
|
|
91
|
+
echo "[node_modules] Timed out waiting ${LOCK_TIMEOUT_SECONDS}s for dependency preparation lock: $LOCK_DIR" >&2
|
|
92
|
+
exit 1
|
|
93
|
+
fi
|
|
94
|
+
echo "[node_modules] Waiting for another dependency preparation for this project..."
|
|
95
|
+
sleep 1
|
|
96
|
+
done
|
|
97
|
+
printf '%s\n' "$$" > "$LOCK_DIR/pid"
|
|
98
|
+
trap release_lock EXIT
|
|
99
|
+
|
|
100
|
+
mkdir -p "$WORK_DIR"
|
|
101
|
+
|
|
102
|
+
# Previous versions mirrored the whole project into WORK_DIR. That gives pnpm
|
|
103
|
+
# and framework dev servers two paths for the same source tree, which breaks
|
|
104
|
+
# file watching and on-demand compilation. Keep only managed local outputs.
|
|
105
|
+
cleanup_legacy_workspace() {
|
|
106
|
+
local workspace_dir="$1" entry name
|
|
107
|
+
if [ -L "$workspace_dir" ] || { [ -e "$workspace_dir" ] && [ ! -d "$workspace_dir" ]; }; then
|
|
108
|
+
rm -rf "$workspace_dir"
|
|
109
|
+
return
|
|
110
|
+
fi
|
|
111
|
+
if [ ! -d "$workspace_dir" ]; then
|
|
112
|
+
return 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
while IFS= read -r -d '' entry; do
|
|
116
|
+
name="$(basename "$entry")"
|
|
117
|
+
[ "$name" = "node_modules" ] || rm -rf "$entry"
|
|
118
|
+
done < <(find "$workspace_dir" -mindepth 1 -maxdepth 1 -print0)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
cleanup_legacy_shadow_project() {
|
|
122
|
+
local entry name
|
|
123
|
+
while IFS= read -r -d '' entry; do
|
|
124
|
+
name="$(basename "$entry")"
|
|
125
|
+
case "$name" in
|
|
126
|
+
node_modules|client|server) continue ;;
|
|
127
|
+
esac
|
|
128
|
+
rm -rf "$entry"
|
|
129
|
+
done < <(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -print0)
|
|
130
|
+
|
|
131
|
+
for workspace in client server; do
|
|
132
|
+
cleanup_legacy_workspace "$WORK_DIR/$workspace"
|
|
133
|
+
done
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
link_install_entry() {
|
|
137
|
+
local source_path="$1" target_path="$2"
|
|
138
|
+
rm -rf "$target_path"
|
|
139
|
+
if [ -e "$source_path" ]; then
|
|
140
|
+
ln -s "$source_path" "$target_path"
|
|
141
|
+
fi
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
copy_install_metadata() {
|
|
145
|
+
local filename source_file target_file workspace
|
|
146
|
+
for filename in pnpm-lock.yaml pnpm-workspace.yaml .npmrc; do
|
|
147
|
+
source_file="$PROJECT_ROOT/$filename"
|
|
148
|
+
target_file="$WORK_DIR/$filename"
|
|
149
|
+
rm -f "$target_file"
|
|
150
|
+
if [ -f "$source_file" ]; then
|
|
151
|
+
cp "$source_file" "$target_file"
|
|
152
|
+
fi
|
|
153
|
+
done
|
|
154
|
+
|
|
155
|
+
link_install_entry "$PROJECT_ROOT/package.json" "$WORK_DIR/package.json"
|
|
156
|
+
link_install_entry "$PROJECT_ROOT/patches" "$WORK_DIR/patches"
|
|
157
|
+
link_install_entry "$PROJECT_ROOT/scripts" "$WORK_DIR/scripts"
|
|
158
|
+
|
|
159
|
+
for workspace in client server; do
|
|
160
|
+
if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
|
|
161
|
+
mkdir -p "$WORK_DIR/$workspace"
|
|
162
|
+
link_install_entry "$PROJECT_ROOT/$workspace/package.json" "$WORK_DIR/$workspace/package.json"
|
|
163
|
+
link_install_entry "$PROJECT_ROOT/$workspace/scripts" "$WORK_DIR/$workspace/scripts"
|
|
164
|
+
else
|
|
165
|
+
rm -rf "$WORK_DIR/$workspace"
|
|
166
|
+
fi
|
|
167
|
+
done
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
link_node_modules() {
|
|
171
|
+
local source_dir="$1" target_dir="$2"
|
|
172
|
+
local current=""
|
|
173
|
+
mkdir -p "$target_dir"
|
|
174
|
+
if [ -L "$source_dir/node_modules" ]; then
|
|
175
|
+
current="$(readlink "$source_dir/node_modules")"
|
|
176
|
+
case "$current" in
|
|
177
|
+
"$NM_ROOT"/*/node_modules|"$NM_ROOT"/*/*/node_modules) ;;
|
|
178
|
+
*)
|
|
179
|
+
echo "[node_modules] refusing to replace unmanaged symlink: $source_dir/node_modules" >&2
|
|
180
|
+
exit 1
|
|
181
|
+
;;
|
|
182
|
+
esac
|
|
183
|
+
rm "$source_dir/node_modules"
|
|
184
|
+
elif [ -e "$source_dir/node_modules" ]; then
|
|
185
|
+
rm -rf "$source_dir/node_modules"
|
|
186
|
+
fi
|
|
187
|
+
ln -s "$target_dir" "$source_dir/node_modules"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
cleanup_legacy_shadow_project
|
|
191
|
+
copy_install_metadata
|
|
192
|
+
|
|
193
|
+
echo "[node_modules] Installing dependencies in $WORK_DIR"
|
|
194
|
+
if ! (cd "$WORK_DIR" && pnpm install "$@"); then
|
|
195
|
+
exit 1
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
if [ -f "$WORK_DIR/pnpm-lock.yaml" ]; then
|
|
199
|
+
temporary_lockfile="$(mktemp "$PROJECT_ROOT/.pnpm-lock.yaml.XXXXXX")"
|
|
200
|
+
cp "$WORK_DIR/pnpm-lock.yaml" "$temporary_lockfile"
|
|
201
|
+
chmod 0644 "$temporary_lockfile"
|
|
202
|
+
mv -f "$temporary_lockfile" "$PROJECT_ROOT/pnpm-lock.yaml"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
link_node_modules "$PROJECT_ROOT" "$WORK_DIR/node_modules"
|
|
206
|
+
for workspace in client server; do
|
|
207
|
+
if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
|
|
208
|
+
link_node_modules "$PROJECT_ROOT/$workspace" "$WORK_DIR/$workspace/node_modules"
|
|
209
|
+
fi
|
|
210
|
+
done
|
|
211
|
+
|
|
212
|
+
echo "[node_modules] Dependencies ready"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
if [ -z "${BASH_VERSION:-}" ]; then exec /usr/bin/env bash "$0" "$@"; fi
|
|
3
3
|
set -euo pipefail
|
|
4
|
-
ROOT_DIR="$(pwd)"
|
|
4
|
+
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
5
5
|
|
|
6
6
|
# ==================== 工具函数 ====================
|
|
7
7
|
info() {
|
|
@@ -32,8 +32,8 @@ info "==================== 安装 Node 依赖 ===================="
|
|
|
32
32
|
info "开始安装 Node 依赖"
|
|
33
33
|
if [ -f "$ROOT_DIR/package.json" ]; then
|
|
34
34
|
info "进入目录:$ROOT_DIR"
|
|
35
|
-
info "
|
|
36
|
-
|
|
35
|
+
info "正在执行受管依赖准备入口"
|
|
36
|
+
bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --registry=https://registry.npmmirror.com || error "Node 依赖安装失败"
|
|
37
37
|
else
|
|
38
38
|
warn "未找到 $ROOT_DIR/package.json 文件,请检查路径是否正确"
|
|
39
39
|
fi
|
|
@@ -6,13 +6,19 @@ import {
|
|
|
6
6
|
View,
|
|
7
7
|
TouchableWithoutFeedback,
|
|
8
8
|
Keyboard,
|
|
9
|
-
ViewStyle,
|
|
9
|
+
type ViewStyle,
|
|
10
10
|
FlatList,
|
|
11
|
+
type FlatListProps,
|
|
11
12
|
SectionList,
|
|
13
|
+
type SectionListProps,
|
|
14
|
+
type ScrollViewProps,
|
|
12
15
|
Modal,
|
|
13
16
|
} from 'react-native';
|
|
14
17
|
import { withUniwind } from 'uniwind';
|
|
15
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
useSafeAreaInsets,
|
|
20
|
+
type Edge,
|
|
21
|
+
} from 'react-native-safe-area-context';
|
|
16
22
|
import { StatusBar } from 'expo-status-bar';
|
|
17
23
|
// 引入 KeyboardAware 系列组件
|
|
18
24
|
import {
|
|
@@ -86,58 +92,92 @@ type KeyboardAwareProps = {
|
|
|
86
92
|
contentInsetBehaviorIOS: 'automatic' | 'never';
|
|
87
93
|
};
|
|
88
94
|
|
|
95
|
+
type NativeScrollableProps = Pick<
|
|
96
|
+
ScrollViewProps,
|
|
97
|
+
| 'contentContainerStyle'
|
|
98
|
+
| 'keyboardShouldPersistTaps'
|
|
99
|
+
| 'keyboardDismissMode'
|
|
100
|
+
| 'contentInsetAdjustmentBehavior'
|
|
101
|
+
>;
|
|
102
|
+
|
|
89
103
|
const KeyboardAwareScrollable = ({
|
|
90
104
|
element,
|
|
91
105
|
extraPadding,
|
|
92
106
|
contentInsetBehaviorIOS,
|
|
93
107
|
}: KeyboardAwareProps) => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
const createEnhancedContentStyle = (
|
|
109
|
+
contentContainerStyle: ScrollViewProps['contentContainerStyle'],
|
|
110
|
+
) => {
|
|
111
|
+
const mergedStyle = StyleSheet.flatten(contentContainerStyle) ?? {};
|
|
112
|
+
const currentPaddingBottom =
|
|
113
|
+
typeof mergedStyle.paddingBottom === 'number'
|
|
114
|
+
? mergedStyle.paddingBottom
|
|
115
|
+
: 0;
|
|
100
116
|
|
|
101
|
-
|
|
102
|
-
|
|
117
|
+
return [
|
|
118
|
+
{
|
|
119
|
+
...mergedStyle,
|
|
120
|
+
paddingBottom: currentPaddingBottom + extraPadding,
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
};
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
125
|
+
const createKeyboardAwareProps = <Props extends NativeScrollableProps>(
|
|
126
|
+
childProps: Props,
|
|
127
|
+
) => ({
|
|
128
|
+
...childProps,
|
|
129
|
+
contentContainerStyle: createEnhancedContentStyle(
|
|
130
|
+
childProps.contentContainerStyle,
|
|
131
|
+
),
|
|
132
|
+
keyboardShouldPersistTaps:
|
|
133
|
+
childProps.keyboardShouldPersistTaps ?? 'handled',
|
|
134
|
+
keyboardDismissMode: childProps.keyboardDismissMode ?? 'on-drag',
|
|
110
135
|
enableOnAndroid: true,
|
|
111
136
|
// 类似于原代码中的 setTimeout/scrollToEnd 逻辑,这里设置额外的滚动高度确保输入框可见
|
|
112
137
|
extraHeight: 100,
|
|
113
138
|
// 禁用自带的 ScrollView 自动 inset,由外部 padding 控制
|
|
114
139
|
enableAutomaticScroll: true,
|
|
115
140
|
...(Platform.OS === 'ios'
|
|
116
|
-
? {
|
|
141
|
+
? {
|
|
142
|
+
contentInsetAdjustmentBehavior:
|
|
143
|
+
childProps.contentInsetAdjustmentBehavior ??
|
|
144
|
+
contentInsetBehaviorIOS,
|
|
145
|
+
}
|
|
117
146
|
: {}),
|
|
118
|
-
};
|
|
147
|
+
});
|
|
119
148
|
|
|
120
|
-
const t =
|
|
149
|
+
const t = element.type;
|
|
121
150
|
|
|
122
151
|
// 根据组件类型返回对应的 KeyboardAware 版本
|
|
123
152
|
// 注意:不再使用 KeyboardAvoidingView,直接替换为增强版 ScrollView
|
|
124
153
|
if (t === ScrollView) {
|
|
125
|
-
|
|
154
|
+
const childProps = element.props as ScrollViewProps;
|
|
155
|
+
return (
|
|
156
|
+
<KeyboardAwareScrollView {...createKeyboardAwareProps(childProps)} />
|
|
157
|
+
);
|
|
126
158
|
}
|
|
127
159
|
|
|
128
160
|
if (t === FlatList) {
|
|
129
|
-
|
|
161
|
+
const childProps = element.props as FlatListProps<unknown>;
|
|
162
|
+
return <KeyboardAwareFlatList {...createKeyboardAwareProps(childProps)} />;
|
|
130
163
|
}
|
|
131
164
|
|
|
132
165
|
if (t === SectionList) {
|
|
133
|
-
|
|
166
|
+
const childProps = element.props as SectionListProps<unknown>;
|
|
167
|
+
return (
|
|
168
|
+
<KeyboardAwareSectionList {...createKeyboardAwareProps(childProps)} />
|
|
169
|
+
);
|
|
134
170
|
}
|
|
135
171
|
|
|
136
172
|
// 理论上不应运行到这里,如果是非标准组件则原样返回,仅修改样式
|
|
173
|
+
const childProps = element.props as NativeScrollableProps;
|
|
137
174
|
return React.cloneElement(element, {
|
|
138
|
-
contentContainerStyle:
|
|
139
|
-
|
|
140
|
-
|
|
175
|
+
contentContainerStyle: createEnhancedContentStyle(
|
|
176
|
+
childProps.contentContainerStyle,
|
|
177
|
+
),
|
|
178
|
+
keyboardShouldPersistTaps:
|
|
179
|
+
childProps.keyboardShouldPersistTaps ?? 'handled',
|
|
180
|
+
keyboardDismissMode: childProps.keyboardDismissMode ?? 'on-drag',
|
|
141
181
|
});
|
|
142
182
|
};
|
|
143
183
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React, { forwardRef, useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type GestureResponderEvent,
|
|
4
|
+
View,
|
|
5
|
+
Text as RNText,
|
|
6
|
+
} from 'react-native';
|
|
3
7
|
import { GestureDetector } from 'react-native-gesture-handler';
|
|
4
8
|
import Animated from 'react-native-reanimated';
|
|
5
9
|
import { useThemeColor } from '../../helpers/external/hooks';
|
|
@@ -339,7 +343,7 @@ const ToastClose = forwardRef<View, ToastCloseProps>((props, ref) => {
|
|
|
339
343
|
* If hide and id are available from context, use them to hide the toast
|
|
340
344
|
* Otherwise, use the provided onPress handler
|
|
341
345
|
*/
|
|
342
|
-
const handlePress = (event:
|
|
346
|
+
const handlePress = (event: GestureResponderEvent) => {
|
|
343
347
|
if (hide && id) {
|
|
344
348
|
hide(id);
|
|
345
349
|
}
|
package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-controllable-state.ts
CHANGED
|
@@ -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:
|
|
111
|
+
function useCallbackRef<T extends (...args: never[]) => unknown>(
|
|
112
112
|
callback: T | undefined
|
|
113
113
|
): T {
|
|
114
114
|
const callbackRef = useRef(callback);
|
|
@@ -269,8 +269,8 @@ importers:
|
|
|
269
269
|
specifier: ^2.8.5
|
|
270
270
|
version: 2.8.6
|
|
271
271
|
coze-coding-dev-sdk:
|
|
272
|
-
specifier: ^0.7.
|
|
273
|
-
version: 0.7.
|
|
272
|
+
specifier: ^0.7.30
|
|
273
|
+
version: 0.7.30(openai@6.16.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)
|
|
274
274
|
dayjs:
|
|
275
275
|
specifier: ^1.11.20
|
|
276
276
|
version: 1.11.20
|
|
@@ -2643,8 +2643,8 @@ packages:
|
|
|
2643
2643
|
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
|
|
2644
2644
|
engines: {node: '>=10'}
|
|
2645
2645
|
|
|
2646
|
-
coze-coding-dev-sdk@0.7.
|
|
2647
|
-
resolution: {integrity: sha512-
|
|
2646
|
+
coze-coding-dev-sdk@0.7.30:
|
|
2647
|
+
resolution: {integrity: sha512-BhyMFh7zZPFeN9VRxvqPJ5NS8WO+MJD/bVdzXkuJivCgvc4e2BnpT895rGodLV0TvgJUYYk2O0XJOZSU1OFRyA==}
|
|
2648
2648
|
engines: {node: '>=18.0.0'}
|
|
2649
2649
|
hasBin: true
|
|
2650
2650
|
|
|
@@ -9088,7 +9088,7 @@ snapshots:
|
|
|
9088
9088
|
path-type: 4.0.0
|
|
9089
9089
|
yaml: 1.10.2
|
|
9090
9090
|
|
|
9091
|
-
coze-coding-dev-sdk@0.7.
|
|
9091
|
+
coze-coding-dev-sdk@0.7.30(openai@6.16.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0):
|
|
9092
9092
|
dependencies:
|
|
9093
9093
|
'@langchain/core': 1.1.17(openai@6.16.0(ws@8.19.0)(zod@4.3.6))
|
|
9094
9094
|
'@langchain/openai': 1.2.3(@langchain/core@1.1.17(openai@6.16.0(ws@8.19.0)(zod@4.3.6)))(ws@8.19.0)
|
|
@@ -5,10 +5,10 @@ project_type = "web"
|
|
|
5
5
|
|
|
6
6
|
[dev]
|
|
7
7
|
build = []
|
|
8
|
-
run = ["
|
|
8
|
+
run = [ "sh", "-c", "exec python3 -m http.server ${DEPLOY_RUN_PORT} --bind 0.0.0.0" ]
|
|
9
9
|
run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/serve.ps1"]
|
|
10
10
|
|
|
11
11
|
[deploy]
|
|
12
12
|
build = []
|
|
13
|
-
run = ["
|
|
13
|
+
run = [ "sh", "-c", "exec python3 -m http.server ${DEPLOY_RUN_PORT} --bind 0.0.0.0" ]
|
|
14
14
|
run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/serve.ps1"]
|
|
@@ -23,6 +23,11 @@ const eslintConfig = defineConfig([
|
|
|
23
23
|
...nextVitals,
|
|
24
24
|
...nextTs,
|
|
25
25
|
{
|
|
26
|
+
settings: {
|
|
27
|
+
// node_modules 里的 barrel 包(lucide-react 等)不参与 ExportMap 构建,
|
|
28
|
+
// import/no-cycle 只需要项目源码的依赖图。
|
|
29
|
+
'import/ignore': ['/node_modules/'],
|
|
30
|
+
},
|
|
26
31
|
rules: {
|
|
27
32
|
'import/no-cycle': ['error', { ignoreExternal: true }],
|
|
28
33
|
'react-hooks/set-state-in-effect': 'off',
|
|
@@ -37,14 +42,15 @@ const eslintConfig = defineConfig([
|
|
|
37
42
|
},
|
|
38
43
|
// Override default ignores of eslint-config-next.
|
|
39
44
|
globalIgnores([
|
|
40
|
-
// Default ignores of eslint-config-next
|
|
41
|
-
|
|
42
|
-
'
|
|
43
|
-
'
|
|
45
|
+
// Default ignores of eslint-config-next (trailing slash prunes the whole
|
|
46
|
+
// directory instead of walking into it):
|
|
47
|
+
'.next/',
|
|
48
|
+
'out/',
|
|
49
|
+
'build/',
|
|
44
50
|
'next-env.d.ts',
|
|
45
51
|
// Build artifacts:
|
|
46
52
|
'server.js',
|
|
47
|
-
'dist
|
|
53
|
+
'dist/',
|
|
48
54
|
// Script files (CommonJS):
|
|
49
55
|
'scripts/**/*.js',
|
|
50
56
|
]),
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import type { NextConfig } from 'next';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
|
|
3
4
|
const nextConfig: NextConfig = {
|
|
4
5
|
// outputFileTracingRoot: path.resolve(__dirname, '../../'), // Uncomment and add 'import path from "path"' if needed
|
|
5
6
|
/* config options here */
|
|
7
|
+
serverExternalPackages: ['coze-coding-dev-sdk'],
|
|
8
|
+
webpack: (config, { dev }) => {
|
|
9
|
+
if (dev && config.cache && config.cache.type === 'filesystem') {
|
|
10
|
+
config.cache.cacheDirectory = path.resolve(
|
|
11
|
+
'node_modules/.cache/next-webpack',
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return config;
|
|
15
|
+
},
|
|
6
16
|
allowedDevOrigins: ['*.dev.coze.site'],
|
|
7
17
|
images: {
|
|
8
18
|
remotePatterns: [
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"build": "bash ./scripts/build.sh",
|
|
7
7
|
"dev": "bash ./scripts/dev.sh",
|
|
8
8
|
"preinstall": "npx only-allow pnpm",
|
|
9
|
-
"lint": "eslint",
|
|
9
|
+
"lint": "eslint --cache --cache-location node_modules/.cache/eslint/",
|
|
10
10
|
"lint:build": "eslint . --quiet",
|
|
11
11
|
"lint:style": "stylelint \"src/**/*.css\"",
|
|
12
12
|
"start": "bash ./scripts/start.sh",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"class-variance-authority": "^0.7.1",
|
|
48
48
|
"clsx": "^2.1.1",
|
|
49
49
|
"cmdk": "^1.1.1",
|
|
50
|
-
"coze-coding-dev-sdk": "^0.7.
|
|
50
|
+
"coze-coding-dev-sdk": "^0.7.30",
|
|
51
51
|
"date-fns": "^4.1.0",
|
|
52
52
|
"dotenv": "^17.2.3",
|
|
53
53
|
"drizzle-kit": "^0.31.8",
|
|
@@ -73,17 +73,14 @@
|
|
|
73
73
|
"zod": "^4.3.5"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@react-dev-inspector/babel-plugin": "^2.0.1",
|
|
77
|
-
"@react-dev-inspector/middleware": "^2.0.1",
|
|
78
76
|
"@tailwindcss/postcss": "^4",
|
|
79
77
|
"@types/node": "^20",
|
|
80
78
|
"@types/pg": "^8.16.0",
|
|
81
79
|
"@types/react": "^19",
|
|
82
80
|
"@types/react-dom": "^19",
|
|
83
81
|
"eslint": "^9",
|
|
84
|
-
"eslint-config-next": "16.
|
|
82
|
+
"eslint-config-next": "16.1.1",
|
|
85
83
|
"only-allow": "^1.2.2",
|
|
86
|
-
"react-dev-inspector": "^2.0.1",
|
|
87
84
|
"shadcn": "latest",
|
|
88
85
|
"stylelint": "^16.4.0",
|
|
89
86
|
"stylelint-config-standard": "^38.0.0",
|