@coze-arch/cli 0.1.4-alpha.e6e18e → 0.1.4-alpha.f69bb1

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 (53) hide show
  1. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.ps1 +1 -1
  2. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +3 -3
  3. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.ps1 +2 -2
  4. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +2 -0
  5. package/lib/__templates__/expo/.cozeproj/scripts/prepare-node-modules.sh +114 -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__/expo/pnpm-lock.yaml +5 -5
  11. package/lib/__templates__/expo/server/package.json +1 -1
  12. package/lib/__templates__/nextjs/eslint.config.mjs +11 -5
  13. package/lib/__templates__/nextjs/next.config.ts +10 -0
  14. package/lib/__templates__/nextjs/package.json +3 -6
  15. package/lib/__templates__/nextjs/pnpm-lock.yaml +19 -950
  16. package/lib/__templates__/nextjs/scripts/build.ps1 +1 -1
  17. package/lib/__templates__/nextjs/scripts/build.sh +3 -2
  18. package/lib/__templates__/nextjs/scripts/dev.ps1 +2 -2
  19. package/lib/__templates__/nextjs/scripts/dev.sh +10 -5
  20. package/lib/__templates__/nextjs/scripts/prepare-next-output.sh +62 -0
  21. package/lib/__templates__/nextjs/scripts/prepare-node-modules.sh +114 -0
  22. package/lib/__templates__/nextjs/scripts/prepare.sh +1 -4
  23. package/lib/__templates__/nextjs/src/app/layout.tsx +0 -4
  24. package/lib/__templates__/nextjs/src/server.ts +1 -1
  25. package/lib/__templates__/nextjs/template.config.js +0 -59
  26. package/lib/__templates__/nuxt-vue/package.json +1 -1
  27. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +5 -5
  28. package/lib/__templates__/nuxt-vue/scripts/build.sh +1 -1
  29. package/lib/__templates__/nuxt-vue/scripts/dev.sh +2 -0
  30. package/lib/__templates__/nuxt-vue/scripts/prepare-node-modules.sh +114 -0
  31. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +1 -4
  32. package/lib/__templates__/pi-agent/package.json +1 -1
  33. package/lib/__templates__/pi-agent/pnpm-lock.yaml +5 -5
  34. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +3 -2
  35. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +3 -0
  36. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +3 -1
  37. package/lib/__templates__/taro/.cozeproj/scripts/prepare-node-modules.sh +114 -0
  38. package/lib/__templates__/taro/pnpm-lock.yaml +5 -5
  39. package/lib/__templates__/taro/server/package.json +1 -1
  40. package/lib/__templates__/vite/package.json +1 -1
  41. package/lib/__templates__/vite/pnpm-lock.yaml +5 -5
  42. package/lib/__templates__/vite/scripts/build.ps1 +4 -1
  43. package/lib/__templates__/vite/scripts/build.sh +1 -1
  44. package/lib/__templates__/vite/scripts/dev.ps1 +7 -23
  45. package/lib/__templates__/vite/scripts/dev.sh +2 -0
  46. package/lib/__templates__/vite/scripts/prepare-node-modules.sh +114 -0
  47. package/lib/__templates__/vite/scripts/prepare.ps1 +6 -1
  48. package/lib/__templates__/vite/scripts/prepare.sh +1 -4
  49. package/lib/__templates__/vite/template.config.js +0 -59
  50. package/lib/cli.js +34 -12
  51. package/package.json +1 -1
  52. package/lib/__templates__/nextjs/.babelrc +0 -15
  53. package/lib/__templates__/vite/scripts/ensure-deps.ps1 +0 -33
@@ -8,7 +8,7 @@ Write-Host "Installing dependencies..."
8
8
  if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
9
9
 
10
10
  Write-Host "Building the Next.js project..."
11
- & pnpm next build
11
+ & pnpm next build --webpack
12
12
  if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
13
13
 
14
14
  Write-Host "Bundling server with tsup..."
