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

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.
@@ -14,9 +14,6 @@ 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
-
20
17
  kill_port_if_listening() {
21
18
  local pids
22
19
  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)
@@ -35,14 +32,89 @@ kill_port_if_listening() {
35
32
  fi
36
33
  }
37
34
 
35
+ <% if (process.env.NODE_ENV === 'test') { %>
36
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
37
+ kill_port_if_listening
38
+ echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
39
+
40
+ # 测试环境保持服务为前台进程,便于 e2e 收集输出并停止进程。
41
+ exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx watch src/server.ts
42
+ <% } else { %>
43
+ LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
44
+ LOG_FILE="${LOG_DIR}/server.log"
45
+ PID_FILE="${LOG_DIR}/server.pid"
46
+
47
+ # coze-daemon 会在 runtime shell 退出时清理原进程组。
48
+ # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
49
+ spawn_detached() {
50
+ local cwd="$1"
51
+ local log_file="$2"
52
+ shift 2
53
+
54
+ node - "$cwd" "$log_file" "$@" <<'NODE'
55
+ const fs = require('node:fs');
56
+ const { spawn } = require('node:child_process');
57
+
58
+ const [cwd, logFile, command, ...args] = process.argv.slice(2);
59
+ if (!cwd || !logFile || !command) {
60
+ throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
61
+ }
62
+
63
+ const logFd = fs.openSync(logFile, 'a');
64
+ try {
65
+ const child = spawn(command, args, {
66
+ cwd,
67
+ detached: true,
68
+ env: process.env,
69
+ stdio: ['ignore', logFd, logFd],
70
+ });
71
+ child.unref();
72
+ process.stdout.write(String(child.pid));
73
+ } finally {
74
+ fs.closeSync(logFd);
75
+ }
76
+ NODE
77
+ }
78
+
79
+ stop_detached() {
80
+ local pid="${1:-}"
81
+ if [[ -z "${pid}" ]]; then
82
+ return
83
+ fi
84
+
85
+ kill -TERM -- "-${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null || true
86
+ sleep 1
87
+ kill -KILL -- "-${pid}" 2>/dev/null || true
88
+ }
89
+
90
+ # 监听端口的是孙进程(pnpm -> tsx -> node),只清端口会漏掉上层 pnpm/tsx,
91
+ # 所以先按上次记录的 PID 把整个进程组回收掉。
92
+ if [[ -f "${PID_FILE}" ]]; then
93
+ stop_detached "$(cat "${PID_FILE}" 2>/dev/null || true)"
94
+ rm -f "${PID_FILE}"
95
+ fi
96
+
38
97
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
39
98
  kill_port_if_listening
40
99
  echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
41
100
 
42
101
  mkdir -p "${LOG_DIR}"
43
- : > "${LOG_SERVER_FILE}"
102
+ : > "${LOG_FILE}"
44
103
 
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
104
+ export PORT="${DEPLOY_RUN_PORT}"
105
+ server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
106
+ "$(command -v pnpm)" tsx watch src/server.ts)"
107
+ echo "${server_pid}" > "${PID_FILE}"
108
+
109
+ sleep 1
110
+ if [[ -z "${server_pid}" ]] || ! kill -0 "${server_pid}" 2>/dev/null; then
111
+ echo "Dev server failed to start. See ${LOG_FILE}." >&2
112
+ tail -n 20 "${LOG_FILE}" >&2 || true
113
+ rm -f "${PID_FILE}"
114
+ exit 1
115
+ fi
116
+
117
+ echo "Dev server started (PID: ${server_pid})."
118
+ echo "Log file: ${LOG_FILE}"
119
+ echo "PID file: ${PID_FILE}"
120
+ <% } %>
@@ -32,8 +32,89 @@ kill_port_if_listening() {
32
32
  fi
33
33
  }
34
34
 
