@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,610 @@
1
+ # Logging helpers for deploy/<deploy-id>/*.sh. Sourced, never executed directly.
2
+ #
3
+ # Environment read by these helpers, and nothing else:
4
+ # RUN_QUIET_DEBUG Stream every line verbatim: no table, no folding, no dropped traces. For an
5
+ # operator watching a step over SSH who needs the run itself, not a report of
6
+ # it. Wins over the two below, which each hide part of the stream by design.
7
+ # RUN_QUIET_CI Marks stdout as a GitHub Actions log, which folds monitor frames into
8
+ # collapsed sections. The CD workflows export it on the far side of the SSH
9
+ # hop because GITHUB_ACTIONS is runner-local and does not travel; a remote
10
+ # deploy has no other way to know. `underpost state publish` reads the same
11
+ # pair to choose workflow commands over JSON.
12
+ # RUN_QUIET_PLAIN No colour, no cursor motion, no folding: frames stream as they arrive.
13
+ # NO_COLOR Colour off, the usual convention. Everything else is unaffected.
14
+ #
15
+ # Whatever the rendering, the parsing behind it is the same: a step that reports a fatal runtime
16
+ # status fails, including one that exits 0, and including in debug mode.
17
+
18
+
19
+ if [ -n "${NO_COLOR:-}${RUN_QUIET_PLAIN:-}" ]; then
20
+ RUN_QUIET_RED=''
21
+ RUN_QUIET_RESET=''
22
+ else
23
+ RUN_QUIET_RED=$'\033[0;31m'
24
+ RUN_QUIET_RESET=$'\033[0m'
25
+ fi
26
+
27
+ RUN_QUIET_NODE_TAG=$(hostname 2>/dev/null | tr '[:upper:]' '[:lower:]')
28
+ RUN_QUIET_NODE_TAG=${RUN_QUIET_NODE_TAG:+ [$RUN_QUIET_NODE_TAG]}
29
+
30
+ # The report pattern and the passthrough window describe the deployment log
31
+ # format, not any one step, so they are declared once here instead of being
32
+ # repeated at every call site.
33
+ DEPLOY_REPORT_PATTERN='Target pod:'
34
+ DEPLOY_REPORT_LINES_AFTER=14
35
+
36
+ # Titles a deploy run, in the same shape as the step lines below it.
37
+ deploy_start() {
38
+ echo "$RUN_QUIET_NODE_TAG $(date -Is) ▶▶ $1"
39
+ }
40
+
41
+ # One deploy step: a label and the command that carries it.
42
+ deploy_step() {
43
+ local label="$1"
44
+ shift
45
+
46
+ run_quiet "$label" "$DEPLOY_REPORT_PATTERN" "$DEPLOY_REPORT_LINES_AFTER" "$@"
47
+ }
48
+
49
+ run_quiet() {
50
+ local label="$1"
51
+ local patterns="$2"
52
+ local lines_after="$3"
53
+ shift 3
54
+
55
+ local debug_log
56
+ local error_log
57
+ local fail_flag
58
+ local fatal
59
+ local fifo_dir
60
+ local filter_pid
61
+ local stderr_pid
62
+ local color=0
63
+ local debug=0
64
+ local groups=0
65
+ local redraw=0
66
+ local width=0
67
+ local rows=0
68
+ local status=0
69
+
70
+ echo "$RUN_QUIET_NODE_TAG $(date -Is) ▶ $label"
71
+
72
+ # How a step renders is decided by what its destination can do, not by preference, and the
73
+ # three renderings are mutually exclusive:
74
+ # debug an operator watching over SSH — nothing filtered, folded or overwritten
75
+ # redraw a terminal — one live region, rewritten in place
76
+ # groups a GitHub Actions log — no cursor motion, so frames fold into a collapsed section
77
+ # With none of them the frames simply stream. RUN_QUIET_DEBUG is resolved first because it
78
+ # is the operator asking to see the stream itself, which neither of the others can show: a
79
+ # live region overwrites what came before, and a collapsed section hides it.
80
+ [ -z "${RUN_QUIET_DEBUG:-}" ] || debug=1
81
+
82
+ [ -n "${NO_COLOR:-}${RUN_QUIET_PLAIN:-}" ] || color=1
83
+
84
+ if [ "$debug" -eq 0 ] && [ -t 1 ] && [ "${TERM:-dumb}" != dumb ] && [ -z "${RUN_QUIET_PLAIN:-}" ]; then
85
+ redraw=1
86
+ width=${COLUMNS:-0}
87
+ [ "$width" -gt 0 ] 2>/dev/null || width=$(tput cols 2>/dev/null || echo 0)
88
+ rows=${LINES:-0}
89
+ [ "$rows" -gt 0 ] 2>/dev/null || rows=$(tput lines 2>/dev/null || echo 0)
90
+ # Without a known width a long row wraps, and the cursor-up count that
91
+ # addresses the table no longer matches the lines it printed.
92
+ [ "$width" -ge 20 ] || redraw=0
93
+ fi
94
+
95
+ # GITHUB_ACTIONS exists on a runner but is not carried across the SSH hop a remote deploy runs
96
+ # over, so RUN_QUIET_CI — which the workflows export on the far side — is what actually marks
97
+ # a step whose stdout a GitHub log will render.
98
+ if [ "$debug" -eq 0 ] && [ "$redraw" -eq 0 ] && [ -z "${RUN_QUIET_PLAIN:-}" ] &&
99
+ [ -n "${GITHUB_ACTIONS:-}${RUN_QUIET_CI:-}" ]; then
100
+ groups=1
101
+ fi
102
+
103
+ debug_log=$(mktemp --suffix=.debug.log)
104
+ error_log=$(mktemp --suffix=.error.log)
105
+ fail_flag=$(mktemp --suffix=.fatal)
106
+ : >"$fail_flag"
107
+ fifo_dir=$(mktemp -d)
108
+ mkfifo "$fifo_dir/merged" "$fifo_dir/stderr"
109
+
110
+ # The filter reads the live stream rather than the finished log: a deployment
111
+ # monitor prints its report for minutes before exiting, so a pass over the
112
+ # completed file would show nothing until then. fflush defeats awk's block
113
+ # buffering, which otherwise withholds output whenever stdout is a pipe.
114
+ # awk writes the debug log itself rather than piping through tee, so the
115
+ # reader stays a single process that a kill can always release.
116
+ #
117
+ # On a terminal the table is the only live region and always sits at the
118
+ # bottom: rows are overwritten one by one (cursor up, then erase to end of
119
+ # line as each row is rewritten) so the section never blanks between frames,
120
+ # and a passthrough line is printed after erasing the table and before
121
+ # drawing it again. All of that is cursor relative, so every row must occupy
122
+ # exactly one terminal line: rows are cut to the terminal width, counting
123
+ # display columns rather than bytes so colour escapes neither inflate the
124
+ # measurement nor get sliced in half. Elsewhere nothing is cut and nothing
125
+ # is overwritten — the frames stream, folded into a CI group when there is
126
+ # one to fold them into.
127
+ awk \
128
+ -v pattern="$patterns" \
129
+ -v lines_after="$lines_after" \
130
+ -v debug_log="$debug_log" \
131
+ -v redraw="$redraw" \
132
+ -v color="$color" \
133
+ -v debug="$debug" \
134
+ -v groups="$groups" \
135
+ -v label="$label" \
136
+ -v width="$width" \
137
+ -v rows="$rows" \
138
+ -v started="$(date +%H:%M:%S)" \
139
+ -v fail_flag="$fail_flag" \
140
+ -v handoff="$RUN_QUIET_NODE_TAG $(date -Is) ▶ Switch traffic" '
141
+ function strip(s) {
142
+ gsub(esc_seq, "", s)
143
+ return s
144
+ }
145
+ function pad(s, w) {
146
+ while (length(s) < w) s = s " "
147
+ return s
148
+ }
149
+ # Pod names differ in their tail, so a name too wide for its column keeps
150
+ # the end rather than the deploy prefix every pod shares.
151
+ function trim(s, w) {
152
+ return length(s) <= w ? s : ".." substr(s, length(s) - w + 3)
153
+ }
154
+ function rule(n, r) {
155
+ r = ""
156
+ while (n-- > 0) r = r "-"
157
+ return r
158
+ }
159
+ function paint(s, sgr) {
160
+ return color ? esc "[" sgr "m" s esc "[0m" : s
161
+ }
162
+ function fit(s, out, visible) {
163
+ if (!redraw) return s
164
+ out = ""
165
+ visible = 0
166
+ while (length(s) > 0) {
167
+ if (match(s, "^" esc_seq)) {
168
+ out = out substr(s, 1, RLENGTH)
169
+ s = substr(s, RLENGTH + 1)
170
+ continue
171
+ }
172
+ if (visible >= width - 1) return out esc "[0m"
173
+ out = out substr(s, 1, 1)
174
+ s = substr(s, 2)
175
+ visible++
176
+ }
177
+ return out
178
+ }
179
+ function put(line) {
180
+ printf "%s%s\n", fit(line), redraw ? esc "[K" : ""
181
+ fflush()
182
+ }
183
+ # GitHub renders no cursor motion, so the live region becomes a
184
+ # collapsed section: every frame streams into it and the settled table
185
+ # is reprinted outside it.
186
+ function open_group() {
187
+ if (!groups || group_open) return
188
+ group_open = 1
189
+ printf "::group::%s monitor frames\n", label
190
+ fflush()
191
+ }
192
+ function close_group() {
193
+ if (!group_open) return
194
+ group_open = 0
195
+ # The next run of rows opens its own section, and a section starts
196
+ # with its title and header.
197
+ appended_header = 0
198
+ appended_cycle = 0
199
+ printf "::endgroup::\n"
200
+ fflush()
201
+ }
202
+ function final_table( i) {
203
+ if (!groups || pod_count == 0) return
204
+ close_group()
205
+ measure()
206
+ title_line()
207
+ header_lines()
208
+ for (i = 1; i <= pod_count; i++) pod_line(pods[i])
209
+ }
210
+ function json_value(key, found) {
211
+ if (!match($0, "\"" key "\"[ ]*:[ ]*\"[^\"]*\"")) return ""
212
+ found = substr($0, RSTART, RLENGTH)
213
+ sub("^\"" key "\"[ ]*:[ ]*\"", "", found)
214
+ sub("\"$", "", found)
215
+ return found
216
+ }
217
+ function apply_event( was_k8s_ready, was_runtime_ready, i) {
218
+ events_seen = 1
219
+ was_k8s_ready = k8s_ready
220
+ was_runtime_ready = runtime_ready
221
+ if (event_phase == "kubernetes") k8s_ready = (event_state == "pod_ready")
222
+ else if (event_phase == "runtime") {
223
+ runtime_ready = (event_state == "runtime_ready")
224
+ if (event_status != "") last_runtime = event_status
225
+ if (is_fatal(event_status)) note_fatal("runtime event", "status=" event_status)
226
+ }
227
+ if (redraw) {
228
+ if (drawn > 0) {
229
+ clear_table()
230
+ draw_table()
231
+ }
232
+ return
233
+ }
234
+ # Readiness reaches the cells through the events alone, so without a
235
+ # live table it is the only thing that can move a row.
236
+ if (was_k8s_ready == k8s_ready && was_runtime_ready == runtime_ready) return
237
+ for (i = 1; i <= pod_count; i++) append_row(pods[i])
238
+ }
239
+ # Both phases confirmed is the monitor signing off; the hand-off waits
240
+ # for the report lines of that iteration so the table lands on its final
241
+ # frame first.
242
+ function ready_pending() {
243
+ return events_seen ? (k8s_ready && runtime_ready) : all_pods_running()
244
+ }
245
+ # One report line per pod: "Target pod: NAME | Pod status: X | Runtime status: Y".
246
+ function read_pod_line(line, plain, cell, pod, k8s, runtime) {
247
+ plain = strip(line)
248
+ if (plain !~ /^Target pod: /) return 0
249
+ if (split(plain, cell, / \| /) < 3) return 0
250
+ pod = cell[1]; sub(/^Target pod:[ ]*/, "", pod)
251
+ k8s = cell[2]; sub(/^Pod status:[ ]*/, "", k8s)
252
+ runtime = cell[3]; sub(/^Runtime status:[ ]*/, "", runtime)
253
+ if (pod == "") return 0
254
+ if (is_fatal(runtime)) note_fatal("pod " pod, "runtime status=" runtime)
255
+ if (!(pod in pod_row)) {
256
+ pod_row[pod] = ++pod_count
257
+ pods[pod_count] = pod
258
+ }
259
+ # The report itself is unstamped: the clock is the one the monitor
260
+ # printed for this iteration, so the title advances with the run.
261
+ cycle_time = last_time != "" ? last_time : started
262
+ pod_k8s[pod] = k8s
263
+ pod_runtime[pod] = runtime
264
+ current_pod = pod
265
+ return 1
266
+ }
267
+ # Every pod reporting its expected runtime status with no pending
268
+ # marker is what the deployment itself calls ready. `error` is
269
+ # the fatal value in the RUNTIME_STATUS contract: a terminal state, not a
270
+ # ready one, and reading it as ready handed off to the traffic switch on
271
+ # a deployment that had already failed.
272
+ function all_pods_running( i, pod, runtime) {
273
+ if (pod_count == 0) return 0
274
+ for (i = 1; i <= pod_count; i++) {
275
+ pod = pods[i]
276
+ if (pod_k8s[pod] != "Running") return 0
277
+ runtime = runtime_cell(pod)
278
+ if (runtime == "" || runtime ~ /pending/ || is_fatal(runtime)) return 0
279
+ }
280
+ return 1
281
+ }
282
+ # The bare contract value, not a substring: a phase name that merely
283
+ # contains it (or a log line quoting it) is not a fatal latch.
284
+ function is_fatal(status) {
285
+ return status == "error"
286
+ }
287
+ # Stack frames and source URLs carry absolute host paths and module layout,
288
+ # which must not reach a CI transcript. Both log files still hold them.
289
+ function is_trace(line) {
290
+ return line ~ /^[ \t]*at [^ ]/ || line ~ /file:\/\/\// || line ~ /^[ \t]*at async / || line ~ /^[A-Za-z_]*Error: /
291
+ }
292
+ # Records the fatal latch for run_quiet. A step can report this and still
293
+ # exit 0 — the in-pod lifecycle deliberately does not crash the container
294
+ # — so the exit status alone cannot be trusted to stop the deployment.
295
+ function note_fatal(source, detail) {
296
+ if (fatal_seen) return
297
+ fatal_seen = 1
298
+ printf "%s: %s\n", source, detail > fail_flag
299
+ close(fail_flag)
300
+ }
301
+ # The table stops being a live region here: the deployment is handing
302
+ # over to the traffic switch, so the last frame stays on screen and the
303
+ # chatter the runner prints below it is dropped.
304
+ function hand_off() {
305
+ handed_off = 1
306
+ remaining = 0
307
+ drawn = 0
308
+ last_pod_line = 0
309
+ final_table()
310
+ put(handoff)
311
+ }
312
+ # A later monitor in the same command (a second colour, a rollback) opens
313
+ # its own table below the one that was handed off.
314
+ function reset_table() {
315
+ close_group()
316
+ handed_off = 0
317
+ events_seen = 0
318
+ k8s_ready = 0
319
+ runtime_ready = 0
320
+ pod_count = 0
321
+ cycles = 0
322
+ cycle_time = ""
323
+ appended_header = 0
324
+ appended_cycle = 0
325
+ drawn = 0
326
+ delete pods
327
+ delete pod_row
328
+ delete pod_k8s
329
+ delete pod_runtime
330
+ delete last_row
331
+ }
332
+ # pod_ready is a deployment-wide event: it only annotates a pod whose
333
+ # own phase already agrees, never a stale one still coming up.
334
+ function k8s_cell(pod, cell) {
335
+ cell = pod_k8s[pod]
336
+ return (k8s_ready && cell == "Running") ? cell " (ready)" : cell
337
+ }
338
+ function runtime_cell(pod) {
339
+ return pod_runtime[pod] != "" ? pod_runtime[pod] : last_runtime
340
+ }
341
+ # Columns only ever grow: a cell that shrinks must not reflow the table
342
+ # under the reader between frames.
343
+ function measure( i, pod, over, budget) {
344
+ for (i = 1; i <= pod_count; i++) {
345
+ pod = pods[i]
346
+ if (length(pod) > w_pod) w_pod = length(pod)
347
+ if (length(k8s_cell(pod)) > w_k8s) w_k8s = length(k8s_cell(pod))
348
+ if (length(runtime_cell(pod)) > w_runtime) w_runtime = length(runtime_cell(pod))
349
+ }
350
+ # 10 columns of borders and padding. On a narrow terminal the pod
351
+ # column gives up room first, then the status columns, before fit()
352
+ # starts cutting cells off the right edge.
353
+ w_pod_fit = w_pod
354
+ w_runtime_fit = w_runtime
355
+ w_k8s_fit = w_k8s
356
+ # A streamed table cannot re-pad the rows it already printed, so the
357
+ # status columns start wide enough for the values the monitor is
358
+ # known to report and stop drifting under the header.
359
+ if (!redraw) {
360
+ if (w_k8s_fit < 17) w_k8s_fit = 17
361
+ if (w_runtime_fit < 28) w_runtime_fit = 28
362
+ return
363
+ }
364
+ # fit() cuts the last column, so the row has to land inside it.
365
+ budget = width - 1
366
+ over = row_width() - budget
367
+ if (over > 0) {
368
+ w_pod_fit = w_pod_fit - over < 12 ? 12 : w_pod_fit - over
369
+ over = row_width() - budget
370
+ }
371
+ if (over > 0) {
372
+ w_runtime_fit = w_runtime_fit - over < 16 ? 16 : w_runtime_fit - over
373
+ over = row_width() - budget
374
+ }
375
+ if (over > 0) w_k8s_fit = w_k8s_fit - over < 12 ? 12 : w_k8s_fit - over
376
+ }
377
+ function row_width() {
378
+ return w_pod_fit + w_k8s_fit + w_runtime_fit + 10
379
+ }
380
+ # The iteration and the clock are one per frame, not one per pod: they
381
+ # title the table instead of repeating down two columns of it.
382
+ function title_line() {
383
+ put(paint(sprintf("%s (refresh #%d, %s)", label, cycles,
384
+ cycle_time != "" ? cycle_time : started), "1"))
385
+ }
386
+ function header_lines() {
387
+ put(paint(sprintf("| %s | %s | %s |", pad("POD NAME", w_pod_fit),
388
+ pad("K8S STATUS", w_k8s_fit), pad("RUNTIME STATUS", w_runtime_fit)), "1"))
389
+ put(paint(sprintf("|%s|%s|%s|", rule(w_pod_fit + 2), rule(w_k8s_fit + 2),
390
+ rule(w_runtime_fit + 2)), "2"))
391
+ }
392
+ function pod_line(pod, runtime) {
393
+ runtime = runtime_cell(pod)
394
+ put(sprintf("| %s | %s | %s |",
395
+ paint(pad(trim(pod, w_pod_fit), w_pod_fit), "1"),
396
+ paint(pad(trim(k8s_cell(pod), w_k8s_fit), w_k8s_fit), k8s_ready ? "32" : "33"),
397
+ paint(pad(trim(runtime, w_runtime_fit), w_runtime_fit), (runtime ~ /pending/ || !runtime_ready) ? "36" : "32")))
398
+ }
399
+ function clear_table() {
400
+ if (!redraw || drawn == 0) return
401
+ printf "%s[%dA%s[J", esc, drawn, esc
402
+ drawn = 0
403
+ }
404
+ function draw_table( i) {
405
+ if (!redraw || pod_count == 0) return
406
+ # A table taller than the screen scrolls, and the cursor-up count no
407
+ # longer addresses the rows it drew; degrade to appended rows.
408
+ if (rows > 0 && pod_count + 3 >= rows) {
409
+ redraw = 0
410
+ drawn = 0
411
+ return
412
+ }
413
+ measure()
414
+ title_line()
415
+ header_lines()
416
+ for (i = 1; i <= pod_count; i++) pod_line(pods[i])
417
+ drawn = pod_count + 3
418
+ }
419
+ # Without a live table a row is only worth printing when its cells
420
+ # actually moved; the iteration count alone is not a change. The title is
421
+ # reprinted whenever a later iteration is the one moving rows, so a
422
+ # streamed row is still dated without carrying its own clock column.
423
+ # The parsing every rendering shares: it advances the monitor'"'"'s event state machine,
424
+ # records what each pod reported, and latches a fatal runtime status. What a line *is*
425
+ # cannot depend on how the run is being displayed, so this answers only that, and the
426
+ # caller decides what to show.
427
+ function track(line) {
428
+ if (in_json) {
429
+ if (line ~ json_close) {
430
+ in_json = 0
431
+ apply_event()
432
+ } else {
433
+ if (json_value("phase") != "") event_phase = json_value("phase")
434
+ if (json_value("state") != "") event_state = json_value("state")
435
+ if (json_value("status") != "") event_status = json_value("status")
436
+ }
437
+ return "event"
438
+ }
439
+ if (line ~ json_open) {
440
+ in_json = 1
441
+ event_phase = event_state = event_status = ""
442
+ return "event"
443
+ }
444
+ return read_pod_line(line) ? "pod" : "other"
445
+ }
446
+ function append_row(pod, cells) {
447
+ if (debug) return
448
+ cells = pod "|" k8s_cell(pod) "|" runtime_cell(pod)
449
+ if (cells == last_row[pod]) return
450
+ last_row[pod] = cells
451
+ measure()
452
+ open_group()
453
+ if (appended_cycle != cycles) {
454
+ title_line()
455
+ appended_cycle = cycles
456
+ }
457
+ if (!appended_header) {
458
+ header_lines()
459
+ appended_header = 1
460
+ }
461
+ pod_line(pod)
462
+ }
463
+ BEGIN {
464
+ w_pod = length("POD NAME")
465
+ w_k8s = length("K8S STATUS")
466
+ w_runtime = length("RUNTIME STATUS")
467
+ group_open = 0
468
+ esc = sprintf("%c", 27)
469
+ esc_seq = esc "\\[[0-9;]*[A-Za-z]"
470
+ clock = "[0-9][0-9]:[0-9][0-9]:[0-9][0-9]"
471
+ json_open = "deploy-monitor:[ ]*[{]"
472
+ json_close = "^[ \t]*[}],?[ \t]*$"
473
+ }
474
+ {
475
+ print > debug_log
476
+ # The monitor stamps its own lines in local time; the ISO field
477
+ # inside an emit is UTC, so it never feeds the column.
478
+ if ($0 !~ /"timestamp"/ && match(strip($0), clock)) last_time = substr(strip($0), RSTART, RLENGTH)
479
+ }
480
+ {
481
+ # DEBUG streams the step verbatim: no table, no group, no passthrough window, and no
482
+ # dropped stack traces — a CI transcript withholds those because it is published,
483
+ # which is not true of the session an operator opened to audit this run. Tracking
484
+ # still runs, so a fatal runtime status latches here exactly as in every other mode
485
+ # and a step that reports one still fails.
486
+ if (debug) {
487
+ track($0)
488
+ put($0)
489
+ next
490
+ }
491
+ if (!handed_off && $0 !~ pattern && ready_pending()) hand_off()
492
+ if (handed_off) {
493
+ if ($0 !~ pattern) next
494
+ reset_table()
495
+ }
496
+ line_kind = track($0)
497
+ # The monitor JSON is state already carried by the table cells: it is
498
+ # consumed here and never reaches the terminal.
499
+ if (line_kind == "event") {
500
+ if (remaining > 0) remaining--
501
+ last_pod_line = 0
502
+ next
503
+ }
504
+ if (line_kind == "pod") {
505
+ # Pod reports arrive back to back, one per pod, once per monitor
506
+ # iteration: the first of a run opens a new cycle.
507
+ if (!last_pod_line) cycles++
508
+ last_pod_line = 1
509
+ remaining = lines_after + 1
510
+ if (redraw) {
511
+ clear_table()
512
+ draw_table()
513
+ }
514
+ if (!redraw) append_row(current_pod)
515
+ next
516
+ }
517
+ last_pod_line = 0
518
+ if ($0 ~ pattern) remaining = lines_after + 1
519
+ if (remaining > 0) {
520
+ if (is_trace($0)) {
521
+ remaining--
522
+ next
523
+ }
524
+ clear_table()
525
+ close_group()
526
+ put($0)
527
+ remaining--
528
+ draw_table()
529
+ }
530
+ }
531
+ END {
532
+ if (!debug && !handed_off && ready_pending()) hand_off()
533
+ close_group()
534
+ }
535
+ ' <"$fifo_dir/merged" &
536
+ filter_pid=$!
537
+
538
+ # stderr is duplicated: on its own for the native error and stack trace, and
539
+ # into the merged stream so both the debug log and the filter see it in
540
+ # chronological order with stdout.
541
+ tee -a "$error_log" <"$fifo_dir/stderr" >"$fifo_dir/merged" &
542
+ stderr_pid=$!
543
+
544
+ "$@" >"$fifo_dir/merged" 2>"$fifo_dir/stderr" || status=$?
545
+
546
+ # Drain both readers before the paths are printed, or the trace can still be
547
+ # in flight. Bounded: a command that leaks a child holding a stream open must
548
+ # not hang the deployment, and by then everything read has been written.
549
+ run_quiet_drain "$stderr_pid"
550
+ run_quiet_drain "$filter_pid"
551
+ rm -rf "$fifo_dir"
552
+
553
+ # A deployment can fail without the command failing. The in-pod lifecycle latches
554
+ # `container-status=error` and deliberately does not crash the container, so a step that
555
+ # reported a fatal runtime state can still exit 0 — and a green step here is a green
556
+ # GitHub Actions job on a deployment that never came up. The latch the filter recorded is
557
+ # therefore promoted to a failure exit of its own.
558
+ fatal=$(cat "$fail_flag" 2>/dev/null) || true
559
+ rm -f "$fail_flag"
560
+ if [ "$status" -eq 0 ] && [ -n "$fatal" ]; then
561
+ status=1
562
+ printf -- '--- fatal runtime latch ---\n%s\n' "$fatal" >>"$error_log"
563
+ printf '%s✖ %s reported a fatal runtime state but exited 0%s\n' \
564
+ "$RUN_QUIET_RED" "$label" "$RUN_QUIET_RESET" >&2
565
+ fi
566
+
567
+ if [ "$status" -ne 0 ]; then
568
+ run_quiet_error_trace "$debug_log" "$error_log"
569
+ printf '%s✖ %s failed (exit %s)%s\n' "$RUN_QUIET_RED" "$label" "$status" "$RUN_QUIET_RESET" >&2
570
+ printf '%s error trace: %s\n debug log: %s%s\n' \
571
+ "$RUN_QUIET_RED" "$error_log" "$debug_log" "$RUN_QUIET_RESET" >&2
572
+ return "$status"
573
+ fi
574
+
575
+ rm -f "$debug_log" "$error_log"
576
+
577
+ return "$status"
578
+ }
579
+
580
+ # Appends the failing part of the merged log to the error trace, so the trace ends
581
+ # with the error rather than with whatever last wrote to stderr. Cuts from the first
582
+ # error marker; with no marker the tail stands in, which is where a logger-only
583
+ # failure reports itself.
584
+ run_quiet_error_trace() {
585
+ local debug_log="$1"
586
+ local error_log="$2"
587
+ local tail_lines="${3:-40}"
588
+ local first
589
+
590
+ # grep exits 1 when it matches nothing, and every deploy script runs under `set -e` with
591
+ # `pipefail`: unguarded, a failing step whose log carries no marker aborted this function
592
+ # before run_quiet could print the exit code and the two log paths, and the tail fallback
593
+ # below was unreachable. The no-match case is the fallback's trigger, not an error.
594
+ first=$(grep -a -n -m1 -E 'Error:|Error \[|^[[:space:]]+at |✖' "$debug_log" 2>/dev/null | cut -d: -f1) || true
595
+
596
+ printf -- '--- error trace (from merged log) ---\n' >>"$error_log"
597
+ if [ -n "$first" ]; then
598
+ tail -n "+$first" "$debug_log" >>"$error_log"
599
+ else
600
+ tail -n "$tail_lines" "$debug_log" >>"$error_log"
601
+ fi
602
+ }
603
+
604
+ run_quiet_drain() {
605
+ local pid="$1"
606
+
607
+ timeout 10 tail --pid="$pid" -f /dev/null 2>/dev/null || true
608
+ kill "$pid" 2>/dev/null || true
609
+ wait "$pid" 2>/dev/null || true
610
+ }