@@ -6,10 +6,11 @@ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
6
  cd "${COZE_WORKSPACE_PATH}"
7
7
 
8
8
  echo "Installing dependencies..."
9
- pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
9
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
10
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-next-output.sh"
10
11
 
11
12
  echo "Building the Next.js project..."
12
- pnpm next build
13
+ pnpm next build --webpack
13
14
 
14
15
  echo "Bundling server with tsup..."
15
16
  pnpm tsup src/server.ts --format cjs --platform node --target node20 --outDir dist --no-splitting --no-minify
@@ -28,7 +28,7 @@ Stop-ListeningProcess $port
28
28
 
29
29
  <% if (process.env.NODE_ENV === 'test') { %>
30
30
  $env:PORT = "$port"
31
- & pnpm tsx watch src/server.ts
31
+ & pnpm tsx watch --ignore .next src/server.ts
32
32
  exit $LASTEXITCODE
33
33
  <% } else { %>
34
34
  $logDirectory = if ($env:COZE_LOG_DIR) { $env:COZE_LOG_DIR } else { Join-Path $workspace "logs" }
@@ -45,7 +45,7 @@ if (Test-Path $pidFile) {
45
45
  $previousPort = $env:PORT
46
46
  $env:PORT = "$port"
47
47
  try {
48
- $process = Start-Process -FilePath $env:ComSpec -ArgumentList @("/d", "/s", "/c", "pnpm tsx watch src/server.ts") -WorkingDirectory $workspace -RedirectStandardOutput $logFile -RedirectStandardError $errorLogFile -PassThru
48
+ $process = Start-Process -FilePath $env:ComSpec -ArgumentList @("/d", "/s", "/c", "pnpm tsx watch --ignore .next src/server.ts") -WorkingDirectory $workspace -RedirectStandardOutput $logFile -RedirectStandardError $errorLogFile -PassThru
49
49
  } finally {
50
50
  if ($null -eq $previousPort) { Remove-Item Env:PORT -ErrorAction SilentlyContinue } else { $env:PORT = $previousPort }
51
51
  }
@@ -55,10 +55,12 @@ kill_port_if_listening() {
55
55
  <% if (process.env.NODE_ENV === 'test') { %>
56
56
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
57
57
  kill_port_if_listening
58
+ bash "${COZE_WORKSPACE_PATH}/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
59
+ bash "${COZE_WORKSPACE_PATH}/scripts/prepare-next-output.sh"
58
60
  echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
59
61
 
60
62
  # 测试环境保持服务为前台进程,便于 e2e 收集输出并停止进程。
61
- exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx watch src/server.ts
63
+ exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx src/server.ts
62
64
  <% } else { %>
63
65
  LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
64
66
  LOG_FILE="${LOG_DIR}/app.log"
@@ -77,6 +79,7 @@ shift
77
79
  child_pid=$!
78
80
 
79
81
  # 先忽略 TERM,才能在向整组发 TERM(自己也在组里)之后存活下来补一发 KILL。
82
+ if [[ -z "${COZE_EVAL:-}" && -z "${COZE_PROJECT_TYPE:-}" ]]; then
80
83
  ( trap "" TERM
81
84
  sleep "${timeout_seconds}"
82
85
  echo "[dev] 后台进程运行超过 ${timeout_seconds}s,回收进程组 $$。"
@@ -84,6 +87,7 @@ child_pid=$!
84
87
  sleep 5
85
88
  kill -KILL -- "-$$" 2>/dev/null || true
86
89
  ) &
90
+ fi
87
91
 
88
92
  wait "${child_pid}"
89
93
  kill -KILL -- "-$$" 2>/dev/null || true
@@ -132,7 +136,7 @@ stop_detached() {
132
136
  kill -KILL -- "-${pid}" 2>/dev/null || true
133
137
  }
134
138
 
135
- READY_RETRIES=10
139
+ READY_RETRIES=30
136
140
  READY_PROBE_HOSTS=("127.0.0.1" "::1")
137
141
  LOG_TAIL_LINES=40
138
142
 
@@ -224,6 +228,8 @@ fi
224
228
 
225
229
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
226
230
  kill_port_if_listening
231
+ bash "${COZE_WORKSPACE_PATH}/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
232
+ bash "${COZE_WORKSPACE_PATH}/scripts/prepare-next-output.sh"
227
233
  echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
228
234
 
229
235
  mkdir -p "${LOG_DIR}"
@@ -231,7 +237,7 @@ mkdir -p "${LOG_DIR}"
231
237
 
232
238
  export PORT="${DEPLOY_RUN_PORT}"
233
239
  server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
234
- "$(command -v pnpm)" tsx watch src/server.ts)"
240
+ "$(command -v pnpm)" tsx src/server.ts)"
235
241
  if [[ -z "${server_pid}" ]]; then
236
242
  echo "Dev server failed to start: 未获取到后台进程 PID。" >&2
237
243
  dump_log
@@ -247,8 +253,7 @@ fi
247
253
 
248
254
  if [[ "${ready_status}" -ne 0 ]]; then
249
255
  if [[ "${ready_status}" -eq 2 ]]; then
250
- # 进程还活着但迟迟没监听端口:多半是编译/运行时报错后 tsx watch 驻留,日志里有真正原因。
251
- echo "Dev server 在 ${READY_RETRIES} 次探测(每次 1s)内未就绪于端口 ${DEPLOY_RUN_PORT}(进程 ${server_pid} 仍在运行,已回收)。" >&2
256
+ echo "Dev server did not listen on port ${DEPLOY_RUN_PORT} after ${READY_RETRIES} attempts; stopping PID ${server_pid}." >&2
252
257
  else
253
258
  echo "Dev server failed to start. See ${LOG_FILE}." >&2
254
259
  fi
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env bash
2
+ # Keep Next.js compiler output off Coze Drive while leaving source files in place.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
6
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
7
+
8
+ DRIVE_ROOT="${COZE_DRIVE_ROOT:-/Coze/Drive}"
9
+ if [ -d "$DRIVE_ROOT" ]; then
10
+ DRIVE_ROOT="$(cd "$DRIVE_ROOT" && pwd -P)"
11
+ else
12
+ DRIVE_ROOT="${DRIVE_ROOT%/}"
13
+ fi
14
+ case "$PROJECT_ROOT" in
15
+ "$DRIVE_ROOT"|"$DRIVE_ROOT"/*) ;;
16
+ *) exit 0 ;;
17
+ esac
18
+
19
+ NM_ROOT="/tmp/nm"
20
+ PROJECT_ID="$(basename "$PROJECT_ROOT")-$(printf '%s' "$PROJECT_ROOT" | cksum | awk '{print $1}')"
21
+ NEXT_DIR="$NM_ROOT/$PROJECT_ID/.next"
22
+ LEGACY_NEXT_DIR="$NM_ROOT/next/$PROJECT_ID"
23
+
24
+ if [ -L "$NEXT_DIR" ]; then
25
+ current="$(readlink "$NEXT_DIR")"
26
+ if [ "$current" = "$PROJECT_ROOT/.next" ]; then
27
+ rm "$NEXT_DIR"
28
+ else
29
+ echo "[next] refusing to replace unmanaged local output symlink: $NEXT_DIR" >&2
30
+ exit 1
31
+ fi
32
+ elif [ -e "$NEXT_DIR" ] && [ ! -d "$NEXT_DIR" ]; then
33
+ echo "[next] local output path is not a directory: $NEXT_DIR" >&2
34
+ exit 1
35
+ fi
36
+ mkdir -p "$NEXT_DIR"
37
+
38
+ if [ -L "$PROJECT_ROOT/.next" ]; then
39
+ current="$(readlink "$PROJECT_ROOT/.next")"
40
+ if [ "$current" = "$NEXT_DIR" ]; then
41
+ exit 0
42
+ fi
43
+ if [ "$current" = "$LEGACY_NEXT_DIR" ]; then
44
+ rm "$PROJECT_ROOT/.next"
45
+ else
46
+ echo "[next] refusing to replace unmanaged symlink: $PROJECT_ROOT/.next" >&2
47
+ exit 1
48
+ fi
49
+ fi
50
+
51
+ if [ -e "$PROJECT_ROOT/.next" ]; then
52
+ rm -rf "$PROJECT_ROOT/.next"
53
+ fi
54
+
55
+ if ! ln -s "$NEXT_DIR" "$PROJECT_ROOT/.next"; then
56
+ if [ ! -L "$PROJECT_ROOT/.next" ] || [ "$(readlink "$PROJECT_ROOT/.next")" != "$NEXT_DIR" ]; then
57
+ echo "[next] failed to link $PROJECT_ROOT/.next to $NEXT_DIR" >&2
58
+ exit 1
59
+ fi
60
+ fi
61
+
62
+ echo "[next] Compiler output ready at $NEXT_DIR"
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # Install dependencies on local disk and expose them to the source tree by symlink.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
6
+ if [ "$(basename "$(dirname "$SCRIPT_DIR")")" = ".cozeproj" ]; then
7
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd -P)"
8
+ else
9
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
10
+ fi
11
+
12
+ command -v pnpm >/dev/null 2>&1 || {
13
+ echo "[node_modules] pnpm is required" >&2
14
+ exit 1
15
+ }
16
+
17
+ DRIVE_ROOT="${COZE_DRIVE_ROOT:-/Coze/Drive}"
18
+ if [ -d "$DRIVE_ROOT" ]; then
19
+ DRIVE_ROOT="$(cd "$DRIVE_ROOT" && pwd -P)"
20
+ else
21
+ DRIVE_ROOT="${DRIVE_ROOT%/}"
22
+ fi
23
+ case "$PROJECT_ROOT" in
24
+ "$DRIVE_ROOT"|"$DRIVE_ROOT"/*) ;;
25
+ *)
26
+ (cd "$PROJECT_ROOT" && pnpm install "$@")
27
+ exit 0
28
+ ;;
29
+ esac
30
+
31
+ NM_ROOT="/tmp/nm"
32
+ PROJECT_ID="$(basename "$PROJECT_ROOT")-$(printf '%s' "$PROJECT_ROOT" | cksum | awk '{print $1}')"
33
+ mkdir -p "$NM_ROOT"
34
+ WORK_DIR="$NM_ROOT/$PROJECT_ID"
35
+ case "$WORK_DIR" in
36
+ "$DRIVE_ROOT"|"$DRIVE_ROOT"/*)
37
+ echo "[node_modules] local dependency directory must not be on Coze Drive: $WORK_DIR" >&2
38
+ exit 1
39
+ ;;
40
+ esac
41
+
42
+ LOCK_DIR="$NM_ROOT/$PROJECT_ID.lock"
43
+ while ! mkdir "$LOCK_DIR" 2>/dev/null; do
44
+ echo "[node_modules] Waiting for another dependency preparation for this project..."
45
+ sleep 1
46
+ done
47
+ trap 'rmdir "$LOCK_DIR" 2>/dev/null || true' EXIT
48
+
49
+ mkdir -p "$WORK_DIR"
50
+
51
+ # Previous versions mirrored the whole project into WORK_DIR. That gives pnpm
52
+ # and framework dev servers two paths for the same source tree, which breaks
53
+ # file watching and on-demand compilation. Keep only managed local outputs.
54
+ cleanup_legacy_workspace() {
55
+ local workspace_dir="$1" entry name
56
+ if [ -L "$workspace_dir" ] || { [ -e "$workspace_dir" ] && [ ! -d "$workspace_dir" ]; }; then
57
+ rm -rf "$workspace_dir"
58
+ return
59
+ fi
60
+ [ -d "$workspace_dir" ] || return
61
+
62
+ while IFS= read -r -d '' entry; do
63
+ name="$(basename "$entry")"
64
+ [ "$name" = "node_modules" ] || rm -rf "$entry"
65
+ done < <(find "$workspace_dir" -mindepth 1 -maxdepth 1 -print0)
66
+ }
67
+
68
+ cleanup_legacy_shadow_project() {
69
+ local entry name
70
+ while IFS= read -r -d '' entry; do
71
+ name="$(basename "$entry")"
72
+ case "$name" in
73
+ node_modules|.next|client|server) continue ;;
74
+ esac
75
+ rm -rf "$entry"
76
+ done < <(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -print0)
77
+
78
+ for workspace in client server; do
79
+ cleanup_legacy_workspace "$WORK_DIR/$workspace"
80
+ done
81
+ }
82
+
83
+ link_node_modules() {
84
+ local source_dir="$1" target_dir="$2"
85
+ local current=""
86
+ mkdir -p "$target_dir"
87
+ if [ -L "$source_dir/node_modules" ]; then
88
+ current="$(readlink "$source_dir/node_modules")"
89
+ case "$current" in
90
+ "$NM_ROOT"/*/node_modules|"$NM_ROOT"/*/*/node_modules) ;;
91
+ *)
92
+ echo "[node_modules] refusing to replace unmanaged symlink: $source_dir/node_modules" >&2
93
+ exit 1
94
+ ;;
95
+ esac
96
+ rm "$source_dir/node_modules"
97
+ elif [ -e "$source_dir/node_modules" ]; then
98
+ rm -rf "$source_dir/node_modules"
99
+ fi
100
+ ln -s "$target_dir" "$source_dir/node_modules"
101
+ }
102
+
103
+ cleanup_legacy_shadow_project
104
+ link_node_modules "$PROJECT_ROOT" "$WORK_DIR/node_modules"
105
+ for workspace in client server; do
106
+ if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
107
+ link_node_modules "$PROJECT_ROOT/$workspace" "$WORK_DIR/$workspace/node_modules"
108
+ fi
109
+ done
110
+
111
+ echo "[node_modules] Installing dependencies for $PROJECT_ROOT with node_modules at $WORK_DIR"
112
+ (cd "$PROJECT_ROOT" && pnpm install "$@")
113
+
114
+ echo "[node_modules] Dependencies ready"
@@ -6,7 +6,4 @@ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
6
  cd "${COZE_WORKSPACE_PATH}"
