@coze-arch/cli 0.0.37 → 0.0.39-alpha.bdff32
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/README.md +69 -104
- package/docs/deploy.md +181 -0
- package/lib/__templates__/expo/.coze +5 -0
- package/lib/__templates__/expo/.cozeproj/scripts/dev_build.ps1 +10 -0
- package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +4 -0
- package/lib/__templates__/expo/.cozeproj/scripts/dev_run.ps1 +74 -0
- package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +108 -19
- package/lib/__templates__/expo/.cozeproj/scripts/prod_build.ps1 +15 -0
- package/lib/__templates__/expo/.cozeproj/scripts/prod_run.ps1 +10 -0
- package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +1 -1
- package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +1 -1
- package/lib/__templates__/expo/.cozeproj/scripts/validate.ps1 +7 -0
- package/lib/__templates__/expo/client/metro.config.js +3 -1
- package/lib/__templates__/expo/pnpm-lock.yaml +5 -5
- package/lib/__templates__/expo/server/package.json +2 -2
- package/lib/__templates__/expo/server/src/index.ts +1 -1
- package/lib/__templates__/expo/template.config.js +11 -2
- package/lib/__templates__/native-static/.coze +4 -2
- package/lib/__templates__/native-static/scripts/serve.ps1 +7 -0
- package/lib/__templates__/nextjs/.coze +5 -0
- package/lib/__templates__/nextjs/package.json +7 -2
- package/lib/__templates__/nextjs/pnpm-lock.yaml +59 -334
- package/lib/__templates__/nextjs/scripts/build.ps1 +16 -0
- package/lib/__templates__/nextjs/scripts/dev.ps1 +63 -0
- package/lib/__templates__/nextjs/scripts/dev.sh +234 -7
- package/lib/__templates__/nextjs/scripts/prepare.ps1 +18 -0
- package/lib/__templates__/nextjs/scripts/start.ps1 +11 -0
- package/lib/__templates__/nextjs/scripts/validate.ps1 +8 -0
- package/lib/__templates__/nextjs/template.config.js +4 -2
- package/lib/__templates__/nuxt-vue/.coze +5 -0
- 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.ps1 +12 -0
- package/lib/__templates__/nuxt-vue/scripts/dev.ps1 +63 -0
- package/lib/__templates__/nuxt-vue/scripts/dev.sh +232 -3
- package/lib/__templates__/nuxt-vue/scripts/prepare.ps1 +12 -0
- package/lib/__templates__/nuxt-vue/scripts/start.ps1 +11 -0
- package/lib/__templates__/nuxt-vue/scripts/validate.ps1 +8 -0
- package/lib/__templates__/phaser/.coze +18 -0
- package/lib/__templates__/phaser/README.md +45 -0
- package/lib/__templates__/phaser/_gitignore +23 -0
- package/lib/__templates__/phaser/_npmrc +14 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0001.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0002.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0003.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0004.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0005.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0006.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0007.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0008.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0009.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0010.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0011.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0012.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0013.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0014.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0015.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0016.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0017.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0018.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0019.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0020.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0021.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0022.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0023.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0024.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/manifest.json +11 -0
- package/lib/__templates__/phaser/debug-runtime/flow-graph.json +20 -0
- package/lib/__templates__/phaser/index.html +12 -0
- package/lib/__templates__/phaser/package.json +31 -0
- package/lib/__templates__/phaser/pnpm-lock.yaml +661 -0
- package/lib/__templates__/phaser/scripts/build.ps1 +12 -0
- package/lib/__templates__/phaser/scripts/build.sh +8 -0
- package/lib/__templates__/phaser/scripts/dev.ps1 +49 -0
- package/lib/__templates__/phaser/scripts/dev.sh +82 -0
- package/lib/__templates__/phaser/scripts/prepare.ps1 +8 -0
- package/lib/__templates__/phaser/scripts/prepare.sh +7 -0
- package/lib/__templates__/phaser/scripts/spawn-detached.cjs +29 -0
- package/lib/__templates__/phaser/scripts/start.ps1 +49 -0
- package/lib/__templates__/phaser/scripts/start.sh +82 -0
- package/lib/__templates__/phaser/scripts/validate.ps1 +7 -0
- package/lib/__templates__/phaser/scripts/validate.sh +7 -0
- package/lib/__templates__/phaser/src/assets.ts +15 -0
- package/lib/__templates__/phaser/src/global.d.ts +39 -0
- package/lib/__templates__/phaser/src/main.ts +28 -0
- package/lib/__templates__/phaser/src/scene/BootScene.ts +213 -0
- package/lib/__templates__/phaser/src/scene/DevLoadingScene.ts +69 -0
- package/lib/__templates__/phaser/src/style.css +28 -0
- package/lib/__templates__/phaser/src/types.ts +32 -0
- package/lib/__templates__/phaser/src/utils/asset-loader.ts +319 -0
- package/lib/__templates__/phaser/src/utils/index.ts +2 -0
- package/lib/__templates__/phaser/src/utils/mark-editable.ts +13 -0
- package/lib/__templates__/phaser/template.config.js +43 -0
- package/lib/__templates__/phaser/tsconfig.json +23 -0
- package/lib/__templates__/phaser/vite.config.ts +96 -0
- package/lib/__templates__/phaser-static/.coze +15 -0
- package/lib/__templates__/phaser-static/README.md +40 -0
- package/lib/__templates__/phaser-static/_gitignore +6 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0001.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0002.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0003.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0004.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0005.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0006.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0007.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0008.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0009.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0010.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0011.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0012.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0013.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0014.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0015.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0016.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0017.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0018.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0019.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0020.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0021.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0022.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0023.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0024.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/manifest.json +11 -0
- package/lib/__templates__/phaser-static/debug-runtime/flow-graph.json +20 -0
- package/lib/__templates__/phaser-static/index.html +17 -0
- package/lib/__templates__/phaser-static/scripts/serve.ps1 +7 -0
- package/lib/__templates__/phaser-static/src/assets.js +15 -0
- package/lib/__templates__/phaser-static/src/main.js +26 -0
- package/lib/__templates__/phaser-static/src/phaser.js +7 -0
- package/lib/__templates__/phaser-static/src/scene/BootScene.js +205 -0
- package/lib/__templates__/phaser-static/src/scene/DevLoadingScene.js +67 -0
- package/lib/__templates__/phaser-static/src/style.css +28 -0
- package/lib/__templates__/phaser-static/src/utils/asset-loader.js +267 -0
- package/lib/__templates__/phaser-static/src/utils/index.js +2 -0
- package/lib/__templates__/phaser-static/src/utils/mark-editable.js +3 -0
- package/lib/__templates__/phaser-static/template.config.js +35 -0
- package/lib/__templates__/pi-agent/package.json +1 -1
- package/lib/__templates__/pi-agent/pnpm-lock.yaml +5 -5
- package/lib/__templates__/taro/.coze +6 -0
- package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.ps1 +10 -0
- package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.ps1 +8 -0
- package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +1 -1
- package/lib/__templates__/taro/.cozeproj/scripts/dev_build.ps1 +3 -0
- package/lib/__templates__/taro/.cozeproj/scripts/dev_run.ps1 +62 -0
- package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +178 -68
- package/lib/__templates__/taro/.cozeproj/scripts/pack.ps1 +7 -0
- package/lib/__templates__/taro/.cozeproj/scripts/validate.ps1 +7 -0
- package/lib/__templates__/taro/AGENTS.md +11 -7
- package/lib/__templates__/taro/README.md +4 -4
- package/lib/__templates__/taro/config/index.ts +10 -2
- package/lib/__templates__/taro/pnpm-lock.yaml +5 -5
- package/lib/__templates__/taro/server/package.json +1 -1
- package/lib/__templates__/taro/server/src/main.ts +8 -2
- package/lib/__templates__/templates.json +51 -1
- package/lib/__templates__/vite/.coze +5 -0
- package/lib/__templates__/vite/package.json +1 -1
- package/lib/__templates__/vite/pnpm-lock.yaml +5 -5
- package/lib/__templates__/vite/scripts/build.ps1 +16 -0
- package/lib/__templates__/vite/scripts/dev.ps1 +63 -0
- package/lib/__templates__/vite/scripts/dev.sh +110 -1
- package/lib/__templates__/vite/scripts/prepare.ps1 +18 -0
- package/lib/__templates__/vite/scripts/start.ps1 +11 -0
- package/lib/__templates__/vite/scripts/validate.ps1 +8 -0
- package/lib/__templates__/vite/template.config.js +4 -2
- package/lib/cli.js +3719 -211
- package/lib/deploy/package-project.js +244 -0
- package/lib/deploy/package-project.py +183 -0
- package/package.json +5 -2
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
echo "⚙️ dev_run.sh 开始运行"
|
|
3
3
|
set -Eeuo pipefail
|
|
4
4
|
|
|
5
|
+
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
6
|
+
COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-${ROOT_DIR}}"
|
|
5
7
|
cd "${COZE_WORKSPACE_PATH}"
|
|
6
8
|
|
|
7
9
|
# ---------------------------------------------------------
|
|
8
|
-
#
|
|
10
|
+
# 项目级日志目录
|
|
9
11
|
# ---------------------------------------------------------
|
|
10
|
-
|
|
12
|
+
LOG_DIR="${COZE_WORKSPACE_PATH}/logs"
|
|
13
|
+
LOG_FILE="${LOG_DIR}/dev.log"
|
|
14
|
+
PID_FILE="${LOG_DIR}/dev.pid"
|
|
15
|
+
DEV_PID=""
|
|
11
16
|
|
|
12
17
|
# ---------------------------------------------------------
|
|
13
18
|
# 工具函数
|
|
@@ -25,99 +30,192 @@ kill_process_tree() {
|
|
|
25
30
|
fi
|
|
26
31
|
}
|
|
27
32
|
|
|
33
|
+
# detached 出去的进程没人负责回收,超过这个时长就自己退出,避免端口与内存长期泄露。
|
|
34
|
+
MAX_RUNTIME_SECONDS=1200
|
|
35
|
+
|
|
36
|
+
# 真正被 detach 的是这层 bash wrapper:它是进程组 leader,组内 watchdog 到点回收整组
|
|
37
|
+
# (wrapper -> pnpm -> taro/nest);被包的进程自己先退出时也顺手清空进程组,不留残余。
|
|
38
|
+
RUN_WITH_TIMEOUT='
|
|
39
|
+
timeout_seconds=$1
|
|
40
|
+
shift
|
|
41
|
+
|
|
42
|
+
"$@" &
|
|
43
|
+
child_pid=$!
|
|
44
|
+
|
|
45
|
+
# 先忽略 TERM,才能在向整组发 TERM(自己也在组里)之后存活下来补一发 KILL。
|
|
46
|
+
( trap "" TERM
|
|
47
|
+
sleep "${timeout_seconds}"
|
|
48
|
+
echo "[dev] 后台进程运行超过 ${timeout_seconds}s,回收进程组 $$。"
|
|
49
|
+
kill -TERM -- "-$$" 2>/dev/null || true
|
|
50
|
+
sleep 5
|
|
51
|
+
kill -KILL -- "-$$" 2>/dev/null || true
|
|
52
|
+
) &
|
|
53
|
+
|
|
54
|
+
wait "${child_pid}"
|
|
55
|
+
kill -KILL -- "-$$" 2>/dev/null || true
|
|
56
|
+
'
|
|
57
|
+
|
|
58
|
+
# coze-daemon 会在 runtime shell 退出时清理原进程组。
|
|
59
|
+
# 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
|
|
60
|
+
# 返回的 PID 是 wrapper 的,同时也是整个进程组的 PGID,后续按组回收。
|
|
61
|
+
spawn_detached() {
|
|
62
|
+
local cwd="$1"
|
|
63
|
+
local log_file="$2"
|
|
64
|
+
shift 2
|
|
65
|
+
|
|
66
|
+
node - "$cwd" "$log_file" \
|
|
67
|
+
/bin/bash -c "${RUN_WITH_TIMEOUT}" detached-runner "${MAX_RUNTIME_SECONDS}" "$@" <<'NODE'
|
|
68
|
+
const fs = require('node:fs');
|
|
69
|
+
const { spawn } = require('node:child_process');
|
|
70
|
+
|
|
71
|
+
const [cwd, logFile, command, ...args] = process.argv.slice(2);
|
|
72
|
+
if (!cwd || !logFile || !command) {
|
|
73
|
+
throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const logFd = fs.openSync(logFile, 'a');
|
|
77
|
+
try {
|
|
78
|
+
const child = spawn(command, args, {
|
|
79
|
+
cwd,
|
|
80
|
+
detached: true,
|
|
81
|
+
env: process.env,
|
|
82
|
+
stdio: ['ignore', logFd, logFd],
|
|
83
|
+
});
|
|
84
|
+
child.unref();
|
|
85
|
+
process.stdout.write(String(child.pid));
|
|
86
|
+
} finally {
|
|
87
|
+
fs.closeSync(logFd);
|
|
88
|
+
}
|
|
89
|
+
NODE
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
stop_detached() {
|
|
93
|
+
local pid="${1:-}"
|
|
94
|
+
if [[ -z "${pid}" ]]; then
|
|
95
|
+
return
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
kill -TERM -- "-${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null || true
|
|
99
|
+
sleep 1
|
|
100
|
+
kill -KILL -- "-${pid}" 2>/dev/null || true
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
process_belongs_to_workspace() {
|
|
104
|
+
local pid=$1
|
|
105
|
+
local cwd=""
|
|
106
|
+
|
|
107
|
+
if [[ -L "/proc/${pid}/cwd" ]]; then
|
|
108
|
+
cwd=$(readlink "/proc/${pid}/cwd" 2>/dev/null || true)
|
|
109
|
+
elif command -v lsof >/dev/null 2>&1; then
|
|
110
|
+
cwd=$(lsof -a -p "${pid}" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' | head -1)
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
case "${cwd}" in
|
|
114
|
+
"${COZE_WORKSPACE_PATH}"|"${COZE_WORKSPACE_PATH}"/*) return 0 ;;
|
|
115
|
+
*) return 1 ;;
|
|
116
|
+
esac
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
process_group_belongs_to_workspace() {
|
|
120
|
+
local pgid=$1
|
|
121
|
+
local pids
|
|
122
|
+
local found=0
|
|
123
|
+
|
|
124
|
+
pids=$(ps -axo pid=,pgid= 2>/dev/null | awk -v pgid="${pgid}" '$2 == pgid {print $1}')
|
|
125
|
+
for pid in ${pids}; do
|
|
126
|
+
found=1
|
|
127
|
+
if ! process_belongs_to_workspace "${pid}"; then
|
|
128
|
+
return 1
|
|
129
|
+
fi
|
|
130
|
+
done
|
|
131
|
+
|
|
132
|
+
[[ "${found}" -eq 1 ]]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# 优先用 ss,无结果或缺少 ss 时回落到 lsof;两者都不可用则显式告警,避免静默误判为端口空闲
|
|
136
|
+
list_port_pids() {
|
|
137
|
+
local port=$1
|
|
138
|
+
local pids=""
|
|
139
|
+
local has_tool=0
|
|
140
|
+
|
|
141
|
+
if command -v ss >/dev/null 2>&1; then
|
|
142
|
+
has_tool=1
|
|
143
|
+
pids=$(ss -H -lntp 2>/dev/null | awk -v port="${port}" '$4 ~ ":"port"$"' | grep -o 'pid=[0-9]*' | cut -d= -f2 | sort -u | paste -sd' ' - || true)
|
|
144
|
+
fi
|
|
145
|
+
if [[ -z "${pids}" ]] && command -v lsof >/dev/null 2>&1; then
|
|
146
|
+
has_tool=1
|
|
147
|
+
pids=$(lsof -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null | sort -u | paste -sd' ' - || true)
|
|
148
|
+
fi
|
|
149
|
+
if [[ "${has_tool}" -eq 0 ]]; then
|
|
150
|
+
echo "Warning: neither ss nor lsof available, cannot inspect port ${port}." >&2
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
echo "${pids}"
|
|
154
|
+
}
|
|
155
|
+
|
|
28
156
|
kill_port_if_listening() {
|
|
29
157
|
local port=$1
|
|
30
158
|
local pids
|
|
31
|
-
pids=$(
|
|
159
|
+
pids=$(list_port_pids "${port}")
|
|
32
160
|
if [[ -z "${pids}" ]]; then
|
|
33
161
|
echo "Port ${port} is free."
|
|
34
162
|
return
|
|
35
163
|
fi
|
|
36
|
-
echo "Port ${port} in use by PIDs: ${pids}"
|
|
164
|
+
echo "Port ${port} in use by PIDs: ${pids} (SIGKILL)"
|
|
37
165
|
for pid in ${pids}; do
|
|
38
166
|
kill_process_tree "${pid}"
|
|
39
167
|
done
|
|
40
168
|
sleep 1
|
|
41
|
-
pids=$(
|
|
169
|
+
pids=$(list_port_pids "${port}")
|
|
42
170
|
if [[ -n "${pids}" ]]; then
|
|
43
|
-
echo "Warning: port ${port} still busy after
|
|
171
|
+
echo "Warning: port ${port} still busy after SIGKILL, PIDs: ${pids}"
|
|
44
172
|
else
|
|
45
173
|
echo "Port ${port} cleared."
|
|
46
174
|
fi
|
|
47
175
|
}
|
|
48
176
|
|
|
49
|
-
#
|
|
50
|
-
# 1. 清理上一次运行残留的整棵进程树
|
|
51
|
-
# ---------------------------------------------------------
|
|
177
|
+
# 只清理当前项目上次记录的 detached 进程。
|
|
52
178
|
cleanup_previous_run() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
local old_pid
|
|
56
|
-
old_pid=$(cat "${PID_FILE}" 2>/dev/null || true)
|
|
57
|
-
if [[ -n "${old_pid}" ]] && kill -0 "${old_pid}" 2>/dev/null; then
|
|
58
|
-
echo "🧹 Killing previous dev process tree (root PID: ${old_pid})..."
|
|
59
|
-
kill_process_tree "${old_pid}"
|
|
60
|
-
fi
|
|
61
|
-
rm -f "${PID_FILE}"
|
|
179
|
+
if [[ ! -f "${PID_FILE}" ]]; then
|
|
180
|
+
return
|
|
62
181
|
fi
|
|
63
182
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"node --enable-source-maps.*/workspace/projects/server/dist/main"
|
|
72
|
-
"esbuild --service.*--ping"
|
|
73
|
-
)
|
|
74
|
-
for pattern in "${patterns[@]}"; do
|
|
75
|
-
local pids
|
|
76
|
-
pids=$(pgrep -f "${pattern}" 2>/dev/null || true)
|
|
77
|
-
for pid in ${pids}; do
|
|
78
|
-
# 不杀自己和自己的父进程链
|
|
79
|
-
if [[ "${pid}" != "$$" ]] && [[ "${pid}" != "${PPID}" ]]; then
|
|
80
|
-
echo " Killing orphan PID ${pid} matching '${pattern}'"
|
|
81
|
-
kill -9 "${pid}" 2>/dev/null || true
|
|
82
|
-
fi
|
|
83
|
-
done
|
|
84
|
-
done
|
|
85
|
-
sleep 1
|
|
183
|
+
local old_pid
|
|
184
|
+
old_pid=$(cat "${PID_FILE}" 2>/dev/null || true)
|
|
185
|
+
if [[ "${old_pid}" =~ ^[1-9][0-9]*$ ]] && process_group_belongs_to_workspace "${old_pid}"; then
|
|
186
|
+
echo "🧹 Killing previous dev process group (PGID: ${old_pid})..."
|
|
187
|
+
stop_detached "${old_pid}"
|
|
188
|
+
fi
|
|
189
|
+
rm -f "${PID_FILE}"
|
|
86
190
|
}
|
|
87
191
|
|
|
88
192
|
# ---------------------------------------------------------
|
|
89
193
|
# 2. 安装依赖
|
|
90
194
|
# ---------------------------------------------------------
|
|
91
195
|
echo "📦 Installing dependencies..."
|
|
92
|
-
pnpm
|
|
196
|
+
PNPM_BIN="$(command -v pnpm)"
|
|
197
|
+
"${PNPM_BIN}" install
|
|
93
198
|
echo "✅ Dependencies installed successfully!"
|
|
94
199
|
|
|
95
200
|
# ---------------------------------------------------------
|
|
96
201
|
# 3. 清理旧进程 + 端口
|
|
97
202
|
# ---------------------------------------------------------
|
|
98
|
-
|
|
203
|
+
# DEPLOY_RUN_PORT 是平台注入的对外端口,项目内统一使用 PORT。
|
|
204
|
+
PORT="${DEPLOY_RUN_PORT:-${PORT:-<%= port %>}}"
|
|
205
|
+
SERVER_PORT="${SERVER_PORT:-<%= serverPort %>}"
|
|
206
|
+
export PORT
|
|
207
|
+
export SERVER_PORT
|
|
99
208
|
|
|
209
|
+
mkdir -p "${LOG_DIR}"
|
|
100
210
|
cleanup_previous_run
|
|
101
211
|
|
|
102
|
-
echo "Clearing port ${
|
|
103
|
-
kill_port_if_listening "${
|
|
212
|
+
echo "Clearing port ${PORT} (web) before start."
|
|
213
|
+
kill_port_if_listening "${PORT}"
|
|
104
214
|
echo "Clearing port ${SERVER_PORT} (server) before start."
|
|
105
215
|
kill_port_if_listening "${SERVER_PORT}"
|
|
106
216
|
|
|
107
217
|
# ---------------------------------------------------------
|
|
108
|
-
# 4.
|
|
109
|
-
# ---------------------------------------------------------
|
|
110
|
-
cleanup_on_exit() {
|
|
111
|
-
echo "🛑 dev_run.sh exiting, cleaning up child processes..."
|
|
112
|
-
# 杀掉当前脚本的所有子进程
|
|
113
|
-
kill -- -$$ 2>/dev/null || true
|
|
114
|
-
rm -f "${PID_FILE}"
|
|
115
|
-
exit 0
|
|
116
|
-
}
|
|
117
|
-
trap cleanup_on_exit EXIT INT TERM HUP
|
|
118
|
-
|
|
119
|
-
# ---------------------------------------------------------
|
|
120
|
-
# 5. 启动服务
|
|
218
|
+
# 4. 启动服务
|
|
121
219
|
# ---------------------------------------------------------
|
|
122
220
|
start_service() {
|
|
123
221
|
cd "${COZE_WORKSPACE_PATH}"
|
|
@@ -133,19 +231,31 @@ start_service() {
|
|
|
133
231
|
# 启动 Taro H5 和 NestJS Server
|
|
134
232
|
echo "Starting Taro H5 Dev Server and NestJS Server..."
|
|
135
233
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
234
|
+
: > "${LOG_FILE}"
|
|
235
|
+
|
|
236
|
+
DEV_PID="$(spawn_detached \
|
|
237
|
+
"${COZE_WORKSPACE_PATH}" \
|
|
238
|
+
"${LOG_FILE}" \
|
|
239
|
+
"${PNPM_BIN}" dev)"
|
|
240
|
+
if [[ -z "${DEV_PID}" ]]; then
|
|
241
|
+
echo "❌ 无法获取 dev 后台进程 PID"
|
|
242
|
+
return 1
|
|
243
|
+
fi
|
|
244
|
+
echo "${DEV_PID}" > "${PID_FILE}"
|
|
139
245
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
246
|
+
sleep 1
|
|
247
|
+
if ! kill -0 "${DEV_PID}" 2>/dev/null; then
|
|
248
|
+
echo "❌ Dev service failed to start. See ${LOG_FILE}." >&2
|
|
249
|
+
tail -n 20 "${LOG_FILE}" >&2 || true
|
|
250
|
+
rm -f "${PID_FILE}"
|
|
251
|
+
return 1
|
|
252
|
+
fi
|
|
145
253
|
|
|
146
|
-
|
|
147
|
-
|
|
254
|
+
echo "📝 Dev process started with PID: ${DEV_PID}"
|
|
255
|
+
echo "Auto stop after ${MAX_RUNTIME_SECONDS}s."
|
|
256
|
+
echo "Log file: ${LOG_FILE}"
|
|
257
|
+
echo "PID file: ${PID_FILE}"
|
|
148
258
|
}
|
|
149
259
|
|
|
150
|
-
echo "Starting HTTP services on port ${
|
|
260
|
+
echo "Starting HTTP services on port ${PORT} (web) and ${SERVER_PORT} (server)..."
|
|
151
261
|
start_service
|
|
@@ -361,20 +361,24 @@ if (isExternalUrl) {
|
|
|
361
361
|
|
|
362
362
|
**工作原理**:
|
|
363
363
|
|
|
364
|
-
1. **开发环境(H5)**:使用 `/api/xxx` 相对路径,Vite 的 proxy
|
|
364
|
+
1. **开发环境(H5)**:使用 `/api/xxx` 相对路径,Vite 的 proxy 会自动将其代理到后端;后端端口读取 `SERVER_PORT`,未设置时使用模板默认端口 `<%= serverPort %>`
|
|
365
365
|
2. **生产环境**:如果配置了 `PROJECT_DOMAIN` 环境变量,Network 会自动拼接为 `${PROJECT_DOMAIN}/api/xxx`
|
|
366
366
|
3. **小程序端**:同样会根据 `PROJECT_DOMAIN` 配置使用正确的域名
|
|
367
367
|
|
|
368
368
|
**Vite 代理配置**(已在项目中配置,无需修改):
|
|
369
369
|
|
|
370
370
|
```typescript
|
|
371
|
-
//
|
|
371
|
+
// config/index.ts
|
|
372
|
+
const serverPort = Number(process.env.SERVER_PORT) || <%= serverPort %>
|
|
373
|
+
|
|
372
374
|
export default {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
375
|
+
h5: {
|
|
376
|
+
devServer: {
|
|
377
|
+
proxy: {
|
|
378
|
+
'/api': {
|
|
379
|
+
target: `http://localhost:${serverPort}`,
|
|
380
|
+
changeOrigin: true
|
|
381
|
+
}
|
|
378
382
|
}
|
|
379
383
|
}
|
|
380
384
|
}
|
|
@@ -63,8 +63,8 @@ pnpm install
|
|
|
63
63
|
pnpm dev
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
- 前端地址:http://localhost
|
|
67
|
-
- 后端地址:http://localhost
|
|
66
|
+
- 前端地址:http://localhost:<%= port %>
|
|
67
|
+
- 后端地址:http://localhost:<%= serverPort %>
|
|
68
68
|
|
|
69
69
|
单独启动:
|
|
70
70
|
|
|
@@ -560,7 +560,7 @@ async function getLocation(): Promise<Taro.getLocation.SuccessCallbackResult> {
|
|
|
560
560
|
### 开发命令
|
|
561
561
|
|
|
562
562
|
```sh
|
|
563
|
-
pnpm dev:server // 启动开发服务 (热重载, 默认端口
|
|
563
|
+
pnpm dev:server // 启动开发服务 (热重载, 默认端口 <%= serverPort %>,可用 SERVER_PORT 环境变量覆盖)
|
|
564
564
|
pnpm build:server // 构建生产版本
|
|
565
565
|
```
|
|
566
566
|
|
|
@@ -586,7 +586,7 @@ npx nest g service modules/order
|
|
|
586
586
|
|
|
587
587
|
```sh
|
|
588
588
|
## 服务端口
|
|
589
|
-
|
|
589
|
+
SERVER_PORT=<%= serverPort %>
|
|
590
590
|
|
|
591
591
|
## 微信小程序配置
|
|
592
592
|
WX_APP_ID=你的AppID
|
|
@@ -12,6 +12,14 @@ import pkg from '../package.json';
|
|
|
12
12
|
|
|
13
13
|
dotenv.config({ path: path.resolve(__dirname, '../.env.local') });
|
|
14
14
|
|
|
15
|
+
const resolvePort = (value: string | undefined, fallback: number): number => {
|
|
16
|
+
const port = Number(value);
|
|
17
|
+
return Number.isInteger(port) && port > 0 && port < 65536 ? port : fallback;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const h5Port = resolvePort(process.env.PORT, <%= port %>);
|
|
21
|
+
const serverPort = resolvePort(process.env.SERVER_PORT, <%= serverPort %>);
|
|
22
|
+
|
|
15
23
|
const generateTTProjectConfig = (outputRoot: string) => {
|
|
16
24
|
const config = {
|
|
17
25
|
miniprogramRoot: './',
|
|
@@ -182,12 +190,12 @@ export default defineConfig<'vite'>(async (merge, _env) => {
|
|
|
182
190
|
mode: 'hash',
|
|
183
191
|
},
|
|
184
192
|
devServer: {
|
|
185
|
-
port:
|
|
193
|
+
port: h5Port,
|
|
186
194
|
host: '0.0.0.0',
|
|
187
195
|
open: false,
|
|
188
196
|
proxy: {
|
|
189
197
|
'/api': {
|
|
190
|
-
target:
|
|
198
|
+
target: `http://localhost:${serverPort}`,
|
|
191
199
|
changeOrigin: true,
|
|
192
200
|
},
|
|
193
201
|
},
|
|
@@ -204,8 +204,8 @@ importers:
|
|
|
204
204
|
specifier: 2.95.3
|
|
205
205
|
version: 2.95.3
|
|
206
206
|
coze-coding-dev-sdk:
|
|
207
|
-
specifier: ^0.7.
|
|
208
|
-
version: 0.7.
|
|
207
|
+
specifier: ^0.7.25
|
|
208
|
+
version: 0.7.25(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0)
|
|
209
209
|
dotenv:
|
|
210
210
|
specifier: ^17.2.3
|
|
211
211
|
version: 17.2.3
|
|
@@ -5416,8 +5416,8 @@ packages:
|
|
|
5416
5416
|
typescript:
|
|
5417
5417
|
optional: true
|
|
5418
5418
|
|
|
5419
|
-
coze-coding-dev-sdk@0.7.
|
|
5420
|
-
resolution: {integrity: sha512-
|
|
5419
|
+
coze-coding-dev-sdk@0.7.25:
|
|
5420
|
+
resolution: {integrity: sha512-5683ngikMdsRW0slGTE2OAZ1Fyj0lhkC4fGNOwsqKc35e68/gtg9KmmtK9CK9SZ+5/oIn/4wLoHXFB0gHJtO2A==}
|
|
5421
5421
|
engines: {node: '>=18.0.0'}
|
|
5422
5422
|
hasBin: true
|
|
5423
5423
|
|
|
@@ -17159,7 +17159,7 @@ snapshots:
|
|
|
17159
17159
|
optionalDependencies:
|
|
17160
17160
|
typescript: 5.9.3
|
|
17161
17161
|
|
|
17162
|
-
coze-coding-dev-sdk@0.7.
|
|
17162
|
+
coze-coding-dev-sdk@0.7.25(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0):
|
|
17163
17163
|
dependencies:
|
|
17164
17164
|
'@langchain/core': 1.1.16(openai@6.16.0(ws@8.19.0)(zod@4.3.5))
|
|
17165
17165
|
'@langchain/openai': 1.2.3(@langchain/core@1.1.16(openai@6.16.0(ws@8.19.0)(zod@4.3.5)))(ws@8.19.0)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@nestjs/core": "^10.4.15",
|
|
18
18
|
"@nestjs/platform-express": "^10.4.15",
|
|
19
19
|
"@supabase/supabase-js": "2.95.3",
|
|
20
|
-
"coze-coding-dev-sdk": "^0.7.
|
|
20
|
+
"coze-coding-dev-sdk": "^0.7.25",
|
|
21
21
|
"dotenv": "^17.2.3",
|
|
22
22
|
"drizzle-kit": "^0.31.8",
|
|
23
23
|
"drizzle-orm": "^0.45.1",
|
|
@@ -12,6 +12,12 @@ function parsePort(): number {
|
|
|
12
12
|
return port;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
const envPort = parseInt(process.env.SERVER_PORT || '', 10);
|
|
17
|
+
if (!isNaN(envPort) && envPort > 0 && envPort < 65536) {
|
|
18
|
+
return envPort;
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
return <%= serverPort %>;
|
|
16
22
|
}
|
|
17
23
|
|
|
@@ -38,12 +44,12 @@ async function bootstrap() {
|
|
|
38
44
|
console.log(`Server running on http://localhost:${port}`);
|
|
39
45
|
} catch (err) {
|
|
40
46
|
if (err.code === 'EADDRINUSE') {
|
|
41
|
-
console.error(`❌ 端口
|
|
47
|
+
console.error(`❌ 端口 ${port} 被占用,请设置其他 SERVER_PORT 后重试。`);
|
|
42
48
|
process.exit(1);
|
|
43
49
|
} else {
|
|
44
50
|
throw err;
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
|
-
console.log(`Application is running on: http://localhost
|
|
53
|
+
console.log(`Application is running on: http://localhost:${port}`);
|
|
48
54
|
}
|
|
49
55
|
bootstrap();
|
|
@@ -16,10 +16,17 @@
|
|
|
16
16
|
},
|
|
17
17
|
"port": {
|
|
18
18
|
"type": "number",
|
|
19
|
-
"default":
|
|
19
|
+
"default": 5000,
|
|
20
20
|
"minimum": 1024,
|
|
21
21
|
"maximum": 65535,
|
|
22
22
|
"description": "Metro bundler port"
|
|
23
|
+
},
|
|
24
|
+
"serverPort": {
|
|
25
|
+
"type": "number",
|
|
26
|
+
"default": 9091,
|
|
27
|
+
"minimum": 1024,
|
|
28
|
+
"maximum": 65535,
|
|
29
|
+
"description": "Express backend server port"
|
|
23
30
|
}
|
|
24
31
|
},
|
|
25
32
|
"required": [],
|
|
@@ -94,6 +101,49 @@
|
|
|
94
101
|
"additionalProperties": false
|
|
95
102
|
}
|
|
96
103
|
},
|
|
104
|
+
{
|
|
105
|
+
"name": "phaser",
|
|
106
|
+
"description": "Phaser(2D 游戏):`coze-dev init ${COZE_WORKSPACE_PATH} --template phaser`\n- 适用:基于 Phaser 3、Vite 和 TypeScript 的 2D Web 游戏。",
|
|
107
|
+
"location": "./phaser",
|
|
108
|
+
"paramsSchema": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"properties": {
|
|
111
|
+
"appName": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"minLength": 1,
|
|
114
|
+
"pattern": "^[a-z0-9-]+$",
|
|
115
|
+
"description": "Application name (lowercase, alphanumeric and hyphens only)"
|
|
116
|
+
},
|
|
117
|
+
"port": {
|
|
118
|
+
"type": "number",
|
|
119
|
+
"default": 5000,
|
|
120
|
+
"minimum": 1024,
|
|
121
|
+
"maximum": 65535,
|
|
122
|
+
"description": "Development and preview server port"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"required": [],
|
|
126
|
+
"additionalProperties": false
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "phaser-static",
|
|
131
|
+
"description": "Phaser Static(纯静态 2D 游戏):coze-dev init ${COZE_WORKSPACE_PATH} --template phaser-static\n- 适用:浏览器原生 JavaScript ESM 的 Phaser 3 游戏。\n- Phaser 与 Phaser Bridge 从 CDN 加载;无需 npm、Vite 或 TypeScript。",
|
|
132
|
+
"location": "./phaser-static",
|
|
133
|
+
"paramsSchema": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"properties": {
|
|
136
|
+
"appName": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"minLength": 1,
|
|
139
|
+
"pattern": "^[a-z0-9-]+$",
|
|
140
|
+
"description": "Application name (lowercase, alphanumeric and hyphens only)"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"required": [],
|
|
144
|
+
"additionalProperties": false
|
|
145
|
+
}
|
|
146
|
+
},
|
|
97
147
|
{
|
|
98
148
|
"name": "pi-agent",
|
|
99
149
|
"description": "Pi Agent:`coze-dev init ${COZE_WORKSPACE_PATH} --template pi-agent`\n- 适用:基于 pi-agent-core 的 AI Agent 应用\n- 支持飞书、微信等多渠道接入\n- 内置 Dashboard 管理面板\n- 使用 TypeScript + Express + Vite",
|
|
@@ -4,11 +4,16 @@ project_type = "web"
|
|
|
4
4
|
|
|
5
5
|
[dev]
|
|
6
6
|
build = ["bash", "./scripts/prepare.sh"]
|
|
7
|
+
build_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/prepare.ps1"]
|
|
7
8
|
run = ["bash", "./scripts/dev.sh"]
|
|
9
|
+
run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/dev.ps1"]
|
|
8
10
|
validate = ["bash", "./scripts/validate.sh"]
|
|
11
|
+
validate_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/validate.ps1"]
|
|
9
12
|
deps = ["git"] # -> apt install git
|
|
10
13
|
|
|
11
14
|
[deploy]
|
|
12
15
|
build = ["bash","./scripts/build.sh"]
|
|
16
|
+
build_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/build.ps1"]
|
|
13
17
|
run = ["bash","./scripts/start.sh"]
|
|
18
|
+
run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/start.ps1"]
|
|
14
19
|
deps = ["git"] # -> apt install git
|
|
@@ -32,8 +32,8 @@ importers:
|
|
|
32
32
|
specifier: ^10.4.20
|
|
33
33
|
version: 10.4.23(postcss@8.5.6)
|
|
34
34
|
coze-coding-dev-sdk:
|
|
35
|
-
specifier: ^0.7.
|
|
36
|
-
version: 0.7.
|
|
35
|
+
specifier: ^0.7.25
|
|
36
|
+
version: 0.7.25(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0)
|
|
37
37
|
esbuild:
|
|
38
38
|
specifier: ^0.27.2
|
|
39
39
|
version: 0.27.2
|
|
@@ -910,8 +910,8 @@ packages:
|
|
|
910
910
|
typescript:
|
|
911
911
|
optional: true
|
|
912
912
|
|
|
913
|
-
coze-coding-dev-sdk@0.7.
|
|
914
|
-
resolution: {integrity: sha512-
|
|
913
|
+
coze-coding-dev-sdk@0.7.25:
|
|
914
|
+
resolution: {integrity: sha512-5683ngikMdsRW0slGTE2OAZ1Fyj0lhkC4fGNOwsqKc35e68/gtg9KmmtK9CK9SZ+5/oIn/4wLoHXFB0gHJtO2A==}
|
|
915
915
|
engines: {node: '>=18.0.0'}
|
|
916
916
|
hasBin: true
|
|
917
917
|
|
|
@@ -3281,7 +3281,7 @@ snapshots:
|
|
|
3281
3281
|
optionalDependencies:
|
|
3282
3282
|
typescript: 5.9.3
|
|
3283
3283
|
|
|
3284
|
-
coze-coding-dev-sdk@0.7.
|
|
3284
|
+
coze-coding-dev-sdk@0.7.25(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0):
|
|
3285
3285
|
dependencies:
|
|
3286
3286
|
'@langchain/core': 1.1.16(openai@6.16.0(ws@8.19.0)(zod@4.3.5))
|
|
3287
3287
|
'@langchain/openai': 1.2.3(@langchain/core@1.1.16(openai@6.16.0(ws@8.19.0)(zod@4.3.5)))(ws@8.19.0)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
$ErrorActionPreference = "Stop"
|
|
2
|
+
|
|
3
|
+
$workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { (Get-Location).Path }
|
|
4
|
+
Set-Location $workspace
|
|
5
|
+
|
|
6
|
+
Write-Host "Installing dependencies..."
|
|
7
|
+
& pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
|
|
8
|
+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
9
|
+
|
|
10
|
+
Write-Host "Building frontend with Vite..."
|
|
11
|
+
& pnpm vite build
|
|
12
|
+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
13
|
+
|
|
14
|
+
Write-Host "Bundling server with tsup..."
|
|
15
|
+
& pnpm tsup server/server.ts --format cjs --platform node --target node20 --outDir dist-server --no-splitting --no-minify --external vite
|
|
16
|
+
exit $LASTEXITCODE
|