@underpostnet/cyberia 3.3.73 → 3.3.77

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 (269) hide show
  1. package/.env.example +17 -5
  2. package/.github/workflows/coverall.cyberia.ci.yml +10 -0
  3. package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
  4. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
  5. package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
  6. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
  7. package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
  8. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
  9. package/.github/workflows/engine-cyberia.ci.yml +1 -1
  10. package/.github/workflows/publish.cyberia.ci.yml +44 -0
  11. package/AGENTS.md +61 -12
  12. package/CHANGELOG.md +159 -161
  13. package/CLI-HELP.md +20 -13
  14. package/Dockerfile +1 -1
  15. package/Dockerfile.dev +1 -1
  16. package/Dockerfile.test +2 -2
  17. package/README.md +28 -28
  18. package/bin/build.js +96 -21
  19. package/bin/cyberia.js +1247 -1373
  20. package/bin/index.js +1247 -1373
  21. package/compose.env +17 -5
  22. package/conf.js +7 -4
  23. package/deploy/cyberia-client/deploy.sh +10 -11
  24. package/deploy/cyberia-client/package.sh +0 -1
  25. package/deploy/cyberia-client/state.sh +3 -2
  26. package/deploy/cyberia-server/deploy.sh +10 -11
  27. package/deploy/cyberia-server/package.sh +0 -1
  28. package/deploy/cyberia-server/state.sh +3 -2
  29. package/deploy/dd-cyberia/deploy.sh +5 -5
  30. package/deploy/dd-cyberia/init.sh +15 -14
  31. package/deploy/dd-cyberia/package.sh +0 -1
  32. package/deploy/dd-cyberia/state.sh +2 -2
  33. package/deploy/dd-cyberia/sync-deploy.sh +139 -75
  34. package/deploy/lib/config.sh +29 -0
  35. package/deploy/lib/github-actions-logging.sh +92 -76
  36. package/deploy/lib/host.sh +28 -19
  37. package/deploy/lib/state.sh +4 -1
  38. package/deploy/pwa-microservices-template/deploy.sh +10 -8
  39. package/deploy/release/deploy.sh +0 -2
  40. package/deployment.yaml +1 -1
  41. package/docker-compose.yml +23 -17
  42. package/docs/coverage/cyberia/api/cyberia-instance/cyberia-fallback-capture.js.html +1591 -0
  43. package/docs/coverage/cyberia/api/cyberia-instance/index.html +116 -0
  44. package/docs/coverage/cyberia/api/cyberia-server-defaults/cyberia-server-defaults.js.html +4138 -0
  45. package/docs/coverage/cyberia/api/cyberia-server-defaults/index.html +116 -0
  46. package/docs/coverage/cyberia/api/object-layer/index.html +116 -0
  47. package/docs/coverage/cyberia/api/object-layer/object-layer.model.js.html +1393 -0
  48. package/docs/coverage/cyberia/base.css +362 -0
  49. package/docs/coverage/cyberia/block-navigation.js +82 -0
  50. package/docs/coverage/cyberia/favicon.png +0 -0
  51. package/docs/coverage/cyberia/index.html +161 -0
  52. package/docs/coverage/cyberia/prettify.css +101 -0
  53. package/docs/coverage/cyberia/prettify.js +937 -0
  54. package/docs/coverage/cyberia/projects/cyberia/atlas-sprite-sheet-generator.js.html +1315 -0
  55. package/docs/coverage/cyberia/projects/cyberia/index.html +176 -0
  56. package/docs/coverage/cyberia/projects/cyberia/instance-backup.js.html +715 -0
  57. package/docs/coverage/cyberia/projects/cyberia/instance-data.js.html +2182 -0
  58. package/docs/coverage/cyberia/projects/cyberia/shape-generator.js.html +3265 -0
  59. package/docs/coverage/cyberia/projects/cyberia/stat-balance.js.html +328 -0
  60. package/docs/coverage/cyberia/sort-arrow-sprite.png +0 -0
  61. package/docs/coverage/cyberia/sorter.js +205 -0
  62. package/hardhat/package-lock.json +2 -2
  63. package/hardhat/package.json +1 -1
  64. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  65. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +1 -1
  66. package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
  67. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  68. package/manifests/deployment/mongo-express/deployment.yaml +46 -27
  69. package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
  70. package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
  71. package/manifests/deployment/mongo-express/service.yaml +16 -0
  72. package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
  73. package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
  74. package/package.json +19 -17
  75. package/scripts/test-monitor.sh +3 -3
  76. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +14 -9
  77. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
  78. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
  79. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +88 -184
  80. package/src/api/cyberia-action/cyberia-action.router.js +2 -2
  81. package/src/api/cyberia-action/cyberia-action.service.js +3 -4
  82. package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
  83. package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
  84. package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
  85. package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
  86. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -3
  87. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
  88. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +12 -34
  89. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +15 -32
  90. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
  91. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
  92. package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
  93. package/src/api/cyberia-entity/cyberia-entity.service.js +1 -1
  94. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
  95. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
  96. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +16 -1
  97. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +466 -3
  98. package/src/api/cyberia-instance/cyberia-fallback-capture.js +87 -51
  99. package/src/api/cyberia-instance/cyberia-fallback-world.js +21 -40
  100. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
  101. package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
  102. package/src/api/cyberia-instance/cyberia-instance-map.service.js +34 -141
  103. package/src/api/cyberia-instance/cyberia-instance.controller.js +1 -4
  104. package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
  105. package/src/api/cyberia-instance/cyberia-instance.router.js +3 -16
  106. package/src/api/cyberia-instance/cyberia-instance.service.js +3 -43
  107. package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
  108. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
  109. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +74 -1
  110. package/src/api/cyberia-map/cyberia-map.service.js +6 -2
  111. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
  112. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
  113. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
  114. package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
  115. package/src/api/cyberia-quest/cyberia-quest.router.js +3 -3
  116. package/src/api/cyberia-quest/cyberia-quest.service.js +3 -3
  117. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
  118. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -188
  119. package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
  120. package/src/api/file/file.ref.js +153 -0
  121. package/src/api/file/file.ref.json +11 -2
  122. package/src/api/object-layer/object-layer.model.js +47 -12
  123. package/src/api/object-layer/object-layer.router.js +10 -3
  124. package/src/api/object-layer/object-layer.service.js +113 -120
  125. package/src/cli/app.js +12 -1
  126. package/src/cli/client.js +2 -2
  127. package/src/cli/cluster.js +80 -18
  128. package/src/cli/deploy.js +215 -34
  129. package/src/cli/docker-compose.js +1 -1
  130. package/src/cli/fs-selection.js +115 -0
  131. package/src/cli/fs.js +158 -342
  132. package/src/cli/index.js +22 -10
  133. package/src/cli/release.js +3 -1
  134. package/src/cli/repository.js +35 -9
  135. package/src/cli/run.js +80 -199
  136. package/src/cli/test.js +4 -0
  137. package/src/cli/wireguard.js +32 -31
  138. package/src/client/components/core/Badge.js +0 -1
  139. package/src/client/components/core/CssCore.js +8 -1
  140. package/src/client/components/core/Docs.js +77 -100
  141. package/src/client/components/core/Modal.js +77 -23
  142. package/src/client/components/core/ToolTip.js +15 -0
  143. package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +0 -2
  144. package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
  145. package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
  146. package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
  147. package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
  148. package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
  149. package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
  150. package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
  151. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
  152. package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
  153. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +0 -34
  154. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
  155. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
  156. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +0 -4
  157. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
  158. package/src/client/components/default/AppShellDefault.js +1 -4
  159. package/src/client/components/itemledger/AppShellItemledger.js +0 -2
  160. package/src/client/components/underpost/AppShellUnderpost.js +1 -1
  161. package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
  162. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +280 -24
  163. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
  164. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
  165. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
  166. package/src/client/public/cyberia-docs/CYBERIA.md +28 -28
  167. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
  168. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  169. package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
  170. package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
  171. package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
  172. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
  173. package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
  174. package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
  175. package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
  176. package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
  177. package/src/client/services/object-layer/object-layer.management.js +6 -10
  178. package/src/client/services/object-layer/object-layer.service.js +3 -1
  179. package/src/client/ssr/views/Cyberia404.js +3 -3
  180. package/src/client-builder/client-build-docs.js +52 -52
  181. package/src/client-builder/client-build.js +67 -44
  182. package/src/client-builder/client-bundle.js +347 -0
  183. package/src/db/mongo/MongoExpress.js +187 -0
  184. package/src/grpc/cyberia/grpc-server.js +5 -7
  185. package/src/index.js +1 -1
  186. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +143 -146
  187. package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
  188. package/src/projects/cyberia/besu-genesis-generator.js +5 -14
  189. package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
  190. package/src/projects/cyberia/catalog-cyberia.js +3 -2
  191. package/src/projects/cyberia/gemini-client.js +3 -3
  192. package/src/projects/cyberia/generate-saga.js +4 -11
  193. package/src/projects/cyberia/hot-reload-trigger.js +17 -28
  194. package/src/projects/cyberia/instance-backup.js +210 -0
  195. package/src/projects/cyberia/instance-data.js +177 -257
  196. package/src/projects/cyberia/map-preview-generator.js +32 -68
  197. package/src/projects/cyberia/object-layer.js +152 -319
  198. package/src/projects/cyberia/seed-audio.js +139 -0
  199. package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
  200. package/src/projects/cyberia/semantic-layer-generator.js +2 -18
  201. package/src/projects/cyberia/stat-balance.js +81 -0
  202. package/src/projects/cyberia/stat-commands.js +23 -0
  203. package/src/projects/cyberia/stat-contract-generator.js +101 -0
  204. package/src/runtime/cyberia-client/Dockerfile +8 -4
  205. package/src/runtime/cyberia-client/Dockerfile.dev +5 -2
  206. package/src/runtime/cyberia-server/Dockerfile +9 -2
  207. package/src/runtime/cyberia-server/Dockerfile.dev +8 -1
  208. package/src/runtime/engine-cyberia/Dockerfile +1 -1
  209. package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
  210. package/src/runtime/engine-cyberia/Dockerfile.test +2 -2
  211. package/src/runtime/engine-cyberia/compose.env +17 -5
  212. package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
  213. package/src/server/build/coverage.js +113 -42
  214. package/src/server/build/package.js +55 -12
  215. package/src/server/build/testing.js +59 -9
  216. package/src/server/network/middlewares.js +8 -2
  217. package/src/server/network/underpost-gateway.js +113 -14
  218. package/src/server/ops/logger.js +70 -35
  219. package/src/server/runtime/conf.js +40 -9
  220. package/src/server/runtime/start.js +11 -2
  221. package/src/server/storage/data-query.js +16 -0
  222. package/src/server/storage/downloader.js +62 -14
  223. package/src/server/storage/zip.js +153 -0
  224. package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
  225. package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
  226. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +34 -0
  227. package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
  228. package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
  229. package/test/integration/app/cyberia/cyberia-instance-conf-defaults.test.js +16 -22
  230. package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
  231. package/test/integration/app/cyberia/cyberia-load.test.js +6 -7
  232. package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
  233. package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
  234. package/test/integration/app/cyberia/fallback-world-capture.test.js +87 -2
  235. package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
  236. package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
  237. package/test/integration/app/cyberia/seed-audio.test.js +275 -0
  238. package/test/integration/infra/2-network/wireguard-cli.test.js +33 -9
  239. package/test/integration/infra/2-network/wireguard-edge.test.js +58 -18
  240. package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
  241. package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
  242. package/test/integration/infra/4-ingress/underpost-ingress.test.js +1 -1
  243. package/test/unit/catalog.test.js +13 -2
  244. package/test/unit/client-build-docs.test.js +97 -70
  245. package/test/unit/client-bundle.test.js +313 -0
  246. package/test/unit/conf-resolution.test.js +58 -7
  247. package/test/unit/coverage-artifact.test.js +120 -29
  248. package/test/unit/cyberia/instance-backup.test.js +183 -0
  249. package/test/unit/cyberia/instance-data.test.js +314 -0
  250. package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
  251. package/test/unit/cyberia/publish-workflow.test.js +22 -0
  252. package/test/unit/cyberia/stat-balance.test.js +69 -0
  253. package/test/unit/deploy-legacy-gateway-sweep.test.js +63 -0
  254. package/test/unit/deploy-log-table.test.js +76 -5
  255. package/test/unit/downloader-integrity.test.js +98 -0
  256. package/test/unit/file-reference-registry.test.js +141 -0
  257. package/test/unit/fs-storage-paths.test.js +596 -0
  258. package/test/unit/gateway-pod-fetch.test.js +95 -0
  259. package/test/unit/letsencrypt-issuer.test.js +101 -0
  260. package/test/unit/logger-redaction.test.js +29 -0
  261. package/test/unit/package.test.js +70 -16
  262. package/test/unit/prepare-host.test.js +84 -1
  263. package/test/unit/release-bump.test.js +3 -1
  264. package/test/unit/start-options.test.js +12 -0
  265. package/test/unit/test-tiers.test.js +27 -0
  266. package/test/unit/zip-archive.test.js +142 -0
  267. package/vitest.config.js +11 -3
  268. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
  269. package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