7
7
 
8
8
  echo "Installing dependencies..."
9
- pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
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
12
- fi
9
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
@@ -1,5 +1,4 @@
1
1
  import type { Metadata } from 'next';
2
- import { Inspector } from 'react-dev-inspector';
3
2
  import './globals.css';
4
3
 
5
4
  export const metadata: Metadata = {
@@ -61,12 +60,9 @@ export default function RootLayout({
61
60
  }: Readonly<{
62
61
  children: React.ReactNode;
63
62
  }>) {
64
- const isDev = process.env.COZE_PROJECT_ENV === 'DEV';
65
-
66
63
  return (
67
64
  <html lang="en">
68
65
  <body className={`antialiased`}>
69
- {isDev && <Inspector />}
70
66
  {children}
71
67
  </body>
72
68
  </html>
@@ -7,7 +7,7 @@ const hostname = process.env.HOSTNAME || 'localhost';
7
7
  const port = parseInt(process.env.PORT || '<%= port %>', 10);
8
8
 
9
9
  // Create Next.js app
10
- const app = next({ dev, hostname, port });
10
+ const app = next({ dev, hostname, port, webpack: true });
11
11
  const handle = app.getRequestHandler();
12
12
 
13
13
  app.prepare().then(() => {
@@ -1,9 +1,5 @@
1
1
 
2
2
 
3
- import { spawn } from 'child_process';
4
- import { resolve, join, basename } from 'path';
5
- import { appendFileSync, openSync, closeSync, mkdirSync } from 'fs';
6
- import { homedir } from 'os';
7
3
 
8
4
 
9
5
 
@@ -57,61 +53,6 @@ const config = {
57
53
  onAfterRender: async (_context, _outputPath) => {
58
54
  // 输出由 init 命令统一处理
59
55
  },
60
-
61
- onComplete: async (_context, outputPath) => {
62
- // Skip pnpm update in test environment to avoid monorepo workspace issues
63
- if (process.env.NODE_ENV === 'test') {
64
- console.log('⊘ Skipping dependency update in test environment');
65
- return;
66
- }
67
-
68
- const cmd = 'pnpm';
69
- const args = ['update', 'coze-coding-dev-sdk@^0.7.25'];
70
- console.log(
71
- `\nTriggering: ${cmd} ${args.join(' ')} (running in background)`,
72
- );
73
-
74
- try {
75
- const projectRoot = resolve(outputPath);
76
-
77
- // Determine log directory
78
- const cozeHome = process.env.COZE_HOME || join(homedir(), '.coze');
79
- const logDir = process.env.COZE_LOG_DIR || join(cozeHome, 'logs');
80
- mkdirSync(logDir, { recursive: true });
81
-
82
- // Use project name in log file to avoid conflicts
83
- const projectName = basename(projectRoot);
84
- const logFile = join(logDir, `${projectName}-init.log`);
85
-
86
- // Write log header
87
- const timestamp = new Date().toISOString();
88
- appendFileSync(
89
- logFile,
90
- `\n=== [${timestamp}] ${cmd} ${args.join(' ')} ===\n`,
91
- );
92
-
93
- // Open log file for appending
94
- const logFd = openSync(logFile, 'a');
95
-
96
- // Spawn in detached mode
97
- const child = spawn(cmd, args, {
98
- cwd: projectRoot,
99
- detached: true,
100
- stdio: ['ignore', logFd, logFd],
101
- });
102
-
103
- child.unref();
104
- closeSync(logFd);
105
-
106
- console.log(
107
- '✓ coze-coding-dev-sdk update triggered (running in background)',
108
- );
109
- console.log(` Log file: ${logFile}`);
110
- } catch (error) {
111
- console.error('✗ Failed to trigger coze-coding-dev-sdk update:', error);
112
- console.log(' You can manually run: pnpm update coze-coding-dev-sdk');
113
- }
114
- },
115
56
  };
116
57
 
117
58
  export default config;
@@ -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.25",
30
+ "coze-coding-dev-sdk": "^0.7.28",
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.25
38
- version: 0.7.25(openai@6.27.0(ws@8.21.3)(zod@4.3.6))(ws@8.21.3)
37
+ specifier: ^0.7.28
38
+ version: 0.7.28(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.25:
2502
- resolution: {integrity: sha512-5683ngikMdsRW0slGTE2OAZ1Fyj0lhkC4fGNOwsqKc35e68/gtg9KmmtK9CK9SZ+5/oIn/4wLoHXFB0gHJtO2A==}
2501
+ coze-coding-dev-sdk@0.7.28:
2502
+ resolution: {integrity: sha512-ku7AiVWUmgCrUuMT1m2iTmHIwG39EfmcAhPASd8M7XyKxIC6A1cjIIe/3YpStRsj8pMF9LU+pxHWxisf+F44oQ==}
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.25(openai@6.27.0(ws@8.21.3)(zod@4.3.6))(ws@8.21.3):
8529
+ coze-coding-dev-sdk@0.7.28(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)
@@ -6,7 +6,7 @@ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
6
  cd "${COZE_WORKSPACE_PATH}"
7
7
 
8
8
  echo "Installing dependencies..."
9
- pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
9
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
10
10
 
11
11
  echo "Building the Nuxt.js project..."
12
12
  pnpm nuxt build
@@ -77,6 +77,7 @@ shift
77
77
  child_pid=$!
78
78
 
79
79
  # 先忽略 TERM,才能在向整组发 TERM(自己也在组里)之后存活下来补一发 KILL。
80
+ if [[ -z "${COZE_EVAL:-}" && -z "${COZE_PROJECT_TYPE:-}" ]]; then
80
81
  ( trap "" TERM
81
82
  sleep "${timeout_seconds}"
82
83
  echo "[dev] 后台进程运行超过 ${timeout_seconds}s,回收进程组 $$。"
@@ -84,6 +85,7 @@ child_pid=$!
84
85
  sleep 5
85
86
  kill -KILL -- "-$$" 2>/dev/null || true
86
87
  ) &
88
+ fi
87
89
 
88
90
  wait "${child_pid}"
89
91
  kill -KILL -- "-$$" 2>/dev/null || true
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # Install dependencies on local disk and expose them to the source tree by symlink.
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
6
+ if [ "$(basename "$(dirname "$SCRIPT_DIR")")" = ".cozeproj" ]; then
7
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd -P)"
8
+ else
9
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
10
+ fi
11
+
12
+ command -v pnpm >/dev/null 2>&1 || {
13
+ echo "[node_modules] pnpm is required" >&2
14
+ exit 1
15
+ }
16
+
17
+ DRIVE_ROOT="${COZE_DRIVE_ROOT:-/Coze/Drive}"
18
+ if [ -d "$DRIVE_ROOT" ]; then
19
+ DRIVE_ROOT="$(cd "$DRIVE_ROOT" && pwd -P)"
20
+ else
21
+ DRIVE_ROOT="${DRIVE_ROOT%/}"
22
+ fi
23
+ case "$PROJECT_ROOT" in
24
+ "$DRIVE_ROOT"|"$DRIVE_ROOT"/*) ;;
25
+ *)
26
+ (cd "$PROJECT_ROOT" && pnpm install "$@")
27
+ exit 0
28
+ ;;
29
+ esac
30
+
31
+ NM_ROOT="/tmp/nm"
32
+ PROJECT_ID="$(basename "$PROJECT_ROOT")-$(printf '%s' "$PROJECT_ROOT" | cksum | awk '{print $1}')"
33
+ mkdir -p "$NM_ROOT"
34
+ WORK_DIR="$NM_ROOT/$PROJECT_ID"
35
+ case "$WORK_DIR" in
36
+ "$DRIVE_ROOT"|"$DRIVE_ROOT"/*)
37
+ echo "[node_modules] local dependency directory must not be on Coze Drive: $WORK_DIR" >&2
38
+ exit 1
39
+ ;;
40
+ esac
41
+
42
+ LOCK_DIR="$NM_ROOT/$PROJECT_ID.lock"
43
+ while ! mkdir "$LOCK_DIR" 2>/dev/null; do
44
+ echo "[node_modules] Waiting for another dependency preparation for this project..."
45
+ sleep 1
46
+ done
47
+ trap 'rmdir "$LOCK_DIR" 2>/dev/null || true' EXIT
48
+
49
+ mkdir -p "$WORK_DIR"
50
+
51
+ # Previous versions mirrored the whole project into WORK_DIR. That gives pnpm
52
+ # and framework dev servers two paths for the same source tree, which breaks
53
+ # file watching and on-demand compilation. Keep only managed local outputs.
54
+ cleanup_legacy_workspace() {
55
+ local workspace_dir="$1" entry name
56
+ if [ -L "$workspace_dir" ] || { [ -e "$workspace_dir" ] && [ ! -d "$workspace_dir" ]; }; then
57
+ rm -rf "$workspace_dir"
58
+ return
59
+ fi
60
+ [ -d "$workspace_dir" ] || return
61
+
62
+ while IFS= read -r -d '' entry; do
63
+ name="$(basename "$entry")"
64
+ [ "$name" = "node_modules" ] || rm -rf "$entry"
65
+ done < <(find "$workspace_dir" -mindepth 1 -maxdepth 1 -print0)
66
+ }
67
+
68
+ cleanup_legacy_shadow_project() {
69
+ local entry name
70
+ while IFS= read -r -d '' entry; do
71
+ name="$(basename "$entry")"
72
+ case "$name" in
73
+ node_modules|.next|client|server) continue ;;
74
+ esac
75
+ rm -rf "$entry"
76
+ done < <(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -print0)
77
+
78
+ for workspace in client server; do
79
+ cleanup_legacy_workspace "$WORK_DIR/$workspace"
80
+ done
81
+ }
82
+
83
+ link_node_modules() {
84
+ local source_dir="$1" target_dir="$2"
85
+ local current=""
86
+ mkdir -p "$target_dir"
87
+ if [ -L "$source_dir/node_modules" ]; then
88
+ current="$(readlink "$source_dir/node_modules")"
89
+ case "$current" in
90
+ "$NM_ROOT"/*/node_modules|"$NM_ROOT"/*/*/node_modules) ;;
91
+ *)
92
+ echo "[node_modules] refusing to replace unmanaged symlink: $source_dir/node_modules" >&2
93
+ exit 1
94
+ ;;
95
+ esac
96
+ rm "$source_dir/node_modules"
97
+ elif [ -e "$source_dir/node_modules" ]; then
98
+ rm -rf "$source_dir/node_modules"
99
+ fi
100
+ ln -s "$target_dir" "$source_dir/node_modules"
101
+ }
102
+
103
+ cleanup_legacy_shadow_project
104
+ link_node_modules "$PROJECT_ROOT" "$WORK_DIR/node_modules"
105
+ for workspace in client server; do
106
+ if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
107
+ link_node_modules "$PROJECT_ROOT/$workspace" "$WORK_DIR/$workspace/node_modules"
108
+ fi
109
+ done
110
+
111
+ echo "[node_modules] Installing dependencies for $PROJECT_ROOT with node_modules at $WORK_DIR"
112
+ (cd "$PROJECT_ROOT" && pnpm install "$@")
113
+
114
+ echo "[node_modules] Dependencies ready"
@@ -6,10 +6,7 @@ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
6
  cd "${COZE_WORKSPACE_PATH}"
7
7
 
8
8
  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
12
- fi
9
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline
13
10
 
14
11
  echo "Preparing Nuxt project..."
15
12
  pnpm exec nuxt prepare
@@ -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.25",
25
+ "coze-coding-dev-sdk": "^0.7.28",
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.25
40
- version: 0.7.25(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)
39
+ specifier: ^0.7.28
40
+ version: 0.7.28(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.25:
2089
- resolution: {integrity: sha512-5683ngikMdsRW0slGTE2OAZ1Fyj0lhkC4fGNOwsqKc35e68/gtg9KmmtK9CK9SZ+5/oIn/4wLoHXFB0gHJtO2A==}
2088
+ coze-coding-dev-sdk@0.7.28:
2089
+ resolution: {integrity: sha512-ku7AiVWUmgCrUuMT1m2iTmHIwG39EfmcAhPASd8M7XyKxIC6A1cjIIe/3YpStRsj8pMF9LU+pxHWxisf+F44oQ==}
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.25(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0):
6123
+ coze-coding-dev-sdk@0.7.28(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)
@@ -1,7 +1,8 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
- cd "${COZE_WORKSPACE_PATH}"
4
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
5
+ cd "$ROOT_DIR"
5
6
  if [ -f "./.cozeproj/scripts/init_env.sh" ]; then
6
7
  echo "⚙️ Initializing environment..."
7
8
  # 使用 bash 执行,确保即使没有 x 权限也能跑
@@ -11,7 +12,7 @@ else
11
12
  fi
12
13
  echo "Installing dependencies..."
13
14
  # 安装所有依赖(包含 Taro 核心和 React)
14
- pnpm install
15
+ bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline
15
16
 
16
17
  echo "Building the Taro project..."
17
18
  pnpm build
@@ -1,2 +1,5 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
5
+ bash "$ROOT_DIR/.cozeproj/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline