comp-hub 0.42.9 → 0.43.9

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 (260) hide show
  1. package/README.md +13 -2
  2. package/README.zh-CN.md +144 -0
  3. package/README.zh-Hant.md +144 -0
  4. package/dist/cli.js +44 -0
  5. package/dist/index.js +11 -30
  6. package/dist/master.js +19 -19
  7. package/package.json +15 -10
  8. package/bin/cli.js +0 -59
  9. package/bin/lib/commands.js +0 -173
  10. package/bin/lib/constants.js +0 -22
  11. package/bin/lib/http.js +0 -130
  12. package/bin/lib/startup.js +0 -254
  13. package/bin/lib/utils.js +0 -112
  14. package/dist/website/container/assets/index-6TGp-7st.css +0 -1
  15. package/dist/website/container/assets/index-BKC7DzZV.js +0 -33
  16. package/dist/website/container/favicon.ico +0 -0
  17. package/dist/website/container/index.html +0 -39
  18. package/dist/website/container/js/less-compiler.js +0 -41
  19. package/dist/website/container/js/react-jsx-loader.js +0 -233
  20. package/dist/website/container/js/sass-compiler.js +0 -418
  21. package/dist/website/container/js/vue2-sfc-loader.js +0 -261
  22. package/dist/website/container/js/vue3-sfc-loader.js +0 -290
  23. package/dist/website/item/assets/index-Pkb33-i2.css +0 -1
  24. package/dist/website/item/assets/index-kBvGmplc.js +0 -62
  25. package/dist/website/item/favicon.ico +0 -0
  26. package/dist/website/item/index.html +0 -34
  27. package/dist/website/main/assets/AuthCodeSendBtn.vue_vue_type_script_setup_true_lang-CH79cQAu.js +0 -1
  28. package/dist/website/main/assets/BaseBadge-D53B9edx.js +0 -1
  29. package/dist/website/main/assets/BaseBadge-ledSuDnX.css +0 -1
  30. package/dist/website/main/assets/BaseDialog.vue_vue_type_script_setup_true_lang-Bcc7UYpp.js +0 -1
  31. package/dist/website/main/assets/BaseSegmented.vue_vue_type_script_setup_true_lang-RYuIoPF7.js +0 -1
  32. package/dist/website/main/assets/CanvasAnimation.vue_vue_type_script_setup_true_lang-BNlJ1yyx.js +0 -1
  33. package/dist/website/main/assets/CodeMirrorEditor-Cqow8ROO-AryRubtp.js +0 -12
  34. package/dist/website/main/assets/EmptyStatusContainer.vue_vue_type_script_setup_true_lang-kK4W-ekr.js +0 -1
  35. package/dist/website/main/assets/GithubCallback-BjmPqH_L.js +0 -1
  36. package/dist/website/main/assets/LoadingWrapper.vue_vue_type_script_setup_true_lang-BPfuSpto.js +0 -1
  37. package/dist/website/main/assets/ReplyForm.vue_vue_type_script_setup_true_lang-BiETILOo.js +0 -1
  38. package/dist/website/main/assets/SiteLogo-DEIcFHUB.js +0 -1
  39. package/dist/website/main/assets/SiteLogo-DbJD21Ac.css +0 -1
  40. package/dist/website/main/assets/apl-B4CMkyY2.js +0 -1
  41. package/dist/website/main/assets/asciiarmor-Df11BRmG.js +0 -1
  42. package/dist/website/main/assets/asn1-EdZsLKOL.js +0 -1
  43. package/dist/website/main/assets/asterisk-B-8jnY81.js +0 -1
  44. package/dist/website/main/assets/brainfuck-C4LP7Hcl.js +0 -1
  45. package/dist/website/main/assets/clike-B9uivgTg.js +0 -1
  46. package/dist/website/main/assets/clojure-BMjYHr_A.js +0 -1
  47. package/dist/website/main/assets/cloud-upload-DVf0ki5J.js +0 -1
  48. package/dist/website/main/assets/cloud-upload-j3Y0taC9.css +0 -1
  49. package/dist/website/main/assets/cmake-BQqOBYOt.js +0 -1
  50. package/dist/website/main/assets/cobol-CWcv1MsR.js +0 -1
  51. package/dist/website/main/assets/coffeescript-S37ZYGWr.js +0 -1
  52. package/dist/website/main/assets/commonlisp-DBKNyK5s.js +0 -1
  53. package/dist/website/main/assets/crystal-SjHAIU92.js +0 -1
  54. package/dist/website/main/assets/css-BnMrqG3P.js +0 -1
  55. package/dist/website/main/assets/cypher-C_CwsFkJ.js +0 -1
  56. package/dist/website/main/assets/d-pRatUO7H.js +0 -1
  57. package/dist/website/main/assets/diff-DbItnlRl.js +0 -1
  58. package/dist/website/main/assets/dockerfile-BKs6k2Af.js +0 -1
  59. package/dist/website/main/assets/dtd-DF_7sFjM.js +0 -1
  60. package/dist/website/main/assets/dylan-DwRh75JA.js +0 -1
  61. package/dist/website/main/assets/ebnf-CDyGwa7X.js +0 -1
  62. package/dist/website/main/assets/ecl-Cabwm37j.js +0 -1
  63. package/dist/website/main/assets/eiffel-CnydiIhH.js +0 -1
  64. package/dist/website/main/assets/el-card-BAyktVMS.css +0 -1
  65. package/dist/website/main/assets/el-dropdown-item-BeIfAqTO.css +0 -1
  66. package/dist/website/main/assets/el-empty-S7fQQ3B8.css +0 -1
  67. package/dist/website/main/assets/el-link-CPQZ-olG.css +0 -1
  68. package/dist/website/main/assets/el-table-column-B3ZEEuPD.css +0 -1
  69. package/dist/website/main/assets/el-table-column-BqpEDPpl.js +0 -1
  70. package/dist/website/main/assets/elm-vLlmbW-K.js +0 -1
  71. package/dist/website/main/assets/en-DJCBTPEu.js +0 -1
  72. package/dist/website/main/assets/erlang-BNw1qcRV.js +0 -1
  73. package/dist/website/main/assets/factor-kuTfRLto.js +0 -1
  74. package/dist/website/main/assets/fcl-Kvtd6kyn.js +0 -1
  75. package/dist/website/main/assets/forth-Ffai-XNe.js +0 -1
  76. package/dist/website/main/assets/fortran-DYz_wnZ1.js +0 -1
  77. package/dist/website/main/assets/gas-Bneqetm1.js +0 -1
  78. package/dist/website/main/assets/gherkin-heZmZLOM.js +0 -1
  79. package/dist/website/main/assets/groovy-D9Dt4D0W.js +0 -1
  80. package/dist/website/main/assets/haskell-Cw1EW3IL.js +0 -1
  81. package/dist/website/main/assets/haxe-H-WmDvRZ.js +0 -1
  82. package/dist/website/main/assets/home-rounded-B4KVwSYb.css +0 -1
  83. package/dist/website/main/assets/home-rounded-DcB333c-.js +0 -1
  84. package/dist/website/main/assets/http-DBlCnlav.js +0 -1
  85. package/dist/website/main/assets/idl-BEugSyMb.js +0 -1
  86. package/dist/website/main/assets/index-0jhSi0Id.js +0 -2
  87. package/dist/website/main/assets/index-6e_pcD2g.js +0 -1
  88. package/dist/website/main/assets/index-72rReQ2I-Dls_4Kw0.js +0 -6
  89. package/dist/website/main/assets/index-8dCw6Y2Z.css +0 -1
  90. package/dist/website/main/assets/index-B-o-geOz.js +0 -1
  91. package/dist/website/main/assets/index-B6DlcvMU.js +0 -1
  92. package/dist/website/main/assets/index-BNYhon33.js +0 -1
  93. package/dist/website/main/assets/index-BOUkLBc8.js +0 -1
  94. package/dist/website/main/assets/index-BPiRmvZl.js +0 -1
  95. package/dist/website/main/assets/index-BWSpWNwa.js +0 -4
  96. package/dist/website/main/assets/index-BhaaT_GF.js +0 -1
  97. package/dist/website/main/assets/index-Bn5vi5XZ.css +0 -1
  98. package/dist/website/main/assets/index-BqUqA7W4.js +0 -1
  99. package/dist/website/main/assets/index-Bqhbsn_n.js +0 -1
  100. package/dist/website/main/assets/index-BrpXOHl6.js +0 -1
  101. package/dist/website/main/assets/index-BvmEG8Qn.css +0 -1
  102. package/dist/website/main/assets/index-BxmgEr3S.js +0 -1
  103. package/dist/website/main/assets/index-C0WquRMM.css +0 -1
  104. package/dist/website/main/assets/index-C1Hw6vXQ.js +0 -1
  105. package/dist/website/main/assets/index-C42i82mF.js +0 -2
  106. package/dist/website/main/assets/index-C81i40Gx.js +0 -1
  107. package/dist/website/main/assets/index-C9BP4kWZ.js +0 -6
  108. package/dist/website/main/assets/index-CFTT7hu0.css +0 -1
  109. package/dist/website/main/assets/index-CIVzXolG.js +0 -1
  110. package/dist/website/main/assets/index-CPc1AP3H.js +0 -1
  111. package/dist/website/main/assets/index-CWMIyyC3.js +0 -1
  112. package/dist/website/main/assets/index-CdWXO9ks.css +0 -1
  113. package/dist/website/main/assets/index-CglP2y1M.js +0 -1
  114. package/dist/website/main/assets/index-ChFpxx4T.css +0 -1
  115. package/dist/website/main/assets/index-CiPfzZM4.js +0 -1
  116. package/dist/website/main/assets/index-CioMG7I6.css +0 -1
  117. package/dist/website/main/assets/index-Cs-jTkU_.js +0 -1
  118. package/dist/website/main/assets/index-CuvsliuR.js +0 -1
  119. package/dist/website/main/assets/index-Cv6z_Edq.js +0 -1
  120. package/dist/website/main/assets/index-CxHPM7Fg.js +0 -1
  121. package/dist/website/main/assets/index-CytdBEyB.js +0 -1
  122. package/dist/website/main/assets/index-D-zBzPPy.css +0 -1
  123. package/dist/website/main/assets/index-D1_g-khQ.js +0 -7
  124. package/dist/website/main/assets/index-D2eSTfJw.js +0 -1
  125. package/dist/website/main/assets/index-D3HuxiUJ.js +0 -84
  126. package/dist/website/main/assets/index-D76eWsZ1-Z0x-dydi.js +0 -1
  127. package/dist/website/main/assets/index-DFsl7Pen.css +0 -1
  128. package/dist/website/main/assets/index-DH0rbH_2.js +0 -1
  129. package/dist/website/main/assets/index-DOlF0Z_P.css +0 -1
  130. package/dist/website/main/assets/index-DPBASOD1.js +0 -1
  131. package/dist/website/main/assets/index-DQfTUb4g.js +0 -1
  132. package/dist/website/main/assets/index-DS0KGu0h.js +0 -1
  133. package/dist/website/main/assets/index-DVxz8FkV.js +0 -2
  134. package/dist/website/main/assets/index-DgXgHraR.js +0 -50
  135. package/dist/website/main/assets/index-DjWcnHPR.js +0 -1
  136. package/dist/website/main/assets/index-Dms7ZQ2h-B_6qoSW-.js +0 -1
  137. package/dist/website/main/assets/index-Dnz1UQnr.js +0 -1
  138. package/dist/website/main/assets/index-DpYJK6hB.js +0 -1
  139. package/dist/website/main/assets/index-DqiFCfGx-uaEe5kQB.js +0 -1
  140. package/dist/website/main/assets/index-Dr-xg5xd.js +0 -1
  141. package/dist/website/main/assets/index-DtBE21vT.js +0 -1
  142. package/dist/website/main/assets/index-DxdtqQU6.js +0 -1
  143. package/dist/website/main/assets/index-DxypSQ0K-zR2L90gm.js +0 -1
  144. package/dist/website/main/assets/index-DzxzRGrk.js +0 -3
  145. package/dist/website/main/assets/index-Ji2WmMDE.css +0 -1
  146. package/dist/website/main/assets/index-Mnu1wKgu.css +0 -1
  147. package/dist/website/main/assets/index-NYRLx08d.js +0 -1
  148. package/dist/website/main/assets/index-PMqboCW5.js +0 -1
  149. package/dist/website/main/assets/index-R79ZeMZV.js +0 -1
  150. package/dist/website/main/assets/index-T76vWLBU-B_wdWDQF.js +0 -13
  151. package/dist/website/main/assets/index-XhJP7gYm.js +0 -1
  152. package/dist/website/main/assets/index-fZBcgzqR-CZSkQJVN.js +0 -1
  153. package/dist/website/main/assets/index-kE41pQo6.js +0 -1
  154. package/dist/website/main/assets/index-mqeGrL6B-Dup8h8xb.js +0 -1
  155. package/dist/website/main/assets/index-rRr1TSL-.css +0 -1
  156. package/dist/website/main/assets/index-tMz4-DEB.js +0 -1
  157. package/dist/website/main/assets/index-ywM9Y30i.js +0 -1
  158. package/dist/website/main/assets/index.vue_vue_type_script_setup_true_lang-B8gjIiIt.js +0 -2
  159. package/dist/website/main/assets/index.vue_vue_type_script_setup_true_lang-BdH7Nx9p.js +0 -1
  160. package/dist/website/main/assets/index.vue_vue_type_script_setup_true_lang-Bphion84.js +0 -1
  161. package/dist/website/main/assets/index.vue_vue_type_script_setup_true_lang-C8D789jG.js +0 -1
  162. package/dist/website/main/assets/index.vue_vue_type_script_setup_true_lang-CfvoANZj.js +0 -1
  163. package/dist/website/main/assets/index.vue_vue_type_script_setup_true_lang-uwxiML83.js +0 -1
  164. package/dist/website/main/assets/index.vue_vue_type_style_index_0_lang-DDVUKgQ8.js +0 -1
  165. package/dist/website/main/assets/index.vue_vue_type_style_index_0_lang-DiN6WUUw.js +0 -6
  166. package/dist/website/main/assets/index3-BB6QcGH6.js +0 -1
  167. package/dist/website/main/assets/javascript-iXu5QeM3.js +0 -1
  168. package/dist/website/main/assets/julia-DuME0IfC.js +0 -1
  169. package/dist/website/main/assets/kid-star-0b7jegzF.js +0 -1
  170. package/dist/website/main/assets/kid-star-D1M-aC1C.css +0 -1
  171. package/dist/website/main/assets/livescript-BwQOo05w.js +0 -1
  172. package/dist/website/main/assets/lua-VAEuO923.js +0 -1
  173. package/dist/website/main/assets/mathematica-DTrFuWx2.js +0 -1
  174. package/dist/website/main/assets/mbox-CNhZ1qSd.js +0 -1
  175. package/dist/website/main/assets/md5-BqUl3L9Y.js +0 -1
  176. package/dist/website/main/assets/mirc-CjQqDB4T.js +0 -1
  177. package/dist/website/main/assets/mllike-CXdrOF99.js +0 -1
  178. package/dist/website/main/assets/modelica-Dc1JOy9r.js +0 -1
  179. package/dist/website/main/assets/moment-B-YVwB4U.js +0 -4
  180. package/dist/website/main/assets/mscgen-BA5vi2Kp.js +0 -1
  181. package/dist/website/main/assets/mumps-BT43cFF4.js +0 -1
  182. package/dist/website/main/assets/nginx-DdIZxoE0.js +0 -1
  183. package/dist/website/main/assets/nsis-LdVXkNf5.js +0 -1
  184. package/dist/website/main/assets/ntriples-BfvgReVJ.js +0 -1
  185. package/dist/website/main/assets/octave-Ck1zUtKM.js +0 -1
  186. package/dist/website/main/assets/oz-BzwKVEFT.js +0 -1
  187. package/dist/website/main/assets/papaparse.min-Brc8PWCw-BsyFjD51.js +0 -10
  188. package/dist/website/main/assets/pascal--L3eBynH.js +0 -1
  189. package/dist/website/main/assets/perl-CdXCOZ3F.js +0 -1
  190. package/dist/website/main/assets/pig-CevX1Tat.js +0 -1
  191. package/dist/website/main/assets/powershell-CFHJl5sT.js +0 -1
  192. package/dist/website/main/assets/properties-C78fOPTZ.js +0 -1
  193. package/dist/website/main/assets/protobuf-ChK-085T.js +0 -1
  194. package/dist/website/main/assets/pug-DeIclll2.js +0 -1
  195. package/dist/website/main/assets/puppet-DMA9R1ak.js +0 -1
  196. package/dist/website/main/assets/python-BuPzkPfP.js +0 -1
  197. package/dist/website/main/assets/q-pXgVlZs6.js +0 -1
  198. package/dist/website/main/assets/r-B6wPVr8A.js +0 -1
  199. package/dist/website/main/assets/rpm-CTu-6PCP.js +0 -1
  200. package/dist/website/main/assets/ruby-B2Rjki9n.js +0 -1
  201. package/dist/website/main/assets/sas-B4kiWyti.js +0 -1
  202. package/dist/website/main/assets/scheme-C41bIUwD.js +0 -1
  203. package/dist/website/main/assets/settings-BhagQj3w.css +0 -1
  204. package/dist/website/main/assets/settings-DpNeh4hy.js +0 -1
  205. package/dist/website/main/assets/shell-CjFT_Tl9.js +0 -1
  206. package/dist/website/main/assets/sieve-C3Gn_uJK.js +0 -1
  207. package/dist/website/main/assets/simple-mode-GW_nhZxv.js +0 -1
  208. package/dist/website/main/assets/smalltalk-CnHTOXQT.js +0 -1
  209. package/dist/website/main/assets/solr-DehyRSwq.js +0 -1
  210. package/dist/website/main/assets/sparql-DkYu6x3z.js +0 -1
  211. package/dist/website/main/assets/spreadsheet-BCZA_wO0.js +0 -1
  212. package/dist/website/main/assets/sql-D0XecflT.js +0 -1
  213. package/dist/website/main/assets/stex-C3f8Ysf7.js +0 -1
  214. package/dist/website/main/assets/stylus-B533Al4x.js +0 -1
  215. package/dist/website/main/assets/supervised-user-circle-B5yCz5Oo.js +0 -1
  216. package/dist/website/main/assets/supervised-user-circle-CZYpyCV4.css +0 -1
  217. package/dist/website/main/assets/swift-BzpIVaGY.js +0 -1
  218. package/dist/website/main/assets/sync-saved-locally-rounded-BX8GcRCO.js +0 -1
  219. package/dist/website/main/assets/sync-saved-locally-rounded-wbwASI26.css +0 -1
  220. package/dist/website/main/assets/tcl-DVfN8rqt.js +0 -1
  221. package/dist/website/main/assets/terminal-DFt3N_TH.css +0 -1
  222. package/dist/website/main/assets/terminal-DXqN9Hoj.js +0 -1
  223. package/dist/website/main/assets/textile-CnDTJFAw.js +0 -1
  224. package/dist/website/main/assets/tiddlywiki-DO-Gjzrf.js +0 -1
  225. package/dist/website/main/assets/tiki-DGYXhP31.js +0 -1
  226. package/dist/website/main/assets/toml-Bm5Em-hy.js +0 -1
  227. package/dist/website/main/assets/troff-wAsdV37c.js +0 -1
  228. package/dist/website/main/assets/ttcn-CfJYG6tj.js +0 -1
  229. package/dist/website/main/assets/ttcn-cfg-B9xdYoR4.js +0 -1
  230. package/dist/website/main/assets/turtle-B1tBg_DP.js +0 -1
  231. package/dist/website/main/assets/useCacheOssStore-DRfQruRw.js +0 -1
  232. package/dist/website/main/assets/useCompEditStore-C2cDxPfw.css +0 -1
  233. package/dist/website/main/assets/useCompEditStore-DpFLk9bE.js +0 -70
  234. package/dist/website/main/assets/useCompMetaLocalStore-Dko7Z-qO.js +0 -1
  235. package/dist/website/main/assets/useKeyword-Dh8n_REW.js +0 -1
  236. package/dist/website/main/assets/useMessage-DeFP0yQy.js +0 -1
  237. package/dist/website/main/assets/useTeamHeaders-BSofrH8c.css +0 -1
  238. package/dist/website/main/assets/useTeamHeaders-Bl2nRtJe.js +0 -380
  239. package/dist/website/main/assets/useUnreadStore-C1fMXHK-.js +0 -1
  240. package/dist/website/main/assets/useVscodeOpen-CcI7l8e8.js +0 -1
  241. package/dist/website/main/assets/v4-EwEgHOG0.js +0 -1
  242. package/dist/website/main/assets/vb-CmGdzxic.js +0 -1
  243. package/dist/website/main/assets/vbscript-BuJXcnF6.js +0 -1
  244. package/dist/website/main/assets/velocity-D8B20fx6.js +0 -1
  245. package/dist/website/main/assets/vendor-core-CfnvwQzw.js +0 -3
  246. package/dist/website/main/assets/vendor-ui-g5RNTRAc.js +0 -50
  247. package/dist/website/main/assets/vendor-xterm-mNFjEaKn.js +0 -9
  248. package/dist/website/main/assets/verilog-C6RDOZhf.js +0 -1
  249. package/dist/website/main/assets/vhdl-lSbBsy5d.js +0 -1
  250. package/dist/website/main/assets/webidl-ZXfAyPTL.js +0 -1
  251. package/dist/website/main/assets/xquery-DzFWVndE.js +0 -1
  252. package/dist/website/main/assets/yacas-BJ4BC0dw.js +0 -1
  253. package/dist/website/main/assets/z80-Hz9HOZM7.js +0 -1
  254. package/dist/website/main/assets/zhCN-VSAW5gZn.js +0 -1
  255. package/dist/website/main/favicon.ico +0 -0
  256. package/dist/website/main/index.html +0 -111
  257. package/dist/website/main/md/COMP_REPEAT.en.md +0 -20
  258. package/dist/website/main/md/COMP_REPEAT.zh.md +0 -20
  259. package/dist/website/main/md/PUT_TREATY.en.md +0 -68
  260. package/dist/website/main/md/PUT_TREATY.zh.md +0 -68
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "comp-hub",
3
- "version": "0.42.9",
3
+ "version": "0.43.9",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
- "comphub": "bin/cli.js"
6
+ "comphub": "dist/cli.js",
7
+ "ch": "dist/cli.js"
7
8
  },
