@coze-arch/cli 0.0.37 → 0.1.3-alpha.32023e

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 (169) hide show
  1. package/README.md +69 -104
  2. package/docs/deploy.md +181 -0
  3. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +7 -3
  4. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +108 -19
  5. package/lib/__templates__/expo/.cozeproj/scripts/prepare-node-modules.sh +142 -0
  6. package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +3 -3
  7. package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +1 -1
  8. package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +1 -1
  9. package/lib/__templates__/expo/client/metro.config.js +3 -1
  10. package/lib/__templates__/expo/pnpm-lock.yaml +5 -5
  11. package/lib/__templates__/expo/server/package.json +2 -2
  12. package/lib/__templates__/expo/server/src/index.ts +1 -1
  13. package/lib/__templates__/expo/template.config.js +11 -2
  14. package/lib/__templates__/native-static/.coze +4 -2
  15. package/lib/__templates__/native-static/scripts/serve.ps1 +7 -0
  16. package/lib/__templates__/nextjs/.coze +5 -0
  17. package/lib/__templates__/nextjs/package.json +2 -2
  18. package/lib/__templates__/nextjs/pnpm-lock.yaml +57 -341
  19. package/lib/__templates__/nextjs/scripts/build.ps1 +16 -0
  20. package/lib/__templates__/nextjs/scripts/build.sh +1 -1
  21. package/lib/__templates__/nextjs/scripts/dev.ps1 +63 -0
  22. package/lib/__templates__/nextjs/scripts/dev.sh +234 -7
  23. package/lib/__templates__/nextjs/scripts/prepare-node-modules.sh +142 -0
  24. package/lib/__templates__/nextjs/scripts/prepare.ps1 +18 -0
  25. package/lib/__templates__/nextjs/scripts/prepare.sh +1 -4
  26. package/lib/__templates__/nextjs/scripts/start.ps1 +11 -0
  27. package/lib/__templates__/nextjs/scripts/validate.ps1 +8 -0
  28. package/lib/__templates__/nextjs/template.config.js +0 -57
  29. package/lib/__templates__/nuxt-vue/.coze +5 -0
  30. package/lib/__templates__/nuxt-vue/package.json +1 -1
  31. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +5 -5
  32. package/lib/__templates__/nuxt-vue/scripts/build.ps1 +12 -0
  33. package/lib/__templates__/nuxt-vue/scripts/build.sh +1 -1
  34. package/lib/__templates__/nuxt-vue/scripts/dev.ps1 +63 -0
  35. package/lib/__templates__/nuxt-vue/scripts/dev.sh +232 -3
  36. package/lib/__templates__/nuxt-vue/scripts/prepare-node-modules.sh +142 -0
  37. package/lib/__templates__/nuxt-vue/scripts/prepare.ps1 +12 -0
  38. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +1 -4
  39. package/lib/__templates__/nuxt-vue/scripts/start.ps1 +11 -0
  40. package/lib/__templates__/nuxt-vue/scripts/validate.ps1 +8 -0
  41. package/lib/__templates__/phaser/.coze +18 -0
  42. package/lib/__templates__/phaser/README.md +45 -0
  43. package/lib/__templates__/phaser/_gitignore +23 -0
  44. package/lib/__templates__/phaser/_npmrc +14 -0
  45. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0001.png +0 -0
  46. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0002.png +0 -0
  47. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0003.png +0 -0
  48. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0004.png +0 -0
  49. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0005.png +0 -0
  50. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0006.png +0 -0
  51. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0007.png +0 -0
  52. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0008.png +0 -0
  53. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0009.png +0 -0
  54. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0010.png +0 -0
  55. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0011.png +0 -0
  56. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0012.png +0 -0
  57. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0013.png +0 -0
  58. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0014.png +0 -0
  59. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0015.png +0 -0
  60. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0016.png +0 -0
  61. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0017.png +0 -0
  62. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0018.png +0 -0
  63. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0019.png +0 -0
  64. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0020.png +0 -0
  65. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0021.png +0 -0
  66. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0022.png +0 -0
  67. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0023.png +0 -0
  68. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0024.png +0 -0
  69. package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/manifest.json +11 -0
  70. package/lib/__templates__/phaser/debug-runtime/flow-graph.json +20 -0
  71. package/lib/__templates__/phaser/index.html +12 -0
  72. package/lib/__templates__/phaser/package.json +31 -0
  73. package/lib/__templates__/phaser/pnpm-lock.yaml +661 -0
  74. package/lib/__templates__/phaser/scripts/build.ps1 +12 -0
  75. package/lib/__templates__/phaser/scripts/build.sh +8 -0
  76. package/lib/__templates__/phaser/scripts/dev.ps1 +49 -0
  77. package/lib/__templates__/phaser/scripts/dev.sh +82 -0
  78. package/lib/__templates__/phaser/scripts/prepare.ps1 +8 -0
  79. package/lib/__templates__/phaser/scripts/prepare.sh +7 -0
  80. package/lib/__templates__/phaser/scripts/spawn-detached.cjs +29 -0
  81. package/lib/__templates__/phaser/scripts/start.ps1 +49 -0
  82. package/lib/__templates__/phaser/scripts/start.sh +82 -0
  83. package/lib/__templates__/phaser/scripts/validate.ps1 +7 -0
  84. package/lib/__templates__/phaser/scripts/validate.sh +7 -0
  85. package/lib/__templates__/phaser/src/assets.ts +15 -0
  86. package/lib/__templates__/phaser/src/global.d.ts +39 -0
  87. package/lib/__templates__/phaser/src/main.ts +28 -0
  88. package/lib/__templates__/phaser/src/scene/BootScene.ts +213 -0
  89. package/lib/__templates__/phaser/src/scene/DevLoadingScene.ts +69 -0
  90. package/lib/__templates__/phaser/src/style.css +28 -0
  91. package/lib/__templates__/phaser/src/types.ts +32 -0
  92. package/lib/__templates__/phaser/src/utils/asset-loader.ts +319 -0
  93. package/lib/__templates__/phaser/src/utils/index.ts +2 -0
  94. package/lib/__templates__/phaser/src/utils/mark-editable.ts +13 -0
  95. package/lib/__templates__/phaser/template.config.js +43 -0
  96. package/lib/__templates__/phaser/tsconfig.json +23 -0
  97. package/lib/__templates__/phaser/vite.config.ts +96 -0
  98. package/lib/__templates__/phaser-static/.coze +15 -0
  99. package/lib/__templates__/phaser-static/README.md +40 -0
  100. package/lib/__templates__/phaser-static/_gitignore +6 -0
  101. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0001.png +0 -0
  102. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0002.png +0 -0
  103. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0003.png +0 -0
  104. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0004.png +0 -0
  105. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0005.png +0 -0
  106. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0006.png +0 -0
  107. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0007.png +0 -0
  108. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0008.png +0 -0
  109. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0009.png +0 -0
  110. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0010.png +0 -0
  111. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0011.png +0 -0
  112. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0012.png +0 -0
  113. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0013.png +0 -0
  114. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0014.png +0 -0
  115. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0015.png +0 -0
  116. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0016.png +0 -0
  117. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0017.png +0 -0
  118. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0018.png +0 -0
  119. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0019.png +0 -0
  120. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0020.png +0 -0
  121. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0021.png +0 -0
  122. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0022.png +0 -0
  123. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0023.png +0 -0
  124. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0024.png +0 -0
  125. package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/manifest.json +11 -0
  126. package/lib/__templates__/phaser-static/debug-runtime/flow-graph.json +20 -0
  127. package/lib/__templates__/phaser-static/index.html +17 -0
  128. package/lib/__templates__/phaser-static/scripts/serve.ps1 +7 -0
  129. package/lib/__templates__/phaser-static/src/assets.js +15 -0
  130. package/lib/__templates__/phaser-static/src/main.js +26 -0
  131. package/lib/__templates__/phaser-static/src/phaser.js +7 -0
  132. package/lib/__templates__/phaser-static/src/scene/BootScene.js +205 -0
  133. package/lib/__templates__/phaser-static/src/scene/DevLoadingScene.js +67 -0
  134. package/lib/__templates__/phaser-static/src/style.css +28 -0
  135. package/lib/__templates__/phaser-static/src/utils/asset-loader.js +267 -0
  136. package/lib/__templates__/phaser-static/src/utils/index.js +2 -0
  137. package/lib/__templates__/phaser-static/src/utils/mark-editable.js +3 -0
  138. package/lib/__templates__/phaser-static/template.config.js +35 -0
  139. package/lib/__templates__/pi-agent/package.json +1 -1
  140. package/lib/__templates__/pi-agent/pnpm-lock.yaml +5 -5
  141. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +3 -2
  142. package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +1 -1
  143. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +3 -0
  144. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +178 -68
  145. package/lib/__templates__/taro/.cozeproj/scripts/prepare-node-modules.sh +142 -0
  146. package/lib/__templates__/taro/AGENTS.md +11 -7
  147. package/lib/__templates__/taro/README.md +4 -4
  148. package/lib/__templates__/taro/config/index.ts +10 -2
  149. package/lib/__templates__/taro/pnpm-lock.yaml +5 -5
  150. package/lib/__templates__/taro/server/package.json +1 -1
  151. package/lib/__templates__/taro/server/src/main.ts +8 -2
  152. package/lib/__templates__/templates.json +51 -1
  153. package/lib/__templates__/vite/.coze +5 -0
  154. package/lib/__templates__/vite/package.json +1 -1
  155. package/lib/__templates__/vite/pnpm-lock.yaml +5 -5
  156. package/lib/__templates__/vite/scripts/build.ps1 +16 -0
  157. package/lib/__templates__/vite/scripts/build.sh +1 -1
  158. package/lib/__templates__/vite/scripts/dev.ps1 +63 -0
  159. package/lib/__templates__/vite/scripts/dev.sh +110 -1
  160. package/lib/__templates__/vite/scripts/prepare-node-modules.sh +142 -0
  161. package/lib/__templates__/vite/scripts/prepare.ps1 +18 -0
  162. package/lib/__templates__/vite/scripts/prepare.sh +1 -4
  163. package/lib/__templates__/vite/scripts/start.ps1 +11 -0
  164. package/lib/__templates__/vite/scripts/validate.ps1 +8 -0
  165. package/lib/__templates__/vite/template.config.js +0 -57
  166. package/lib/cli.js +3751 -222
  167. package/lib/deploy/package-project.js +244 -0
  168. package/lib/deploy/package-project.py +183 -0
  169. package/package.json +5 -2
