@coze-arch/cli 0.1.5 → 0.1.8-alpha.2ee669

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 (63) hide show
  1. package/README.md +18 -0
  2. package/docs/deploy.md +12 -1
  3. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +3 -3
  4. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +11 -3
  5. package/lib/__templates__/expo/.cozeproj/scripts/prepare-node-modules.sh +380 -0
  6. package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +3 -3
  7. package/lib/__templates__/expo/client/components/Screen.tsx +65 -25
  8. package/lib/__templates__/expo/client/heroui/components/toast/toast.tsx +6 -2
  9. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-controllable-state.ts +1 -1
  10. package/lib/__templates__/native-static/.coze +2 -2
  11. package/lib/__templates__/nextjs/.coze +1 -1
  12. package/lib/__templates__/nextjs/README.md +18 -0
  13. package/lib/__templates__/nextjs/eslint.config.mjs +11 -5
  14. package/lib/__templates__/nextjs/next.config.ts +10 -0
  15. package/lib/__templates__/nextjs/package.json +2 -5
  16. package/lib/__templates__/nextjs/pnpm-lock.yaml +14 -945
  17. package/lib/__templates__/nextjs/scripts/build.ps1 +1 -1
  18. package/lib/__templates__/nextjs/scripts/build.sh +1 -1
  19. package/lib/__templates__/nextjs/scripts/dev.ps1 +2 -2
  20. package/lib/__templates__/nextjs/scripts/dev.sh +70 -12
  21. package/lib/__templates__/nextjs/scripts/local-workspace.cjs +302 -0
  22. package/lib/__templates__/nextjs/scripts/prepare-node-modules.sh +380 -0
  23. package/lib/__templates__/nextjs/scripts/prepare.sh +9 -4
  24. package/lib/__templates__/nextjs/scripts/validate.sh +11 -1
  25. package/lib/__templates__/nextjs/src/app/layout.tsx +0 -4
  26. package/lib/__templates__/nextjs/src/server.ts +1 -1
  27. package/lib/__templates__/nextjs/template.config.js +20 -6
  28. package/lib/__templates__/nextjs/tsconfig.json +0 -1
  29. package/lib/__templates__/nuxt-vue/.coze +1 -1
  30. package/lib/__templates__/nuxt-vue/README.md +20 -2
  31. package/lib/__templates__/nuxt-vue/scripts/dev.sh +21 -7
  32. package/lib/__templates__/nuxt-vue/scripts/local-workspace.cjs +302 -0
  33. package/lib/__templates__/nuxt-vue/scripts/prepare-node-modules.sh +380 -0
  34. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +9 -4
  35. package/lib/__templates__/nuxt-vue/scripts/validate.sh +11 -1
  36. package/lib/__templates__/taro/.coze +2 -2
  37. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +10 -1
  38. package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +4 -0
  39. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +12 -0
  40. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.ps1 +4 -2
  41. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +84 -10
  42. package/lib/__templates__/taro/.cozeproj/scripts/init_env.sh +4 -0
  43. package/lib/__templates__/taro/.cozeproj/scripts/local-workspace.cjs +351 -0
  44. package/lib/__templates__/taro/.cozeproj/scripts/pack.ps1 +3 -1
  45. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +24 -6
  46. package/lib/__templates__/taro/.cozeproj/scripts/prepare-node-modules.sh +380 -0
  47. package/lib/__templates__/taro/.cozeproj/scripts/taro-build.cjs +66 -0
  48. package/lib/__templates__/taro/.cozeproj/scripts/validate.ps1 +3 -1
  49. package/lib/__templates__/taro/.cozeproj/scripts/validate.sh +7 -0
  50. package/lib/__templates__/taro/_gitignore +1 -0
  51. package/lib/__templates__/taro/package.json +5 -5
  52. package/lib/__templates__/vite/.coze +1 -1
  53. package/lib/__templates__/vite/README.md +20 -0
  54. package/lib/__templates__/vite/scripts/dev.ps1 +2 -2
  55. package/lib/__templates__/vite/scripts/dev.sh +21 -7
  56. package/lib/__templates__/vite/scripts/local-workspace.cjs +302 -0
  57. package/lib/__templates__/vite/scripts/prepare-node-modules.sh +380 -0
  58. package/lib/__templates__/vite/scripts/prepare.sh +9 -4
  59. package/lib/__templates__/vite/scripts/validate.sh +7 -1
  60. package/lib/__templates__/vite/template.config.js +20 -6
  61. package/lib/cli.js +511 -199
  62. package/package.json +3 -2
  63. package/lib/__templates__/nextjs/.babelrc +0 -15