35
+ <% if (process.env.NODE_ENV === 'test') { %>
36
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
37
+ kill_port_if_listening
38
+ echo "Starting Nuxt dev server on port ${DEPLOY_RUN_PORT}..."
39
+
40
+ # 测试环境保持服务为前台进程,便于 e2e 收集输出并停止进程。
41
+ exec env PORT="${DEPLOY_RUN_PORT}" pnpm nuxt dev
42
+ <% } else { %>
43
+ LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
44
+ LOG_FILE="${LOG_DIR}/server.log"
45
+ PID_FILE="${LOG_DIR}/server.pid"
46
+
47
+ # coze-daemon 会在 runtime shell 退出时清理原进程组。
48
+ # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
49
+ spawn_detached() {
50
+ local cwd="$1"
51
+ local log_file="$2"
52
+ shift 2
53
+
54
+ node - "$cwd" "$log_file" "$@" <<'NODE'
55
+ const fs = require('node:fs');
56
+ const { spawn } = require('node:child_process');
57
+
58
+ const [cwd, logFile, command, ...args] = process.argv.slice(2);
59
+ if (!cwd || !logFile || !command) {
60
+ throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
61
+ }
62
+
63
+ const logFd = fs.openSync(logFile, 'a');
64
+ try {
65
+ const child = spawn(command, args, {
66
+ cwd,
67
+ detached: true,
68
+ env: process.env,
69
+ stdio: ['ignore', logFd, logFd],
70
+ });
71
+ child.unref();
72
+ process.stdout.write(String(child.pid));
73
+ } finally {
74
+ fs.closeSync(logFd);
75
+ }
76
+ NODE
77
+ }
78
+
79
+ stop_detached() {
80
+ local pid="${1:-}"
81
+ if [[ -z "${pid}" ]]; then
82
+ return
83
+ fi
84
+
85
+ kill -TERM -- "-${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null || true
86
+ sleep 1
87
+ kill -KILL -- "-${pid}" 2>/dev/null || true
88
+ }
89
+
90
+ # 监听端口的是孙进程(pnpm -> nuxt -> node),只清端口会漏掉上层 pnpm/nuxt,
91
+ # 所以先按上次记录的 PID 把整个进程组回收掉。
92
+ if [[ -f "${PID_FILE}" ]]; then
93
+ stop_detached "$(cat "${PID_FILE}" 2>/dev/null || true)"
94
+ rm -f "${PID_FILE}"
95
+ fi
96
+
35
97
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
98
  kill_port_if_listening
37
99
  echo "Starting Nuxt dev server on port ${DEPLOY_RUN_PORT}..."
38
100
 
39
- PORT=${DEPLOY_RUN_PORT} pnpm nuxt dev
101
+ mkdir -p "${LOG_DIR}"
102
+ : > "${LOG_FILE}"
103
+
104
+ export PORT="${DEPLOY_RUN_PORT}"
105
+ server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
106
+ "$(command -v pnpm)" nuxt dev)"
107
+ echo "${server_pid}" > "${PID_FILE}"
108
+
109
+ sleep 1
110
+ if [[ -z "${server_pid}" ]] || ! kill -0 "${server_pid}" 2>/dev/null; then
111
+ echo "Dev server failed to start. See ${LOG_FILE}." >&2
112
+ tail -n 20 "${LOG_FILE}" >&2 || true
113
+ rm -f "${PID_FILE}"
114
+ exit 1
115
+ fi
116
+
117
+ echo "Dev server started (PID: ${server_pid})."
118
+ echo "Log file: ${LOG_FILE}"
119
+ echo "PID file: ${PID_FILE}"
120
+ <% } %>
@@ -28,6 +28,49 @@ kill_process_tree() {
28
28
  fi
29
29
  }
30
30
 