@@ -16,10 +16,17 @@
16
16
  },
17
17
  "port": {
18
18
  "type": "number",
19
- "default": 8081,
19
+ "default": 5000,
20
20
  "minimum": 1024,
21
21
  "maximum": 65535,
22
22
  "description": "Metro bundler port"
23
+ },
24
+ "serverPort": {
25
+ "type": "number",
26
+ "default": 9091,
27
+ "minimum": 1024,
28
+ "maximum": 65535,
29
+ "description": "Express backend server port"
23
30
  }
24
31
  },
25
32
  "required": [],
@@ -94,6 +101,49 @@
94
101
  "additionalProperties": false
95
102
  }
96
103
  },
104
+ {
105
+ "name": "phaser",
106
+ "description": "Phaser(2D 游戏):`coze-dev init ${COZE_WORKSPACE_PATH} --template phaser`\n- 适用:基于 Phaser 3、Vite 和 TypeScript 的 2D Web 游戏。",
107
+ "location": "./phaser",
108
+ "paramsSchema": {
109
+ "type": "object",
110
+ "properties": {
111
+ "appName": {
112
+ "type": "string",
113
+ "minLength": 1,
114
+ "pattern": "^[a-z0-9-]+$",
115
+ "description": "Application name (lowercase, alphanumeric and hyphens only)"
116
+ },
117
+ "port": {
118
+ "type": "number",
119
+ "default": 5000,
120
+ "minimum": 1024,
121
+ "maximum": 65535,
122
+ "description": "Development and preview server port"
123
+ }
124
+ },
125
+ "required": [],
126
+ "additionalProperties": false
127
+ }
128
+ },
129
+ {
130
+ "name": "phaser-static",
131
+ "description": "Phaser Static(纯静态 2D 游戏):coze-dev init ${COZE_WORKSPACE_PATH} --template phaser-static\n- 适用:浏览器原生 JavaScript ESM 的 Phaser 3 游戏。\n- Phaser 与 Phaser Bridge 从 CDN 加载;无需 npm、Vite 或 TypeScript。",
132
+ "location": "./phaser-static",
133
+ "paramsSchema": {
134
+ "type": "object",
135
+ "properties": {
136
+ "appName": {
137
+ "type": "string",
138
+ "minLength": 1,
139
+ "pattern": "^[a-z0-9-]+$",
140
+ "description": "Application name (lowercase, alphanumeric and hyphens only)"
141
+ }
142
+ },
143
+ "required": [],
144
+ "additionalProperties": false
145
+ }
146
+ },
97
147
  {
98
148
  "name": "pi-agent",
99
149
  "description": "Pi Agent:`coze-dev init ${COZE_WORKSPACE_PATH} --template pi-agent`\n- 适用:基于 pi-agent-core 的 AI Agent 应用\n- 支持飞书、微信等多渠道接入\n- 内置 Dashboard 管理面板\n- 使用 TypeScript + Express + Vite",
@@ -4,11 +4,16 @@ project_type = "web"
4
4
 
5
5
  [dev]
6
6
  build = ["bash", "./scripts/prepare.sh"]
7
+ build_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/prepare.ps1"]
7
8
  run = ["bash", "./scripts/dev.sh"]
9
+ run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/dev.ps1"]
8
10
  validate = ["bash", "./scripts/validate.sh"]
11
+ validate_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/validate.ps1"]
9
12
  deps = ["git"] # -> apt install git
10
13
 
11
14
  [deploy]
12
15
  build = ["bash","./scripts/build.sh"]
16
+ build_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/build.ps1"]
13
17
  run = ["bash","./scripts/start.sh"]
18
+ run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/start.ps1"]
14
19
  deps = ["git"] # -> apt install git
@@ -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",
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
36
+ version: 0.7.25(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:
914
+ resolution: {integrity: sha512-5683ngikMdsRW0slGTE2OAZ1Fyj0lhkC4fGNOwsqKc35e68/gtg9KmmtK9CK9SZ+5/oIn/4wLoHXFB0gHJtO2A==}
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(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)
@@ -0,0 +1,16 @@
1
+ $ErrorActionPreference = "Stop"
2
+
3
+ $workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { (Get-Location).Path }
4
+ Set-Location $workspace
5
+
6
+ Write-Host "Installing dependencies..."
7
+ & pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
8
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
9
+
10
+ Write-Host "Building frontend with Vite..."
11
+ & pnpm vite build
12
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
13
+
14
+ Write-Host "Bundling server with tsup..."
15
+ & pnpm tsup server/server.ts --format cjs --platform node --target node20 --outDir dist-server --no-splitting --no-minify --external vite
16
+ exit $LASTEXITCODE
@@ -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 frontend with Vite..."
12
12
  pnpm vite build
@@ -0,0 +1,63 @@
1
+ $ErrorActionPreference = "Stop"
2
+
3
+ function Get-WorkspacePath {
4
+ if ($env:COZE_WORKSPACE_PATH) {
5
+ return $env:COZE_WORKSPACE_PATH
6
+ }
7
+ return (Get-Location).Path
8
+ }
9
+
10
+ function Stop-ProcessTree([int] $processId) {
11
+ if ($processId -gt 0 -and (Get-Process -Id $processId -ErrorAction SilentlyContinue)) {
12
+ & taskkill.exe /PID $processId /T /F *> $null
13
+ }
14
+ }
15
+
16
+ function Stop-ListeningProcess([int] $port) {
17
+ $connections = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue
18
+ $connections | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object {
19
+ Stop-ProcessTree $_
20
+ }
21
+ }
22
+
23
+ $workspace = Get-WorkspacePath
24
+ $defaultPort = <%= port %>
25
+ $port = if ($env:DEPLOY_RUN_PORT) { [int] $env:DEPLOY_RUN_PORT } elseif ($env:PORT) { [int] $env:PORT } else { $defaultPort }
26
+ Set-Location $workspace
27
+ Stop-ListeningProcess $port
28
+
29
+ <% if (process.env.NODE_ENV === 'test') { %>
30
+ $env:PORT = "$port"
31
+ & pnpm tsx watch server/server.ts
32
+ exit $LASTEXITCODE
33
+ <% } else { %>
34
+ $logDirectory = if ($env:COZE_LOG_DIR) { $env:COZE_LOG_DIR } else { Join-Path $workspace "logs" }
35
+ $logFile = Join-Path $logDirectory "server.log"
36
+ $errorLogFile = Join-Path $logDirectory "server-error.log"
37
+ $pidFile = Join-Path $logDirectory "server.pid"
38
+ New-Item -ItemType Directory -Force -Path $logDirectory | Out-Null
39
+
40
+ if (Test-Path $pidFile) {
41
+ Stop-ProcessTree ([int] (Get-Content $pidFile -Raw))
42
+ Remove-Item $pidFile -Force
43
+ }
44
+
45
+ $previousPort = $env:PORT
46
+ $env:PORT = "$port"
47
+ try {
48
+ $process = Start-Process -FilePath $env:ComSpec -ArgumentList @("/d", "/s", "/c", "pnpm tsx watch server/server.ts") -WorkingDirectory $workspace -RedirectStandardOutput $logFile -RedirectStandardError $errorLogFile -PassThru
49
+ } finally {
50
+ if ($null -eq $previousPort) { Remove-Item Env:PORT -ErrorAction SilentlyContinue } else { $env:PORT = $previousPort }
51
+ }
52
+
53
+ $process.Id | Set-Content $pidFile
54
+ Start-Sleep -Seconds 1
55
+ if ($process.HasExited) {
56
+ Get-Content $errorLogFile -Tail 20 -ErrorAction SilentlyContinue
57
+ Remove-Item $pidFile -Force -ErrorAction SilentlyContinue
58
+ exit 1
59
+ }
60
+
61
+ Write-Host "Dev server started (PID: $($process.Id))."
62
+ Write-Host "Log file: $logFile"
63
+ <% } %>
@@ -32,8 +32,117 @@ kill_port_if_listening() {
32
32
  fi
33
33
  }
34
34
 
35
+ <% if (process.env.NODE_ENV === 'test') { %>
35
36
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
36
37
  kill_port_if_listening
37
38
  echo "Starting express + Vite dev server on port ${DEPLOY_RUN_PORT}..."
38
39
 
39
- PORT=${DEPLOY_RUN_PORT} pnpm tsx watch server/server.ts
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
+ # detached 出去的进程没人负责回收,超过这个时长就自己退出,避免端口与内存长期泄露。
48
+ MAX_RUNTIME_SECONDS=1200
49
+
50
+ # 真正被 detach 的是这层 bash wrapper:它是进程组 leader,组内 watchdog 到点回收整组
51
+ # (wrapper -> pnpm -> tsx -> node);被包的进程自己先退出时也顺手清空进程组,不留残余。
52
+ RUN_WITH_TIMEOUT='
53
+ timeout_seconds=$1
54
+ shift
55
+
56
+ "$@" &
57
+ child_pid=$!
58
+
59
+ # 先忽略 TERM,才能在向整组发 TERM(自己也在组里)之后存活下来补一发 KILL。
60
+ ( trap "" TERM
61
+ sleep "${timeout_seconds}"
62
+ echo "[dev] 后台进程运行超过 ${timeout_seconds}s,回收进程组 $$。"
63
+ kill -TERM -- "-$$" 2>/dev/null || true
64
+ sleep 5
65
+ kill -KILL -- "-$$" 2>/dev/null || true
66
+ ) &
67
+
68
+ wait "${child_pid}"
69
+ kill -KILL -- "-$$" 2>/dev/null || true
70
+ '
71
+
72
+ # coze-daemon 会在 runtime shell 退出时清理原进程组。
73
+ # 通过 Node detached spawn 创建独立 session/进程组,并将 stdio 直接写入日志。
74
+ # 返回的 PID 是 wrapper 的,同时也是整个进程组的 PGID,后续按组回收。
75
+ spawn_detached() {
76
+ local cwd="$1"
77
+ local log_file="$2"
78
+ shift 2
79
+
80
+ node - "$cwd" "$log_file" \
81
+ /bin/bash -c "${RUN_WITH_TIMEOUT}" detached-runner "${MAX_RUNTIME_SECONDS}" "$@" <<'NODE'
82
+ const fs = require('node:fs');
83
+ const { spawn } = require('node:child_process');
84
+
85
+ const [cwd, logFile, command, ...args] = process.argv.slice(2);
86
+ if (!cwd || !logFile || !command) {
87
+ throw new Error('spawn_detached 缺少 cwd、log_file 或 command');
88
+ }
89
+
90
+ const logFd = fs.openSync(logFile, 'a');
91
+ try {
92
+ const child = spawn(command, args, {
93
+ cwd,
94
+ detached: true,
95
+ env: process.env,
96
+ stdio: ['ignore', logFd, logFd],
97
+ });
98
+ child.unref();
99
+ process.stdout.write(String(child.pid));
100
+ } finally {
101
+ fs.closeSync(logFd);
102
+ }
103
+ NODE
104
+ }
105
+
106
+ stop_detached() {
107
+ local pid="${1:-}"
108
+ if [[ -z "${pid}" ]]; then
109
+ return
110
+ fi
111
+
112
+ kill -TERM -- "-${pid}" 2>/dev/null || kill -TERM "${pid}" 2>/dev/null || true
113
+ sleep 1
114
+ kill -KILL -- "-${pid}" 2>/dev/null || true
115
+ }
116
+
117
+ # 监听端口的是孙进程(pnpm -> tsx -> node),只清端口会漏掉上层 pnpm/tsx,
118
+ # 所以先按上次记录的 PID 把整个进程组回收掉。
119
+ if [[ -f "${PID_FILE}" ]]; then
120
+ stop_detached "$(cat "${PID_FILE}" 2>/dev/null || true)"
121
+ rm -f "${PID_FILE}"
122
+ fi
123
+
124
+ echo "Clearing port ${DEPLOY_RUN_PORT} before start."
125
+ kill_port_if_listening
126
+ echo "Starting express + Vite dev server on port ${DEPLOY_RUN_PORT}..."
127
+
128
+ mkdir -p "${LOG_DIR}"
129
+ : > "${LOG_FILE}"
130
+
131
+ export PORT="${DEPLOY_RUN_PORT}"
132
+ server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
133
+ "$(command -v pnpm)" tsx watch server/server.ts)"
134
+ echo "${server_pid}" > "${PID_FILE}"
135
+
136
+ sleep 1
137
+ if [[ -z "${server_pid}" ]] || ! kill -0 "${server_pid}" 2>/dev/null; then
138
+ echo "Dev server failed to start. See ${LOG_FILE}." >&2
139
+ tail -n 20 "${LOG_FILE}" >&2 || true
140
+ rm -f "${PID_FILE}"
141
+ exit 1
142
+ fi
143
+
144
+ echo "Dev server started (PID: ${server_pid})."
145
+ echo "Auto stop after ${MAX_RUNTIME_SECONDS}s."
146
+ echo "Log file: ${LOG_FILE}"
147
+ echo "PID file: ${PID_FILE}"
148
+ <% } %>
@@ -0,0 +1,142 @@
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
+ COZE_ROOT="${COZE_DIR_PATH:-${HOME}/Coze/tmp}"
32
+ PROJECT_ID="$(basename "$PROJECT_ROOT")-$(printf '%s' "$PROJECT_ROOT" | cksum | awk '{print $1}')"
33
+ mkdir -p "$COZE_ROOT/nm"
34
+ COZE_ROOT="$(cd "$COZE_ROOT" && pwd -P)"
35
+ WORK_DIR="$COZE_ROOT/nm/$PROJECT_ID"
36
+ mkdir -p "$WORK_DIR"
37
+ case "$WORK_DIR" in
38
+ "$DRIVE_ROOT"|"$DRIVE_ROOT"/*)
39
+ echo "[node_modules] local dependency directory must not be on Coze Drive: $WORK_DIR" >&2
40
+ exit 1
41
+ ;;
42
+ esac
43
+
44
+ # Mirror the project with symlinks. node_modules stays real in WORK_DIR;
45
+ # workspace directories stay real too, so pnpm never writes them to Drive.
46
+ mirror_root() {
47
+ local entry name
48
+ while IFS= read -r -d '' entry; do
49
+ name="$(basename "$entry")"
50
+ case "$name" in
51
+ node_modules|pnpm-lock.yaml) continue ;;
52
+ client|server)
53
+ [ -f "$PROJECT_ROOT/$name/package.json" ] && continue
54
+ ;;
55
+ esac
56
+ rm -rf "$entry"
57
+ done < <(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -print0)
58
+
59
+ while IFS= read -r -d '' entry; do
60
+ name="$(basename "$entry")"
61
+ case "$name" in
62
+ node_modules|pnpm-lock.yaml) continue ;;
63
+ client|server)
64
+ [ -f "$entry/package.json" ] && continue
65
+ ;;
66
+ esac
67
+ ln -s "$entry" "$WORK_DIR/$name"
68
+ done < <(find "$PROJECT_ROOT" -mindepth 1 -maxdepth 1 -print0)
69
+ }
70
+
71
+ mirror_workspace() {
72
+ local workspace="$1" source_dir="$PROJECT_ROOT/$1" work_dir="$WORK_DIR/$1"
73
+ local entry name
74
+ if [ -L "$work_dir" ] || { [ -e "$work_dir" ] && [ ! -d "$work_dir" ]; }; then
75
+ rm -rf "$work_dir"
76
+ fi
77
+ mkdir -p "$work_dir"
78
+
79
+ while IFS= read -r -d '' entry; do
80
+ [ "$(basename "$entry")" = "node_modules" ] || rm -rf "$entry"
81
+ done < <(find "$work_dir" -mindepth 1 -maxdepth 1 -print0)
82
+
83
+ while IFS= read -r -d '' entry; do
84
+ name="$(basename "$entry")"
85
+ [ "$name" = "node_modules" ] || ln -s "$entry" "$work_dir/$name"
86
+ done < <(find "$source_dir" -mindepth 1 -maxdepth 1 -print0)
87
+ }
88
+
89
+ mirror_root
90
+ for workspace in client server; do
91
+ if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
92
+ mirror_workspace "$workspace"
93
+ fi
94
+ done
95
+
96
+ # pnpm refuses to update a symlinked lockfile, so install against a local copy.
97
+ rm -rf "$WORK_DIR/pnpm-lock.yaml"
98
+ if [ -f "$PROJECT_ROOT/pnpm-lock.yaml" ]; then
99
+ cp "$PROJECT_ROOT/pnpm-lock.yaml" "$WORK_DIR/pnpm-lock.yaml"
100
+ fi
101
+
102
+ echo "[node_modules] Installing dependencies in $WORK_DIR"
103
+ if ! (cd "$WORK_DIR" && pnpm install "$@"); then
104
+ rm -f "$WORK_DIR/pnpm-lock.yaml"
105
+ exit 1
106
+ fi
107
+
108
+ if [ -f "$WORK_DIR/pnpm-lock.yaml" ]; then
109
+ temporary_lockfile="$(mktemp "$PROJECT_ROOT/.pnpm-lock.yaml.XXXXXX")"
110
+ cp "$WORK_DIR/pnpm-lock.yaml" "$temporary_lockfile"
111
+ chmod 0644 "$temporary_lockfile"
112
+ mv -f "$temporary_lockfile" "$PROJECT_ROOT/pnpm-lock.yaml"
113
+ fi
114
+
115
+ link_node_modules() {
116
+ local source_dir="$1" target_dir="$2"
117
+ local current=""
118
+ mkdir -p "$target_dir"
119
+ if [ -L "$source_dir/node_modules" ]; then
120
+ current="$(readlink "$source_dir/node_modules")"
121
+ case "$current" in
122
+ "$COZE_ROOT"/nm/*/node_modules|"$COZE_ROOT"/nm/*/*/node_modules) ;;
123
+ *)
124
+ echo "[node_modules] refusing to replace unmanaged symlink: $source_dir/node_modules" >&2
125
+ exit 1
126
+ ;;
127
+ esac
128
+ rm "$source_dir/node_modules"
129
+ elif [ -e "$source_dir/node_modules" ]; then
130
+ rm -rf "$source_dir/node_modules"
131
+ fi
132
+ ln -s "$target_dir" "$source_dir/node_modules"
133
+ }
134
+
135
+ link_node_modules "$PROJECT_ROOT" "$WORK_DIR/node_modules"
136
+ for workspace in client server; do
137
+ if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
138
+ link_node_modules "$PROJECT_ROOT/$workspace" "$WORK_DIR/$workspace/node_modules"
139
+ fi
140
+ done
141
+
142
+ echo "[node_modules] Dependencies ready"
@@ -0,0 +1,18 @@
1
+ $ErrorActionPreference = "Stop"
2
+
3
+ $workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { (Get-Location).Path }
4
+ Set-Location $workspace
5
+
6
+ Write-Host "Installing dependencies..."
7
+ & pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
8
+ if ($LASTEXITCODE -ne 0) {
9
+ exit $LASTEXITCODE
10
+ }
11
+
12
+ if (Get-Command coze-dev -ErrorAction SilentlyContinue) {
13
+ & coze-dev check-bins --help *> $null
14
+ if ($LASTEXITCODE -eq 0) {
15
+ & coze-dev check-bins --fix
16
+ exit $LASTEXITCODE
17
+ }
18
+ }
@@ -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
@@ -0,0 +1,11 @@
1
+ $ErrorActionPreference = "Stop"
2
+
3
+ $workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { (Get-Location).Path }
4
+ $defaultPort = <%= port %>
5
+ $port = if ($env:DEPLOY_RUN_PORT) { $env:DEPLOY_RUN_PORT } elseif ($env:PORT) { $env:PORT } else { $defaultPort }
6
+ Set-Location $workspace
7
+
8
+ Write-Host "Starting express production server on port $port..."
9
+ $env:PORT = "$port"
10
+ & node dist-server/server.js
11
+ exit $LASTEXITCODE
@@ -0,0 +1,8 @@
1
+ $ErrorActionPreference = "Stop"
2
+
3
+ $workspace = if ($env:COZE_WORKSPACE_PATH) { $env:COZE_WORKSPACE_PATH } else { (Get-Location).Path }
4
+ Set-Location $workspace
5
+
6
+ Write-Host "Running validate..."
7
+ & pnpm validate
8
+ exit $LASTEXITCODE
@@ -1,7 +1,4 @@
1
1
 