8
9
  "scripts": {
9
- "build": "node scripts/build.js",
10
- "build-ui": "node scripts/build-ui.js",
11
- "build-iframes": "node scripts/build-iframes.js",
10
+ "build": "node scripts/build.js && node scripts/build-cli.js",
11
+ "build:cli": "node scripts/build-cli.js",
12
+ "type-check": "tsc --noEmit",
12
13
  "release": "node scripts/publish.js",
13
14
  "lint:eslint": "eslint",
14
15
  "lint:fix": "eslint . --fix",
@@ -18,17 +19,21 @@
18
19
  },
19
20
  "files": [
20
21
  "dist",
21
- "bin",
22
- "README.md"
22
+ "README.md",
23
+ "README.zh-CN.md",
24
+ "README.zh-Hant.md"
23
25
  ],
24
26
  "dependencies": {
25
- "commander": "^9.5.0",
26
- "esbuild": "^0.28.0",
27
- "get-port": "^5.1.1"
27
+ "esbuild": "^0.28.0"
28
28
  },
29
29
  "devDependencies": {
30
+ "@comp-hub/constants": "workspace:*",
31
+ "@types/node": "^20.14.0",
30
32
  "@vitest/coverage-v8": "^4.1.9",
33
+ "commander": "^9.5.0",
31
34
  "fs-extra": "^11.3.0",
35
+ "get-port": "^5.1.1",
36
+ "typescript": "^5.4.0",
32
37
  "vitest": "^4.1.9"
33
38
  },
