@underpostnet/cyberia 3.3.0 → 3.3.73

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 (471) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/coverall.cyberia.ci.yml +34 -14
  3. package/.github/workflows/cyberia-client.cd.yml +5 -0
  4. package/.github/workflows/cyberia-server.cd.yml +5 -0
  5. package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
  6. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
  7. package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
  8. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
  9. package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
  10. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
  11. package/.github/workflows/engine-cyberia.cd.yml +3 -0
  12. package/.github/workflows/engine-cyberia.ci.yml +4 -5
  13. package/.github/workflows/ghpkg.ci.yml +35 -20
  14. package/.github/workflows/hardhat.ci.yml +12 -11
  15. package/.github/workflows/npmpkg.ci.yml +17 -15
  16. package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
  17. package/.github/workflows/release.cd.yml +1 -0
  18. package/.prettierignore +1 -0
  19. package/AGENTS.md +47 -0
  20. package/CHANGELOG.md +565 -2510
  21. package/CLI-HELP.md +306 -147
  22. package/Dockerfile +25 -9
  23. package/Dockerfile.dev +25 -9
  24. package/Dockerfile.test +4 -4
  25. package/README.md +21 -1
  26. package/bin/build.js +66 -41
  27. package/bin/build.template.js +8 -3
  28. package/bin/cyberia.js +308 -91
  29. package/bin/deploy.js +18 -104
  30. package/bin/index.js +308 -91
  31. package/conf.js +91 -4
  32. package/deploy/cyberia-client/deploy.sh +47 -0
  33. package/deploy/cyberia-client/package.sh +18 -0
  34. package/deploy/cyberia-client/state.sh +14 -0
  35. package/deploy/cyberia-server/deploy.sh +47 -0
  36. package/deploy/cyberia-server/package.sh +18 -0
  37. package/deploy/cyberia-server/state.sh +14 -0
  38. package/deploy/dd-cyberia/deploy.sh +6 -26
  39. package/deploy/dd-cyberia/init.sh +35 -43
  40. package/deploy/dd-cyberia/package.sh +17 -0
  41. package/deploy/dd-cyberia/state.sh +14 -0
  42. package/deploy/dd-cyberia/sync-deploy.sh +92 -170
  43. package/deploy/lib/github-actions-logging.sh +594 -0
  44. package/deploy/lib/host.sh +185 -0
  45. package/deploy/lib/state.sh +62 -0
  46. package/deploy/pwa-microservices-template/deploy.sh +12 -39
  47. package/deploy/release/deploy.sh +9 -39
  48. package/deployment.yaml +7 -2
  49. package/docker-compose.yml +7 -7
  50. package/examples/static-page/README.md +19 -19
  51. package/examples/static-page/ssr-components/CustomPage.js +2 -2
  52. package/hardhat/hardhat.config.js +1 -6
  53. package/hardhat/package-lock.json +101 -40
  54. package/hardhat/package.json +2 -2
  55. package/manifests/alertmanager/deployment.yaml +81 -0
  56. package/manifests/blackbox-exporter/deployment.yaml +75 -0
  57. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
  58. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
  59. package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
  60. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  61. package/manifests/grafana/deployment.yaml +26 -7
  62. package/manifests/grafana/kustomization.yaml +1 -0
  63. package/manifests/grafana/service.yaml +6 -1
  64. package/manifests/mariadb/pv.yaml +1 -0
  65. package/manifests/mongodb/statefulset.yaml +9 -2
  66. package/manifests/mysql/pv-pvc.yaml +14 -1
  67. package/manifests/postgresql/pv.yaml +12 -1
  68. package/manifests/postgresql/pvc.yaml +1 -0
  69. package/manifests/prometheus/deployment.yaml +18 -22
  70. package/package.json +83 -10
  71. package/scripts/event-monitor.sh +56 -0
  72. package/scripts/k3s-node-setup.sh +27 -14
  73. package/scripts/kubeadm-node-setup.sh +31 -11
  74. package/scripts/maas-setup.sh +8 -8
  75. package/scripts/selinux-normalize.sh +907 -0
  76. package/scripts/shutdown-machine.sh +843 -0
  77. package/scripts/test-monitor.sh +3 -3
  78. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +1 -1
  79. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +2 -2
  80. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +2 -2
  81. package/src/api/core/core.controller.js +1 -1
  82. package/src/api/core/core.router.js +2 -2
  83. package/src/api/core/core.service.js +2 -2
  84. package/src/api/crypto/crypto.controller.js +1 -1
  85. package/src/api/crypto/crypto.service.js +1 -1
  86. package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
  87. package/src/api/cyberia-action/cyberia-action.router.js +1 -1
  88. package/src/api/cyberia-action/cyberia-action.service.js +2 -2
  89. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -1
  90. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +1 -1
  91. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +2 -2
  92. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
  93. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
  94. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
  95. package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
  96. package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
  97. package/src/api/cyberia-entity/cyberia-entity.service.js +2 -2
  98. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +1 -1
  99. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +1 -1
  100. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +2 -2
  101. package/src/api/cyberia-instance/cyberia-fallback-capture.js +466 -0
  102. package/src/api/cyberia-instance/cyberia-fallback-world.js +8 -0
  103. package/src/api/cyberia-instance/cyberia-instance-map.service.js +1 -1
  104. package/src/api/cyberia-instance/cyberia-instance.controller.js +1 -1
  105. package/src/api/cyberia-instance/cyberia-instance.router.js +2 -2
  106. package/src/api/cyberia-instance/cyberia-instance.service.js +2 -2
  107. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
  108. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
  109. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +2 -2
  110. package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
  111. package/src/api/cyberia-map/cyberia-map.router.js +1 -1
  112. package/src/api/cyberia-map/cyberia-map.service.js +2 -2
  113. package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
  114. package/src/api/cyberia-quest/cyberia-quest.router.js +1 -1
  115. package/src/api/cyberia-quest/cyberia-quest.service.js +2 -2
  116. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
  117. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
  118. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
  119. package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
  120. package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
  121. package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
  122. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +0 -26
  123. package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
  124. package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
  125. package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
  126. package/src/api/default/default.controller.js +1 -1
  127. package/src/api/default/default.router.js +1 -1
  128. package/src/api/default/default.service.js +2 -2
  129. package/src/api/document/document.controller.js +1 -1
  130. package/src/api/document/document.router.js +1 -1
  131. package/src/api/document/document.service.js +2 -2
  132. package/src/api/file/file.controller.js +1 -1
  133. package/src/api/file/file.router.js +1 -1
  134. package/src/api/file/file.service.js +2 -2
  135. package/src/api/instance/instance.controller.js +1 -1
  136. package/src/api/instance/instance.router.js +1 -1
  137. package/src/api/instance/instance.service.js +2 -2
  138. package/src/api/ipfs/ipfs.controller.js +1 -1
  139. package/src/api/ipfs/ipfs.router.js +2 -2
  140. package/src/api/ipfs/ipfs.service.js +2 -2
  141. package/src/api/object-layer/object-layer.controller.js +1 -1
  142. package/src/api/object-layer/object-layer.router.js +2 -2
  143. package/src/api/object-layer/object-layer.service.js +3 -3
  144. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
  145. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
  146. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
  147. package/src/api/test/test.controller.js +1 -1
  148. package/src/api/test/test.service.js +1 -1
  149. package/src/api/user/guest.service.js +3 -3
  150. package/src/api/user/user.controller.js +1 -1
  151. package/src/api/user/user.router.js +2 -2
  152. package/src/api/user/user.service.js +4 -4
  153. package/src/api.js +5 -9
  154. package/src/cli/app.js +391 -0
  155. package/src/cli/baremetal.js +30 -35
  156. package/src/cli/client.js +306 -0
  157. package/src/cli/cloud-init.js +3 -3
  158. package/src/cli/cluster.js +184 -82
  159. package/src/cli/db.js +120 -68
  160. package/src/cli/deploy.js +153 -71
  161. package/src/cli/docker-compose.js +5 -5
  162. package/src/cli/domains.js +184 -0
  163. package/src/cli/dotenv-store.js +143 -0
  164. package/src/cli/event.js +2281 -0
  165. package/src/cli/fs.js +3 -3
  166. package/src/cli/host.js +672 -0
  167. package/src/cli/image.js +4 -6
  168. package/src/cli/index.js +322 -142
  169. package/src/cli/ipfs.js +34 -30
  170. package/src/cli/kickstart.js +1 -1
  171. package/src/cli/kubectl.js +218 -41
  172. package/src/cli/lxd.js +3 -3
  173. package/src/cli/monitor.js +1359 -26
  174. package/src/cli/package.js +90 -0
  175. package/src/cli/release.js +16 -12
  176. package/src/cli/repository.js +558 -363
  177. package/src/cli/run.js +331 -650
  178. package/src/cli/secrets.js +2158 -964
  179. package/src/cli/ssh.js +478 -279
  180. package/src/cli/state.js +394 -0
  181. package/src/cli/static.js +2 -2
  182. package/src/cli/system.js +1 -1
  183. package/src/cli/test.js +199 -125
  184. package/src/cli/vultr.js +61 -21
  185. package/src/cli/wireguard.js +1111 -306
  186. package/src/client/components/core/CalendarCore.js +53 -96
  187. package/src/client/components/core/Docs.js +258 -211
  188. package/src/client/components/core/FileExplorer.js +0 -21
  189. package/src/client/components/core/PanelForm.js +4 -4
  190. package/src/client/components/core/Repository.js +56 -0
  191. package/src/client/components/core/Translate.js +7 -0
  192. package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
  193. package/src/client/components/core/Wallet.js +0 -11
  194. package/src/client/components/core/Worker.js +7 -1
  195. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
  196. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -1
  197. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
  198. package/src/client/components/default/AppShellDefault.js +1 -1
  199. package/src/client/components/default/SettingsDefault.js +2 -2
  200. package/src/client/components/itemledger/SettingsItemledger.js +2 -2
  201. package/src/client/components/underpost/AppShellUnderpost.js +3 -2
  202. package/src/client/components/underpost/SettingsUnderpost.js +2 -2
  203. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +32 -5
  204. package/src/client/public/cyberia-docs/CYBERIA.md +21 -1
  205. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
  206. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  207. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  208. package/src/client/public/default/android-chrome-144x144.png +0 -0
  209. package/src/client/public/default/android-chrome-192x192.png +0 -0
  210. package/src/client/public/default/android-chrome-256x256.png +0 -0
  211. package/src/client/public/default/android-chrome-36x36.png +0 -0
  212. package/src/client/public/default/android-chrome-384x384.png +0 -0
  213. package/src/client/public/default/android-chrome-48x48.png +0 -0
  214. package/src/client/public/default/android-chrome-512x512.png +0 -0
  215. package/src/client/public/default/android-chrome-72x72.png +0 -0
  216. package/src/client/public/default/android-chrome-96x96.png +0 -0
  217. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  218. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  219. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  220. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  221. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  222. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  223. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  224. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  225. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  226. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  227. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  228. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  229. package/src/client/public/default/apple-touch-icon.png +0 -0
  230. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  231. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  232. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  233. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  234. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  235. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  236. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  237. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  238. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  239. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  240. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  241. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  242. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  243. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  244. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  245. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  246. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  247. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  248. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  249. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  250. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  251. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  252. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  253. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  254. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  255. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  256. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  257. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  258. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  259. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  260. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  261. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  262. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  263. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  264. package/src/client/public/default/assets/background/white.jpg +0 -0
  265. package/src/client/public/default/browserconfig.xml +1 -1
  266. package/src/client/public/default/favicon-16x16.png +0 -0
  267. package/src/client/public/default/favicon-32x32.png +0 -0
  268. package/src/client/public/default/favicon-48x48.png +0 -0
  269. package/src/client/public/default/favicon.ico +0 -0
  270. package/src/client/public/default/manifest.webmanifest +5 -5
  271. package/src/client/public/default/mstile-144x144.png +0 -0
  272. package/src/client/public/default/mstile-150x150.png +0 -0
  273. package/src/client/public/default/mstile-310x150.png +0 -0
  274. package/src/client/public/default/mstile-310x310.png +0 -0
  275. package/src/client/public/default/mstile-70x70.png +0 -0
  276. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  277. package/src/client/public/default/yandex-browser-manifest.json +1 -1
  278. package/src/client/ssr/RootDocument.js +1 -1
  279. package/src/client/ssr/body/404.js +1 -1
  280. package/src/client/ssr/body/500.js +1 -1
  281. package/src/client/ssr/body/CacheControl.js +1 -1
  282. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
  283. package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
  284. package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
  285. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
  286. package/src/client/ssr/head/CryptokoynScripts.js +1 -1
  287. package/src/client/ssr/head/Css.js +1 -1
  288. package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
  289. package/src/client/ssr/head/DefaultScripts.js +1 -1
  290. package/src/client/ssr/head/ItemledgerScripts.js +1 -1
  291. package/src/client/ssr/head/Microdata.js +1 -1
  292. package/src/client/ssr/head/Production.js +1 -1
  293. package/src/client/ssr/head/Pwa.js +1 -1
  294. package/src/client/ssr/head/PwaItemledger.js +1 -1
  295. package/src/client/ssr/head/Seo.js +1 -1
  296. package/src/client/ssr/head/UnderpostScripts.js +1 -1
  297. package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
  298. package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
  299. package/src/client/ssr/views/Cyberia404.js +7 -5
  300. package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
  301. package/src/client/ssr/views/Maintenance.js +1 -1
  302. package/src/client/ssr/views/NoNetworkConnection.js +1 -1
  303. package/src/client/ssr/views/Test.js +1 -1
  304. package/src/client/sw/core.sw.js +20 -14
  305. package/src/client-builder/client-build-docs.js +61 -46
  306. package/src/client-builder/client-build-live.js +2 -2
  307. package/src/client-builder/client-build.js +38 -30
  308. package/src/client-builder/client-dev-server.js +3 -3
  309. package/src/client-builder/client-icons.js +2 -2
  310. package/src/client-builder/ssr.js +3 -3
  311. package/src/client.build.js +3 -6
  312. package/src/client.dev.js +3 -6
  313. package/src/db/DataBaseProvider.js +186 -3
  314. package/src/db/mariadb/MariaDB.js +3 -2
  315. package/src/db/mongo/MongoBootstrap.js +273 -101
  316. package/src/db/mongo/MongooseDB.js +7 -8
  317. package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
  318. package/src/grpc/cyberia/grpc-server.js +1 -1
  319. package/src/index.js +79 -23
  320. package/src/mailer/EmailRender.js +2 -2
  321. package/src/mailer/MailerInterceptor.js +87 -0
  322. package/src/mailer/MailerProvider.js +50 -6
  323. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +1 -1
  324. package/src/projects/cyberia/besu-genesis-generator.js +3 -3
  325. package/src/projects/cyberia/catalog-cyberia.js +53 -10
  326. package/src/projects/cyberia/gemini-client.js +1 -1
  327. package/src/projects/cyberia/generate-saga.js +1 -1
  328. package/src/projects/cyberia/hot-reload-trigger.js +1 -1
  329. package/src/projects/cyberia/instance-data.js +1 -1
  330. package/src/projects/cyberia/ipfs-client.js +4 -4
  331. package/src/projects/cyberia/map-preview-generator.js +1 -1
  332. package/src/projects/cyberia/object-layer.js +1 -1
  333. package/src/projects/cyberia/semantic-layer-generator.js +1 -1
  334. package/src/projects/underpost/catalog-underpost.js +9 -1
  335. package/src/proxy.js +4 -7
  336. package/src/runtime/cyberia-client/Dockerfile +9 -4
  337. package/src/runtime/cyberia-client/Dockerfile.dev +8 -2
  338. package/src/runtime/cyberia-server/Dockerfile +9 -4
  339. package/src/runtime/cyberia-server/Dockerfile.dev +8 -2
  340. package/src/runtime/engine-cyberia/Dockerfile +25 -9
  341. package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
  342. package/src/runtime/engine-cyberia/Dockerfile.test +4 -4
  343. package/src/runtime/engine-cyberia/docker-compose.yml +7 -7
  344. package/src/runtime/express/Express.js +32 -27
  345. package/src/runtime/lampp/Lampp.js +22 -70
  346. package/src/runtime/nginx/Nginx.js +1 -1
  347. package/src/runtime/wp/Wp.js +16 -48
  348. package/src/server/{catalog.js → build/catalog.js} +15 -5
  349. package/src/server/build/coverage.js +117 -0
  350. package/src/server/build/execution.js +402 -0
  351. package/src/server/build/package.js +465 -0
  352. package/src/server/build/testing.js +528 -0
  353. package/src/server/{dns.js → network/dns.js} +144 -11
  354. package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
  355. package/src/server/{middlewares.js → network/middlewares.js} +3 -3
  356. package/src/server/network/node-capability.js +98 -0
  357. package/src/server/{peer.js → network/peer.js} +3 -3
  358. package/src/server/{proxy.js → network/proxy.js} +7 -13
  359. package/src/server/network/router.js +356 -0
  360. package/src/server/{tls.js → network/tls.js} +2 -2
  361. package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
  362. package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
  363. package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
  364. package/src/server/{cri.js → ops/cri.js} +2 -2
  365. package/src/server/{cron.js → ops/cron.js} +349 -74
  366. package/src/server/ops/event-notification.js +284 -0
  367. package/src/server/{logger.js → ops/logger.js} +108 -23
  368. package/src/server/ops/monitoring.js +1724 -0
  369. package/src/server/{systemd.js → ops/systemd.js} +55 -1
  370. package/src/server/{conf.js → runtime/conf.js} +513 -422
  371. package/src/server/runtime/config-scope.js +215 -0
  372. package/src/server/runtime/environment.js +149 -0
  373. package/src/server/{process.js → runtime/process.js} +153 -12
  374. package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
  375. package/src/server/{runtime.js → runtime/runtime.js} +12 -8
  376. package/src/server/{start.js → runtime/start.js} +128 -39
  377. package/src/server/{auth.js → security/auth.js} +7 -8
  378. package/src/server/security/container-storage.js +382 -0
  379. package/src/server/{crypto.js → security/crypto.js} +1 -1
  380. package/src/server/{selinux.js → security/selinux.js} +1 -1
  381. package/src/server/{backup.js → storage/backup.js} +17 -8
  382. package/src/server/{data-query.js → storage/data-query.js} +1 -1
  383. package/src/server/{downloader.js → storage/downloader.js} +2 -2
  384. package/src/server/storage/repository.js +68 -0
  385. package/src/server.js +4 -7
  386. package/src/ws/IoInterface.js +1 -1
  387. package/src/ws/IoServer.js +1 -1
  388. package/src/ws/core/core.ws.connection.js +1 -1
  389. package/src/ws/core/core.ws.emit.js +1 -1
  390. package/src/ws/core/core.ws.server.js +1 -1
  391. package/src/ws/default/default.ws.connection.js +1 -1
  392. package/src/ws/default/default.ws.emit.js +1 -1
  393. package/src/ws/default/default.ws.server.js +1 -1
  394. package/test/e2e/event-e2e-public-ingress-down.js +45 -0
  395. package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
  396. package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
  397. package/test/{api.test.js → integration/app/api.test.js} +33 -14
  398. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +30 -0
  399. package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +1 -1
  400. package/test/integration/app/cyberia/cyberia-load.test.js +467 -0
  401. package/test/integration/app/cyberia/fallback-world-capture.test.js +253 -0
  402. package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
  403. package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
  404. package/test/integration/infra/1-security/config-scope.test.js +305 -0
  405. package/test/integration/infra/1-security/container-storage.test.js +356 -0
  406. package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
  407. package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
  408. package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
  409. package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
  410. package/test/integration/infra/1-security/systemd-service.test.js +70 -0
  411. package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
  412. package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
  413. package/test/integration/infra/2-network/node-capability.test.js +182 -0
  414. package/test/integration/infra/2-network/wireguard-cli.test.js +1163 -0
  415. package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +609 -55
  416. package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
  417. package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
  418. package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
  419. package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
  420. package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
  421. package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
  422. package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
  423. package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
  424. package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
  425. package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
  426. package/test/integration/infra/5-observability/event-notification.test.js +197 -0
  427. package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
  428. package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
  429. package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
  430. package/test/support/shell-harness.js +73 -0
  431. package/test/unit/build-template.test.js +97 -0
  432. package/test/unit/build-workflow-offline.test.js +132 -0
  433. package/test/unit/catalog.test.js +71 -0
  434. package/test/unit/client-build-docs.test.js +334 -0
  435. package/test/unit/conf-loading.test.js +303 -0
  436. package/test/unit/conf-resolution.test.js +979 -0
  437. package/test/unit/coverage-artifact.test.js +130 -0
  438. package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
  439. package/test/unit/deploy-env-resolution.test.js +38 -0
  440. package/test/unit/deploy-log-table.test.js +447 -0
  441. package/test/unit/execution-profiles.test.js +219 -0
  442. package/test/unit/fleet-sync-source.test.js +149 -0
  443. package/test/unit/logger-redaction.test.js +112 -0
  444. package/test/unit/package.test.js +403 -0
  445. package/test/unit/prepare-host.test.js +299 -0
  446. package/test/unit/process-environment.test.js +18 -0
  447. package/test/unit/propagation-message.test.js +78 -0
  448. package/test/unit/redeploy-plan.test.js +24 -0
  449. package/test/unit/release-bump.test.js +474 -0
  450. package/test/unit/ssh-output-redaction.test.js +28 -0
  451. package/test/unit/start-options.test.js +46 -0
  452. package/test/unit/test-tiers.test.js +193 -0
  453. package/vitest.config.js +58 -0
  454. package/.nycrc +0 -9
  455. package/deploy/lib/logging.sh +0 -96
  456. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
  457. package/manifests/mongodb/pv-pvc.yaml +0 -59
  458. package/scripts/coverall-test-cyberia.sh +0 -24
  459. package/scripts/coverall-test.sh +0 -24
  460. package/scripts/link-local-underpost-cli.sh +0 -6
  461. package/src/api/user/user.build.js +0 -16
  462. package/src/cli/env.js +0 -177
  463. package/src/client/components/core/Blockchain.js +0 -41
  464. package/src/client/components/core/Blog.js +0 -9
  465. package/src/client/components/core/KeyboardAvoidance.js +0 -145
  466. package/src/client/public/default/assets/background/dark.jpg +0 -0
  467. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  468. package/src/client/public/default/assets/background/white0.jpg +0 -0
  469. package/src/client/public/doc/favicon.ico +0 -0
  470. package/src/client/public/doc/sitemap +0 -148
  471. package/src/server/environment.js +0 -98