package/CLI-HELP.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Underpost CLI
2
2
 
3
- > underpost ci/cd cli v3.3.73
3
+ > underpost ci/cd cli v3.3.77
4
4
 
5
5
  **Usage:** `underpost [options] [command]`
6
6
 
@@ -37,7 +37,7 @@
37
37
  | [`db`](#underpost-db) | Manages database operations with support for MariaDB and MongoDB, including import/export, multi-pod targeting, and Git integration. |
38
38
  | [`metadata`](#underpost-metadata) | Manages cluster metadata operations, including import and export. |
39
39
  | [`cron`](#underpost-cron) | Manages cron jobs: execute jobs directly or generate and apply K8s CronJob manifests. |
40
- | [`fs`](#underpost-fs) | Manages file storage, defaulting to file upload operations. |
40
+ | [`fs`](#underpost-fs) | Uploads, pulls, or deletes Cloudinary assets and synchronizes the selected storage manifest. |
41
41
  | [`monitor`](#underpost-monitor) | Manages health server monitoring, the cluster observability stack, and host dashboards. |
42
42
  | [`event`](#underpost-event) | Dispatches operational events and provisions the monitoring rules that trigger them. |
43
43
  | [`ssh`](#underpost-ssh) | Manages cluster scoped SSH credentials and sessions for remote access to cluster nodes or services. Users are registered in engine-private/deploy/conf.users.json and keys are stored in engine-private/deploy/users/<user>. |
@@ -387,6 +387,7 @@ Manages Kubernetes clusters, defaulting to Kind cluster initialization.
387
387
  | `--service-host <host>` | Set custom host/IP for exposed MongoDB and Valkey clients. |
388
388
  | `--postgresql` | Initializes the cluster with a PostgreSQL statefulset. |
389
389
  | `--mongodb4` | Initializes the cluster with a MongoDB 4.4 service. |
390
+ | `--mongo-express` | Deploys the mongo-express web client for inspecting the MongoDB statefulset databases and collections. Reuses the mongodb-secret credentials, and drops them when the deployed mongod runs without --auth. Combine with --node-port to expose it on the node network. |
390
391
  | `--valkey` | Initializes the cluster with a Valkey service. |
391
392
  | `--ipfs` | Initializes the cluster with an ipfs-cluster statefulset. |
392
393
  | `--contour` | Initializes the cluster with Project Contour base HTTPProxy and Envoy. |
@@ -747,7 +748,7 @@ Manages cron jobs: execute jobs directly or generate and apply K8s CronJob manif
747
748
 
748
749
  ### underpost fs
749
750
 
750
- Manages file storage, defaulting to file upload operations.
751
+ Uploads, pulls, or deletes Cloudinary assets and synchronizes the selected storage manifest.
751
752
 
752
753
  **Usage:** `underpost fs [options] [path]`
753
754
 
@@ -755,20 +756,25 @@ Manages file storage, defaulting to file upload operations.
755
756
 
756
757
  | Argument | Description |
757
758
  | --- | --- |
758
- | `path` | The absolute or relative directory path for file operations. |
759
+ | `path` | Selects one file or all files below a directory. Required unless --tracked is set. |
759
760
 
760
761
  #### Options
761
762
 
762
763
  | Option | Description |
763
764
  | --- | --- |
764
- | `--rm` | Removes the specified file. |
765
- | `--git` | Displays current Git changes related to file storage. |
766
- | `--recursive` | Uploads files recursively from the specified path. |
767
- | `--deploy-id <deploy-id>` | Specifies the deployment configuration ID for file operations. |
768
- | `--pull` | Downloads the specified file. |
765
+ | `--rm` | Deletes selected remote assets and their manifest entries. |
766
+ | `--git` | Restricts filesystem selection to Git-tracked files. Does not change Git state. |
767
+ | `--recursive` | Compatibility option. Directories always select files recursively. |
768
+ | `--tracked` | Selects only manifest entries. An optional path limits their scope. |
769
+ | `--deploy-id <deploy-id>` | Selects the deployment configuration. |
770
+ | `--pull` | Downloads selected manifest assets. Use --tracked to restore missing local files. |
769
771
  | `--omit-unzip` | With --pull, keeps the downloaded .zip file and skips extraction. |
770
- | `--force` | Forces the action, overriding any warnings or conflicts. |
771
- | `--storage-file-path <storage-file-path>` | Specifies a custom file storage path. |
772
+ | `--force` | Overwrites remote uploads or local downloads. Does not change selection. |
773
+ | `--storage-id <sub-id>` | Selects storage.<sub-id>.json. The default is storage.json. |
774
+ | `--key <path>` | Selects one exact manifest key within the path scope and filters. |
775
+ | `--from-key <path>` | Starts an inclusive range in manifest key order. |
776
+ | `--to-key <path>` | Ends an inclusive range. The default start is the first manifest key. |
777
+ | `--key-regex <pattern>` | Filters manifest keys by a JavaScript regular expression. |
772
778
  | `-h, --help` | display help for command |
773
779
 
774
780
  ---
@@ -853,7 +859,7 @@ Dispatches operational events and provisions the monitoring rules that trigger t
853
859
  | `--service-status` | Reports whether the underpost-event unit is active and enabled. |
854
860
  | `--list` | Lists the registered events with their resolved probe targets. |
855
861
  | `--port <port>` | Listening port for --serve and the generated unit (default: 39099). |
856
- | `--cooldown-ms <ms>` | Minimum interval between two dispatches of one event in --serve (default: 300000). |
862
+ | `--cooldown-ms <ms>` | Minimum interval between two dispatches of one event in --serve (default: 10000). |
857
863
  | `--spoke <spoke-id>` | Spoke to remediate when dispatching wireguard-spoke-down by hand; a webhook takes it from the alert labels. |
858
864
  | `--nodes <node-names>` | Comma-separated node documents to act on — hubs for wireguard-server-down, peers for wireguard-spoke-down. Empty covers every registered hub, or every peer of this node hub. |
859
865
  | `--namespace <namespace>` | Kubernetes namespace holding the observability stack. Defaults to "default". |
@@ -1124,6 +1130,7 @@ Runs specified scripts using various runners.
1124
1130
  | `--deploy-id <deploy-id>` | Sets deploy id context for the runner execution. |
1125
1131
  | `--user <user>` | Sets user context for the runner execution. |
1126
1132
  | `--hosts <hosts>` | Comma-separated list of hosts for the runner execution. |
1133
+ | `--split <mb>` | Zip part size in MB for push-bundle, or "none" to upload a single zip. Defaults to 8. |
1127
1134
  | `--instance-id <instance-id>` | Sets instance id context for the runner execution. |
1128
1135
  | `--pid <process-id>` | Sets process id context for the runner execution. |
1129
1136
  | `--timeout-response <duration>` | Sets HTTPProxy per-route response timeout (e.g., "1s", "300ms", "infinity"). |
@@ -1166,7 +1173,7 @@ Runs the test tiers locally, inside deployment pods, or as a cluster Job with Al
1166
1173
 
1167
1174
  | Argument | Description |
1168
1175
  | --- | --- |
1169
- | `suite` | A comma-separated list of suites or tiers to run. Suites: unit, infra, app, cyberia, contracts, all. Tiers: unit, infra:1-security, infra:2-network, infra:3-cluster, infra:4-ingress, infra:5-observability, app, cyberia, contracts. Defaults to every tier, in tier order. (default: "") |
1176
+ | `suite` | A comma-separated list of suites or tiers to run. Suites: unit, cyberia, infra, app, contracts, all. Tiers: unit, cyberia:unit, infra:1-security, infra:2-network, infra:3-cluster, infra:4-ingress, infra:5-observability, app, cyberia:app, contracts. Defaults to every tier, in tier order. (default: "") |
1170
1177
 
1171
1178
  #### Options
1172
1179
 
package/Dockerfile CHANGED
@@ -6,7 +6,7 @@
6
6
  # Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
7
7
  # ---------------------------------------------------------------------------
8
8
  FROM rockylinux/rockylinux:9 AS builder
9
- ARG UNDERPOST_VERSION=3.3.73
9
+ ARG UNDERPOST_VERSION=3.3.77
10
10
  # Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
11
11
  # underpost's dependencies require >=24.15.0, so install the official binary.
12
12
  ARG NODE_VERSION=24.15.0
package/Dockerfile.dev CHANGED
@@ -6,7 +6,7 @@
6
6
  # Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
7
7
  # ---------------------------------------------------------------------------
8
8
  FROM rockylinux/rockylinux:9 AS builder
9
- ARG UNDERPOST_VERSION=3.3.73
9
+ ARG UNDERPOST_VERSION=3.3.77
10
10
  # Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
11
11
  # underpost's dependencies require >=24.15.0, so install the official binary.
12
12
  ARG NODE_VERSION=24.15.0
package/Dockerfile.test CHANGED
@@ -6,7 +6,7 @@
6
6
  # Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
7
7
  # ---------------------------------------------------------------------------
8
8
  FROM rockylinux/rockylinux:9 AS builder
9
- ARG UNDERPOST_VERSION=3.3.73
9
+ ARG UNDERPOST_VERSION=3.3.77
10
10
  # Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
11
11
  # underpost's dependencies require >=24.15.0, so install the official binary.
12
12
  ARG NODE_VERSION=24.15.0
@@ -72,7 +72,7 @@ RUN --mount=type=secret,id=github_token \
72
72
  # --- install deps + env, then replay build-safe itc provisioning ----------
73
73
  npm install; \
74
74
  node bin app load --env development --args deploy-id=dd-cyberia; \
75
- node bin fs --pull --recursive --deploy-id dd-cyberia --storage-file-path './engine-private/conf/dd-cyberia/storage.engine-cyberia.json'; \
75
+ node bin fs --pull --tracked --deploy-id dd-cyberia --storage-id engine-cyberia; \
76
76
  ( cd /home/dd/engine/hardhat && npm install --include=dev ); \
77
77
  ( cd /home/dd/engine && underpost clone underpostnet/cyberia-server ); \
78
78
  \
package/README.md CHANGED
@@ -20,7 +20,7 @@ _Stackable Rendering Layers as a Unified Tokenized Reality_
20
20
  <!-- CI/CD and health -->
21
21
  <div align="center">
22
22
 
23
- [![Node.js CI](https://img.shields.io/github/actions/workflow/status/underpostnet/engine-cyberia/docker-image.engine-cyberia.ci.yml?branch=main&label=Node.js%20CI)](https://github.com/underpostnet/engine-cyberia/actions/workflows/docker-image.engine-cyberia.ci.yml) [![Test](https://img.shields.io/github/actions/workflow/status/underpostnet/engine-cyberia/coverall.cyberia.ci.yml?branch=main&label=Test)](https://github.com/underpostnet/engine-cyberia/actions/workflows/coverall.cyberia.ci.yml) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine-cyberia/badge.svg?branch=main)](https://coveralls.io/github/underpostnet/engine-cyberia?branch=main) [![Socket Badge](https://socket.dev/api/badge/npm/package/cyberia/3.3.73)](https://socket.dev/npm/package/cyberia/overview/3.3.73)
23
+ [![Node.js CI](https://img.shields.io/github/actions/workflow/status/underpostnet/engine-cyberia/docker-image.engine-cyberia.ci.yml?branch=main&label=Node.js%20CI)](https://github.com/underpostnet/engine-cyberia/actions/workflows/docker-image.engine-cyberia.ci.yml) [![Test](https://img.shields.io/github/actions/workflow/status/underpostnet/engine-cyberia/coverall.cyberia.ci.yml?branch=main&label=Test)](https://github.com/underpostnet/engine-cyberia/actions/workflows/coverall.cyberia.ci.yml) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine-cyberia/badge.svg?branch=main)](https://coveralls.io/github/underpostnet/engine-cyberia?branch=main) [![Socket Badge](https://socket.dev/api/badge/npm/package/cyberia/3.3.77)](https://socket.dev/npm/package/cyberia/overview/3.3.77)
24
24
 
25
25
  </div>
26
26
 
@@ -45,26 +45,26 @@ Go server and the WASM client with data — it does not run the simulation or th
45
45
 
46
46
  ```text
47
47
  ┌───────────────────────────────────────────────┐
48
- │ UNDERPOST PLATFORM
49
- │ toolchain · deploy · PWA build · static
50
- │ delivery · cluster/image/db · monitoring
51
-
52
- │ underpost CLI ──▶ builds & deploys all
48
+ │ UNDERPOST PLATFORM
49
+ │ toolchain · deploy · PWA build · static
50
+ │ delivery · cluster/image/db · monitoring
51
+
52
+ │ underpost CLI ──▶ builds & deploys all
53
53
  └───────────────────────────────────────────────┘
54
54
  │ hosts / delivers
55
55
 
56
- ╔═══════════════════════════════ CYBERIA MMO ══════════════════════════════════╗
56
+ ╔═══════════════════════════════ CYBERIA MMO ═══════════════════════════════════╗
57
57
  ║ ║
58
- ║ ┌──────────────────┐ gRPC ┌──────────────────┐ WebSocket
59
- ║ │ engine-cyberia │ ────────▶ │ cyberia-server │ ───────────┐
60
- ║ │ (Node.js) │ │ (Go) │ │
61
- ║ │ │ │ │ ▼
62
- ║ │ content │ │ authoritative │ ┌──────────────────┐ ║
63
- ║ │ validation │ │ simulation │ │ cyberia-client │ ║
64
- ║ │ persistence │ │ world tick │ │ (C / WASM) │ ║
65
- ║ │ gRPC/REST data │ │ AOI replication │ │ │ ║
66
- ║ │ asset metadata │ │ │ │ rendering │ ║
67
- ║ └──────────────────┘ └──────────────────┘ │ input │ ║
58
+ ║ ┌──────────────────┐ gRPC ┌──────────────────┐ WebSocket
59
+ ║ │ engine-cyberia │ ────────▶ │ cyberia-server │ ───────────┐
60
+ ║ │ (Node.js) │ │ (Go) │ │
61
+ ║ │ │ │ │ ▼
62
+ ║ │ content │ │ authoritative │ ┌──────────────────┐ ║
63
+ ║ │ validation │ │ simulation │ │ cyberia-client │ ║
64
+ ║ │ persistence │ │ world tick │ │ (C / WASM) │ ║
65
+ ║ │ gRPC/REST data │ │ AOI replication │ │ │ ║
66
+ ║ │ asset metadata │ │ │ │ rendering │ ║
67
+ ║ └──────────────────┘ └──────────────────┘ │ input │ ║
68
68
  ║ │ │ prediction │ ║
69
69
  ║ └──────────────── REST (content/assets) ─────▶│ presentation │ ║
70
70
  ║ └──────────────────┘ ║
@@ -157,17 +157,17 @@ Three supervised processes run in parallel, each with its own monitor and reconn
157
157
 
158
158
  ```text
159
159
  ┌──────────────────────────────────────────────────────────────┐
160
- │ SUPERVISION (parallel)
161
-
162
- │ engine-cyberia cyberia-server cyberia-client
163
- │ ┌────────────┐ ┌────────────┐ ┌────────────┐
164
- │ │ monitor │ │ monitor │ │ monitor │
165
- │ │ +reconnect │ │ +reconnect │ │ +reconnect │
166
- │ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘
167
- │ │ │ │
168
- │ └──────────┬──────────┴──────────┬──────────┘
169
- │ ▼ ▼
170
- │ all three up & connected?
160
+ │ SUPERVISION (parallel)
161
+
162
+ │ engine-cyberia cyberia-server cyberia-client
163
+ │ ┌────────────┐ ┌────────────┐ ┌────────────┐
164
+ │ │ monitor │ │ monitor │ │ monitor │
165
+ │ │ +reconnect │ │ +reconnect │ │ +reconnect │
166
+ │ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘
167
+ │ │ │ │
168
+ │ └──────────┬──────────┴──────────┬──────────┘
169
+ │ ▼ ▼
170
+ │ all three up & connected?
171
171
  └────────────────────────────┬─────────────────────────────────┘
172
172
 
173
173
  ┌─────────────────────┼─────────────────────┐
package/bin/build.js CHANGED
@@ -8,13 +8,23 @@ import {
8
8
  getPathsSSR,
9
9
  syncPrivateConf,
10
10
  syncDeployIdSources,
11
+ syncDeployIdSourcesBack,
11
12
  buildTemplate,
12
13
  updatePrivateEngineTestRepo,
13
14
  } from '../src/server/runtime/conf.js';
14
15
  import { resolveDeployList } from '../src/server/network/router.js';
15
16
  import { loadDeployCatalog } from '../src/server/build/catalog.js';
16
- import { buildProductPackageJson, productPackageOptionsFactory } from '../src/server/build/package.js';
17
- import { COVERAGE_BUNDLE_DIRECTORY, bundleCoverageReport } from '../src/server/build/coverage.js';
17
+ import {
18
+ buildProductPackageJson,
19
+ installDeployDependencies,
20
+ productPackageOptionsFactory,
21
+ } from '../src/server/build/package.js';
22
+ import {
23
+ COVERAGE_BUNDLE_DIRECTORY,
24
+ bundleCoverageReports,
25
+ coverageReportCommand,
26
+ deployCoverageReports,
27
+ } from '../src/server/build/coverage.js';
18
28
  import { shellExec } from '../src/server/runtime/process.js';
19
29
  import Underpost from '../src/index.js';
20
30
 
@@ -33,13 +43,16 @@ const basePath = '../pwa-microservices-template';
33
43
  * SSR assets, manifests, and packaging declared by its conf into the template repo.
34
44
  * @param {string} confName - A concrete deploy id (e.g. `dd-prototype`).
35
45
  */
36
- const buildDeployTemplate = async (confName) => {
46
+ const buildDeployTemplate = async (confName, { force = false } = {}) => {
37
47
  const repoName = Underpost.repo.engineRepoFactory(confName);
38
48
  const catalog = await loadDeployCatalog(confName);
39
49
 
40
50
  if (catalog.sourceMoves.length) {
41
51
  Underpost.repo.sparseCheckoutDirectory(`conf/${confName}`);
42
- if (catalog.sourceMoves.some(([src]) => !fs.existsSync(src))) Underpost.repo.pullSourceRepo(repoName);
52
+ // Only a path neither tree holds needs the repo: one the engine holds is mirrored out.
53
+ // --force pulls regardless, to bring the repo up to date before the mirror.
54
+ if (force || catalog.sourceMoves.some(([src, dest]) => !fs.existsSync(src) && !fs.existsSync(dest)))
55
+ Underpost.repo.pullSourceRepo(repoName);
43
56
  }
44
57
  syncDeployIdSources(catalog.sourceMoves);
45
58
 
@@ -125,7 +138,7 @@ const buildDeployTemplate = async (confName) => {
125
138
 
126
139
  // The manifest a product publishes is its catalog's declaration, resolved the same way for
127
140
  // every product: only the files a product places in the template are its own business.
128
- const packageOptions = productPackageOptionsFactory({ catalog, underpostVersion: Underpost.version });
141
+ const packageOptions = productPackageOptionsFactory({ catalog, engineDependencies: sourcePackageJson.dependencies });
129
142
 
130
143
  switch (confName) {
131
144
  case 'dd-cyberia': {
@@ -221,16 +234,49 @@ const buildDeployTemplate = async (confName) => {
221
234
  };
222
235
 
223
236
  /**
224
- * Carries this build stage's coverage HTML report into the assembled template, so every
225
- * container started from the published source serves the report instead of generating one.
237
+ * The coverage reports a deploy id's conf declares, as {@link deployCoverageReports} reads them.
238
+ * The conf is fetched when this checkout does not carry it yet: a CI runner builds from a bare
239
+ * engine tree, and a deploy without source moves never pulls its conf through the assembly.
240
+ * @param {string} deployId - A concrete deploy id.
241
+ * @returns {Array<{id: string, suite?: string, path?: string}>}
226
242
  */
227
- const bundleDeployCoverage = () => {
228
- const { bundled, from, to } = bundleCoverageReport('.', basePath);
229
- if (bundled) return void logger.info('Build coverage artifact', { from, to });
230
- logger.warn('No coverage report to bundle; the deploy will publish the unavailable page', {
231
- hint: 'node bin/build <deploy-id> --coverage',
232
- to,
233
- });
243
+ const deployReports = (deployId) => {
244
+ Underpost.repo.sparseCheckoutDirectory(`conf/${deployId}`);
245
+ return deployCoverageReports(
246
+ JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8')),
247
+ );
248
+ };
249
+
250
+ /**
251
+ * Runs, once each, the test suites the deploy ids' coverage reports name. A product suite
252
+ * imports the modules its catalog pins, so those dependencies are installed into this
253
+ * checkout first — the same install a product deploy performs before it builds.
254
+ * @param {string[]} deployIds - Concrete deploy ids.
255
+ */
256
+ const runDeployCoverage = async (deployIds) => {
257
+ const suites = new Set();
258
+ for (const deployId of deployIds) {
259
+ await installDeployDependencies(deployId);
260
+ for (const { suite } of deployReports(deployId)) if (suite) suites.add(suite);
261
+ }
262
+ for (const suite of suites) shellExec(coverageReportCommand({ suite }));
263
+ };
264
+
265
+ /**
266
+ * Carries this build stage's coverage HTML reports into the assembled template, so every
267
+ * container started from the published source serves them instead of generating one.
268
+ * @param {string} deployId - A concrete deploy id.
269
+ */
270
+ const bundleDeployCoverage = (deployId) => {
271
+ for (const { id, bundled, from, to } of bundleCoverageReports(deployReports(deployId), basePath)) {
272
+ if (bundled) logger.info('Build coverage artifact', { id, from, to });
273
+ else
274
+ logger.warn('No coverage report to bundle; the deploy will publish the unavailable page', {
275
+ id,
276
+ hint: 'node bin/build <deploy-id> --coverage',
277
+ to,
278
+ });
279
+ }
234
280
  };
235
281
 
236
282
  const program = new Command();
@@ -247,7 +293,7 @@ program
247
293
  )
248
294
  .option(
249
295
  '--coverage',
250
- `Run the test suite to refresh ./coverage before assembly, so the artifact carries a current ${COVERAGE_BUNDLE_DIRECTORY} report.`,
296
+ `Run the test suites the deploy ids' coverage reports name before assembly, so the artifact carries current ${COVERAGE_BUNDLE_DIRECTORY} reports.`,
251
297
  false,
252
298
  )
253
299
  .option(
@@ -255,6 +301,16 @@ program
255
301
  'After assembling each deploy id, publish it to its private test source repo (underpostnet/engine-test-<id>) for isolated test deploys.',
256
302
  false,
257
303
  )
304
+ .option(
305
+ '--force',
306
+ 'Always pull each deploy id source repo (e.g. ../engine-prototype) before syncing its sourceMoves, instead of only when a path is missing from both trees.',
307
+ false,
308
+ )
309
+ .option(
310
+ '--sync-sources',
311
+ 'Copy each deploy id catalog sourceMoves path from this tree back to its source repo (e.g. ../engine-prototype) and exit (no template assembly). The engine ignores these paths, so the change is reviewed and committed there.',
312
+ false,
313
+ )
258
314
  .action(async (confName, env, options) => {
259
315
  const deployList = resolveDeployList(confName);
260
316
  logger.info('Build repository', { confName, basePath, deployList, conf: !!options.conf });
@@ -267,18 +323,37 @@ program
267
323
  return;
268
324
  }
269
325
 
270
- // Tests run here, in the build stage, and exactly once: the artifact carries the report so
271
- // no container ever has to produce its own. Refreshing is opt-in because a template
272
- // assembly is not otherwise a test run.
273
- if (options.coverage) shellExec(`npm run test:coverage`);
326
+ if (options.syncSources) {
327
+ for (const deployId of deployList) {
328
+ const { sourceMoves } = await loadDeployCatalog(deployId);
329
+ if (!sourceMoves.length) {
330
+ logger.warn('No sourceMoves declared; nothing to sync back', { deployId });
331
+ continue;
332
+ }
333
+ const mirrored = syncDeployIdSourcesBack(sourceMoves);
334
+ for (const src of mirrored) logger.info('Build sync source', src);
335
+ if (mirrored.length !== sourceMoves.length)
336
+ logger.warn('Some declared sources are not in this tree and were left as they are in the source repo', {
337
+ deployId,
338
+ hint: `node bin/build ${deployId}`,
339
+ skipped: sourceMoves.length - mirrored.length,
340
+ });
341
+ }
342
+ return;
343
+ }
344
+
345
+ // Tests run here, in the build stage, and once per declared suite: the artifact carries
346
+ // each report so no container ever has to produce its own. Refreshing is opt-in because
347
+ // a template assembly is not otherwise a test run.
348
+ if (options.coverage) await runDeployCoverage(deployList);
274
349
 
275
350
  for (const deployId of deployList) {
276
351
  // Reconstruct the base template from 0 before each deploy id so neither a previous
277
352
  // build run nor the deploy id assembled before this one leaks into it. Opt out with
278
353
  // --no-template-rebuild.
279
354
  if (options.templateRebuild) await buildTemplate({ toPath: basePath });
280
- await buildDeployTemplate(deployId);
281
- bundleDeployCoverage();
355
+ await buildDeployTemplate(deployId, { force: options.force });
356
+ bundleDeployCoverage(deployId);
282
357
  // Publish the just-assembled tree to the deploy id's private test repo so a
283
358
  // pod started with `--private-test-repo` clones this work-in-progress source.
284
359
  if (options.updatePrivate) await updatePrivateEngineTestRepo(deployId);