@underpostnet/cyberia 3.3.0 → 3.3.76

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 (568) hide show
  1. package/.dockerignore +1 -0
  2. package/.env.example +17 -5
  3. package/.github/workflows/coverall.cyberia.ci.yml +39 -14
  4. package/.github/workflows/cyberia-client.cd.yml +5 -0
  5. package/.github/workflows/cyberia-server.cd.yml +5 -0
  6. package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
  7. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
  8. package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
  9. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
  10. package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
  11. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
  12. package/.github/workflows/engine-cyberia.cd.yml +3 -0
  13. package/.github/workflows/engine-cyberia.ci.yml +4 -5
  14. package/.github/workflows/ghpkg.ci.yml +35 -20
  15. package/.github/workflows/hardhat.ci.yml +12 -11
  16. package/.github/workflows/npmpkg.ci.yml +17 -15
  17. package/.github/workflows/publish.cyberia.ci.yml +44 -0
  18. package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
  19. package/.github/workflows/release.cd.yml +1 -0
  20. package/.prettierignore +1 -0
  21. package/AGENTS.md +96 -0
  22. package/CHANGELOG.md +653 -2513
  23. package/CLI-HELP.md +323 -157
  24. package/Dockerfile +25 -9
  25. package/Dockerfile.dev +25 -9
  26. package/Dockerfile.test +5 -5
  27. package/README.md +48 -28
  28. package/bin/build.js +86 -41
  29. package/bin/build.template.js +8 -3
  30. package/bin/cyberia.js +1494 -1403
  31. package/bin/deploy.js +18 -104
  32. package/bin/index.js +1494 -1403
  33. package/compose.env +17 -5
  34. package/conf.js +98 -7
  35. package/deploy/cyberia-client/deploy.sh +46 -0
  36. package/deploy/cyberia-client/package.sh +17 -0
  37. package/deploy/cyberia-client/state.sh +15 -0
  38. package/deploy/cyberia-server/deploy.sh +46 -0
  39. package/deploy/cyberia-server/package.sh +17 -0
  40. package/deploy/cyberia-server/state.sh +15 -0
  41. package/deploy/dd-cyberia/deploy.sh +9 -29
  42. package/deploy/dd-cyberia/init.sh +38 -45
  43. package/deploy/dd-cyberia/package.sh +16 -0
  44. package/deploy/dd-cyberia/state.sh +14 -0
  45. package/deploy/dd-cyberia/sync-deploy.sh +133 -147
  46. package/deploy/lib/config.sh +29 -0
  47. package/deploy/lib/github-actions-logging.sh +610 -0
  48. package/deploy/lib/host.sh +194 -0
  49. package/deploy/lib/state.sh +65 -0
  50. package/deploy/pwa-microservices-template/deploy.sh +17 -42
  51. package/deploy/release/deploy.sh +9 -41
  52. package/deployment.yaml +7 -2
  53. package/docker-compose.yml +23 -17
  54. package/examples/static-page/README.md +19 -19
  55. package/examples/static-page/ssr-components/CustomPage.js +2 -2
  56. package/hardhat/hardhat.config.js +1 -6
  57. package/hardhat/package-lock.json +101 -40
  58. package/hardhat/package.json +2 -2
  59. package/manifests/alertmanager/deployment.yaml +81 -0
  60. package/manifests/blackbox-exporter/deployment.yaml +75 -0
  61. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
  62. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
  63. package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
  64. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  65. package/manifests/deployment/mongo-express/deployment.yaml +46 -27
  66. package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
  67. package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
  68. package/manifests/deployment/mongo-express/service.yaml +16 -0
  69. package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
  70. package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
  71. package/manifests/grafana/deployment.yaml +26 -7
  72. package/manifests/grafana/kustomization.yaml +1 -0
  73. package/manifests/grafana/service.yaml +6 -1
  74. package/manifests/mariadb/pv.yaml +1 -0
  75. package/manifests/mongodb/statefulset.yaml +9 -2
  76. package/manifests/mysql/pv-pvc.yaml +14 -1
  77. package/manifests/postgresql/pv.yaml +12 -1
  78. package/manifests/postgresql/pvc.yaml +1 -0
  79. package/manifests/prometheus/deployment.yaml +18 -22
  80. package/package.json +87 -12
  81. package/scripts/event-monitor.sh +56 -0
  82. package/scripts/k3s-node-setup.sh +27 -14
  83. package/scripts/kubeadm-node-setup.sh +31 -11
  84. package/scripts/maas-setup.sh +8 -8
  85. package/scripts/selinux-normalize.sh +907 -0
  86. package/scripts/shutdown-machine.sh +843 -0
  87. package/scripts/test-monitor.sh +5 -5
  88. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +15 -10
  89. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
  90. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +7 -2
  91. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +90 -186
  92. package/src/api/core/core.controller.js +1 -1
  93. package/src/api/core/core.router.js +2 -2
  94. package/src/api/core/core.service.js +2 -2
  95. package/src/api/crypto/crypto.controller.js +1 -1
  96. package/src/api/crypto/crypto.service.js +1 -1
  97. package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
  98. package/src/api/cyberia-action/cyberia-action.router.js +3 -3
  99. package/src/api/cyberia-action/cyberia-action.service.js +5 -6
  100. package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
  101. package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
  102. package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
  103. package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
  104. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +2 -4
  105. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
  106. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +13 -35
  107. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +17 -34
  108. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
  109. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
  110. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
  111. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
  112. package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
  113. package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
  114. package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
  115. package/src/api/cyberia-entity/cyberia-entity.service.js +3 -3
  116. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
  117. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
  118. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -2
  119. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +468 -5
  120. package/src/api/cyberia-instance/cyberia-fallback-capture.js +502 -0
  121. package/src/api/cyberia-instance/cyberia-fallback-world.js +29 -40
  122. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
  123. package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
  124. package/src/api/cyberia-instance/cyberia-instance-map.service.js +35 -142
  125. package/src/api/cyberia-instance/cyberia-instance.controller.js +2 -5
  126. package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
  127. package/src/api/cyberia-instance/cyberia-instance.router.js +5 -18
  128. package/src/api/cyberia-instance/cyberia-instance.service.js +5 -45
  129. package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
  130. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
  131. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
  132. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
  133. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +76 -3
  134. package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
  135. package/src/api/cyberia-map/cyberia-map.router.js +1 -1
  136. package/src/api/cyberia-map/cyberia-map.service.js +8 -4
  137. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
  138. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
  139. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
  140. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
  141. package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
  142. package/src/api/cyberia-quest/cyberia-quest.router.js +4 -4
  143. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  144. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
  145. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
  146. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
  147. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
  148. package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
  149. package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
  150. package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
  151. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -214
  152. package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
  153. package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
  154. package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
  155. package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
  156. package/src/api/default/default.controller.js +1 -1
  157. package/src/api/default/default.router.js +1 -1
  158. package/src/api/default/default.service.js +2 -2
  159. package/src/api/document/document.controller.js +1 -1
  160. package/src/api/document/document.router.js +1 -1
  161. package/src/api/document/document.service.js +2 -2
  162. package/src/api/file/file.controller.js +1 -1
  163. package/src/api/file/file.ref.js +153 -0
  164. package/src/api/file/file.ref.json +11 -2
  165. package/src/api/file/file.router.js +1 -1
  166. package/src/api/file/file.service.js +2 -2
  167. package/src/api/instance/instance.controller.js +1 -1
  168. package/src/api/instance/instance.router.js +1 -1
  169. package/src/api/instance/instance.service.js +2 -2
  170. package/src/api/ipfs/ipfs.controller.js +1 -1
  171. package/src/api/ipfs/ipfs.router.js +2 -2
  172. package/src/api/ipfs/ipfs.service.js +2 -2
  173. package/src/api/object-layer/object-layer.controller.js +1 -1
  174. package/src/api/object-layer/object-layer.model.js +47 -12
  175. package/src/api/object-layer/object-layer.router.js +12 -5
  176. package/src/api/object-layer/object-layer.service.js +116 -123
  177. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
  178. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
  179. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
  180. package/src/api/test/test.controller.js +1 -1
  181. package/src/api/test/test.service.js +1 -1
  182. package/src/api/user/guest.service.js +3 -3
  183. package/src/api/user/user.controller.js +1 -1
  184. package/src/api/user/user.router.js +2 -2
  185. package/src/api/user/user.service.js +4 -4
  186. package/src/api.js +5 -9
  187. package/src/cli/app.js +402 -0
  188. package/src/cli/baremetal.js +30 -35
  189. package/src/cli/client.js +306 -0
  190. package/src/cli/cloud-init.js +3 -3
  191. package/src/cli/cluster.js +191 -82
  192. package/src/cli/db.js +120 -68
  193. package/src/cli/deploy.js +157 -75
  194. package/src/cli/docker-compose.js +5 -5
  195. package/src/cli/domains.js +184 -0
  196. package/src/cli/dotenv-store.js +143 -0
  197. package/src/cli/event.js +2281 -0
  198. package/src/cli/fs-selection.js +115 -0
  199. package/src/cli/fs.js +159 -343
  200. package/src/cli/host.js +672 -0
  201. package/src/cli/image.js +4 -6
  202. package/src/cli/index.js +343 -151
  203. package/src/cli/ipfs.js +34 -30
  204. package/src/cli/kickstart.js +1 -1
  205. package/src/cli/kubectl.js +218 -41
  206. package/src/cli/lxd.js +3 -3
  207. package/src/cli/monitor.js +1359 -26
  208. package/src/cli/package.js +90 -0
  209. package/src/cli/release.js +16 -12
  210. package/src/cli/repository.js +586 -363
  211. package/src/cli/run.js +398 -843
  212. package/src/cli/secrets.js +2158 -964
  213. package/src/cli/ssh.js +478 -279
  214. package/src/cli/state.js +394 -0
  215. package/src/cli/static.js +2 -2
  216. package/src/cli/system.js +1 -1
  217. package/src/cli/test.js +203 -125
  218. package/src/cli/vultr.js +61 -21
  219. package/src/cli/wireguard.js +1112 -306
  220. package/src/client/components/core/CalendarCore.js +53 -96
  221. package/src/client/components/core/Docs.js +327 -303
  222. package/src/client/components/core/FileExplorer.js +0 -21
  223. package/src/client/components/core/Modal.js +56 -1
  224. package/src/client/components/core/PanelForm.js +4 -4
  225. package/src/client/components/core/Repository.js +56 -0
  226. package/src/client/components/core/Translate.js +7 -0
  227. package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
  228. package/src/client/components/core/Wallet.js +0 -11
  229. package/src/client/components/core/Worker.js +7 -1
  230. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
  231. package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
  232. package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
  233. package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
  234. package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
  235. package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
  236. package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
  237. package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
  238. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
  239. package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
  240. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -35
  241. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
  242. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
  243. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
  244. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
  245. package/src/client/components/default/AppShellDefault.js +1 -1
  246. package/src/client/components/default/SettingsDefault.js +2 -2
  247. package/src/client/components/itemledger/SettingsItemledger.js +2 -2
  248. package/src/client/components/underpost/AppShellUnderpost.js +3 -2
  249. package/src/client/components/underpost/SettingsUnderpost.js +2 -2
  250. package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
  251. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +313 -30
  252. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
  253. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
  254. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
  255. package/src/client/public/cyberia-docs/CYBERIA.md +48 -28
  256. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
  257. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
  258. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  259. package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
  260. package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
  261. package/src/client/public/default/android-chrome-144x144.png +0 -0
  262. package/src/client/public/default/android-chrome-192x192.png +0 -0
  263. package/src/client/public/default/android-chrome-256x256.png +0 -0
  264. package/src/client/public/default/android-chrome-36x36.png +0 -0
  265. package/src/client/public/default/android-chrome-384x384.png +0 -0
  266. package/src/client/public/default/android-chrome-48x48.png +0 -0
  267. package/src/client/public/default/android-chrome-512x512.png +0 -0
  268. package/src/client/public/default/android-chrome-72x72.png +0 -0
  269. package/src/client/public/default/android-chrome-96x96.png +0 -0
  270. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  271. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  272. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  273. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  274. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  275. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  276. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  277. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  278. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  279. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  280. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  281. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  282. package/src/client/public/default/apple-touch-icon.png +0 -0
  283. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  284. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  285. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  286. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  287. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  288. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  289. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  290. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  291. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  292. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  293. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  294. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  295. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  296. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  297. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  298. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  299. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  300. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  301. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  302. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  303. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  304. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  305. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  306. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  307. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  308. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  309. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  310. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  311. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  312. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  313. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  314. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  315. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  316. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  317. package/src/client/public/default/assets/background/white.jpg +0 -0
  318. package/src/client/public/default/browserconfig.xml +1 -1
  319. package/src/client/public/default/favicon-16x16.png +0 -0
  320. package/src/client/public/default/favicon-32x32.png +0 -0
  321. package/src/client/public/default/favicon-48x48.png +0 -0
  322. package/src/client/public/default/favicon.ico +0 -0
  323. package/src/client/public/default/manifest.webmanifest +5 -5
  324. package/src/client/public/default/mstile-144x144.png +0 -0
  325. package/src/client/public/default/mstile-150x150.png +0 -0
  326. package/src/client/public/default/mstile-310x150.png +0 -0
  327. package/src/client/public/default/mstile-310x310.png +0 -0
  328. package/src/client/public/default/mstile-70x70.png +0 -0
  329. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  330. package/src/client/public/default/yandex-browser-manifest.json +1 -1
  331. package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
  332. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
  333. package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
  334. package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
  335. package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
  336. package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
  337. package/src/client/services/object-layer/object-layer.management.js +6 -10
  338. package/src/client/services/object-layer/object-layer.service.js +3 -1
  339. package/src/client/ssr/RootDocument.js +1 -1
  340. package/src/client/ssr/body/404.js +1 -1
  341. package/src/client/ssr/body/500.js +1 -1
  342. package/src/client/ssr/body/CacheControl.js +1 -1
  343. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
  344. package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
  345. package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
  346. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
  347. package/src/client/ssr/head/CryptokoynScripts.js +1 -1
  348. package/src/client/ssr/head/Css.js +1 -1
  349. package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
  350. package/src/client/ssr/head/DefaultScripts.js +1 -1
  351. package/src/client/ssr/head/ItemledgerScripts.js +1 -1
  352. package/src/client/ssr/head/Microdata.js +1 -1
  353. package/src/client/ssr/head/Production.js +1 -1
  354. package/src/client/ssr/head/Pwa.js +1 -1
  355. package/src/client/ssr/head/PwaItemledger.js +1 -1
  356. package/src/client/ssr/head/Seo.js +1 -1
  357. package/src/client/ssr/head/UnderpostScripts.js +1 -1
  358. package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
  359. package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
  360. package/src/client/ssr/views/Cyberia404.js +7 -5
  361. package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
  362. package/src/client/ssr/views/Maintenance.js +1 -1
  363. package/src/client/ssr/views/NoNetworkConnection.js +1 -1
  364. package/src/client/ssr/views/Test.js +1 -1
  365. package/src/client/sw/core.sw.js +20 -14
  366. package/src/client-builder/client-build-docs.js +92 -77
  367. package/src/client-builder/client-build-live.js +2 -2
  368. package/src/client-builder/client-build.js +105 -74
  369. package/src/client-builder/client-bundle.js +347 -0
  370. package/src/client-builder/client-dev-server.js +3 -3
  371. package/src/client-builder/client-icons.js +2 -2
  372. package/src/client-builder/ssr.js +3 -3
  373. package/src/client.build.js +3 -6
  374. package/src/client.dev.js +3 -6
  375. package/src/db/DataBaseProvider.js +186 -3
  376. package/src/db/mariadb/MariaDB.js +3 -2
  377. package/src/db/mongo/MongoBootstrap.js +273 -101
  378. package/src/db/mongo/MongoExpress.js +187 -0
  379. package/src/db/mongo/MongooseDB.js +7 -8
  380. package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
  381. package/src/grpc/cyberia/grpc-server.js +6 -8
  382. package/src/index.js +79 -23
  383. package/src/mailer/EmailRender.js +2 -2
  384. package/src/mailer/MailerInterceptor.js +87 -0
  385. package/src/mailer/MailerProvider.js +50 -6
  386. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +144 -147
  387. package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
  388. package/src/projects/cyberia/besu-genesis-generator.js +8 -17
  389. package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
  390. package/src/projects/cyberia/catalog-cyberia.js +54 -10
  391. package/src/projects/cyberia/gemini-client.js +4 -4
  392. package/src/projects/cyberia/generate-saga.js +5 -12
  393. package/src/projects/cyberia/hot-reload-trigger.js +18 -29
  394. package/src/projects/cyberia/instance-backup.js +210 -0
  395. package/src/projects/cyberia/instance-data.js +178 -258
  396. package/src/projects/cyberia/ipfs-client.js +4 -4
  397. package/src/projects/cyberia/map-preview-generator.js +33 -69
  398. package/src/projects/cyberia/object-layer.js +153 -320
  399. package/src/projects/cyberia/seed-audio.js +139 -0
  400. package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
  401. package/src/projects/cyberia/semantic-layer-generator.js +3 -19
  402. package/src/projects/cyberia/stat-balance.js +81 -0
  403. package/src/projects/cyberia/stat-commands.js +23 -0
  404. package/src/projects/cyberia/stat-contract-generator.js +101 -0
  405. package/src/projects/underpost/catalog-underpost.js +9 -1
  406. package/src/proxy.js +4 -7
  407. package/src/runtime/cyberia-client/Dockerfile +17 -8
  408. package/src/runtime/cyberia-client/Dockerfile.dev +13 -4
  409. package/src/runtime/cyberia-server/Dockerfile +18 -6
  410. package/src/runtime/cyberia-server/Dockerfile.dev +16 -3
  411. package/src/runtime/engine-cyberia/Dockerfile +25 -9
  412. package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
  413. package/src/runtime/engine-cyberia/Dockerfile.test +5 -5
  414. package/src/runtime/engine-cyberia/compose.env +17 -5
  415. package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
  416. package/src/runtime/express/Express.js +32 -27
  417. package/src/runtime/lampp/Lampp.js +22 -70
  418. package/src/runtime/nginx/Nginx.js +1 -1
  419. package/src/runtime/wp/Wp.js +16 -48
  420. package/src/server/{catalog.js → build/catalog.js} +15 -5
  421. package/src/server/build/coverage.js +188 -0
  422. package/src/server/build/execution.js +402 -0
  423. package/src/server/build/package.js +508 -0
  424. package/src/server/build/testing.js +578 -0
  425. package/src/server/{dns.js → network/dns.js} +144 -11
  426. package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
  427. package/src/server/{middlewares.js → network/middlewares.js} +11 -5
  428. package/src/server/network/node-capability.js +98 -0
  429. package/src/server/{peer.js → network/peer.js} +3 -3
  430. package/src/server/{proxy.js → network/proxy.js} +7 -13
  431. package/src/server/network/router.js +356 -0
  432. package/src/server/{tls.js → network/tls.js} +2 -2
  433. package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
  434. package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
  435. package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
  436. package/src/server/{cri.js → ops/cri.js} +2 -2
  437. package/src/server/{cron.js → ops/cron.js} +349 -74
  438. package/src/server/ops/event-notification.js +284 -0
  439. package/src/server/{logger.js → ops/logger.js} +143 -23
  440. package/src/server/ops/monitoring.js +1724 -0
  441. package/src/server/{systemd.js → ops/systemd.js} +55 -1
  442. package/src/server/{conf.js → runtime/conf.js} +516 -423
  443. package/src/server/runtime/config-scope.js +215 -0
  444. package/src/server/runtime/environment.js +149 -0
  445. package/src/server/{process.js → runtime/process.js} +153 -12
  446. package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
  447. package/src/server/{runtime.js → runtime/runtime.js} +12 -8
  448. package/src/server/{start.js → runtime/start.js} +128 -39
  449. package/src/server/{auth.js → security/auth.js} +7 -8
  450. package/src/server/security/container-storage.js +382 -0
  451. package/src/server/{crypto.js → security/crypto.js} +1 -1
  452. package/src/server/{selinux.js → security/selinux.js} +1 -1
  453. package/src/server/{backup.js → storage/backup.js} +17 -8
  454. package/src/server/{data-query.js → storage/data-query.js} +17 -1
  455. package/src/server/storage/downloader.js +121 -0
  456. package/src/server/storage/repository.js +68 -0
  457. package/src/server/storage/zip.js +153 -0
  458. package/src/server.js +4 -7
  459. package/src/ws/IoInterface.js +1 -1
  460. package/src/ws/IoServer.js +1 -1
  461. package/src/ws/core/core.ws.connection.js +1 -1
  462. package/src/ws/core/core.ws.emit.js +1 -1
  463. package/src/ws/core/core.ws.server.js +1 -1
  464. package/src/ws/default/default.ws.connection.js +1 -1
  465. package/src/ws/default/default.ws.emit.js +1 -1
  466. package/src/ws/default/default.ws.server.js +1 -1
  467. package/test/e2e/event-e2e-public-ingress-down.js +45 -0
  468. package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
  469. package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
  470. package/test/{api.test.js → integration/app/api.test.js} +33 -14
  471. package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
  472. package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
  473. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +64 -0
  474. package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
  475. package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
  476. package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +17 -23
  477. package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
  478. package/test/integration/app/cyberia/cyberia-load.test.js +466 -0
  479. package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
  480. package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
  481. package/test/integration/app/cyberia/fallback-world-capture.test.js +338 -0
  482. package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
  483. package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
  484. package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
  485. package/test/integration/app/cyberia/seed-audio.test.js +275 -0
  486. package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
  487. package/test/integration/infra/1-security/config-scope.test.js +305 -0
  488. package/test/integration/infra/1-security/container-storage.test.js +356 -0
  489. package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
  490. package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
  491. package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
  492. package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
  493. package/test/integration/infra/1-security/systemd-service.test.js +70 -0
  494. package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
  495. package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
  496. package/test/integration/infra/2-network/node-capability.test.js +182 -0
  497. package/test/integration/infra/2-network/wireguard-cli.test.js +1187 -0
  498. package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +649 -55
  499. package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
  500. package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
  501. package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
  502. package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
  503. package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
  504. package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
  505. package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
  506. package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
  507. package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
  508. package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
  509. package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
  510. package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
  511. package/test/integration/infra/5-observability/event-notification.test.js +197 -0
  512. package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
  513. package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
  514. package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
  515. package/test/support/shell-harness.js +73 -0
  516. package/test/unit/build-template.test.js +97 -0
  517. package/test/unit/build-workflow-offline.test.js +132 -0
  518. package/test/unit/catalog.test.js +71 -0
  519. package/test/unit/client-build-docs.test.js +361 -0
  520. package/test/unit/client-bundle.test.js +313 -0
  521. package/test/unit/conf-loading.test.js +303 -0
  522. package/test/unit/conf-resolution.test.js +996 -0
  523. package/test/unit/coverage-artifact.test.js +221 -0
  524. package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
  525. package/test/unit/cyberia/instance-backup.test.js +183 -0
  526. package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
  527. package/test/unit/cyberia/publish-workflow.test.js +22 -0
  528. package/test/unit/cyberia/stat-balance.test.js +69 -0
  529. package/test/unit/deploy-env-resolution.test.js +38 -0
  530. package/test/unit/deploy-log-table.test.js +518 -0
  531. package/test/unit/downloader-integrity.test.js +98 -0
  532. package/test/unit/execution-profiles.test.js +219 -0
  533. package/test/unit/file-reference-registry.test.js +141 -0
  534. package/test/unit/fleet-sync-source.test.js +149 -0
  535. package/test/unit/fs-storage-paths.test.js +596 -0
  536. package/test/unit/logger-redaction.test.js +141 -0
  537. package/test/unit/package.test.js +457 -0
  538. package/test/unit/prepare-host.test.js +382 -0
  539. package/test/unit/process-environment.test.js +18 -0
  540. package/test/unit/propagation-message.test.js +78 -0
  541. package/test/unit/redeploy-plan.test.js +24 -0
  542. package/test/unit/release-bump.test.js +474 -0
  543. package/test/unit/ssh-output-redaction.test.js +28 -0
  544. package/test/unit/start-options.test.js +46 -0
  545. package/test/unit/test-tiers.test.js +220 -0
  546. package/test/unit/zip-archive.test.js +142 -0
  547. package/vitest.config.js +66 -0
  548. package/.nycrc +0 -9
  549. package/deploy/lib/logging.sh +0 -96
  550. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
  551. package/manifests/mongodb/pv-pvc.yaml +0 -59
  552. package/scripts/coverall-test-cyberia.sh +0 -24
  553. package/scripts/coverall-test.sh +0 -24
  554. package/scripts/link-local-underpost-cli.sh +0 -6
  555. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
  556. package/src/api/user/user.build.js +0 -16
  557. package/src/cli/env.js +0 -177
  558. package/src/client/components/core/Blockchain.js +0 -41
  559. package/src/client/components/core/Blog.js +0 -9
  560. package/src/client/components/core/KeyboardAvoidance.js +0 -145
  561. package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
  562. package/src/client/public/default/assets/background/dark.jpg +0 -0
  563. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  564. package/src/client/public/default/assets/background/white0.jpg +0 -0
  565. package/src/client/public/doc/favicon.ico +0 -0
  566. package/src/client/public/doc/sitemap +0 -148
  567. package/src/server/downloader.js +0 -73
  568. package/src/server/environment.js +0 -98