package/bin/index.js CHANGED
@@ -13,11 +13,17 @@ import dotenv from 'dotenv';
13
13
  import { Command } from 'commander';
14
14
  import fs from 'fs-extra';
15
15
  import stringify from 'fast-json-stable-stringify';
16
- import { shellExec } from '../src/server/process.js';
17
- import { loggerFactory } from '../src/server/logger.js';
16
+ import { shellExec } from '../src/server/runtime/process.js';
17
+ import { cli } from '../src/server/build/execution.js';
18
+ import { loggerFactory } from '../src/server/ops/logger.js';
18
19
  import { generateBesuManifests, deployBesu, removeBesu } from '../src/projects/cyberia/besu-genesis-generator.js';
19
20
  import { DataBaseProviderService } from '../src/db/DataBaseProvider.js';
20
- import { etcHostFactory, loadConfServerJson, normalizeInstanceTopology } from '../src/server/conf.js';
21
+ import {
22
+ deployEnvFilePath,
23
+ etcHostFactory,
24
+ loadConfServerJson,
25
+ normalizeInstanceTopology,
26
+ } from '../src/server/runtime/conf.js';
21
27
  import {
22
28
  ObjectLayerEngine,
23
29
  resolveCanonicalCid,
@@ -46,16 +52,22 @@ import {
46
52
  DefaultCyberiaQuests,
47
53
  ENTITY_TYPE_DEFAULTS,
48
54
  fillInstanceConfDefaults,
49
- DOCKER_SCRIPTS,
50
- CyberiaDependencies,
51
55
  } from '../src/api/cyberia-server-defaults/cyberia-server-defaults.js';
56
+ import cyberiaCatalog from '../src/projects/cyberia/catalog-cyberia.js';
52
57
 
53
58
  import {
54
59
  DEFAULT_INSTANCE_CODE,
55
60
  ITEM_TYPES as itemTypes,
56
61
  DefaultCyberiaItems,
57
62
  } from '../src/client/components/cyberia/SharedDefaultsCyberia.js';
58
- import { loadDeployCatalog } from '../src/server/catalog.js';
63
+ import { loadDeployCatalog } from '../src/server/build/catalog.js';
64
+ import {
65
+ DEPLOY_MANIFEST_INDENT,
66
+ STAGED_CLI_PACKAGE,
67
+ buildDeployPackageJson,
68
+ deployPackagePathFactory,
69
+ stageCliPackage,
70
+ } from '../src/server/build/package.js';
59
71
 
60
72
  /**
61
73
  * Connect to the project MongoDB instance using the standard env / conf layout.
@@ -366,7 +378,7 @@ try {
366
378
  `IPFS cleanup: ${unpinCount}/${cidsToUnpin.size} CIDs unpinned, ${mfsCount}/${itemIdsToClean.size} MFS paths removed`,
367
379
  );
368
380
  if (options.gitClean) {
369
- shellExec(`cd src/client/public/cyberia && underpost run clean .`);
381
+ shellExec(`cd src/client/public/cyberia && ${cli()} run clean .`);
370
382
  logger.info('Asset directory cleaned');
371
383
  }
372
384
 
@@ -1721,6 +1733,18 @@ try {
1721
1733
  'When used with --export or --import, only process cyberia-instance.json and cyberia-instance-conf.json',
1722
1734
  )
1723
1735
  .option('--drop', 'Drop all documents associated with the instance code before importing or as a standalone action')
1736
+ .option(
1737
+ '--export-current-fallbackworld',
1738
+ 'Capture the in-memory procedural fallback world as instance [instance-code]: materialize it into MongoDB (maps, conf, actions, quests, missing content defaults) and then export it',
1739
+ )
1740
+ .option(
1741
+ '--keep-fallback-codes',
1742
+ 'With --export-current-fallbackworld, keep the raw fallback-map-* / canonical action-quest codes instead of namespacing them under the instance code',
1743
+ )
1744
+ .option(
1745
+ '--fallback-url <url>',
1746
+ 'With --export-current-fallbackworld, capture the world a running engine currently serves (e.g. http://localhost:4001) instead of regenerating it locally',
1747
+ )
1724
1748
  .option('--env-path <env-path>', 'Env path e.g. ./engine-private/conf/dd-cyberia/.env.development')
1725
1749
  .option('--mongo-host <mongo-host>', 'Mongo host override')
1726
1750
  .option('--dev', 'Force development environment')
@@ -1735,16 +1759,40 @@ try {
1735
1759
  .description('Export/import a Cyberia instance with all related maps, entities and object layers')
1736
1760
  .action(async (instanceCode, options = {}) => {
1737
1761
  if (options.revert) {
1738
- shellExec(`cd /home/dd/cyberia-instances && underpost cmt . reset && underpost run clean .`);
1739
- shellExec(`cd /home/dd/engine/cyberia-server && underpost cmt . reset && underpost run clean .`);
1740
- shellExec(`cd /home/dd/engine/cyberia-client && underpost cmt . reset && underpost run clean .`);
1762
+ Underpost.repo.declareSafeDirectory('/home/dd/cyberia-instances');
1763
+ shellExec(`cd /home/dd/cyberia-instances && ${cli()} cmt . reset && ${cli()} run clean .`);
1764
+ shellExec(`cd /home/dd/engine/cyberia-server && ${cli()} cmt . reset && ${cli()} run clean .`);
1765
+ shellExec(`cd /home/dd/engine/cyberia-client && ${cli()} cmt . reset && ${cli()} run clean .`);
1741
1766
  return;
1742
1767
  }
1768
+ if (options.exportCurrentFallbackworld) {
1769
+ // A capture writes one named instance: no default list, no import in the
1770
+ // same run, and never the reserved code the in-memory world itself uses.
1771
+ if (!instanceCode || instanceCode.includes(',')) {
1772
+ logger.error('--export-current-fallbackworld requires a single [instance-code] to capture the world under');
1773
+ process.exit(1);
1774
+ }
1775
+ if (instanceCode === 'fallback') {
1776
+ logger.error('"fallback" is reserved for the in-memory world — capture it under a different instance code');
1777
+ process.exit(1);
1778
+ }
1779
+ if (options.import !== undefined) {
1780
+ logger.error('--export-current-fallbackworld cannot be combined with --import');
1781
+ process.exit(1);
1782
+ }
1783
+ }
1784
+
1743
1785
  if (!instanceCode) {
1744
- instanceCode = 'amethyst-strata-expansion,FOREST';
1786
+ instanceCode = 'amethyst-strata-expansion,FOREST,TEST';
1745
1787
  logger.warn(`No instance code provided, defaulting to: ${instanceCode}`);
1746
1788
  }
1747
1789
 
1790
+ // An explicitly named env must exist: falling through to the ambient `./.env` resolves the
1791
+ // instance against whatever deployment was loaded last, which is not the one the caller named.
1792
+ if (options.envPath && !fs.existsSync(options.envPath)) {
1793
+ logger.error(`Env file not found: ${options.envPath}`);
1794
+ process.exit(1);
1795
+ }
1748
1796
  if (!options.envPath) options.envPath = `./.env`;
1749
1797
  if (fs.existsSync(options.envPath)) dotenv.config({ path: options.envPath, override: true });
1750
1798
 
@@ -1766,12 +1814,15 @@ try {
1766
1814
  }
1767
1815
 
1768
1816
  if (options.publish || options.publishBuild || options.publishRemove) {
1817
+ // The instances checkout is cloned by the deploy user and driven by root during a deploy,
1818
+ // and git refuses to touch a tree owned by someone else until it is declared safe.
1819
+ Underpost.repo.declareSafeDirectory('/home/dd/cyberia-instances');
1769
1820
  if (options.publishBuild) {
1770
1821
  if (!fs.existsSync('/home/dd/cyberia-instances')) {
1771
- shellExec('cd /home/dd && underpost clone underpostnet/cyberia-instances');
1822
+ shellExec(`cd /home/dd && ${cli()} clone underpostnet/cyberia-instances`);
1772
1823
  } else {
1773
- shellExec(`underpost run clean /home/dd/cyberia-instances`);
1774
- shellExec(`cd /home/dd/cyberia-instances && underpost pull . underpostnet/cyberia-instances`, {
1824
+ shellExec(`${cli()} run clean /home/dd/cyberia-instances`);
1825
+ shellExec(`cd /home/dd/cyberia-instances && ${cli()} pull . underpostnet/cyberia-instances`, {
1775
1826
  silentOnError: true,
1776
1827
  });
1777
1828
  }
@@ -1798,40 +1849,24 @@ try {
1798
1849
  `/home/dd/cyberia-instances/conf/dd-cyberia/conf.volume.json`,
1799
1850
  );
1800
1851
  {
1801
- const catalog = await loadDeployCatalog('dd-cyberia');
1802
- fs.copyFileSync(
1803
- `./engine-private/conf/dd-cyberia/package.json`,
1804
- `/home/dd/cyberia-instances/conf/dd-cyberia/package.json`,
1805
- );
1806
- const originPackageJson = JSON.parse(
1807
- fs.readFileSync(`./engine-private/conf/dd-cyberia/package.json`, 'utf-8'),
1808
- );
1809
- const scriptsOrigin = originPackageJson.scripts;
1810
- const scriptsTarget = JSON.parse(fs.readFileSync(`./package.json`, 'utf-8')).scripts;
1811
- originPackageJson.name = 'cyberia';
1812
- originPackageJson.bin = {
1813
- cyberia: 'bin/index.js',
1814
- };
1815
- originPackageJson.keywords = catalog.keywords;
1816
- originPackageJson.description = catalog.description;
1852
+ // The published manifest is the deploy's, under the product's own identity — one
1853
+ // builder for every generated package.json in the project, so the instances repo
1854
+ // cannot drift from what the deploy and the product CLI declare.
1855
+ const deployPackagePath = deployPackagePathFactory('dd-cyberia');
1817
1856
  fs.writeFileSync(
1818
1857
  `/home/dd/cyberia-instances/conf/dd-cyberia/package.json`,
1819
- JSON.stringify(
1820
- {
1821
- ...originPackageJson,
1822
- scripts: {
1823
- ...scriptsTarget,
1824
- start: scriptsOrigin.start,
1825
- ...DOCKER_SCRIPTS,
1826
- },
1827
- dependencies: {
1828
- ...originPackageJson.dependencies,
1829
- ...CyberiaDependencies,
1830
- },
1831
- },
1858
+ `${JSON.stringify(
1859
+ buildDeployPackageJson({
1860
+ deployId: 'dd-cyberia',
1861
+ enginePackageJson: JSON.parse(fs.readFileSync(`./package.json`, 'utf-8')),
1862
+ catalog: await loadDeployCatalog('dd-cyberia'),
1863
+ currentPackageJson: JSON.parse(fs.readFileSync(deployPackagePath, 'utf-8')),
1864
+ productIdentity: true,
1865
+ }),
1832
1866
  null,
1833
- 2,
1834
- ),
1867
+ DEPLOY_MANIFEST_INDENT,
1868
+ )}\n`,
1869
+ 'utf8',
1835
1870
  );
1836
1871
  }
1837
1872
  fs.copyFileSync(
@@ -1848,7 +1883,11 @@ try {
1848
1883
  );
1849
1884
 
1850
1885
  fs.mkdirpSync(`/home/dd/cyberia-instances/deployments`);
1851
- fs.copySync(`./src/runtime/engine-cyberia`, `/home/dd/cyberia-instances/deployments/engine-cyberia`);
1886
+ // The staged CLI package is a local image-build artifact, not a deployment manifest —
1887
+ // it must never be published into the instances repository.
1888
+ fs.copySync(`./src/runtime/engine-cyberia`, `/home/dd/cyberia-instances/deployments/engine-cyberia`, {
1889
+ filter: (src) => nodePath.basename(src) !== STAGED_CLI_PACKAGE,
1890
+ });
1852
1891
  fs.copySync(
1853
1892
  `./manifests/deployment/dd-cyberia-development/.`,
1854
1893
  `/home/dd/cyberia-instances/deployments/engine-cyberia/.`,
@@ -1863,32 +1902,8 @@ try {
1863
1902
  `./engine-private/conf/dd-cyberia/instances/mmo-server/build/development/.`,
1864
1903
  `/home/dd/cyberia-instances/deployments/cyberia-server/.`,
1865
1904
  );
1866
- fs.removeSync(`/home/dd/cyberia-instances/public/cyberia`);
1867
- fs.mkdirpSync(`/home/dd/cyberia-instances/public/cyberia`);
1868
- for (const assetPath of Object.keys(
1869
- JSON.parse(fs.readFileSync(`./engine-private/conf/dd-cyberia/storage.engine-cyberia.json`, 'utf-8')),
1870
- )) {
1871
- const relativePath = assetPath.replace(/^src\/client\/public\/cyberia\//, '');
1872
- const targetPath = `/home/dd/cyberia-instances/public/cyberia/${relativePath}`;
1873
- fs.mkdirpSync(nodePath.dirname(targetPath));
1874
- logger.info(`Copying asset: ${assetPath} → ${targetPath}`);
1875
- fs.copySync(`./${assetPath}`, targetPath);
1876
- }
1877
-
1878
- // Copy default-items asset folders (src/client/public/cyberia/assets/<type>/<id>/ → public/cyberia/assets/<type>/<id>/)
1879
- for (const entry of DefaultCyberiaItems) {
1880
- const { id, type } = entry.item;
1881
- const srcDir = `src/client/public/cyberia/assets/${type}/${id}`;
1882
- const targetDir = `/home/dd/cyberia-instances/public/cyberia/assets/${type}/${id}`;
1883
- if (fs.existsSync(srcDir)) {
1884
- fs.mkdirpSync(nodePath.dirname(targetDir));
1885
- logger.info(`Copying default-item asset: ${srcDir} → ${targetDir}`);
1886
- fs.copySync(srcDir, targetDir);
1887
- } else {
1888
- logger.warn(`Default-item asset directory not found, skipping: ${srcDir}`);
1889
- }
1890
- }
1891
-
1905
+ // fs.removeSync(`/home/dd/cyberia-instances/public/cyberia`);
1906
+ // fs.mkdirpSync(`/home/dd/cyberia-instances/public/cyberia`);
1892
1907
  fs.mkdirpSync(`/home/dd/cyberia-instances/instances`);
1893
1908
  fs.mkdirpSync(`/home/dd/cyberia-instances/sagas`);
1894
1909
  for (const _instanceCode of instanceCode.split(',')) {
@@ -1945,7 +1960,7 @@ try {
1945
1960
  shellExec(`rm -rf /home/dd/cyberia-instances/sagas/${instanceCode}.json`);
1946
1961
  return;
1947
1962
  }
1948
- shellExec(`cd /home/dd/cyberia-instances && underpost push . underpostnet/cyberia-instances`);
1963
+ shellExec(`cd /home/dd/cyberia-instances && ${cli()} push . underpostnet/cyberia-instances`);
1949
1964
  return;
1950
1965
  }
1951
1966
 
@@ -2124,6 +2139,89 @@ try {
2124
2139
  }
2125
2140
  };
2126
2141
 
2142
+ // ── CAPTURE CURRENT FALLBACK WORLD ──────────────────────────────
2143
+ //
2144
+ // The procedural fallback world only exists in engine memory (see
2145
+ // cyberia-fallback-world.js): it is rebuilt from code defaults on every
2146
+ // boot and intercepts any service that asks for an absent instance.
2147
+ // Capturing writes that exact world into MongoDB under [instance-code] —
2148
+ // together with the content collections the fallback path serves from
2149
+ // code defaults rather than the DB — so the export below can back it up
2150
+ // and `--import` can restore it as an ordinary persisted instance.
2151
+ if (options.exportCurrentFallbackworld) {
2152
+ const { generateFallbackWorld } = await import('../src/api/cyberia-instance/cyberia-fallback-world.js');
2153
+ const { captureFallbackWorld } = await import('../src/api/cyberia-instance/cyberia-fallback-capture.js');
2154
+
2155
+ let world;
2156
+ if (options.fallbackUrl) {
2157
+ // Staged fallback default items live only in the serving engine
2158
+ // process, so a faithful capture of a live world must read it back
2159
+ // over REST instead of regenerating it here.
2160
+ const base = options.fallbackUrl.replace(/\/+$/, '');
2161
+ const worldUrl = base.includes('/fallback-world') ? base : `${base}/api/cyberia-instance/fallback-world`;
2162
+ logger.info('Fetching live fallback world', { url: worldUrl });
2163
+ const response = await fetch(worldUrl);
2164
+ if (!response.ok) {
2165
+ logger.error(`Fallback world fetch failed: ${response.status} ${response.statusText}`, { url: worldUrl });
2166
+ await DataBaseProviderService.getProvider({ host, path }, 'mongoose').close();
2167
+ process.exit(1);
2168
+ }
2169
+ const payload = await response.json();
2170
+ world = payload?.data ?? payload;
2171
+ } else {
2172
+ world = generateFallbackWorld();
2173
+ }
2174
+
2175
+ if (!world?.instance || !Array.isArray(world.maps) || world.maps.length === 0) {
2176
+ logger.error('Fallback world payload has no maps — nothing to capture');
2177
+ await DataBaseProviderService.getProvider({ host, path }, 'mongoose').close();
2178
+ process.exit(1);
2179
+ }
2180
+
2181
+ const capture = await captureFallbackWorld({
2182
+ models: {
2183
+ CyberiaInstance,
2184
+ CyberiaInstanceConf,
2185
+ CyberiaMap,
2186
+ CyberiaAction,
2187
+ CyberiaQuest,
2188
+ CyberiaSkill,
2189
+ CyberiaEntityTypeDefault,
2190
+ CyberiaDialogue,
2191
+ ObjectLayer,
2192
+ },
2193
+ world,
2194
+ instanceCode,
2195
+ keepFallbackCodes: !!options.keepFallbackCodes,
2196
+ });
2197
+
2198
+ // Sprites are the one thing a capture cannot synthesise: without their
2199
+ // ObjectLayer documents the backup would export atlas-less items and
2200
+ // the restored world would render solid-colour rectangles.
2201
+ if (capture.missingObjectLayerItemIds.length > 0) {
2202
+ logger.error(
2203
+ `Capture aborted: ${capture.missingObjectLayerItemIds.length} referenced item id(s) have no ObjectLayer in MongoDB:`,
2204
+ capture.missingObjectLayerItemIds.join(', '),
2205
+ `— run \`node bin/cyberia ol ${capture.missingObjectLayerItemIds.join(' ')} --import\` (or ` +
2206
+ '`node bin/cyberia run-workflow import-default-items`) first.',
2207
+ );
2208
+ await DataBaseProviderService.getProvider({ host, path }, 'mongoose').close();
2209
+ process.exit(1);
2210
+ }
2211
+
2212
+ logger.info('Captured fallback world into MongoDB', {
2213
+ code: instanceCode,
2214
+ mapCodes: capture.plan.instance.cyberiaMapCodes,
2215
+ actions: capture.plan.actions.length,
2216
+ quests: capture.plan.quests.length,
2217
+ objectLayerItemIds: capture.plan.itemIds.length,
2218
+ });
2219
+
2220
+ // The capture is only half the command — fall through to the export so
2221
+ // it lands in ./engine-private/cyberia-instances/<instance-code>.
2222
+ if (options.export === undefined) options.export = true;
2223
+ }
2224
+
2127
2225
  // ── EXPORT ──────────────────────────────────────────────────────
2128
2226
  if (options.export !== undefined) {
2129
2227
  const instance = await CyberiaInstance.findOne({ code: instanceCode }).lean();
@@ -2295,6 +2393,37 @@ try {
2295
2393
  }
2296
2394
  }
2297
2395
 
2396
+ // 4c-bis. Add the item ids the instance's vendor / assembler / quest
2397
+ // catalogs name. The interact modal draws an icon for every shop
2398
+ // item, recipe ingredient/output and quest reward, so their atlases
2399
+ // must travel with the backup even when no map entity wears them.
2400
+ // Kept out of contentItemIds: catalogs must not widen the
2401
+ // entity-type-default match surface below.
2402
+ for (const action of actions) {
2403
+ for (const shopItem of action.shopItems || []) {
2404
+ if (shopItem.itemId) objectLayerItemIds.add(shopItem.itemId);
2405
+ if (shopItem.priceItemId) objectLayerItemIds.add(shopItem.priceItemId);
2406
+ }
2407
+ for (const recipe of action.craftRecipes || []) {
2408
+ for (const ingredient of recipe.ingredients || []) {
2409
+ if (ingredient.itemId) objectLayerItemIds.add(ingredient.itemId);
2410
+ }
2411
+ for (const output of recipe.outputItems || []) {
2412
+ if (output.itemId) objectLayerItemIds.add(output.itemId);
2413
+ }
2414
+ }
2415
+ }
2416
+ for (const quest of quests) {
2417
+ for (const step of quest.steps || []) {
2418
+ for (const objective of step.objectives || []) {
2419
+ if (objective.itemId) objectLayerItemIds.add(objective.itemId);
2420
+ }
2421
+ }
2422
+ for (const reward of quest.rewards || []) {
2423
+ if (reward.itemId) objectLayerItemIds.add(reward.itemId);
2424
+ }
2425
+ }
2426
+
2298
2427
  // 4d. Export skills whose trigger item belongs to this instance (own model:
2299
2428
  // CyberiaSkill, keyed by triggerItemId). Their summoned-entity items are
2300
2429
  // added to the OL set so those atlases export too. Runs before the
@@ -4830,16 +4959,23 @@ try {
4830
4959
  shellExec(
4831
4960
  `node bin/cyberia generate-saga --import engine-private/cyberia-sagas/${sagaCode}.json${devFlag}${mongoHostFlag}`,
4832
4961
  );
4833
- shellExec(`node bin/cyberia ol ${DefaultCyberiaItems.map((e) => e.item.id)} --import${devFlag}${mongoHostFlag}`);
4834
- shellExec(`node bin/cyberia run-workflow seed-skills${devFlag}${mongoHostFlag}`);
4835
- shellExec(`node bin/cyberia run-workflow seed-entities${devFlag}${mongoHostFlag}`);
4836
- shellExec(`node bin/cyberia run-workflow seed-dialogues${devFlag}${mongoHostFlag}`);
4837
- shellExec(`node bin/cyberia run-workflow seed-actions-quests${devFlag}${mongoHostFlag}`);
4838
- shellExec(`node bin/cyberia client-hints ${instanceHintsCode} --seed-defaults${devFlag}${mongoHostFlag}`);
4962
+ // shellExec(`node bin/cyberia ol ${DefaultCyberiaItems.map((e) => e.item.id)} --import${devFlag}${mongoHostFlag}`);
4963
+ // shellExec(`node bin/cyberia run-workflow seed-skills${devFlag}${mongoHostFlag}`);
4964
+ // shellExec(`node bin/cyberia run-workflow seed-entities${devFlag}${mongoHostFlag}`);
4965
+ // shellExec(`node bin/cyberia run-workflow seed-dialogues${devFlag}${mongoHostFlag}`);
4966
+ // shellExec(`node bin/cyberia run-workflow seed-actions-quests${devFlag}${mongoHostFlag}`);
4967
+ // shellExec(`node bin/cyberia client-hints ${instanceHintsCode} --seed-defaults${devFlag}${mongoHostFlag}`);
4839
4968
  shellExec(`node bin/cyberia instance ${sagaCode} --import${devFlag}`);
4840
4969
  shellExec(`node bin/cyberia instance FOREST --import${devFlag}`);
4970
+ shellExec(`node bin/cyberia instance TEST --import${devFlag}`);
4841
4971
  });
4842
4972
 
4973
+ runner
4974
+ .command('stage-cli')
4975
+ .option('--output-path <output-path>', "Build context to stage the package in (default: '.')")
4976
+ .description('Packs this engine checkout as underpost-cli.tgz for a runtime image build context')
4977
+ .action((options) => stageCliPackage(options.outputPath || '.'));
4978
+
4843
4979
  runner.command('sync-src').action(() => {
4844
4980
  fs.copyFileSync('./cyberia-server/README.md', './src/client/public/cyberia-docs/CYBERIA-SERVER.md');
4845
4981
  fs.copyFileSync('./cyberia-server/Dockerfile', './src/runtime/cyberia-server/Dockerfile');
@@ -4847,6 +4983,25 @@ try {
4847
4983
  fs.copyFileSync('./cyberia-client/Dockerfile', './src/runtime/cyberia-client/Dockerfile');
4848
4984
  });
4849
4985
 
4986
+ runner.command('setup-workspace').action(() => {
4987
+ shellExec(`node bin fs src/client/public/cyberia --git --recursive --pull --deploy-id dd-cyberia`);
4988
+ shellExec(`node bin/deploy.js cyberia`);
4989
+ if (!fs.existsSync('./cyberia-server')) shellExec(`${cli()} clone underpostnet/cyberia-server`);
4990
+ if (!fs.existsSync('./cyberia-client')) shellExec(`${cli()} clone underpostnet/cyberia-client`);
4991
+ });
4992
+
4993
+ runner.command('e2e-build').action(() => {
4994
+ shellExec(`node bin run build-cluster-deployment-manifests`);
4995
+ shellExec(`node bin/cyberia run-workflow build-manifest`);
4996
+ shellExec(`node bin/cyberia run-workflow publish --dry-run`);
4997
+ shellExec(`npm run security`);
4998
+ shellExec(`sudo rm -rf ./conf.dd*.js`);
4999
+ });
5000
+
5001
+ runner.command('cluster').action(() => {
5002
+ shellExec(`node bin run cluster --runtime-image express --deploy-id dd-cyberia --instance-id mmo-server --dev`);
5003
+ });
5004
+
4850
5005
  runner
4851
5006
  .command('dev-env')
4852
5007
  .option('--run', 'Run docker:reset, cluster --dev --reset, docker-image, and docker:up after updating compose.env')
@@ -5029,6 +5184,44 @@ try {
5029
5184
  shellExec(`gh workflow run ${id}.cd.yml -R underpostnet/${id} -f job=deploy`);
5030
5185
  });
5031
5186
 
5187
+ runner.command('cp-assets').action(() => {
5188
+ for (const assetPath of Object.keys(
5189
+ JSON.parse(fs.readFileSync(`./engine-private/conf/dd-cyberia/storage.engine-cyberia.json`, 'utf-8')),
5190
+ )) {
5191
+ const relativePath = assetPath.replace(/^src\/client\/public\/cyberia\//, '');
5192
+ const targetPath = `/home/dd/cyberia-instances/public/cyberia/${relativePath}`;
5193
+ fs.mkdirpSync(nodePath.dirname(targetPath));
5194
+ logger.info(`Copying asset: ${assetPath} → ${targetPath}`);
5195
+ fs.copySync(`./${assetPath}`, targetPath);
5196
+ }
5197
+
5198
+ // Copy default-items asset folders (src/client/public/cyberia/assets/<type>/<id>/ → public/cyberia/assets/<type>/<id>/)
5199
+ for (const entry of DefaultCyberiaItems) {
5200
+ const { id, type } = entry.item;
5201
+ const srcDir = `src/client/public/cyberia/assets/${type}/${id}`;
5202
+ const targetDir = `/home/dd/cyberia-instances/public/cyberia/assets/${type}/${id}`;
5203
+ if (fs.existsSync(srcDir)) {
5204
+ fs.mkdirpSync(nodePath.dirname(targetDir));
5205
+ logger.info(`Copying default-item asset: ${srcDir} → ${targetDir}`);
5206
+ fs.copySync(srcDir, targetDir);
5207
+ } else {
5208
+ logger.warn(`Default-item asset directory not found, skipping: ${srcDir}`);
5209
+ }
5210
+ }
5211
+ });
5212
+
5213
+ runner
5214
+ .command('sync-cluster')
5215
+ .option('--build')
5216
+ .action((options) => {
5217
+ shellExec(`node bin/build dd-cyberia --update-private`);
5218
+ shellExec(`node bin/build dd-core --update-private`);
5219
+ if (options.build) return;
5220
+ shellExec(
5221
+ `node bin wireguard --sync --repo-engine underpostnet/engine-test-cyberia --repo-engine-private underpostnet/engine-private`,
5222
+ );
5223
+ });
5224
+
5032
5225
  runner
5033
5226
  .command('test')
5034
5227
  .option('--n-con <connections>', 'Number of concurrent WebSocket connections')
@@ -5039,7 +5232,7 @@ try {
5039
5232
  CYBERIA_LOAD_CONNECTIONS=${options.nCon ?? 40} \
5040
5233
  CYBERIA_LOAD_TAP_FREQUENCY=${options.tapFreq ?? 5} \
5041
5234
  CYBERIA_LOAD_DURATION_MS=${options.duration ?? 1000 * 60 * 30} \
5042
- c8 mocha test/cyberia-load.test.js`);
5235
+ node bin test cyberia --grep 'Cyberia load'`);
5043
5236
  });
5044
5237
 
5045
5238
  runner
@@ -5049,46 +5242,49 @@ c8 mocha test/cyberia-load.test.js`);
5049
5242
  // no funca
5050
5243
  if (options.loadTar) {
5051
5244
  for (const imageId of dockerImageIds)
5052
- if (imageId === id || id === '.') shellExec(`docker load -i ./${imageId}-dev_v3.3.0.tar`);
5245
+ if (imageId === id || id === '.') shellExec(`docker load -i ./${imageId}-dev_v3.3.73.tar`);
5053
5246
  return;
5054
5247
  }
5055
5248
  switch (id) {
5056
5249
  case 'engine-cyberia':
5250
+ stageCliPackage(`./src/runtime/engine-cyberia`);
5057
5251
  shellExec(`
5058
5252
  node bin/build dd-cyberia --conf
5059
5253
  node bin/build dd-cyberia --update-private
5060
5254
  node bin image --path src/runtime/engine-cyberia \
5061
5255
  --docker-compose --pull-base --build \
5062
5256
  --dockerfile-name Dockerfile.dev \
5063
- --image-name engine-cyberia-dev:v3.3.0 \
5257
+ --image-name engine-cyberia-dev:v3.3.73 \
5064
5258
  --image-out-path .
5065
5259
  `);
5066
5260
  break;
5067
5261
 
5068
5262
  case 'cyberia-server':
5263
+ stageCliPackage(`./cyberia-server`);
5069
5264
  shellExec(`
5070
5265
  cp -f src/runtime/cyberia-server/Dockerfile.dev cyberia-server/Dockerfile.dev
5071
5266
  node bin image --path cyberia-server \
5072
5267
  --docker-compose --pull-base --build \
5073
5268
  --dockerfile-name Dockerfile.dev \
5074
- --image-name cyberia-server-dev:v3.3.0 \
5269
+ --image-name cyberia-server-dev:v3.3.73 \
5075
5270
  --image-out-path .
5076
5271
  `);
5077
5272
  break;
5078
5273
  case 'cyberia-client':
5274
+ stageCliPackage(`./cyberia-client`);
5079
5275
  shellExec(`
5080
5276
  cp -f src/runtime/cyberia-client/Dockerfile.dev cyberia-client/Dockerfile.dev
5081
5277
  node bin image --path cyberia-client \
5082
5278
  --docker-compose --pull-base --build \
5083
5279
  --dockerfile-name Dockerfile.dev \
5084
- --image-name cyberia-client-dev:v3.3.0 \
5280
+ --image-name cyberia-client-dev:v3.3.73 \
5085
5281
  --image-out-path .
5086
5282
  `);
5087
5283
  break;
5088
5284
  }
5089
5285
  });
5090
5286
 
5091
- for (const [cmd, action] of Object.entries(DOCKER_SCRIPTS))
5287
+ for (const [cmd, action] of Object.entries(cyberiaCatalog.packageScripts))
5092
5288
  runner.command(cmd).action(() => {
5093
5289
  if (cmd === 'docker:up' || cmd === 'docker:up:build' || cmd === 'docker:restart') {
5094
5290
  const { aliases, changed } = installCyberiaDockerHostAliases();
@@ -5642,12 +5838,25 @@ node bin image --path cyberia-client \
5642
5838
 
5643
5839
  // Copy canonical doc sources into the generated project READMEs.
5644
5840
  // Edit the canonical sources; never hand-edit these generated outputs.
5645
- fs.copySync('./deploy/lib', './cyberia-server/deploy/lib', { overwrite: true });
5646
- fs.copySync('./deploy/lib', './cyberia-client/deploy/lib', { overwrite: true });
5841
+ // The mirrored deploy tree is a generated artifact, rebuilt from scratch so a file
5842
+ // dropped or renamed upstream cannot linger in the published repo. It reproduces the
5843
+ // engine layout exactly — the <deploy-id> directory beside lib/ — because every deploy
5844
+ // script sources `$SCRIPT_DIR/../lib/logging.sh`, which only resolves when lib/ is the
5845
+ // script directory's sibling there too.
5846
+ for (const project of ['cyberia-client', 'cyberia-server']) {
5847
+ const scripts = `./deploy/${project}`;
5848
+ // A tree assembled before these scripts were packaged does not carry them; mirroring is
5849
+ // what publishes them, so say so and continue rather than failing the whole manifest build.
5850
+ if (!fs.existsSync(scripts)) {
5851
+ logger.warn(`[build-manifest] No deploy scripts to mirror for ${project}`, { path: scripts });
5852
+ continue;
5853
+ }
5854
+ fs.removeSync(`./${project}/deploy`);
5855
+ fs.copySync('./deploy/lib', `./${project}/deploy/lib`);
5856
+ fs.copySync(scripts, `./${project}/deploy/${project}`);
5857
+ }
5647
5858
  fs.copyFileSync('./src/client/public/cyberia-docs/CYBERIA-CLIENT.md', './cyberia-client/README.md');
5648
- fs.copySync('./deploy/cyberia-client', './cyberia-client/deploy');
5649
5859
  fs.copyFileSync('./src/client/public/cyberia-docs/CYBERIA-SERVER.md', './cyberia-server/README.md');
5650
- fs.copySync('./deploy/cyberia-server', './cyberia-server/deploy');
5651
5860
  fs.copyFileSync(
5652
5861
  './.github/workflows/cyberia-client.cd.yml',
5653
5862
  './cyberia-client/.github/workflows/cyberia-client.cd.yml',
@@ -5657,7 +5866,15 @@ node bin image --path cyberia-client \
5657
5866
  './cyberia-server/.github/workflows/cyberia-server.cd.yml',
5658
5867
  );
5659
5868
  shellExec('cp -a ./engine-private/conf/dd-cyberia/docker-compose/cyberia/. ./src/runtime/engine-cyberia/');
5660
- shellExec('node bin/cyberia.js instance --publish-build');
5869
+ // The publish is scoped to the deployment this workflow builds — every other step here is —
5870
+ // so it reads dd-cyberia's own environment instead of the working-tree `./.env`, which names
5871
+ // whichever deployment `app load` ran for last.
5872
+ shellExec(
5873
+ `node bin/cyberia.js instance --publish-build --env-path ${deployEnvFilePath(
5874
+ 'dd-cyberia',
5875
+ isDev ? 'development' : 'production',
5876
+ )}`,
5877
+ );
5661
5878
  logger.info(`run-workflow build-manifest complete (${isDev ? 'dev' : 'prod'})`);
5662
5879
  });
5663
5880
 
@@ -5787,7 +6004,7 @@ node bin image --path cyberia-client \
5787
6004
  // line.
5788
6005
  if (error && error.message === 'Trigger underpost passthrough') {
5789
6006
  process.argv = process.argv.filter((c) => c !== 'underpost');
5790
- logger.warn('Rerouting to underpost cli...');
6007
+ if (!process.argv.includes('--plain')) logger.info('Rerouting to underpost cli...');
5791
6008
  try {
5792
6009
  await underpostProgram.parseAsync();
5793
6010
  } catch (err) {