2
- import { spawn } from 'child_process';
3
- import { resolve, join, basename } from 'path';
4
- import { appendFileSync, openSync, closeSync, mkdirSync } from 'fs';
5
2
 
6
3
 
7
4
 
@@ -63,60 +60,6 @@ const config = {
63
60
  onAfterRender: async (_context, _outputPath) => {
64
61
  // 输出由 init 命令统一处理
65
62
  },
66
-
67
- onComplete: async (_context, outputPath) => {
68
- // Skip pnpm update in test environment to avoid monorepo workspace issues
69
- if (process.env.NODE_ENV === 'test') {
70
- console.log('⊘ Skipping dependency update in test environment');
71
- return;
72
- }
73
-
74
- const cmd = 'pnpm';
75
- const args = ['update', 'coze-coding-dev-sdk@^0.7.0'];
76
- console.log(
77
- `\nTriggering: ${cmd} ${args.join(' ')} (running in background)`,
78
- );
79
-
80
- try {
81
- const projectRoot = resolve(outputPath);
82
-
83
- // Determine log directory
84
- const logDir = process.env.COZE_LOG_DIR || resolve(__dirname, '../.log');
85
- mkdirSync(logDir, { recursive: true });
86
-
87
- // Use project name in log file to avoid conflicts
88
- const projectName = basename(projectRoot);
89
- const logFile = join(logDir, `${projectName}-init.log`);
90
-
91
- // Write log header
92
- const timestamp = new Date().toISOString();
93
- appendFileSync(
94
- logFile,
95
- `\n=== [${timestamp}] ${cmd} ${args.join(' ')} ===\n`,
96
- );
97
-
98
- // Open log file for appending
99
- const logFd = openSync(logFile, 'a');
100
-
101
- // Spawn in detached mode
102
- const child = spawn(cmd, args, {
103
- cwd: projectRoot,
104
- detached: true,
105
- stdio: ['ignore', logFd, logFd],
106
- });
107
-
108
- child.unref();
109
- closeSync(logFd);
110
-
111
- console.log(
112
- '✓ coze-coding-dev-sdk update triggered (running in background)',
113
- );
114
- console.log(` Log file: ${logFile}`);
115
- } catch (error) {
116
- console.error('✗ Failed to trigger coze-coding-dev-sdk update:', error);
117
- console.log(' You can manually run: pnpm update coze-coding-dev-sdk');
118
- }
119
- },
120
63
  };
121
64
 
122
65
  export default config;