@coze-arch/cli 0.0.36-alpha.64974b → 0.0.36-alpha.80ccd6

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,22 +14,42 @@ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
14
14
 
15
15
  cd "${COZE_WORKSPACE_PATH}"
16
16
 
17
+ list_port_pids() {
18
+ local port=$1
19
+ local pids=""
20
+ local has_tool=0
21
+
22
+ if command -v ss >/dev/null 2>&1; then
23
+ has_tool=1
24
+ 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)
25
+ fi
26
+ if [[ -z "${pids}" ]] && command -v lsof >/dev/null 2>&1; then
27
+ has_tool=1
28
+ pids=$(lsof -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null | sort -u | paste -sd' ' - || true)
29
+ fi
30
+ if [[ "${has_tool}" -eq 0 ]]; then
31
+ echo "Warning: neither ss nor lsof available, cannot inspect port ${port}." >&2
32
+ fi
33
+
34
+ echo "${pids}"
35
+ }
36
+
17
37
  kill_port_if_listening() {
18
38
  local pids
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)
39
+ pids=$(list_port_pids "${DEPLOY_RUN_PORT}")
20
40
  if [[ -z "${pids}" ]]; then
21
41
  echo "Port ${DEPLOY_RUN_PORT} is free."
22
42
  return
23
43
  fi
24
44
  echo "Port ${DEPLOY_RUN_PORT} in use by PIDs: ${pids} (SIGKILL)"
25
- echo "${pids}" | xargs -I {} kill -9 {}
45
+ echo "${pids}" | xargs -I {} kill -9 {} || true
26
46
  sleep 1
27
- 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)
47
+ pids=$(list_port_pids "${DEPLOY_RUN_PORT}")
28
48
  if [[ -n "${pids}" ]]; then
29
- echo "Warning: port ${DEPLOY_RUN_PORT} still busy after SIGKILL, PIDs: ${pids}"
30
- else
31
- echo "Port ${DEPLOY_RUN_PORT} cleared."
49
+ echo "端口 ${DEPLOY_RUN_PORT} PID ${pids} 占用且无法清理(SIGKILL 后仍在监听),dev server 无法启动。" >&2
50
+ exit 1
32
51
  fi
52
+ echo "Port ${DEPLOY_RUN_PORT} cleared."
33
53
  }
34
54
 