@@ -0,0 +1,139 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { getFallbackMapCodes } from '../../api/cyberia-instance/cyberia-fallback-world.js';
5
+ import {
6
+ DEFAULT_AUDIO_BANK,
7
+ DEFAULT_AUDIO_SETTINGS,
8
+ DEFAULT_MAP_MUSIC,
9
+ buildAudioEventBindings,
10
+ } from '../../api/cyberia-server-defaults/cyberia-server-defaults.js';
11
+ import { CyberiaAudioService } from '../../api/cyberia-audio/cyberia-audio.service.js';
12
+ import { CyberiaMapAudioConfService } from '../../api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js';
13
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
14
+
15
+ /**
16
+ * Resolves the canonical audio defaults against a list of map codes.
17
+ *
18
+ * The vocabulary, the bank and the bindings are owned by cyberia-server-defaults; this only states
19
+ * them per map. Every map of a world carries the same bed and the same bindings, so a world sounds
20
+ * like itself wherever the player stands, and what changes a place is the event that fires there.
21
+ *
22
+ * @param {string[]} mapCodes - Map codes the world declares.
23
+ * @returns {{assets: string[], settings: object, events: object[], maps: object[]}}
24
+ */
25
+ const audioConfigForMaps = (mapCodes) => ({
26
+ // The codes the world needs imported; the client fetches every one of them by code.
27
+ assets: DEFAULT_AUDIO_BANK.map(({ code }) => code),
28
+ settings: DEFAULT_AUDIO_SETTINGS,
29
+ events: buildAudioEventBindings(),
30
+ maps: mapCodes.map((mapCode) => ({ mapCode, defaultMusic: DEFAULT_MAP_MUSIC })),
31
+ });
32
+
33
+ /** The canonical audio configuration of the fallback world. */
34
+ const fallbackAudioConfig = () => audioConfigForMaps(getFallbackMapCodes());
35
+
36
+ // The renderer lives in cyberia-audio, a sibling repository this one does not contain (see
37
+ // .gitignore, alongside cyberia-server and cyberia-client). Named once so the runtime and the
38
+ // suites that need real bytes ask the same question of the same path.
39
+ const AUDIO_RENDERER_URL = new URL('../../../cyberia-audio/src/dispatcher.js', import.meta.url);
40
+
41
+ /** Whether the cyberia-audio renderer is present beside this repository. */
42
+ const hasAudioRenderer = () => fs.existsSync(AUDIO_RENDERER_URL);
43
+
44
+ /**
45
+ * Loads the cyberia-audio dispatcher, or says plainly what is missing.
46
+ *
47
+ * A bare dynamic import fails here with a resolver message that names neither the project nor
48
+ * what to do about it, and a fresh checkout hits that before anything else.
49
+ *
50
+ * @returns {Promise<{dispatch: Function}>}
51
+ */
52
+ async function loadAudioRenderer() {
53
+ if (!hasAudioRenderer()) {
54
+ throw new Error(
55
+ `cyberia-audio renderer not found at ${fileURLToPath(AUDIO_RENDERER_URL)}. It is a sibling ` +
56
+ 'repository, not part of engine — clone it beside this one to record the audio bank.',
57
+ );
58
+ }
59
+ return await import(AUDIO_RENDERER_URL.href);
60
+ }
61
+
62
+ /**
63
+ * Records the fallback audio the world needs, as `<code>.wav` + `<code>.json` pairs.
64
+ *
65
+ * Recording is where the bytes are produced and nowhere else: the client ships no audio and
66
+ * fetches every asset from engine-cyberia by code, so there is no bundle to build alongside these.
67
+ *
68
+ * @param {{recordsPath: string}} params - Output directory for the recorded pairs.
69
+ * @returns {Promise<object>} The fallback audio configuration these recordings satisfy.
70
+ */
71
+ async function prepareFallbackAudio({ recordsPath }) {
72
+ const { dispatch } = await loadAudioRenderer();
73
+ const config = fallbackAudioConfig();
74
+ await fs.ensureDir(recordsPath);
75
+ for (const { code, bus, options } of DEFAULT_AUDIO_BANK) {
76
+ const output = path.resolve(recordsPath, `${code}.wav`);
77
+ await dispatch(bus, code, { sampleRate: 22050, ...options }, { play: false, record: true, path: output });
78
+ }
79
+ return config;
80
+ }
81
+
82
+ /**
83
+ * Imports the bank and writes one complete audio configuration per map.
84
+ *
85
+ * @param {object} config - As {@link audioConfigForMaps} resolves it.
86
+ * @param {{recordsPath: string}} params - Directory holding the recorded pairs.
87
+ * @param {{host: string, path: string}} options - Provider context.
88
+ * @returns {Promise<{assets: object[], maps: object[]}>}
89
+ */
90
+ async function seedMapAudio(config, { recordsPath }, options) {
91
+ const assets = await CyberiaAudioService.importRecords({ recordsPath, codes: config.assets }, options);
92
+ if (assets.length !== config.assets.length) throw new Error('Seeding audio requires every WAV and manifest pair');
93
+ const maps = [];
94
+ for (const map of config.maps) {
95
+ // The seed states the whole configuration, so re-running it converges: a binding whose logic
96
+ // event this bank no longer declares is dropped rather than left behind pointing at an asset
97
+ // the client can no longer resolve.
98
+ maps.push(
99
+ await CyberiaMapAudioConfService.assign(
100
+ { ...map, settings: config.settings, events: config.events, replaceEvents: true },
101
+ options,
102
+ ),
103
+ );
104
+ }
105
+ return { assets, maps };
106
+ }
107
+
108
+ const seedFallbackAudio = ({ recordsPath }, options) =>
109
+ seedMapAudio(fallbackAudioConfig(), { recordsPath }, options);
110
+
111
+ /**
112
+ * Scores one instance's maps with the canonical bank.
113
+ *
114
+ * Every map the instance declares is scored with the same bank, bed and bindings the fallback
115
+ * world uses, so any world sounds the way that one does.
116
+ *
117
+ * @param {{instanceCode: string, recordsPath: string}} params - Target instance and records directory.
118
+ * @param {{host: string, path: string}} options - Provider context.
119
+ * @returns {Promise<{assets: object[], maps: object[]}>}
120
+ * @throws {Error} When the instance does not exist or declares no maps.
121
+ */
122
+ async function seedInstanceAudio({ instanceCode, recordsPath }, options) {
123
+ const CyberiaInstance = DataBaseProviderService.getModel('CyberiaInstance', options);
124
+ const instance = await CyberiaInstance.findOne({ code: instanceCode }).select('cyberiaMapCodes').lean();
125
+ if (!instance) throw new Error(`cyberia-instance not found for code="${instanceCode}"`);
126
+ const mapCodes = instance.cyberiaMapCodes ?? [];
127
+ if (mapCodes.length === 0) throw new Error(`cyberia-instance "${instanceCode}" declares no maps`);
128
+ return seedMapAudio(audioConfigForMaps(mapCodes), { recordsPath }, options);
129
+ }
130
+
131
+ export {
132
+ audioConfigForMaps,
133
+ fallbackAudioConfig,
134
+ hasAudioRenderer,
135
+ loadAudioRenderer,
136
+ prepareFallbackAudio,
137
+ seedFallbackAudio,
138
+ seedInstanceAudio,
139
+ };
@@ -28,6 +28,7 @@
28
28
  * @namespace SemanticLayerGeneratorSkin
