@coze-arch/cli 0.0.36-alpha.a7a716 → 0.0.36-alpha.dd2af3

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 CHANGED
@@ -54,7 +54,7 @@ coze-dev deploy code deploy logs|log-count|count|build-log|config
54
54
  coze-dev deploy code domain list [--unit-type dev|prod]
55
55
  coze-dev deploy code domain add <domain>
56
56
  coze-dev deploy code domain set-prefix <prefix> --app-id <app_id> --yes
57
- coze-dev deploy code mini-program status|bind|submit-code|unbind
57
+ coze-dev deploy code mini-program status|bind|submit-code|unbind|auth|preview
58
58
  ```
59
59
 
60
60
  `code app list` 是真分页:一次只返回一页(`--page-size` 默认 20、上限 100),`has_more` 为真时用返回的 `next_page_token` 取下一页;要一次拿到名下全部应用用 `--all`,它会自己翻到底。
@@ -119,6 +119,13 @@ coze-dev deploy code deploy --source-root . --application-type mini_program \
119
119
  --connector-id 10000127 --yes --wait
120
120
  ```
121
121
 
122
+ 小程序预览先完成授权,再执行 preview。preview 会打包微信的 dist/ 或抖音的 dist-tt/ 并上传。Project ID 可通过参数传入或从 .coze 自动读取。
123
+
124
+ ```bash
125
+ coze-dev deploy code mini-program auth --platform wechat --mini-app-id wx123 --source-root .
126
+ coze-dev deploy code mini-program preview --platform wechat --mini-app-id wx123 --source-root .
127
+ ```
128
+
122
129
  绑定小程序 AppID 时,默认从源码目录 `.coze [project]` 读取该目录的 `project_id`:
123
130
 