35
55
  <% if (process.env.NODE_ENV === 'test') { %>
@@ -41,11 +61,9 @@ echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
41
61
  exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx watch src/server.ts
42
62
  <% } else { %>
43
63
  LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
44
- LOG_FILE="${LOG_DIR}/server.log"
64
+ LOG_FILE="${LOG_DIR}/app.log"
45
65
  PID_FILE="${LOG_DIR}/server.pid"
46
66
 
47
- # coze-daemon 会在 runtime shell 退出时清理原进程组。
48
- # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
49
67
  spawn_detached() {
50
68
  local cwd="$1"
51
69
  local log_file="$2"
@@ -87,6 +105,89 @@ stop_detached() {
87
105
  kill -KILL -- "-${pid}" 2>/dev/null || true
88
106
  }
89
107
 
108
+ READY_RETRIES=10
109
+ READY_PROBE_HOSTS=("127.0.0.1" "::1")
110
+ LOG_TAIL_LINES=40
111
+
112
+ dump_log() {
113
+ echo "---- tail -n ${LOG_TAIL_LINES} ${LOG_FILE} ----" >&2
114
+ tail -n "${LOG_TAIL_LINES}" "${LOG_FILE}" >&2 || true
115
+ echo "---- end of ${LOG_FILE} ----" >&2
116
+ }
117
+
118
+ # 仅用于无 ss/lsof 时的兜底探测。服务可能只 bind IPv4 loopback、只 bind IPv6 loopback
119
+ # (server.listen(port, 'localhost') 会变成 ::1 独占),或 bind 双栈通配地址,
120
+ port_connectable() {
121
+ local port=$1
122
+ local host
123
+ for host in "${READY_PROBE_HOSTS[@]}"; do
124
+ if command -v nc >/dev/null 2>&1; then
125
+ if nc -z -w 1 "${host}" "${port}" >/dev/null 2>&1; then
126
+ return 0
127
+ fi
128
+ elif (exec 3<>"/dev/tcp/${host}/${port}") >/dev/null 2>&1; then
129
+ return 0
130
+ fi
131
+ done
132
+ return 1
133
+ }
134
+
135
+ port_probe_available() {
136
+ command -v ss >/dev/null 2>&1 || command -v lsof >/dev/null 2>&1
137
+ }
138
+
139
+ # 端口监听者是否属于本进程组:spawn detached 后 PID == PGID,子孙进程继承该 PGID。
140
+ # 0 = 是;1 = 不是(无人监听,或监听者不属于本进程组);2 = 无探测工具,无法判断
141
+ port_listened_by_pgid() {
142
+ local port=$1 pgid=$2
143
+ local listener owner
144
+
145
+ if ! port_probe_available; then
146
+ return 2
147
+ fi
148
+
149
+ for listener in $(list_port_pids "${port}" 2>/dev/null); do
150
+ owner=$(ps -o pgid= -p "${listener}" 2>/dev/null | tr -d ' ')
151
+ if [[ "${owner}" == "${pgid}" ]]; then
152
+ return 0
153
+ fi
154
+ done
155
+ return 1
156
+ }
157
+
158
+ wait_for_ready() {
159
+ local pid=$1 port=$2
160
+ local attempt=0 owned
161
+
162
+ if ! port_probe_available; then
163
+ echo "Warning: 缺少 ss 与 lsof,无法确认端口监听者归属,仅按 loopback 可连接性判断就绪。" >&2
164
+ fi
165
+
166
+ while [[ "${attempt}" -lt "${READY_RETRIES}" ]]; do
167
+ if ! kill -0 "${pid}" 2>/dev/null; then
168
+ echo "Dev server 进程在启动过程中退出。" >&2
169
+ return 1
170
+ fi
171
+
172
+ if port_listened_by_pgid "${port}" "${pid}"; then
173
+ owned=0
174
+ else
175
+ owned=$?
176
+ fi
177
+ if [[ "${owned}" -eq 0 ]]; then
178
+ return 0
179
+ fi
180
+ if [[ "${owned}" -eq 2 ]] && port_connectable "${port}"; then
181
+ return 0
182
+ fi
183
+
184
+ sleep 1
185
+ attempt=$((attempt + 1))
186
+ done
187
+
188
+ return 2
189
+ }
190
+
90
191
  # 监听端口的是孙进程(pnpm -> tsx -> node),只清端口会漏掉上层 pnpm/tsx,
91
192
  # 所以先按上次记录的 PID 把整个进程组回收掉。
92
193
  if [[ -f "${PID_FILE}" ]]; then
@@ -104,17 +205,33 @@ mkdir -p "${LOG_DIR}"
104
205
  export PORT="${DEPLOY_RUN_PORT}"
105
206
  server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
106
207
  "$(command -v pnpm)" tsx watch src/server.ts)"
208
+ if [[ -z "${server_pid}" ]]; then
209
+ echo "Dev server failed to start: 未获取到后台进程 PID。" >&2
210
+ dump_log
211
+ exit 1
212
+ fi
107
213
  echo "${server_pid}" > "${PID_FILE}"
108
214
 
109
- sleep 1
110
- if [[ -z "${server_pid}" ]] || ! kill -0 "${server_pid}" 2>/dev/null; then
215
+ if wait_for_ready "${server_pid}" "${DEPLOY_RUN_PORT}"; then
216
+ ready_status=0
217
+ else
218
+ ready_status=$?
219
+ fi
220
+
221
+ if [[ "${ready_status}" -eq 2 ]]; then
222
+ # 进程还活着但迟迟没监听端口:多半是编译/运行时报错后 tsx watch 驻留,日志里有真正原因。
223
+ echo "Dev server 在 ${READY_RETRIES} 次探测(每次 1s)内未就绪于端口 ${DEPLOY_RUN_PORT}(进程 ${server_pid} 仍在运行)。" >&2
224
+ dump_log
225
+ exit 1
226
+ elif [[ "${ready_status}" -ne 0 ]]; then
111
227
  echo "Dev server failed to start. See ${LOG_FILE}." >&2
112
- tail -n 20 "${LOG_FILE}" >&2 || true
228
+ dump_log
229
+ stop_detached "${server_pid}"
113
230
  rm -f "${PID_FILE}"
114
231
  exit 1
115
232
  fi
116
233
 
117
- echo "Dev server started (PID: ${server_pid})."
234
+ echo "Dev server started (PID: ${server_pid}), listening on port ${DEPLOY_RUN_PORT}."
118
235
  echo "Log file: ${LOG_FILE}"
119
236
  echo "PID file: ${PID_FILE}"
120
237
  <% } %>
@@ -66,7 +66,7 @@ const config = {
66
66
  }
67
67
 
68
68
  const cmd = 'pnpm';
69
- const args = ['update', 'coze-coding-dev-sdk@^0.7.0'];
69
+ const args = ['update', 'coze-coding-dev-sdk@^0.7.25-beta.8'];
70
70
  console.log(
71
71
  `\nTriggering: ${cmd} ${args.join(' ')} (running in background)`,
72
72
  );
@@ -27,7 +27,7 @@
27
27
  "@nuxtjs/tailwindcss": "^6.14.0",
28
28
  "@types/node": "^20",
29
29
  "autoprefixer": "^10.4.20",
30
- "coze-coding-dev-sdk": "^0.7.16",
30
+ "coze-coding-dev-sdk": "^0.7.25-beta.8",
31
31
  "eslint": "^9",
32
32
  "eslint-plugin-import": "^2.32.0",
33
33
  "eslint-plugin-vue": "^10",
@@ -34,8 +34,8 @@ importers:
34
34
  specifier: ^10.4.20
35
35
  version: 10.4.27(postcss@8.5.8)
36
36
  coze-coding-dev-sdk:
37
- specifier: ^0.7.16
38
- version: 0.7.17(openai@6.27.0(ws@8.21.3)(zod@4.3.6))(ws@8.21.3)
37
+ specifier: ^0.7.25-beta.8
38
+ version: 0.7.25-beta.8(openai@6.27.0(ws@8.21.3)(zod@4.3.6))(ws@8.21.3)
39
39
  eslint:
40
40
  specifier: ^9
41
41
  version: 9.39.4(jiti@2.7.0)
@@ -2498,8 +2498,8 @@ packages:
2498
2498
  typescript:
2499
2499
  optional: true
2500
2500
 
2501
- coze-coding-dev-sdk@0.7.17:
2502
- resolution: {integrity: sha512-ABq84CkmEtvIAat9QGnfY+b1na5Z7XGyAJP/N2XzqFkVfEF268EwFZLpDOQsBBoYWT+6fmpKLZzBoJDVkQU47w==}
2501
+ coze-coding-dev-sdk@0.7.25-beta.8:
2502
+ resolution: {integrity: sha512-RSKlXCO0W/OPDjx9D9JICn2cGeOJw3iG+y0Pr1AhAf7YdAjjNbBZoG7qfg0Zg2SqgaVN2qSLQFmKPbhNq9ZWSg==}
2503
2503
  engines: {node: '>=18.0.0'}
2504
2504
  hasBin: true
2505
2505
 
@@ -8526,7 +8526,7 @@ snapshots:
8526
8526
  optionalDependencies:
8527
8527
  typescript: 5.9.3
8528
8528
 
8529
- coze-coding-dev-sdk@0.7.17(openai@6.27.0(ws@8.21.3)(zod@4.3.6))(ws@8.21.3):
8529
+ coze-coding-dev-sdk@0.7.25-beta.8(openai@6.27.0(ws@8.21.3)(zod@4.3.6))(ws@8.21.3):
8530
8530
  dependencies:
8531
8531
  '@langchain/core': 1.1.31(openai@6.27.0(ws@8.21.3)(zod@4.3.6))
8532
8532
  '@langchain/openai': 1.2.12(@langchain/core@1.1.31(openai@6.27.0(ws@8.21.3)(zod@4.3.6)))(ws@8.21.3)
@@ -22,7 +22,7 @@
22
22
  "@mariozechner/pi-ai": "^0.63.2",
23
23
  "@mariozechner/pi-coding-agent": "^0.63.2",
24
24
  "@sinclair/typebox": "^0.34.48",
25
- "coze-coding-dev-sdk": "^0.7.17",
25
+ "coze-coding-dev-sdk": "^0.7.25-beta.8",
26
26
  "@radix-ui/react-select": "^2.2.6",
27
27
  "@radix-ui/react-slot": "^1.2.4",
28
28
  "@streamdown/code": "^1.1.1",
@@ -36,8 +36,8 @@ importers:
36
36
  specifier: ^2.1.1
37
37
  version: 2.1.1
38
38
  coze-coding-dev-sdk:
39
- specifier: ^0.7.17
40
- version: 0.7.20(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)
39
+ specifier: ^0.7.25-beta.8
40
+ version: 0.7.25-beta.8(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)
41
41
  express:
42
42
  specifier: ^4.21.2
43
43
  version: 4.22.1