29
29
  */
30
30
  import { readFileSync } from 'fs';
31
+ import { STAT_DEFAULTS } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
31
32
  import path from 'path';
32
33
  import { fileURLToPath } from 'url';
33
34
  import crypto from 'crypto';
@@ -1070,14 +1071,7 @@ function generateSkinMultiFrame(options, _descriptor) {
1070
1071
  description: `Procedurally generated character skin (seed: ${seed})`,
1071
1072
  activable: true,
1072
1073
  },
1073
- stats: {
1074
- effect: 0,
1075
- resistance: 0,
1076
- agility: 0,
1077
- range: 0,
1078
- intelligence: 0,
1079
- utility: 0,
1080
- },
1074
+ stats: { ...STAT_DEFAULTS },
1081
1075
  ledger: { type: 'OFF_CHAIN' },
1082
1076
  seed: localSeedToUUIDv4(`${seed}:${itemId}`),
1083
1077
  },
@@ -17,9 +17,10 @@
17
17
  */
18
18
 
19
19
  import crypto from 'crypto';
20
+ import { generateRandomStats } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
20
21
 
21
22
  import { createRng, seedToInt, createNoise2D, generateShape, listShapes } from './shape-generator.js';
22
- import { loggerFactory } from '../../server/logger.js';
23
+ import { loggerFactory } from '../../server/ops/logger.js';
23
24
 