31
+ # coze-daemon 会在 runtime shell 退出时清理原进程组。
32
+ # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
33
+ spawn_detached() {
34
+ local cwd="$1"
35
+ local log_file="$2"
36
+ shift 2
37
+
38
+ node - "$cwd" "$log_file" "$@" <<'NODE'
39
+ const fs = require('node:fs');
40
+ const { spawn } = require('node:child_process');
41
+
42
+ const [cwd, logFile, command, ...args] = process.argv.slice(2);
43
+ if (!cwd || !logFile || !command) {
44
+ throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
45
+ }
46
+
47
+ const logFd = fs.openSync(logFile, 'a');
48
+ try {
49
+ const child = spawn(command, args, {
50
+ cwd,
51
+ detached: true,
52
+ env: process.env,
53
+ stdio: ['ignore', logFd, logFd],
54
+ });
55
+ child.unref();
56
+ process.stdout.write(String(child.pid));
57
+ } finally {
58
+ fs.closeSync(logFd);
59
+ }
60
+ NODE
61
+ }
62
+
63
+ stop_detached() {
64
+ local pid="${1:-}"
65
+ if [[ -z "${pid}" ]]; then
66
+ return
67
+ fi
68
+
69
+ kill -TERM -- "-${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null || true
70
+ sleep 1
71
+ kill -KILL -- "-${pid}" 2>/dev/null || true
72
+ }
73
+
31
74
  kill_port_if_listening() {
32
75
  local port=$1
33
76
  local pids
@@ -59,7 +102,7 @@ cleanup_previous_run() {
59
102
  old_pid=$(cat "${PID_FILE}" 2>/dev/null || true)
60
103
  if [[ -n "${old_pid}" ]] && kill -0 "${old_pid}" 2>/dev/null; then
61
104
  echo "🧹 Killing previous dev process tree (root PID: ${old_pid})..."
62
- kill_process_tree "${old_pid}"
105
+ stop_detached "${old_pid}"
63
106
  fi
64
107
  rm -f "${PID_FILE}"
65
108
  fi
@@ -109,22 +152,7 @@ echo "Clearing port ${SERVER_PORT} (server) before start."
109
152
  kill_port_if_listening "${SERVER_PORT}"
110
153
 
111
154
  # ---------------------------------------------------------
112
- # 4. 退出时自动清理子进程(信号 trap)
113
- # ---------------------------------------------------------
114
- cleanup_on_exit() {
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
121
- rm -f "${PID_FILE}"
122
- exit "${exit_code}"
123
- }
124
- trap cleanup_on_exit EXIT INT TERM HUP
125
-
126
- # ---------------------------------------------------------
127
- # 5. 启动服务
155
+ # 4. 启动服务
128
156
  # ---------------------------------------------------------
129
157
  start_service() {
130
158
  cd "${COZE_WORKSPACE_PATH}"
@@ -144,13 +172,16 @@ start_service() {
144
172
  mkdir -p "${LOG_DIR}"
145
173
  : > "${LOG_FILE}"
146
174
 
147
- # 后台启动以便记录真实 pnpm PID,但脚本持续 wait,保持外层 CLI 生命周期有效。
148
- "${PNPM_BIN}" dev > >(tee -a "${LOG_FILE}") 2>&1 &
149
- DEV_PID=$!
175
+ DEV_PID="$(spawn_detached \
176
+ "${COZE_WORKSPACE_PATH}" \
177
+ "${LOG_FILE}" \
178
+ "${PNPM_BIN}" dev)"
179
+ if [[ -z "${DEV_PID}" ]]; then
180
+ echo "❌ 无法获取 dev 后台进程 PID"
181
+ return 1
182
+ fi
150
183
  echo "${DEV_PID}" > "${PID_FILE}"
151
184
  echo "📝 Dev process started with PID: ${DEV_PID} (saved to ${PID_FILE})"
152
-
153
- wait "${DEV_PID}"
154
185
  }
155
186
 
156
187
  echo "Starting HTTP services on port ${DEPLOY_RUN_PORT} (web) and ${SERVER_PORT} (server)..."
@@ -32,8 +32,89 @@ kill_port_if_listening() {
32
32
  fi
33
33
  }
34
34
 
35
+ <% if (process.env.NODE_ENV === 'test') { %>
36
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
37
+ kill_port_if_listening
38
+ echo "Starting express + Vite dev server on port ${DEPLOY_RUN_PORT}..."
39
+
40
+ # 测试环境保持服务为前台进程,便于 e2e 收集输出并停止进程。
41
+ exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx watch server/server.ts
42
+ <% } else { %>
43
+ LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
44
+ LOG_FILE="${LOG_DIR}/server.log"
45
+ PID_FILE="${LOG_DIR}/server.pid"
46
+
47
+ # coze-daemon 会在 runtime shell 退出时清理原进程组。
48
+ # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
49
+ spawn_detached() {
50
+ local cwd="$1"
51
+ local log_file="$2"
52
+ shift 2
53
+
54
+ node - "$cwd" "$log_file" "$@" <<'NODE'
55
+ const fs = require('node:fs');
56
+ const { spawn } = require('node:child_process');
57
+
58
+ const [cwd, logFile, command, ...args] = process.argv.slice(2);
59
+ if (!cwd || !logFile || !command) {
60
+ throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
61
+ }
62
+
63
+ const logFd = fs.openSync(logFile, 'a');
64
+ try {
65
+ const child = spawn(command, args, {
66
+ cwd,
67
+ detached: true,
68
+ env: process.env,
69
+ stdio: ['ignore', logFd, logFd],
70
+ });
71
+ child.unref();
72
+ process.stdout.write(String(child.pid));
73
+ } finally {
74
+ fs.closeSync(logFd);
75
+ }
76
+ NODE
77
+ }
78
+
79
+ stop_detached() {
80
+ local pid="${1:-}"
81
+ if [[ -z "${pid}" ]]; then
82
+ return
83
+ fi
84
+
85
+ kill -TERM -- "-${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null || true
86
+ sleep 1
87
+ kill -KILL -- "-${pid}" 2>/dev/null || true
88
+ }
89
+
90
+ # 监听端口的是孙进程(pnpm -> tsx -> node),只清端口会漏掉上层 pnpm/tsx,
91
+ # 所以先按上次记录的 PID 把整个进程组回收掉。
92
+ if [[ -f "${PID_FILE}" ]]; then
93
+ stop_detached "$(cat "${PID_FILE}" 2>/dev/null || true)"
94
+ rm -f "${PID_FILE}"
95
+ fi
96
+
35
97
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
98
  kill_port_if_listening
37
99
  echo "Starting express + Vite dev server on port ${DEPLOY_RUN_PORT}..."
38
100
 
39
- PORT=${DEPLOY_RUN_PORT} pnpm tsx watch server/server.ts
101
+ mkdir -p "${LOG_DIR}"
102
+ : > "${LOG_FILE}"
103
+
104
+ export PORT="${DEPLOY_RUN_PORT}"
105
+ server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
106
+ "$(command -v pnpm)" tsx watch server/server.ts)"
107
+ echo "${server_pid}" > "${PID_FILE}"
108
+
109
+ sleep 1
110
+ if [[ -z "${server_pid}" ]] || ! kill -0 "${server_pid}" 2>/dev/null; then
111
+ echo "Dev server failed to start. See ${LOG_FILE}." >&2
112
+ tail -n 20 "${LOG_FILE}" >&2 || true
113
+ rm -f "${PID_FILE}"
114
+ exit 1
115
+ fi
116
+
117
+ echo "Dev server started (PID: ${server_pid})."
118
+ echo "Log file: ${LOG_FILE}"
119
+ echo "PID file: ${PID_FILE}"
120
+ <% } %>
package/lib/cli.js CHANGED
@@ -2114,7 +2114,7 @@ const EventBuilder = {
2114
2114
  };
2115
2115
 
2116
2116
  var name = "@coze-arch/cli";
2117
- var version = "0.0.36-alpha.dd2af3";
2117
+ var version = "0.0.36-alpha.fd6b86";
2118
2118
  var description = "coze coding devtools cli";
2119
2119
  var license = "MIT";
2120
2120
  var author = "fanwenjie.fe@bytedance.com";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-arch/cli",
3
- "version": "0.0.36-alpha.dd2af3",
3
+ "version": "0.0.36-alpha.fd6b86",
4
4
  "private": false,
5
5
  "description": "coze coding devtools cli",
6
6
  "license": "MIT",