@@ -1,14 +1,19 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
- COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
4
+ # Resolve the source project from this script, then let the Web runner choose its local mirror.
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
6
+ PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd -P)"
7
+ if [[ "${COZE_WEB_LOCAL_ACTIVE:-}" != "${PROJECT_ROOT}" ]]; then
8
+ exec node "${SCRIPT_DIR}/local-workspace.cjs" prepare "$@"
9
+ fi
10
+ COZE_WORKSPACE_PATH="${PROJECT_ROOT}"
5
11
 
6
12
  cd "${COZE_WORKSPACE_PATH}"
7
13
 
8
14
  echo "Installing dependencies..."
9
- pnpm install --prefer-frozen-lockfile --prefer-offline
10
- if command -v coze-dev > /dev/null 2>&1 && coze-dev check-bins --help > /dev/null 2>&1; then
11
- coze-dev check-bins --fix
15
+ if [[ "${COZE_WEB_LOCAL_MIRROR:-}" != "1" ]]; then
16
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline
12
17
  fi
13
18
 
14
19
  echo "Preparing Nuxt project..."
@@ -1,10 +1,20 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
- COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
4
+ # Resolve the source project from this script, then let the Web runner choose its local mirror.
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
6
+ PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd -P)"
7
+ if [[ "${COZE_WEB_LOCAL_ACTIVE:-}" != "${PROJECT_ROOT}" ]]; then
8
+ exec node "${SCRIPT_DIR}/local-workspace.cjs" validate "$@"
9
+ fi
10
+ COZE_WORKSPACE_PATH="${PROJECT_ROOT}"
5
11
 
6
12
  cd "${COZE_WORKSPACE_PATH}"
7
13
 
14
+ if [[ "${COZE_WEB_LOCAL_MIRROR:-}" == "1" ]]; then
15
+ pnpm exec nuxt prepare
16
+ fi
17
+
8
18
  echo "🔍 Running validate..."
9
19
  pnpm validate
10
20
  echo "✅ Validate passed!"
@@ -8,7 +8,7 @@ build = ["bash", ".cozeproj/scripts/dev_build.sh"]
8
8
  build_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ".cozeproj/scripts/dev_build.ps1"]
9
9
  run = ["bash", ".cozeproj/scripts/dev_run.sh"]
10
10
  run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ".cozeproj/scripts/dev_run.ps1"]
11
- deps = ["git"] # -> apt install git
11
+ deps = ["git", "rsync"] # -> apt install git rsync
12
12
  pack = ["bash", ".cozeproj/scripts/pack.sh"]
13
13
  pack_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ".cozeproj/scripts/pack.ps1"]
14
14
  validate = ["bash", ".cozeproj/scripts/validate.sh"]
@@ -17,4 +17,4 @@ validate_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-
17
17
  [deploy]
18
18
  build = ["bash", ".cozeproj/scripts/deploy_build.sh"]
19
19
  run = ["bash", ".cozeproj/scripts/deploy_run.sh"]
20
- deps = ["git"] # -> apt install git
20
+ deps = ["git", "rsync"] # -> apt install git rsync
@@ -1,6 +1,13 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
5
+ if [[ "${COZE_TARO_LOCAL_ACTIVE:-}" != "${ROOT_DIR}" ]]; then
6
+ exec node "$ROOT_DIR/.cozeproj/scripts/local-workspace.cjs" build "$@"
7
+ fi
8
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-${ROOT_DIR}}"
9
+ export COZE_WORKSPACE_PATH
10
+
4
11
  cd "${COZE_WORKSPACE_PATH}"
5
12
  if [ -f "./.cozeproj/scripts/init_env.sh" ]; then
6
13
  echo "⚙️ Initializing environment..."
@@ -11,7 +18,9 @@ else
11
18
  fi
12
19
  echo "Installing dependencies..."
13
20
  # 安装所有依赖(包含 Taro 核心和 React)
14
- pnpm install
21
+ if [[ "${COZE_TARO_LOCAL_MIRROR:-}" != "1" ]]; then
22
+ bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline
23
+ fi
15
24
 