24
25
  import { registerFloorSemantics } from './semantic-layer-generator-floor.js';
25
26
  import { registerSkinSemantics } from './semantic-layer-generator-skin.js';
@@ -703,14 +704,7 @@ export function generateMultiFrame(options) {
703
704
  description: `Procedurally generated ${descriptor.semanticTags.join(', ')} (seed: ${seed})`,
704
705
  activable: true,
705
706
  },
706
- stats: {
707
- effect: hashMod(seed + ':effect', 11),
708
- resistance: hashMod(seed + ':resistance', 11),
709
- agility: hashMod(seed + ':agility', 11),
710
- range: hashMod(seed + ':range', 11),
711
- intelligence: hashMod(seed + ':intelligence', 11),
712
- utility: hashMod(seed + ':utility', 11),
713
- },
707
+ stats: generateRandomStats(undefined, undefined, createRng(seedToInt(seed + ':stats'))),
714
708
  ledger: { type: 'OFF_CHAIN' },
715
709
  seed: seedToUUIDv4(seed + ':' + itemId),
716
710
  },
@@ -726,16 +720,6 @@ export function generateMultiFrame(options) {
726
720
  };
727
721
  }
728
722
 
729
- /**
730
- * Deterministic modulo hash for stat generation.
731
- * @param {string} str
732
- * @param {number} mod
733
- * @returns {number}
734
- */
735
- function hashMod(str, mod) {
736
- return ((hashString(str) % mod) + mod) % mod;
737
- }
738
-
739
723
  /* ═══════════════════════════════════════════════════════════════════════════
740
724
  * EXPORTS
741
725
  * ═══════════════════════════════════════════════════════════════════════════ */