124
131
  ```bash
@@ -1,17 +1,20 @@
1
+ #!/usr/bin/env bash
2
+
1
3
  ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
2
4
  PREVIEW_DIR="/source/preview"
3
5
  LOG_DIR="${COZE_LOG_DIR:-$ROOT_DIR/logs}"
4
6
  LOG_CLIENT_FILE="$LOG_DIR/client.log"
7
+ LOG_SERVER_FILE="$LOG_DIR/server.log"
5
8
  mkdir -p "$LOG_DIR"
6
9
 
7
10
  # ==================== 配置项 ====================
8
11
  # Server 服务配置
9
12
  SERVER_HOST="0.0.0.0"
10
- SERVER_PORT="9091"
13
+ SERVER_PORT="${SERVER_PORT:-9091}"
11
14
  # Expo 项目配置
12
15
  EXPO_HOST="0.0.0.0"
13
16
  EXPO_DIR="expo"
14
- EXPO_PORT="5000"
17
+ EXPO_PORT="${EXPO_PORT:-5000}"
15
18
  WEB_URL="${COZE_PROJECT_DOMAIN_DEFAULT:-http://127.0.0.1:${SERVER_PORT}}"
16
19
  ASSUME_YES="1"
17
20
  EXPO_PUBLIC_BACKEND_BASE_URL="${EXPO_PUBLIC_BACKEND_BASE_URL:-$WEB_URL}"
@@ -22,6 +25,7 @@ export EXPO_PUBLIC_BACKEND_BASE_URL EXPO_PACKAGER_PROXY_URL EXPO_PUBLIC_COZE_PRO
22
25
  # 运行时变量(为避免 set -u 的未绑定错误,预置为空)
23
26
  SERVER_PID=""
24
27
  EXPO_PID=""
28
+ PNPM_BIN=""
25
29
 
26
30
  # ==================== 工具函数 ====================
27
31
  check_command() {
@@ -112,22 +116,67 @@ wait_port_connectable() {
112
116
  return 1
113
117
  }
114
118
 
115
- start_expo() {
116
- local offline="${1:-0}"
119
+ # coze-daemon 会在 runtime shell 退出时清理原进程组。
120
+ # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
121
+ spawn_detached() {
122
+ local cwd="$1"
123
+ local log_file="$2"
124
+ shift 2
125
+
126
+ node - "$cwd" "$log_file" "$@" <<'NODE'
127
+ const fs = require('node:fs');
128
+ const { spawn } = require('node:child_process');
117
129
 
118
- pushd "$ROOT_DIR/client"
130
+ const [cwd, logFile, command, ...args] = process.argv.slice(2);
131
+ if (!cwd || !logFile || !command) {
132
+ throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
133
+ }
134
+
135
+ const logFd = fs.openSync(logFile, 'a');
136
+ try {
137
+ const child = spawn(command, args, {
138
+ cwd,
139
+ detached: true,
140
+ env: process.env,
141
+ stdio: ['ignore', logFd, logFd],
142
+ });
143
+ child.unref();
144
+ process.stdout.write(String(child.pid));
145
+ } finally {
146
+ fs.closeSync(logFd);
147
+ }
148
+ NODE
149
+ }
119
150
 
151
+ stop_detached() {
152
+ local pid="${1:-}"
153
+ if [ -z "$pid" ]; then
154
+ return
155
+ fi
156
+
157
+ kill -TERM -- "-$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
158
+ sleep 1
159
+ kill -KILL -- "-$pid" 2>/dev/null || true
160
+ }
161
+
162
+ start_expo() {
163
+ local offline="${1:-0}"
164
+ local -a expo_env
165
+ expo_env=(
166
+ "EXPO_NO_DEPENDENCY_VALIDATION=1"
167
+ "EXPO_PUBLIC_BACKEND_BASE_URL=$EXPO_PUBLIC_BACKEND_BASE_URL"
168
+ "EXPO_PACKAGER_PROXY_URL=$EXPO_PACKAGER_PROXY_URL"
169
+ "EXPO_PUBLIC_COZE_PROJECT_ID=$EXPO_PUBLIC_COZE_PROJECT_ID"
170
+ )
120
171
  if [ "$offline" = "1" ]; then
121
- ( EXPO_OFFLINE=1 EXPO_NO_DEPENDENCY_VALIDATION=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" EXPO_PUBLIC_COZE_PROJECT_ID="$EXPO_PUBLIC_COZE_PROJECT_ID" \
122
- nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$LOG_CLIENT_FILE" ) &
123
- else
124
- ( EXPO_NO_DEPENDENCY_VALIDATION=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" EXPO_PUBLIC_COZE_PROJECT_ID="$EXPO_PUBLIC_COZE_PROJECT_ID" \
125
- nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$LOG_CLIENT_FILE" ) &
172
+ expo_env+=("EXPO_OFFLINE=1")
126
173
  fi
127
- EXPO_PID=$!
128
- disown $EXPO_PID 2>/dev/null || true
129
174
 
130
- popd
175
+ EXPO_PID="$(spawn_detached \
176
+ "$ROOT_DIR/client" \
177
+ "$LOG_CLIENT_FILE" \
178
+ /usr/bin/env "${expo_env[@]}" \
179
+ "$PNPM_BIN" exec expo start --clear --port "$EXPO_PORT")"
131
180
  }
132
181
 
133
182
  detect_expo_fetch_failed() {
@@ -168,6 +217,8 @@ check_command "npm"
168
217
  check_command "pnpm"
169
218
  check_command "lsof"
170
219
  check_command "bash"
220
+ check_command "node"
221
+ PNPM_BIN="$(command -v pnpm)"
171
222
 
172
223
  # 端口占用预检查与处理
173
224
  ensure_port SERVER_PORT "$SERVER_PORT"
@@ -175,9 +226,12 @@ ensure_port EXPO_PORT "$EXPO_PORT"
175
226
 
176
227
  echo "==================== 启动 server 服务 ===================="
177
228
  echo "正在执行:pnpm run dev (server)"
178
- ( pushd "$ROOT_DIR/server" > /dev/null && SERVER_PORT="$SERVER_PORT" nohup pnpm run dev; popd > /dev/null ) &
179
- SERVER_PID=$!
180
- disown $SERVER_PID 2>/dev/null || true
229
+ : > "$LOG_SERVER_FILE"
230
+ export SERVER_PORT
231
+ SERVER_PID="$(spawn_detached \
232
+ "$ROOT_DIR/server" \
233
+ /dev/null \
234
+ "$PNPM_BIN" run dev)"
181
235
  if [ -z "${SERVER_PID}" ]; then
182
236
  echo "无法获取 server 后台进程 PID"
183
237
  fi
@@ -185,11 +239,12 @@ echo "server 服务已启动,进程 ID:${SERVER_PID:-unknown}"
185
239
 
186
240
  echo "==================== 启动 Expo 项目 ===================="
187
241
  echo "开始启动 Expo 服务,端口 ${EXPO_PORT}"
242
+ : > "$LOG_CLIENT_FILE"
188
243
  start_expo 0
189
244
  if detect_expo_fetch_failed 8; then
190
245
  echo "Expo 启动检测到网络错误:TypeError: fetch failed,启用离线模式重试"
191
- if [ -n "${EXPO_PID}" ]; then kill -9 "$EXPO_PID" 2>/dev/null || true; fi
192
- : > "$ROOT_DIR/logs/client.log"
246
+ stop_detached "$EXPO_PID"
247
+ : > "$LOG_CLIENT_FILE"
193
248
  start_expo 1
194
249
  fi
195
250
  # 输出以下环境变量,确保 Expo 项目能正确连接到 Server 服务
@@ -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.24
273
- version: 0.7.24(openai@6.16.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)
272
+ specifier: ^0.7.25-beta.4
273
+ version: 0.7.25-beta.4(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.24:
2647
- resolution: {integrity: sha512-oL9Tg5PwxP6iMixonzzMO4aBjOKWcFUMVM+iz5dPyaqQkG84HP1y9DqK5DJVmtdfJuYdAW7pzOatDqLvgvZiXg==}
2646
+ coze-coding-dev-sdk@0.7.25-beta.4:
2647
+ resolution: {integrity: sha512-+PCoJ8yhsAIlx3YT898bCkB2gx5EMBunJMP7/kI/Jq/8dj7SDU9EUBZ2Z8ZJocSaPBT9T6dVvFHBsDLZh4FN/Q==}
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.24(openai@6.16.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0):
9091
+ coze-coding-dev-sdk@0.7.25-beta.4(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)
@@ -12,7 +12,7 @@
12
12
  "dependencies": {
13
13
  "@supabase/supabase-js": "2.95.3",
14
14
  "cors": "^2.8.5",
15
- "coze-coding-dev-sdk": "^0.7.24",
15
+ "coze-coding-dev-sdk": "^0.7.25-beta.4",
16
16
  "dayjs": "^1.11.20",
17
17
  "dotenv": "^17.2.3",
18
18
  "drizzle-orm": "^0.45.1",
@@ -14,6 +14,9 @@ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
14
14
 
15
15
  cd "${COZE_WORKSPACE_PATH}"
16
16
 
17
+ LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
18
+ LOG_SERVER_FILE="${LOG_DIR}/server.log"
19
+
17
20
  kill_port_if_listening() {
18
21
  local pids
19
22
  pids=$(ss -H -lntp 2>/dev/null | awk -v port="${DEPLOY_RUN_PORT}" '$4 ~ ":"port"$"' | grep -o 'pid=[0-9]*' | cut -d= -f2 | paste -sd' ' - || true)
@@ -36,4 +39,10 @@ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
39
  kill_port_if_listening
37
40
  echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
38
41
 
39
- PORT=${DEPLOY_RUN_PORT} pnpm tsx watch src/server.ts
42
+ mkdir -p "${LOG_DIR}"
43
+ : > "${LOG_SERVER_FILE}"
44
+
45
+ # 保持服务为前台进程,让外层 coze-dev dev 的 PID 在整个服务生命周期内有效。
46
+ # 同时通过 tee 将同一份输出写入 logs/server.log。
47
+ exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx watch src/server.ts \
48
+ > >(tee -a "${LOG_SERVER_FILE}") 2>&1
@@ -4,7 +4,7 @@ import { defineConfig, type Plugin } from "vite";
4
4
  import serveStatic from "serve-static";
5
5
 
6
6
  const DEV_PHASER_BRIDGE_URL =
7
- "https://unpkg.byted-static.com/latest/coze-game/phaser-bridge/dist/index.js";
7
+ "https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze-game/js/phaser-bridge.min.js";
8
8
 
9
9
  function injectDevPhaserBridge(): Plugin {
10
10
  return {
@@ -8,6 +8,9 @@ cd "${COZE_WORKSPACE_PATH}"
8
8
  # PID 文件,用于追踪上一次启动的进程树
9
9
  # ---------------------------------------------------------
10
10
  PID_FILE="/tmp/coze-dev-run.pid"
11
+ LOG_DIR="/tmp/coze-logs"
12
+ LOG_FILE="${LOG_DIR}/dev.log"
13
+ DEV_PID=""
11
14
 
12
15
  # ---------------------------------------------------------
13
16
  # 工具函数
@@ -89,7 +92,8 @@ cleanup_previous_run() {
89
92
  # 2. 安装依赖
90
93
  # ---------------------------------------------------------
91
94
  echo "📦 Installing dependencies..."
92
- pnpm install
95
+ PNPM_BIN="$(command -v pnpm)"
96
+ "${PNPM_BIN}" install
93
97
  echo "✅ Dependencies installed successfully!"
94
98
 
95
99
  # ---------------------------------------------------------
@@ -108,11 +112,14 @@ kill_port_if_listening "${SERVER_PORT}"
108
112
  # 4. 退出时自动清理子进程(信号 trap)
109
113
  # ---------------------------------------------------------
110
114
  cleanup_on_exit() {
111
- echo "🛑 dev_run.sh exiting, cleaning up child processes..."
112
- # 杀掉当前脚本的所有子进程
113
- kill -- -$$ 2>/dev/null || true
115
+ local exit_code=$?
116
+ trap - EXIT INT TERM HUP
117
+ if [[ -n "${DEV_PID}" ]] && kill -0 "${DEV_PID}" 2>/dev/null; then
118
+ echo "🛑 dev_run.sh exiting, cleaning up child processes..."
119
+ kill_process_tree "${DEV_PID}"
120
+ fi
114
121
  rm -f "${PID_FILE}"
115
- exit 0
122
+ exit "${exit_code}"
116
123
  }
117
124
  trap cleanup_on_exit EXIT INT TERM HUP
118
125
 
@@ -134,17 +141,16 @@ start_service() {
134
141
  echo "Starting Taro H5 Dev Server and NestJS Server..."
135
142
 
136
143
  export PORT=${DEPLOY_RUN_PORT}
137
- rm -f /tmp/coze-logs/dev.log
138
- mkdir -p /tmp/coze-logs
144
+ mkdir -p "${LOG_DIR}"
145
+ : > "${LOG_FILE}"
139
146
 
140
- # 后台启动并记录 PID
141
- pnpm dev 2>&1 | tee /tmp/coze-logs/dev.log &
142
- local dev_pid=$!
143
- echo "${dev_pid}" > "${PID_FILE}"
144
- echo "📝 Dev process started with PID: ${dev_pid} (saved to ${PID_FILE})"
147
+ # 后台启动以便记录真实 pnpm PID,但脚本持续 wait,保持外层 CLI 生命周期有效。
148
+ "${PNPM_BIN}" dev > >(tee -a "${LOG_FILE}") 2>&1 &
149
+ DEV_PID=$!
150
+ echo "${DEV_PID}" > "${PID_FILE}"
151
+ echo "📝 Dev process started with PID: ${DEV_PID} (saved to ${PID_FILE})"
145
152
 
146
- # 前台等待,保证 trap 能正常捕获信号
147
- wait "${dev_pid}" || true
153
+ wait "${DEV_PID}"
148
154
  }
149
155
 
150
156
  echo "Starting HTTP services on port ${DEPLOY_RUN_PORT} (web) and ${SERVER_PORT} (server)..."
@@ -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.24
208
- version: 0.7.24(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0)
207
+ specifier: ^0.7.25-beta.4
208
+ version: 0.7.25-beta.4(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.24:
5420
- resolution: {integrity: sha512-oL9Tg5PwxP6iMixonzzMO4aBjOKWcFUMVM+iz5dPyaqQkG84HP1y9DqK5DJVmtdfJuYdAW7pzOatDqLvgvZiXg==}
5419
+ coze-coding-dev-sdk@0.7.25-beta.4:
5420
+ resolution: {integrity: sha512-+PCoJ8yhsAIlx3YT898bCkB2gx5EMBunJMP7/kI/Jq/8dj7SDU9EUBZ2Z8ZJocSaPBT9T6dVvFHBsDLZh4FN/Q==}
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.24(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0):
17162
+ coze-coding-dev-sdk@0.7.25-beta.4(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.24",
20
+ "coze-coding-dev-sdk": "^0.7.25-beta.4",
21
21
  "dotenv": "^17.2.3",
22
22
  "drizzle-kit": "^0.31.8",
23
23
  "drizzle-orm": "^0.45.1",