34
39
  "keywords": [
package/bin/cli.js DELETED
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env node
2
- const { program, Option } = require("commander");
3
- const { getLocalPkgInfo } = require("./lib/utils");
4
- const { statusCommand, stopCommand, killCommand, fixCommand } = require("./lib/commands");
5
- const { main } = require("./lib/startup");
6
-
7
- const { pkg } = getLocalPkgInfo();
8
-
9
- function portArg(v) {
10
- return parseInt(v, 10);
11
- }
12
-
13
- // Global options
14
- program
15
- .name("comphub")
16
- .option("-p, --port <number>", "Startup port", portArg)
17
- .option("-d, --dir <path>", "Resource directory relative path")
18
- .option("-l, --log-level <level>", "Log level: debug, info, warn, error (default: info)", "error")
19
- .version(pkg.version, "-v, --version", "Show version")
20
- .addOption(new Option("--allow-debug", "Enable debug mode").hideHelp())
21
- .addOption(new Option("--api <url>", "API URL").hideHelp())
22
- .helpOption("-h, --help", "Show help");
23
-
24
- // status subcommand: view master status and all projects
25
- program
26
- .command("status")
27
- .description("View master service status and all running projects")
28
- .addOption(new Option("-p, --port <number>", "Master port").argParser(portArg).hideHelp())
29
- .action(statusCommand);
30
-
31
- // stop subcommand: stop projects
32
- program
33
- .command("stop [hash]")
34
- .description("Stop a specific project (by hash) or stop all projects (--all)")
35
- .addOption(new Option("-p, --port <number>", "Master port").argParser(portArg).hideHelp())
36
- .option("-a, --all", "Stop all projects")
37
- .action(stopCommand);
38
-
39
- // kill subcommand: shutdown master process
40
- program.command("kill").description("Shutdown master process").addOption(new Option("-p, --port <number>", "Master port").argParser(portArg).hideHelp()).action(killCommand);
41
-
42
- // fix subcommand: clean up stale runtime file
43
- program.command("fix").description("Fix common issues (stale runtime file, etc.)").action(fixCommand);
44
-
45
- // Default startup command
46
- program.action(async () => {
47
- try {
48
- await main(pkg, program.opts());
49
- } catch (e) {
50
- console.error(`✗ Startup failed: ${e.message}`);
51
- process.exit(1);
52
- }
53
- });
54
-
55
- // parseAsync 确保异步 action(如 main 中 await new Promise)完成后进程才退出
56
- program.parseAsync().catch(err => {
57
- console.error(`✗ CLI error: ${err.message}`);
58
- process.exit(1);
59
- });
@@ -1,173 +0,0 @@
1
- const { httpGet, httpPost } = require("./http");
2
- const { ADMIN_API, DEFAULT_PORT } = require("./constants");
3
- const { readMasterRuntime, colors, apiUrl } = require("./utils");
4
- const { green, yellow, cyan, white, red } = colors;
5
-
6
- function formatUptime(seconds) {
7
- const UNITS = [
8
- { label: "d", divisor: 86400 },
9
- { label: "h", divisor: 3600 },
10
- { label: "m", divisor: 60 },
11
- { label: "s", divisor: 1 }
12
- ];
13
-
14
- let remaining = Math.floor(seconds);
15
- const parts = [];
16
-
17
- for (const { label, divisor } of UNITS) {
18
- if (remaining >= divisor) {
19
- const value = Math.floor(remaining / divisor);
20
- remaining = remaining % divisor;
21
- parts.push(`${value}${label}`);
22
- }
23
- }
24
-
25
- return parts.length > 0 ? parts.join(" ") : "0s";
26
- }
27
-
28
- async function resolveMasterPort(opts) {
29
- // 用户明确指定了端口,直接使用
30
- if (opts.port != null) {
31
- return opts.port;
32
- }
33
- // 从 runtime 文件读取 master 实际端口
34
- const runtime = await readMasterRuntime();
35
- if (runtime) {
36
- return runtime.managementPort;
37
- }
38
- // 兜底:默认端口
39
- return DEFAULT_PORT;
40
- }
41
-
42
- async function statusCommand(opts) {
43
- const masterPort = await resolveMasterPort(opts);
44
- const runtime = await readMasterRuntime();
45
- const displayPort = runtime ? runtime.publicPort : masterPort;
46
-
47
- console.log(`\n${yellow("●")} Master Status\n`);
48
-
49
- const health = await httpGet(apiUrl(masterPort, ADMIN_API.HEALTH));
50
- if (!health.ok || !health.body || typeof health.body.status !== "string") {
51
- console.error(`${red("✗")} Master service is not running`);
52
- process.exit(1);
53
- }
54
-
55
- const info = health.body;
56
- const statusIcon = info.status === "running" ? green("●") : cyan("●");
57
-
58
- console.log(` ${green("Status")} ${statusIcon} ${info.status}`);
59
- console.log(` ${green("Version")} ${white(info.version)}`);
60
- console.log(` ${green("Uptime")} ${white(formatUptime(info.uptime))}`);
61
- console.log(` ${green("Projects")} ${white(info.projects)}`);
62
- console.log("");
63
-
64
- const projects = await httpGet(apiUrl(masterPort, ADMIN_API.PROJECTS));
65
- if (projects.ok && projects.body) {
66
- const list = projects.body.projects;
67
- if (Array.isArray(list) && list.length > 0) {
68
- console.log(` ${yellow("▸")} Registered Projects (${list.length}):`);
69
- console.log(" " + white("─".repeat(56)));
70
- for (const p of list) {
71
- console.log(` ${green("hash")} ${white(p.hash)}`);
72
- console.log(` ${green("path")} ${white(p.cwd)}`);
73
- // console.log(` ${green('port')} ${p.port}`);
74
- // if (p.subPort) console.log(` ${green('subPort')} ${p.subPort}`);
75
- console.log(` ${green("url")} ${cyan(`http://localhost:${displayPort}/${p.hash}/main/`)}`);
76
- console.log(" " + white("─".repeat(56)));
77
- }
78
- } else {
79
- console.log(` ${white("─".repeat(58))}`);
80
- console.log(` ${white("(No registered projects)")}`);
81
- console.log(` ${white("─".repeat(58))}`);
82
- }
83
- }
84
- console.log("");
85
- process.exit(0);
86
- }
87
-
88
- async function stopCommand(hash, opts) {
89
- const masterPort = await resolveMasterPort(opts);
90
-
91
- if (opts.all) {
92
- const projects = await httpGet(apiUrl(masterPort, ADMIN_API.PROJECTS));
93
- if (!projects.ok || !projects.body) {
94
- console.error(`${red("✗")} Cannot connect to master service`);
95
- process.exit(1);
96
- }
97
- const list = projects.body.projects;
98
- if (!Array.isArray(list) || list.length === 0) {
99
- console.log(`${yellow("ℹ")} No running projects`);
100
- process.exit(0);
101
- }
102
- console.log(`\n${yellow("▸")} Stopping all ${list.length} projects...\n`);
103
- for (const p of list) {
104
- const res = await httpPost(apiUrl(masterPort, ADMIN_API.DEREGISTER), { hash: p.hash });
105
- if (res.ok) {
106
- console.log(` ${green("✓")} Stopped: ${p.hash} (${p.cwd})`);
107
- } else {
108
- console.error(` ${red("✗")} Failed to stop: ${p.hash} - ${res.error}`);
109
- }
110
- }
111
- console.log("");
112
- process.exit(0);
113
- }
114
-
115
- if (!hash) {
116
- console.error(`${red("✗")} Please specify project hash or use --all to stop all projects`);
117
- console.error(` Usage: comphub stop <hash>`);
118
- console.error(` Usage: comphub stop --all`);
119
- process.exit(1);
120
- }
121
-
122
- console.log(`\n${yellow("▸")} Stopping project ${hash}...`);
123
- const res = await httpPost(apiUrl(masterPort, ADMIN_API.DEREGISTER), { hash });
124
- if (res.ok) {
125
- console.log(` ${green("✓")} Stopped: ${hash}\n`);
126
- } else {
127
- console.error(` ${red("✗")} Failed to stop: ${res.error}\n`);
128
- process.exit(1);
129
- }
130
- process.exit(0);
131
- }
132
-
133
- async function killCommand(opts) {
134
- const masterPort = await resolveMasterPort(opts);
135
- console.log(`\n${yellow("▸")} Shutting down master process...\n`);
136
-
137
- const res = await httpPost(apiUrl(masterPort, ADMIN_API.SHUTDOWN), {});
138
- if (res.ok) {
139
- console.log(`${green("✓")} Master process has been shut down\n`);
140
- } else {
141
- console.error(`${red("✗")} Shutdown failed: ${res.error}\n`);
142
- process.exit(1);
143
- }
144
- process.exit(0);
145
- }
146
-
147
- async function fixCommand() {
148
- const fs = require("fs");
149
- const { MASTER_RUNTIME_FILE } = require("./constants");
150
-
151
- console.log(`\n${yellow("▸")} Checking master runtime...\n`);
152
-
153
- const runtime = await readMasterRuntime();
154
- if (runtime) {
155
- console.log(` ${green("✓")} Master is running normally on port ${runtime.publicPort}\n`);
156
- process.exit(0);
157
- }
158
-
159
- if (fs.existsSync(MASTER_RUNTIME_FILE)) {
160
- try {
161
- fs.unlinkSync(MASTER_RUNTIME_FILE);
162
- console.log(` ${green("✓")} Removed stale runtime file\n`);
163
- } catch {
164
- console.error(` ${red("✗")} Failed to remove runtime file\n`);
165
- process.exit(1);
166
- }
167
- } else {
168
- console.log(` ${yellow("ℹ")} No stale runtime file found\n`);
169
- }
170
- process.exit(0);
171
- }
172
-
173
- module.exports = { formatUptime, resolveMasterPort, statusCommand, stopCommand, killCommand, fixCommand };
@@ -1,22 +0,0 @@
1
- const path = require("path");
2
- const os = require("os");
3
-
4
- const DEFAULT_PORT = 5478;
5
-
6
- const MASTER_RUNTIME_FILE = path.join(os.tmpdir(), ".comphub", "master.json");
7
-
8
- const ADMIN_API = {
9
- PREFIX: "/__master__",
10
- HEALTH: "/__master__/health",
11
- REGISTER: "/__master__/register",
12
- DEREGISTER: "/__master__/deregister",
13
- PROJECTS: "/__master__/projects",
14
- SHUTDOWN: "/__master__/shutdown"
15
- };
16
-
17
- const POLL_INTERVAL = 500;
18
- const MAX_RETRIES = 40;
19
- const HTTP_TIMEOUT_GET = 2000;
20
- const HTTP_TIMEOUT_POST = 5000;
21
-
22
- module.exports = { DEFAULT_PORT, MASTER_RUNTIME_FILE, ADMIN_API, POLL_INTERVAL, MAX_RETRIES, HTTP_TIMEOUT_GET, HTTP_TIMEOUT_POST };
package/bin/lib/http.js DELETED
@@ -1,130 +0,0 @@
1
- const http = require("http");
2
- const { HTTP_TIMEOUT_GET, HTTP_TIMEOUT_POST } = require("./constants");
3
- const { apiUrl } = require("./utils");
4
-
5
- function parseBody(raw) {
6
- try {
7
- return JSON.parse(raw);
8
- } catch {
9
- return raw;
10
- }
11
- }
12
-
13
- function httpGet(url) {
14
- return new Promise(resolve => {
15
- const req = http.get(url, res => {
16
- let body = "";
17
- res.on("data", chunk => (body += chunk));
18
- res.on("end", () => resolve({ ok: true, status: res.statusCode, body: parseBody(body) }));
19
- });
20
- req.on("error", err => resolve({ ok: false, error: err.message }));
21
- req.setTimeout(HTTP_TIMEOUT_GET, () => {
22
- req.destroy();
23
- resolve({ ok: false, error: "请求超时" });
24
- });
25
- });
26
- }
27
-
28
- function httpPost(url, data) {
29
- return new Promise(resolve => {
30
- const postData = JSON.stringify(data);
31
- const urlObj = new URL(url);
32
- const options = {
33
- hostname: urlObj.hostname,
34
- port: urlObj.port,
35
- path: urlObj.pathname,
36
- method: "POST",
37
- headers: {
38
- "Content-Type": "application/json",
39
- "Content-Length": Buffer.byteLength(postData)
40
- }
41
- };
42
- const req = http.request(options, res => {
43
- let body = "";
44
- res.on("data", chunk => (body += chunk));
45
- res.on("end", () => {
46
- try {
47
- resolve({ ok: true, body: JSON.parse(body) });
48
- } catch {
49
- resolve({ ok: false, error: "Invalid JSON response" });
50
- }
51
- });
52
- });
53
- req.on("error", err => resolve({ ok: false, error: err.message }));
54
- req.setTimeout(HTTP_TIMEOUT_POST, () => {
55
- req.destroy();
56
- resolve({ ok: false, error: "请求超时" });
57
- });
58
- req.write(postData);
59
- req.end();
60
- });
61
- }
62
-
63
- /**
64
- * SSE 日志流 — 连接 master 的 /__master__/projects/:hash/logs 端点
65
- * 持续输出 MidwayJS 子进程的实时日志到终端
66
- * 返回一个 Promise,在连接关闭时 resolve
67
- */
68
- function streamLogs(url, _hash) {
69
- return new Promise((resolve, reject) => {
70
- const urlObj = new URL(url);
71
- const options = {
72
- hostname: urlObj.hostname,
73
- port: urlObj.port,
74
- path: urlObj.pathname,
75
- method: "GET",
76
- headers: { Accept: "text/event-stream" }
77
- };
78
-
79
- const req = http.request(options, res => {
80
- if (res.statusCode !== 200) {
81
- reject(new Error(`SSE connection failed (HTTP ${res.statusCode})`));
82
- return;
83
- }
84
-
85
- let buffer = "";
86
-
87
- res.on("data", chunk => {
88
- buffer += chunk.toString();
89
- // SSE 格式: "data: <json>\n\n"
90
- const events = buffer.split("\n\n");
91
- buffer = events.pop() || ""; // 保留不完整的最后一个事件
92
-
93
- for (const event of events) {
94
- const dataLine = event.startsWith("data: ") ? event.slice(6) : event;
95
- try {
96
- const line = JSON.parse(dataLine);
97
- // 直接输出日志内容(已有换行符)
98
- process.stdout.write(line);
99
- } catch {
100
- // 非 JSON 数据,忽略
101
- }
102
- }
103
- });
104
-
105
- res.on("end", () => {
106
- resolve();
107
- });
108
-
109
- res.on("error", err => {
110
- reject(err);
111
- });
112
- });
113
-
114
- req.on("error", err => {
115
- reject(err);
116
- });
117
-
118
- req.setTimeout(0); // 无超时限制
119
- req.end();
120
- });
121
- }
122
-
123
- /**
124
- * 从 master 注销项目(Ctrl+C 时通知 master 停止对应 MidwayJS 子进程)
125
- */
126
- function deregisterProject(masterPort, hash) {
127
- return httpPost(apiUrl(masterPort, "/__master__/deregister"), { hash });
128
- }
129
-
130
- module.exports = { httpGet, httpPost, streamLogs, deregisterProject };
@@ -1,254 +0,0 @@
1
- const path = require("path");
2
- const fs = require("fs");
3
- const { spawn } = require("child_process");
4
- const { httpPost, streamLogs, deregisterProject } = require("./http");
5
- const { computeHash, projectRoot, readMasterRuntime, loadComphubConfig, colors, apiUrl } = require("./utils");
6
- const { cyan, green, white, yellow, red } = colors;
7
- const { ADMIN_API, POLL_INTERVAL, MAX_RETRIES, DEFAULT_PORT } = require("./constants");
8
- const getPort = require("get-port");
9
-
10
- // ---- Config ----
11
-
12
- function mergeConfig(opts, cwd) {
13
- // 加载项目配置文件,作为命令行参数的 fallback
14
- const fileConfig = loadComphubConfig(cwd);
15
- // 优先级:命令行 > 配置文件 > 默认值
16
- return {
17
- dir: opts.dir || fileConfig.dir || "./",
18
- api: opts.api || fileConfig.api,
19
- allowDebug: opts.allowDebug != null ? opts.allowDebug : fileConfig.allowDebug != null ? fileConfig.allowDebug : false,
20
- proxy: opts.proxy || fileConfig.proxy,
21
- port: opts.port,
22
- logLevel: opts.logLevel || fileConfig.logLevel || "info"
23
- };
24
- }
25
-
26
- // ---- Master lifecycle ----
27
-
28
- async function waitForMasterRuntime() {
29
- for (let i = 0; i < MAX_RETRIES; i++) {
30
- const runtime = await readMasterRuntime();
31
- if (runtime) return runtime;
32
- await new Promise(r => setTimeout(r, POLL_INTERVAL));
33
- }
34
- return null;
35
- }
36
-
37
- async function spawnMaster(publicPort, pkg, cwd) {
38
- const masterEntry = path.join(projectRoot, "dist/master.js");
39
-
40
- if (!fs.existsSync(masterEntry)) {
41
- throw new Error("Master entry file not found, startup failed");
42
- }
43
-
44
- const masterArgs = ["--port", String(publicPort), "--public-port", String(publicPort)];
45
- // 不再使用 stdio:inherit,改为 pipe stdout/stderr:
46
- // - stdin: inherit(Ctrl+C 信号需要)
47
- // - stdout: pipe(过滤掉 MidwayJS 子进程日志,只保留 master 自身消息)
48
- // - stderr: pipe(转发给 CLI 用于崩溃诊断)
49
- const child = spawn(process.execPath, ["--no-deprecation", masterEntry, ...masterArgs], {
50
- stdio: ["inherit", "pipe", "pipe"],
51
- cwd,
52
- env: {
53
- ...process.env,
54
- COMP_HUB_VERSION: pkg.version
55
- }
56
- });
57
-
58
- // stdout 行缓冲(跨 data 事件的未完成行)
59
- let stdoutPending = "";
60
-
61
- // 转发 stderr 给 CLI(用于崩溃诊断)
62
- if (child.stderr) {
63
- child.stderr.on("data", chunk => {
64
- process.stderr.write(chunk);
65
- });
66
- }
67
-
68
- // 过滤 stdout:只转发 master 自身消息,跳过带 [hash] 前缀的 MidwayJS 子进程日志
69
- // MidwayJS 日志会通过 SSE 按项目过滤后展示
70
- if (child.stdout) {
71
- child.stdout.on("data", chunk => {
72
- stdoutPending += chunk.toString();
73
- const lines = stdoutPending.split("\n");
74
- stdoutPending = lines.pop() || ""; // 保留不完整行
75
- for (const line of lines) {
76
- // 跳过 [8位hex_hash] 前缀的行(属于 MidwayJS 子进程日志)
77
- if (!/^\[[0-9a-f]{8}\]/.test(line)) {
78
- process.stdout.write(line + "\n");
79
- }
80
- }
81
- });
82
- }
83
-
84
- // 转发父进程信号,确保 Ctrl+C 时 master 也能优雅退出
85
- ["SIGINT", "SIGTERM"].forEach(sig => {
86
- process.on(sig, () => {
87
- child.kill(sig);
88
- });
89
- });
90
-
91
- // Master 退出时 CLI 也跟着退出
92
- child.on("exit", code => {
93
- // 输出剩余的 pending 数据
94
- if (stdoutPending && !/^\[[0-9a-f]{8}\]/.test(stdoutPending)) {
95
- process.stdout.write(stdoutPending);
96
- }
97
- process.exit(code || 0);
98
- });
99
-
100
- const runtime = await waitForMasterRuntime();
101
- if (!runtime) {
102
- child.kill();
103
- throw new Error("Master startup timeout");
104
- }
105
-
106
- return { runtime };
107
- }
108
-
109
- /**
110
- * 确保 master 在运行,返回运行时信息。
111
- * 如果已在运行则复用,否则 spawn 新的 master 进程。
112
- */
113
- async function ensureMasterRunning(opts, pkg) {
114
- let portMismatch = false;
115
- let runningPublicPort = 0;
116
-
117
- const existingRuntime = await readMasterRuntime();
118
-
119
- if (existingRuntime) {
120
- // Master 已在运行,检查用户指定的端口是否匹配
121
- const expectedPort = opts.port != null ? opts.port : existingRuntime.publicPort;
122
- if (opts.port != null && existingRuntime.publicPort !== expectedPort) {
123
- portMismatch = true;
124
- runningPublicPort = existingRuntime.publicPort;
125
- }
126
- return { runtime: existingRuntime, portMismatch, runningPublicPort };
127
- }
128
-
129
- // 启动新 master(前台运行,日志输出到终端)
130
- const portHint = opts.port != null ? opts.port : DEFAULT_PORT;
131
- const publicPort = await getPort({ port: getPort.makeRange(portHint, portHint + 100) });
132
-
133
- const { runtime } = await spawnMaster(publicPort, pkg, process.cwd());
134
-
135
- return { runtime, portMismatch, runningPublicPort };
136
- }
137
-
138
- // ---- Registration ----
139
-
140
- async function registerProject(masterPort, hash, cwd, opts) {
141
- const body = {
142
- hash,
143
- cwd,
144
- dir: opts.dir || "./"
145
- };
146
- if (opts.api) body.api = opts.api;
147
- if (opts.allowDebug) body.allowDebug = true;
148
- if (opts.proxy) body.proxy = opts.proxy;
149
- if (opts.logLevel) body.logLevel = opts.logLevel;
150
-
151
- const res = await httpPost(apiUrl(masterPort, ADMIN_API.REGISTER), body);
152
- if (!res.ok) {
153
- throw new Error(res.error || "Registration failed");
154
- }
155
- console.log(`${green("✓")} Project registered (hash: ${hash})`);
156
- return res;
157
- }
158
-
159
- // ---- Banner ----
160
-
161
- function printBanner(pkg, cwd, hash, displayPort, opts, { portMismatch, runningPublicPort }) {
162
- const url = `http://localhost:${displayPort}/${hash}/main/`;
163
-
164
- const lines = [
165
- "",
166
- cyan(" ██████╗ ██████╗ ███╗ ███╗ ██████╗ ██╗ ██╗ ██╗ ██╗ ██████╗ "),
167
- cyan(" ██╔════╝ ██╔═══██╗ ████╗ ████║ ██╔══██╗ ██║ ██║ ██║ ██║ ██╔══██╗"),
168
- cyan(" ██║ ██║ ██║ ██╔████╔██║ ██████╔╝ ███████║ ██║ ██║ ██████╔╝"),
169
- cyan(" ██║ ██║ ██║ ██║╚██╔╝██║ ██╔═══╝ ██╔══██║ ██║ ██║ ██╔══██╗"),
170
- cyan(" ╚██████╗ ╚██████╔╝ ██║ ╚═╝ ██║ ██║ ██║ ██║ ╚██████╔╝ ██████╔╝"),
171
- cyan(" ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ "),
172
- "",
173
- "",
174
- ` ${green("Version")} ${pkg.version}`,
175
- ` ${green("Project")} ${cwd}`,
176
- ` ${green("Hash")} ${hash}`,
177
- ` ${green("Port")} ${displayPort}`,
178
- "",
179
- ` ${yellow("URL")} ${cyan(url)}`,
180
- "",
181
- white(" ─────────────────────────────────────────────"),
182
- "",
183
- ` ${"comphub status".padEnd(30)}View all projects`,
184
- ` ${`comphub stop ${hash}`.padEnd(30)}Stop current project`,
185
- ` ${"comphub stop --all".padEnd(30)}Stop all projects`,
186
- ` ${"comphub kill".padEnd(30)}Shutdown master`,
187
- ""
188
- ];
189
-
190
- if (portMismatch) {
191
- lines.push(
192
- white(" ─────────────────────────────────────────────"),
193
- "",
194
- red(` ⚠ Master is already running on port ${runningPublicPort}, ignoring -p ${opts.port}`),
195
- red(` To change port, please run comphub kill first`),
196
- ""
197
- );
198
- }
199
-
200
- console.log(lines.join("\n"));
201
- }
202
-
203
- // ---- Main ----
204
-
205
- async function main(pkg, opts) {
206
- if (!fs.existsSync(path.join(process.cwd(), "package.json"))) {
207
- console.error(`${red("✗")} Current directory is not a Node.js project`);
208
- process.exit(1);
209
- }
210
-
211
- const cwd = process.cwd();
212
- const hash = computeHash(cwd);
213
-
214
- opts = mergeConfig(opts, cwd);
215
-
216
- console.log(`${green("✓")} ${pkg.name} v${pkg.version}`);
217
-
218
- const { runtime, portMismatch, runningPublicPort } = await ensureMasterRunning(opts, pkg);
219
-
220
- const masterPort = runtime.managementPort;
221
- const displayPort = runtime.publicPort;
222
-
223
- await registerProject(masterPort, hash, cwd, opts);
224
-
225
- printBanner(pkg, cwd, hash, displayPort, opts, { portMismatch, runningPublicPort });
226
-
227
- // Ctrl+C / kill 时通知 master 注销本项目,使 MidwayJS 子进程能够停止
228
- let deregistered = false;
229
- const cleanup = async () => {
230
- if (deregistered) return;
231
- deregistered = true;
232
- try {
233
- await deregisterProject(masterPort, hash);
234
- } catch {
235
- // 忽略注销失败(master 可能已关闭)
236
- }
237
- process.exit(0);
238
- };
239
- process.on("SIGINT", cleanup);
240
- process.on("SIGTERM", cleanup);
241
-
242
- // 统一通过 SSE 实时接收本项目 MidwayJS 子进程日志(按 hash 过滤)
243
- // 第一个 CLI(spawn master 的)不再通过 stdio:inherit 看到其他项目的日志
244
- console.log(`\n ${white("─")} Streaming logs from MidwayJS (${hash}) ${white("─")}\n`);
245
-
246
- const logsUrl = `http://localhost:${masterPort}/__master__/projects/${hash}/logs`;
247
- try {
248
- await streamLogs(logsUrl, hash);
249
- } catch (err) {
250
- console.error(`\n ${red("✗")} Log stream error: ${err.message}`);
251
- }
252
- }
253
-
254
- module.exports = { mergeConfig, main };