@@ -0,0 +1,81 @@
1
+ import {
2
+ STAT_MODIFIER_MAX,
3
+ STAT_MODIFIER_MIN,
4
+ STAT_TYPES,
5
+ statBoundsForType,
6
+ validateStatModifier,
7
+ validateStats,
8
+ } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
9
+
10
+ /**
11
+ * Stat balancing for every object layer the content pipeline writes.
12
+ *
13
+ * One policy resolves the bounds each stat may take, then either clamps the stats the content
14
+ * carries or draws new ones inside those bounds. The same policy answers every write path, so a
15
+ * run with a given policy over given content is deterministic.
16
+ *
17
+ * @typedef {Object} StatPolicy
18
+ * @property {boolean} [normalize=false] - Bound each stat by the item type's semantic range.
19
+ * @property {boolean} [random=false] - Replace every stat with a value drawn inside its bounds.
20
+ * @property {number} [min] - Narrow every bound from below.
21
+ * @property {number} [max] - Narrow every bound from above.
22
+ */
23
+
24
+ /** Whether a policy changes anything at all. */
25
+ export const statPolicyActive = ({ normalize = false, random = false } = {}) => normalize || random;
26
+
27
+ /**
28
+ * The inclusive `[min, max]` each stat may take under a policy for one item type.
29
+ *
30
+ * The semantic range wins: `min` and `max` narrow it, and a request that leaves no overlap pins
31
+ * the stat to the semantic edge nearest the request. Without `normalize` the contract range is
32
+ * the whole range.
33
+ *
34
+ * @param {string} itemType
35
+ * @param {StatPolicy} policy
36
+ * @returns {Record<string,[number,number]>}
37
+ */
38
+ export function resolveStatBounds(itemType, { normalize = false, min, max } = {}) {
39
+ if (min !== undefined) validateStatModifier(min);
40
+ if (max !== undefined) validateStatModifier(max);
41
+ if (min !== undefined && max !== undefined && min > max)
42
+ throw new RangeError('Stat minimum must not exceed maximum.');
43
+ const semantic = normalize
44
+ ? statBoundsForType(itemType)
45
+ : Object.fromEntries(STAT_TYPES.map((key) => [key, [STAT_MODIFIER_MIN, STAT_MODIFIER_MAX]]));
46
+ return Object.fromEntries(
47
+ STAT_TYPES.map((key) => {
48
+ const [lo, hi] = semantic[key];
49
+ const low = Math.max(lo, min ?? lo);
50
+ const high = Math.min(hi, max ?? hi);
51
+ if (low <= high) return [key, [low, high]];
52
+ // No overlap: the semantic edge the request points at.
53
+ const pinned = (min ?? lo) > hi ? hi : lo;
54
+ return [key, [pinned, pinned]];
55
+ }),
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Applies a policy to one item's stats.
61
+ *
62
+ * @param {Object} params
63
+ * @param {Object} params.stats - Stats as the content carries them.
64
+ * @param {string} params.itemType
65
+ * @param {StatPolicy} [params.policy]
66
+ * @param {() => number} [params.random=Math.random] - Source in [0, 1) for a random draw.
67
+ * @returns {Record<string,number>} The balanced stats, in canonical order.
68
+ */
69
+ export function balanceStats({ stats, itemType, policy = {}, random = Math.random }) {
70
+ const current = validateStats(stats);
71
+ const bounds = resolveStatBounds(itemType, policy);
72
+ return Object.fromEntries(
73
+ STAT_TYPES.map((key) => {
74
+ const [lo, hi] = bounds[key];
75
+ if (!policy.random) return [key, Math.min(hi, Math.max(lo, current[key]))];
76
+ const value = random();
77
+ if (!Number.isFinite(value) || value < 0 || value >= 1) throw new RangeError('Random source must return [0, 1).');
78
+ return [key, Math.floor(value * (hi - lo + 1)) + lo];
79
+ }),
80
+ );
81
+ }
@@ -0,0 +1,23 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { generateRandomStats, validateStats } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
3
+ import { PROGRESSION_RULES_DEFAULTS } from '../../api/cyberia-server-defaults/cyberia-server-defaults.js';
4
+ import { generateStatContract } from './stat-contract-generator.js';
5
+
6
+ export function registerStatCommands(program) {
7
+ const stats = program.command('stats').description('Validate signed stats and inspect progression rules.');
8
+ stats.command('random').option('--min <number>').option('--max <number>').action((options) => {
9
+ const min = options.min === undefined ? undefined : Number(options.min);
10
+ const max = options.max === undefined ? undefined : Number(options.max);
11
+ console.log(JSON.stringify(generateRandomStats(min, max), null, 2));
12
+ });
13
+ stats.command('validate <file>').action(async (file) => {
14
+ const input = JSON.parse(await readFile(file, 'utf8'));
15
+ const records = Array.isArray(input) ? input : [input];
16
+ for (const record of records) validateStats(record.data?.stats ?? record.stats ?? record);
17
+ console.log(JSON.stringify({ valid: true, records: records.length }));
18
+ });
19
+ stats.command('progression').action(() => console.log(JSON.stringify(PROGRESSION_RULES_DEFAULTS, null, 2)));
20
+ program.command('stat-contract').option('--check', 'Check generated Go and C files.').action(async (options) => {
21
+ console.log(JSON.stringify(await generateStatContract({ check: !!options.check })));
22
+ });
23
+ }
@@ -0,0 +1,101 @@
1
+ import { buildBootContractArtifacts } from './boot-contract-fixtures.js';
2
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { existsSync, mkdtempSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
5
+ import { tmpdir } from 'node:os';
6
+ import { join } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { resolve, dirname } from 'node:path';
9
+ import { STAT_TYPES, STAT_DEFINITIONS, STAT_MODIFIER_MIN, STAT_MODIFIER_MAX, STAT_EFFECTIVE_FLOORS, STAT_SCALES, STAT_REGEN_PER_RESISTANCE } from '../../client/components/cyberia/SharedDefaultsCyberia.js';
10
+ import { PROGRESSION_RULES_DEFAULTS, PROGRESSION_RULE_LIMITS } from '../../api/cyberia-server-defaults/cyberia-server-defaults.js';
11
+
12
+ const field = (key) => key[0].toUpperCase() + key.slice(1);
13
+ const values = (stats) => STAT_TYPES.map((key) => stats[key]).join(', ');
14
+
15
+ export function buildStatContractArtifacts() {
16
+ const go = `// Code generated by Cyberia stat-contract. DO NOT EDIT.
17
+ package game
18
+ const StatCount = ${STAT_TYPES.length}
19
+ const StatModifierMin = ${STAT_MODIFIER_MIN}
20
+ const StatModifierMax = ${STAT_MODIFIER_MAX}
21
+ func (r ProgressionRules) validScalarBounds() bool { return ${Object.entries(PROGRESSION_RULE_LIMITS).map(([key, [min, max]]) => `r.${field(key)} >= ${min} && r.${field(key)} <= ${max}`).join(' && ')} }
22
+ var statNames = [StatCount]string{${STAT_TYPES.map(JSON.stringify).join(', ')}}
23
+ var statEffectiveFloors = [StatCount]float64{${values(STAT_EFFECTIVE_FLOORS)}}
24
+ // statScales is what one point of each stat is worth in the simulation.
25
+ var statScales = ComputedStats{${STAT_TYPES.map((key) => `${field(key)}: ${STAT_SCALES[key]}`).join(', ')}}
26
+ const statRegenPerResistance = ${STAT_REGEN_PER_RESISTANCE}
27
+ type Stats struct {
28
+ ${STAT_TYPES.map((key) => `${field(key)} int \`json:"${key}"\``).join('\n')}
29
+ }
30
+ type ComputedStats struct {
31
+ ${STAT_TYPES.map((key) => `${field(key)} float64 \`json:"${key}"\``).join('\n')}
32
+ }
33
+ func (s Stats) computed() ComputedStats { return ComputedStats{${STAT_TYPES.map((key) => `${field(key)}: float64(s.${field(key)})`).join(', ')}} }
34
+ func (s ComputedStats) Values() [StatCount]float64 { return [StatCount]float64{${STAT_TYPES.map((key) => `s.${field(key)}`).join(', ')}} }
35
+ func statsFromValues(v [StatCount]float64) ComputedStats { return ComputedStats{${STAT_TYPES.map((key, i) => `${field(key)}: v[${i}]`).join(', ')}} }
36
+ func defaultProgressionRules() ProgressionRules { return ProgressionRules{
37
+ ${Object.entries(PROGRESSION_RULES_DEFAULTS).map(([key, value]) => `${field(key)}: ${typeof value === 'object' ? `ComputedStats{${values(value)}}` : value},`).join('\n')}
38
+ } }
39
+ `;
40
+ const header = `/* Code generated by Cyberia stat-contract. DO NOT EDIT. */
41
+ #ifndef CYBERIA_STAT_CONTRACT_H
42
+ #define CYBERIA_STAT_CONTRACT_H
43
+ #define CYBERIA_STAT_COUNT ${STAT_TYPES.length}
44
+ static const char* const CYBERIA_STAT_NAMES[CYBERIA_STAT_COUNT] = {${STAT_TYPES.map(JSON.stringify).join(', ')}};
45
+ typedef struct {
46
+ ${STAT_TYPES.map((key) => ' int ' + key + ';').join('\n')}
47
+ } Stats;
48
+ static inline void cyberia_stats_values(const Stats* stats, int values[CYBERIA_STAT_COUNT]) {
49
+ ${STAT_TYPES.map((key, i) => ' values[' + i + '] = stats->' + key + ';').join('\n')}
50
+ }
51
+ static inline Stats cyberia_stats_from_values(const int values[CYBERIA_STAT_COUNT]) {
52
+ return (Stats){${STAT_TYPES.map((key, i) => 'values[' + i + ']').join(', ')}};
53
+ }
54
+ static const char* const CYBERIA_STAT_ICONS[CYBERIA_STAT_COUNT] = {${STAT_TYPES.map((key) => JSON.stringify('stat-' + key)).join(', ')}};
55
+ static const char* const CYBERIA_STAT_LABELS[CYBERIA_STAT_COUNT] = {${STAT_DEFINITIONS.map(({ title }) => JSON.stringify(title)).join(', ')}};
56
+ #endif
57
+ `;
58
+ const temporary = mkdtempSync(join(tmpdir(), 'cyberia-stat-contract-'));
59
+ let formatted;
60
+ try {
61
+ const source = join(temporary, 'contract.go');
62
+ writeFileSync(source, go);
63
+ execFileSync('gofmt', ['-w', source], { stdio: 'inherit', timeout: 30000 });
64
+ formatted = readFileSync(source, 'utf8');
65
+ } finally {
66
+ rmSync(temporary, { recursive: true, force: true });
67
+ }
68
+ return {
69
+ 'cyberia-server/game/stat_contract_generated.go': formatted,
70
+ 'cyberia-client/src/domain/stat_contract_generated.h': header,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Whether cyberia-server and cyberia-client sit beside this repository.
76
+ *
77
+ * Both are gitignored siblings (see .gitignore, alongside cyberia-audio), so a checkout that
78
+ * publishes only this repo's tracked tree — the engine-cyberia npm mirrors, for one — never has
79
+ * them. {@link generateStatContract} writes into both; callers that only run in a full
80
+ * multi-repo checkout should skip rather than fail on a missing sibling.
81
+ *
82
+ * @param {string} [root] - Defaults to this repository's own root.
83
+ * @returns {boolean}
84
+ */
85
+ export function hasCyberiaSiblings(root = fileURLToPath(new URL('../../../', import.meta.url))) {
86
+ return existsSync(resolve(root, 'cyberia-server')) && existsSync(resolve(root, 'cyberia-client'));
87
+ }
88
+
89
+ export async function generateStatContract({ root = fileURLToPath(new URL('../../../', import.meta.url)), check = false } = {}) {
90
+ const artifacts = { ...buildStatContractArtifacts(), ...buildBootContractArtifacts() };
91
+ for (const [path, content] of Object.entries(artifacts)) {
92
+ const target = resolve(root, path);
93
+ if (check) {
94
+ if (await readFile(target, 'utf8') !== content) throw new Error(`Regenerate ${path} with cyberia stat-contract.`);
95
+ } else {
96
+ await mkdir(dirname(target), { recursive: true });
97
+ await writeFile(target, content);
98
+ }
99
+ }
100
+ return Object.keys(artifacts);
101
+ }
@@ -28,6 +28,14 @@ const TEMPLATE_RESTORE_PATHS = [
28
28
  './manifests/deployment/dd-default-development',
29
29
  ];
30
30
 
31
+ /**
32
+ * Template checkout entries a rebuild keeps. Everything else is reconstructed from
33
+ * the engine tree, so a file the engine no longer produces cannot survive a build.
34
+ * @constant {string[]}
35
+ * @memberof UnderpostCatalog
36
+ */
37
+ const TEMPLATE_PRESERVED_ENTRIES = ['.git', 'node_modules'];
38
+
31
39
  /**
32
40
  * npm keywords for the standalone Underpost platform / template package.
33
41
  * @constant {string[]}
@@ -60,4 +68,4 @@ const TEMPLATE_KEYWORDS = [
60
68
  const TEMPLATE_DESCRIPTION =
61
69
  'Underpost Platform — end-to-end CI/CD and application-delivery toolchain CLI. Covers bare metal, Kubernetes, K3s, kubeadm, LXD, container/image orchestration, secrets, databases, cron jobs, monitoring, SSH, runners, PWA + Workbox delivery, and release orchestration. Extensible via downstream CLIs.';
62
70
 
63
- export { TEMPLATE_RESTORE_PATHS, TEMPLATE_KEYWORDS, TEMPLATE_DESCRIPTION };
71
+ export { TEMPLATE_RESTORE_PATHS, TEMPLATE_PRESERVED_ENTRIES, TEMPLATE_KEYWORDS, TEMPLATE_DESCRIPTION };
package/src/proxy.js CHANGED
@@ -1,12 +1,9 @@
1
1
  'use strict';
2
2
 
3
- // https://nodejs.org/api
4
- // https://expressjs.com/en/4x/api.html
5
-
6
- import { loggerFactory } from './server/logger.js';
7
- import { buildProxy } from './server/proxy.js';
8
- import { ProcessController } from './server/process.js';
9
- import { Config } from './server/conf.js';
3
+ import { loggerFactory } from './server/ops/logger.js';
4
+ import { buildProxy } from './server/network/proxy.js';
5
+ import { ProcessController } from './server/runtime/process.js';
6
+ import { Config } from './server/runtime/conf.js';
10
7
 
11
8
  await Config.build(process.argv[2], process.argv[3], process.argv[4]);
12
9
 
@@ -14,7 +14,6 @@ RUN make -f Web.mk clean all BUILD_MODE=${BUILD_MODE} OUTPUT_DIR=bin/
14
14
 
15
15
  # --- Runtime Image ---
16
16
  FROM rockylinux/rockylinux:9 AS runtime
17
- ARG UNDERPOST_VERSION=3.3.0
18
17
  ARG NODE_VERSION=24.15.0
19
18
 
20
19
  RUN set -eux; \
@@ -28,22 +27,32 @@ RUN set -eux; \
28
27
  curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
29
28
  | tar -xJ -C /usr/local --strip-components=1; \
30
29
  node --version; npm --version; \
31
- npm install -g underpost@${UNDERPOST_VERSION}; \
32
- dnf clean all; rm -rf /var/cache/dnf; \
33
- npm cache clean --force
30
+ dnf clean all; rm -rf /var/cache/dnf
31
+
32
+
33
+ COPY underpost-cli.tgz /tmp/underpost-cli.tgz
34
+ RUN set -eux; \
35
+ npm install -g /tmp/underpost-cli.tgz --omit=dev; \
36
+ rm -f /tmp/underpost-cli.tgz; \
37
+ npm cache clean --force; \
38
+ underpost --version
34
39
 
35
40
  # Path + server layout is the contract with conf.instances.json mmo-client cmd,
36
- # which execs `python3 /home/dd/engine/cyberia-client/docker-driver.py <port>
37
- # /home/dd/engine/cyberia-client/bin` in both development and production.
41
+ # which execs `python3 /home/dd/engine/cyberia-client/wasm-driver.py --port=<port>
42
+ # --directory=/home/dd/engine/cyberia-client/bin --data-server-url=<url>` in both
43
+ # development and production.
38
44
  # Keep this identical to Dockerfile.dev so prod and dev images are interchangeable.
39
45
  WORKDIR /home/dd/engine/cyberia-client
40
46
 
41
- COPY --from=builder /cyberia-client/docker-driver.py ./docker-driver.py
47
+ COPY --from=builder /cyberia-client/wasm-driver.py ./wasm-driver.py
42
48
  COPY --from=builder /cyberia-client/bin ./bin/
43
49
 
44
50
  ENV PYTHONUNBUFFERED=1
45
51
  ENV CYBERIA_PORT=8081
52
+ # Mirrors the --data-server-url default in wasm-driver.py: the CMD below always passes the flag,
53
+ # so leaving this unset would hand the client an empty origin rather than that default.
54
+ ENV CYBERIA_DATA_SERVER_URL=https://cyberiaonline.com
46
55
 
47
56
  EXPOSE 8081
48
57
 
49
- CMD ["sh", "-c", "exec python3 docker-driver.py ${CYBERIA_PORT} bin"]
58
+ CMD ["sh", "-c", "exec python3 wasm-driver.py --port=${CYBERIA_PORT} --directory=bin --data-server-url=${CYBERIA_DATA_SERVER_URL}"]
@@ -43,7 +43,6 @@ RUN make -f Web.mk all BUILD_MODE=${BUILD_MODE} OUTPUT_DIR=bin/
43
43
  # --- Runtime Image ---
44
44
  FROM rockylinux/rockylinux:9 AS runtime
45
45
 
46
- ARG UNDERPOST_VERSION=3.3.0
47
46
  ARG NODE_VERSION=24.15.0
48
47
  RUN set -eux; \
49
48
  dnf -y update; \
@@ -60,16 +59,26 @@ RUN set -eux; \
60
59
  curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
61
60
  | tar -xJ -C /usr/local --strip-components=1; \
62
61
  node --version; npm --version; \
63
- npm install -g underpost@${UNDERPOST_VERSION}; \
64
62
  dnf clean all
65
63
 
64
+
65
+ COPY underpost-cli.tgz /tmp/underpost-cli.tgz
66
+ RUN set -eux; \
67
+ npm install -g /tmp/underpost-cli.tgz --omit=dev; \
68
+ rm -f /tmp/underpost-cli.tgz; \
69
+ npm cache clean --force; \
70
+ underpost --version
71
+
66
72
  WORKDIR /home/dd/engine/cyberia-client
67
73
 
68
- COPY --from=builder /cyberia-client/docker-driver.py ./docker-driver.py
74
+ COPY --from=builder /cyberia-client/wasm-driver.py ./wasm-driver.py
69
75
  COPY --from=builder /cyberia-client/bin ./bin/
70
76
 
71
77
  ENV CYBERIA_PORT=8082
78
+ # Mirrors the --data-server-url default in wasm-driver.py: the CMD below always passes the flag,
79
+ # so leaving this unset would hand the client an empty origin rather than that default.
80
+ ENV CYBERIA_DATA_SERVER_URL=https://cyberiaonline.com
72
81
 
73
82
  EXPOSE 8081 8082
74
83
 
75
- CMD ["sh", "-c", "exec python3 docker-driver.py ${CYBERIA_PORT} bin"]
84
+ CMD ["sh", "-c", "exec python3 wasm-driver.py --port=${CYBERIA_PORT} --directory=bin --data-server-url=${CYBERIA_DATA_SERVER_URL}"]
@@ -1,5 +1,5 @@
1
1
  # --- Build Image ---
2
- FROM golang:1.24 AS builder
2
+ FROM golang:1.25 AS builder
3
3
 
4
4
  WORKDIR /build
5
5
 
@@ -11,7 +11,6 @@ RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o server ./cmd/cyberia-se
11
11
 
12
12
  # --- Runtime Image ---
13
13
  FROM rockylinux/rockylinux:9 AS runtime
14
- ARG UNDERPOST_VERSION=3.3.0
15
14
  ARG NODE_VERSION=24.15.0
16
15
 
17
16
  RUN set -eux; \
@@ -25,9 +24,15 @@ RUN set -eux; \
25
24
  curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
26
25
  | tar -xJ -C /usr/local --strip-components=1; \
27
26
  node --version; npm --version; \
28
- npm install -g underpost@${UNDERPOST_VERSION}; \
29
- dnf clean all; rm -rf /var/cache/dnf; \
30
- npm cache clean --force
27
+ dnf clean all; rm -rf /var/cache/dnf
28
+
29
+
30
+ COPY underpost-cli.tgz /tmp/underpost-cli.tgz
31
+ RUN set -eux; \
32
+ npm install -g /tmp/underpost-cli.tgz --omit=dev; \
33
+ rm -f /tmp/underpost-cli.tgz; \
34
+ npm cache clean --force; \
35
+ underpost --version
31
36
 
32
37
  # Path is the contract with conf.instances.json mmo-server cmd, which execs
33
38
  # /home/dd/engine/cyberia-server/server in both development and production.
@@ -40,4 +45,11 @@ COPY public/ ./public/
40
45
 
41
46
  EXPOSE 8081
42
47
 
43
- ENTRYPOINT ["/home/dd/engine/cyberia-server/server"]
48
+ # Both Data Server endpoints are flags, not environment reads (cmd/cyberia-server/main.go), and
49
+ # the server refuses to start without them. Passing them here from the environment is what lets a
50
+ # plain `docker run` or a Compose service that sets no command still start: a Kubernetes pod spec
51
+ # supplies its own command and overrides this.
52
+ ENV CYBERIA_DATA_SERVER_URL=http://engine-cyberia
53
+ ENV CYBERIA_DATA_SERVER_GRPC=engine-cyberia-runtime:50051
54
+
55
+ CMD ["sh", "-c", "exec /home/dd/engine/cyberia-server/server --data-server-url=${CYBERIA_DATA_SERVER_URL} --data-server-grpc=${CYBERIA_DATA_SERVER_GRPC}"]
@@ -25,7 +25,6 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
25
25
  # --- Runtime Image ---
26
26
  FROM rockylinux/rockylinux:9 AS runtime
27
27
 
28
- ARG UNDERPOST_VERSION=3.3.0
29
28
  ARG NODE_VERSION=24.15.0
30
29
  RUN set -eux; \
31
30
  dnf -y update; \
@@ -42,9 +41,16 @@ RUN set -eux; \
42
41
  curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
43
42
  | tar -xJ -C /usr/local --strip-components=1; \
44
43
  node --version; npm --version; \
45
- npm install -g underpost@${UNDERPOST_VERSION}; \
46
44
  dnf clean all
47
45
 
46
+
47
+ COPY underpost-cli.tgz /tmp/underpost-cli.tgz
48
+ RUN set -eux; \
49
+ npm install -g /tmp/underpost-cli.tgz --omit=dev; \
50
+ rm -f /tmp/underpost-cli.tgz; \
51
+ npm cache clean --force; \
52
+ underpost --version
53
+
48
54
  WORKDIR /home/dd/engine/cyberia-server
49
55
 
50
56
  COPY --from=builder /build/server ./server
@@ -53,4 +59,11 @@ COPY public/ ./public/
53
59
 
54
60
  EXPOSE 8081
55
61
 
56
- ENTRYPOINT ["/home/dd/engine/cyberia-server/server"]
62
+ # Both Data Server endpoints are flags, not environment reads (cmd/cyberia-server/main.go), and
63
+ # the server refuses to start without them. Passing them here from the environment is what lets a
64
+ # plain `docker run` or a Compose service that sets no command still start: a Kubernetes pod spec
65
+ # supplies its own command and overrides this.
66
+ ENV CYBERIA_DATA_SERVER_URL=http://engine-cyberia
67
+ ENV CYBERIA_DATA_SERVER_GRPC=engine-cyberia-runtime:50051
68
+
69
+ CMD ["sh", "-c", "exec /home/dd/engine/cyberia-server/server --data-server-url=${CYBERIA_DATA_SERVER_URL} --data-server-grpc=${CYBERIA_DATA_SERVER_GRPC}"]