16
25
  echo "Building the Taro project..."
17
26
  pnpm build
@@ -1,6 +1,10 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
5
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-${ROOT_DIR}}"
6
+ export COZE_WORKSPACE_PATH
7
+
4
8
  start_service() {
5
9
  cd "${COZE_WORKSPACE_PATH}/server/dist"
6
10
 
@@ -1,2 +1,14 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
5
+ if [[ "${COZE_TARO_LOCAL_ACTIVE:-}" != "${ROOT_DIR}" ]]; then
6
+ exec node "$ROOT_DIR/.cozeproj/scripts/local-workspace.cjs" prepare "$@"
7
+ fi
8
+ COZE_WORKSPACE_PATH="${ROOT_DIR}"
9
+ export COZE_WORKSPACE_PATH
10
+
11
+ cd "${COZE_WORKSPACE_PATH}"
12
+ if [[ "${COZE_TARO_LOCAL_MIRROR:-}" != "1" ]]; then
13
+ bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline
14
+ fi
@@ -28,7 +28,9 @@ function Start-DevProcess([string] $workingDirectory, [string] $logFile, [hashta
28
28
  }
29
29
  }
30
30
 
31
- $workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { (Get-Location).Path }
31
+ $projectRoot = (Resolve-Path (Join-Path $PSScriptRoot "../..")).Path
32
+ $workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { $projectRoot }
33
+ $env:COZE_WORKSPACE_PATH = $workspace
32
34
  $port = if ($env:DEPLOY_RUN_PORT) { [int] $env:DEPLOY_RUN_PORT } elseif ($env:PORT) { [int] $env:PORT } else { <%= port %> }
33
35
  $serverPort = if ($env:SERVER_PORT) { [int] $env:SERVER_PORT } else { <%= serverPort %> }
34
36
  $logDirectory = if ($env:COZE_LOG_DIR) { $env:COZE_LOG_DIR } else { Join-Path $workspace "logs" }
@@ -43,7 +45,7 @@ if (Test-Path $pidFile) {
43
45
  Stop-ListeningProcess $port
44
46
  Stop-ListeningProcess $serverPort
45
47
 
46
- $environment = @{ PORT = "$port"; SERVER_PORT = "$serverPort" }
48
+ $environment = @{ COZE_WORKSPACE_PATH = $workspace; PORT = "$port"; SERVER_PORT = "$serverPort" }
47
49
  if ($env:COZE_PROJECT_DOMAIN_DEFAULT) {
48
50
  $environment.PROJECT_DOMAIN = $env:COZE_PROJECT_DOMAIN_DEFAULT
49
51
  }
@@ -3,13 +3,17 @@ echo "⚙️ dev_run.sh 开始运行"
3
3
  set -Eeuo pipefail
4
4
 
5
5
  ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
6
+ if [[ "${COZE_TARO_LOCAL_ACTIVE:-}" != "${ROOT_DIR}" ]]; then
7
+ exec node "$ROOT_DIR/.cozeproj/scripts/local-workspace.cjs" dev "$@"
8
+ fi
6
9
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-${ROOT_DIR}}"
10
+ export COZE_WORKSPACE_PATH
7
11
  cd "${COZE_WORKSPACE_PATH}"
8
12
 
9
13
  # ---------------------------------------------------------
10
14
  # 项目级日志目录
11
15
  # ---------------------------------------------------------
12
- LOG_DIR="${COZE_WORKSPACE_PATH}/logs"
16
+ LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
13
17
  LOG_FILE="${LOG_DIR}/dev.log"
14
18
  PID_FILE="${LOG_DIR}/dev.pid"
15
19
  DEV_PID=""
@@ -31,11 +35,15 @@ kill_process_tree() {
31
35
  }
32
36
 
33
37
  # detached 出去的进程没人负责回收,超过这个时长就自己退出,避免端口与内存长期泄露。
34
- MAX_RUNTIME_SECONDS=1200
38
+ MAX_RUNTIME_SECONDS=3600
39
+
40
+ timeout_watchdog_enabled() {
41
+ [[ -z "${COZE_EVAL:-}" && -z "${COZE_PROJECT_TYPE:-}" ]]
42
+ }
35
43
 
36
44
  # 真正被 detach 的是这层 bash wrapper:它是进程组 leader,组内 watchdog 到点回收整组
37
45
  # (wrapper -> pnpm -> taro/nest);被包的进程自己先退出时也顺手清空进程组,不留残余。
38
- RUN_WITH_TIMEOUT='
46
+ RUN_WITH_TIMEOUT="$(declare -f timeout_watchdog_enabled)"'
39
47
  timeout_seconds=$1
40
48
  shift
41
49
 
@@ -43,6 +51,7 @@ shift
43
51
  child_pid=$!
44
52
 
45
53
  # 先忽略 TERM,才能在向整组发 TERM(自己也在组里)之后存活下来补一发 KILL。
54
+ if timeout_watchdog_enabled; then
46
55
  ( trap "" TERM
47
56
  sleep "${timeout_seconds}"
48
57
  echo "[dev] 后台进程运行超过 ${timeout_seconds}s,回收进程组 $$。"
@@ -50,6 +59,7 @@ child_pid=$!
50
59
  sleep 5
51
60
  kill -KILL -- "-$$" 2>/dev/null || true
52
61
  ) &
62
+ fi
53
63
 
54
64
  wait "${child_pid}"
55
65
  kill -KILL -- "-$$" 2>/dev/null || true
@@ -112,8 +122,15 @@ process_belongs_to_workspace() {
112
122
 
113
123
  case "${cwd}" in
114
124
  "${COZE_WORKSPACE_PATH}"|"${COZE_WORKSPACE_PATH}"/*) return 0 ;;
115
- *) return 1 ;;
116
125
  esac
126
+
127
+ if [[ -n "${COZE_TARO_SOURCE_PATH:-}" ]]; then
128
+ case "${cwd}" in
129
+ "${COZE_TARO_SOURCE_PATH}"|"${COZE_TARO_SOURCE_PATH}"/*) return 0 ;;
130
+ esac
131
+ fi
132
+
133
+ return 1
117
134
  }
118
135
 
119
136
  process_group_belongs_to_workspace() {
@@ -155,12 +172,24 @@ list_port_pids() {
155
172
 
156
173
  kill_port_if_listening() {
157
174
  local port=$1
175
+ # 用于错误提示的端口环境变量名称,例如 DEPLOY_RUN_PORT 或 SERVER_PORT。
176
+ local port_env_name=$2
158
177
  local pids
178
+ local pid
159
179
  pids=$(list_port_pids "${port}")
160
180
  if [[ -z "${pids}" ]]; then
161
181
  echo "Port ${port} is free."
162
182
  return
163
183
  fi
184
+
185
+ # 端口可能由另一个项目占用。必须在杀进程前校验全部 PID,避免清理到一半才发现外部进程。
186
+ for pid in ${pids}; do
187
+ if ! process_belongs_to_workspace "${pid}"; then
188
+ echo "Error: port ${port} is occupied by PID ${pid}, which does not belong to workspace ${COZE_WORKSPACE_PATH}. Refusing to kill it. Set ${port_env_name} to another port and retry." >&2
189
+ return 1
190
+ fi
191
+ done
192
+
164
193
  echo "Port ${port} in use by PIDs: ${pids} (SIGKILL)"
165
194
  for pid in ${pids}; do
166
195
  kill_process_tree "${pid}"
@@ -168,7 +197,8 @@ kill_port_if_listening() {
168
197
  sleep 1
169
198
  pids=$(list_port_pids "${port}")
170
199
  if [[ -n "${pids}" ]]; then
171
- echo "Warning: port ${port} still busy after SIGKILL, PIDs: ${pids}"
200
+ echo "Error: port ${port} is still occupied after cleaning up this project's processes, PIDs: ${pids}. Check the remaining processes manually or set ${port_env_name} to another port and retry." >&2
201
+ return 1
172
202
  else
173
203
  echo "Port ${port} cleared."
174
204
  fi
@@ -194,7 +224,9 @@ cleanup_previous_run() {
194
224
  # ---------------------------------------------------------
195
225
  echo "📦 Installing dependencies..."
196
226
  PNPM_BIN="$(command -v pnpm)"
197
- "${PNPM_BIN}" install
227
+ if [[ "${COZE_TARO_LOCAL_MIRROR:-}" != "1" ]]; then
228
+ bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline
229
+ fi
198
230
  echo "✅ Dependencies installed successfully!"
199
231
 
200
232
  # ---------------------------------------------------------
@@ -210,9 +242,9 @@ mkdir -p "${LOG_DIR}"
210
242
  cleanup_previous_run
211
243
 
212
244
  echo "Clearing port ${PORT} (web) before start."
213
- kill_port_if_listening "${PORT}"
245
+ kill_port_if_listening "${PORT}" "DEPLOY_RUN_PORT"
214
246
  echo "Clearing port ${SERVER_PORT} (server) before start."
215
- kill_port_if_listening "${SERVER_PORT}"
247
+ kill_port_if_listening "${SERVER_PORT}" "SERVER_PORT"
216
248
 
217
249
  # ---------------------------------------------------------
218
250
  # 4. 启动服务
@@ -236,7 +268,7 @@ start_service() {
236
268
  DEV_PID="$(spawn_detached \
237
269
  "${COZE_WORKSPACE_PATH}" \
238
270
  "${LOG_FILE}" \
239
- "${PNPM_BIN}" dev)"
271
+ "$(command -v node)" "$ROOT_DIR/.cozeproj/scripts/local-workspace.cjs" watch "${PNPM_BIN}" dev)"
240
272
  if [[ -z "${DEV_PID}" ]]; then
241
273
  echo "❌ 无法获取 dev 后台进程 PID"
242
274
  return 1
@@ -252,10 +284,52 @@ start_service() {
252
284
  fi
253
285
 
254
286
  echo "📝 Dev process started with PID: ${DEV_PID}"
255
- echo "Auto stop after ${MAX_RUNTIME_SECONDS}s."
287
+ if timeout_watchdog_enabled; then
288
+ echo "Auto stop after ${MAX_RUNTIME_SECONDS}s."
289
+ fi
256
290
  echo "Log file: ${LOG_FILE}"
257
291
  echo "PID file: ${PID_FILE}"
258
292
  }
259
293
 
294
+ warmup_preview() {
295
+ local base="http://127.0.0.1:${PORT}"
296
+ local waited=0
297
+
298
+ if ! command -v curl >/dev/null 2>&1; then
299
+ echo "Warmup skipped: curl is not available."
300
+ return 0
301
+ fi
302
+
303
+ echo "🔥 Warmup: waiting for web server to accept connections..."
304
+ while (( waited < 60 )); do
305
+ if curl -s -o /dev/null --max-time 3 "${base}/"; then
306
+ break
307
+ fi
308
+ sleep 2
309
+ waited=$(( waited + 2 ))
310
+ done
311
+
312
+ local app_config="${COZE_WORKSPACE_PATH}/src/app.config.ts"
313
+ local pages=""
314
+ if [[ -f "${app_config}" ]]; then
315
+ pages=$(grep -oE "[\"']pages/[^\"']+[\"']" "${app_config}" | tr -d "\"'" | sort -u || true)
316
+ fi
317
+
318
+ local p
319
+ for p in "/" "/app.config.ts"; do
320
+ echo "🔥 Warmup ${p}"
321
+ curl -s -o /dev/null --max-time 300 "${base}${p}" || echo "Warmup ${p} timed out or failed (ignored)."
322
+ done
323
+ for p in ${pages}; do
324
+ echo "🔥 Warmup /${p}.tsx"
325
+ curl -s -o /dev/null --max-time 300 "${base}/${p}.tsx" || echo "Warmup /${p}.tsx timed out or failed (ignored)."
326
+ done
327
+ }
328
+
260
329
  echo "Starting HTTP services on port ${PORT} (web) and ${SERVER_PORT} (server)..."
261
330
  start_service
331
+
332
+ if [[ "${COZE_TARO_LOCAL_MIRROR:-}" = "1" && "${COZE_DEV_SKIP_WARMUP:-0}" != "1" ]]; then
333
+ warmup_preview || true
334
+ echo "✅ Warmup finished (or timed out). Preview should load fast now."
335
+ fi
@@ -1,5 +1,9 @@
1
1
  #!/bin/bash
2
2
 
3
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
4
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-${ROOT_DIR}}"
5
+ export COZE_WORKSPACE_PATH
6
+
3
7
  cd "${COZE_WORKSPACE_PATH}"
4
8
 
5
9
  echo "✅ 初始化完成"