@@ -2085,8 +2085,8 @@ packages:
2085
2085
  cose-base@2.2.0:
2086
2086
  resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==}
2087
2087
 
2088
- coze-coding-dev-sdk@0.7.20:
2089
- resolution: {integrity: sha512-f3UeZcYB/udyWrlFrsOViM47PCW+Nk0I4FcXEGzcjEfaQsa1CPBpf/y5UbBM6GIZ1v+lnuh/MiBlAaALFeMTqw==}
2088
+ coze-coding-dev-sdk@0.7.25-beta.8:
2089
+ resolution: {integrity: sha512-RSKlXCO0W/OPDjx9D9JICn2cGeOJw3iG+y0Pr1AhAf7YdAjjNbBZoG7qfg0Zg2SqgaVN2qSLQFmKPbhNq9ZWSg==}
2090
2090
  engines: {node: '>=18.0.0'}
2091
2091
  hasBin: true
2092
2092
 
@@ -6120,7 +6120,7 @@ snapshots:
6120
6120
  dependencies:
6121
6121
  layout-base: 2.0.1
6122
6122
 
6123
- coze-coding-dev-sdk@0.7.20(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0):
6123
+ coze-coding-dev-sdk@0.7.25-beta.8(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0):
6124
6124
  dependencies:
6125
6125
  '@langchain/core': 1.1.40(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)
6126
6126
  '@langchain/openai': 1.4.3(@langchain/core@1.1.40(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))(ws@8.20.0)
@@ -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.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)
207
+ specifier: ^0.7.25-beta.8
208
+ version: 0.7.25-beta.8(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.25-beta.4:
5420
- resolution: {integrity: sha512-+PCoJ8yhsAIlx3YT898bCkB2gx5EMBunJMP7/kI/Jq/8dj7SDU9EUBZ2Z8ZJocSaPBT9T6dVvFHBsDLZh4FN/Q==}
5419
+ coze-coding-dev-sdk@0.7.25-beta.8:
5420
+ resolution: {integrity: sha512-RSKlXCO0W/OPDjx9D9JICn2cGeOJw3iG+y0Pr1AhAf7YdAjjNbBZoG7qfg0Zg2SqgaVN2qSLQFmKPbhNq9ZWSg==}
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.25-beta.4(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.8(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.25-beta.4",
20
+ "coze-coding-dev-sdk": "^0.7.25-beta.8",
21
21
  "dotenv": "^17.2.3",
22
22
  "drizzle-kit": "^0.31.8",
23
23
  "drizzle-orm": "^0.45.1",
@@ -22,7 +22,7 @@
22
22
  "@types/express": "^5.0.0",
23
23
  "@types/node": "^22.10.5",
24
24
  "autoprefixer": "^10.4.20",
25
- "coze-coding-dev-sdk": "^0.7.16",
25
+ "coze-coding-dev-sdk": "^0.7.25-beta.8",
26
26
  "esbuild": "^0.24.2",
27
27
  "eslint": "^9",
28
28
  "eslint-plugin-import": "^2.32.0",
@@ -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.16
36
- version: 0.7.16(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0)
35
+ specifier: ^0.7.25-beta.8
36
+ version: 0.7.25-beta.8(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.16:
914
- resolution: {integrity: sha512-B7gRPBa+sfrZL8ur0+F/92SOgZgFaWD/fOnCN2DjthnHSdmCYhAJWCfqzG2oO2vwTiYCXkKUuTBZ3MJLMj886g==}
913
+ coze-coding-dev-sdk@0.7.25-beta.8:
914
+ resolution: {integrity: sha512-RSKlXCO0W/OPDjx9D9JICn2cGeOJw3iG+y0Pr1AhAf7YdAjjNbBZoG7qfg0Zg2SqgaVN2qSLQFmKPbhNq9ZWSg==}
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.16(openai@6.16.0(ws@8.19.0)(zod@4.3.5))(ws@8.19.0):
3284
+ coze-coding-dev-sdk@0.7.25-beta.8(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)
@@ -73,7 +73,7 @@ const config = {
73
73
  }
74
74
 
75
75
  const cmd = 'pnpm';
76
- const args = ['update', 'coze-coding-dev-sdk@^0.7.0'];
76
+ const args = ['update', 'coze-coding-dev-sdk@^0.7.25-beta.8'];
77
77
  console.log(
78
78
  `\nTriggering: ${cmd} ${args.join(' ')} (running in background)`,
79
79
  );