cyberia 3.2.22 → 3.2.70

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 (185) hide show
  1. package/.env.example +127 -68
  2. package/.github/workflows/cyberia-client.cd.yml +40 -0
  3. package/.github/workflows/cyberia-server.cd.yml +40 -0
  4. package/.github/workflows/docker-image.cyberia-client.ci.yml +49 -0
  5. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +48 -0
  6. package/.github/workflows/docker-image.cyberia-server.ci.yml +69 -0
  7. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +69 -0
  8. package/.github/workflows/docker-image.engine-cyberia.ci.yml +52 -0
  9. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +52 -0
  10. package/.github/workflows/engine-cyberia.cd.yml +33 -24
  11. package/.github/workflows/engine-cyberia.ci.yml +13 -3
  12. package/.github/workflows/ghpkg.ci.yml +88 -1
  13. package/.github/workflows/gitlab.ci.yml +1 -1
  14. package/.github/workflows/hardhat.ci.yml +1 -1
  15. package/.github/workflows/npmpkg.ci.yml +10 -7
  16. package/.github/workflows/publish.ci.yml +2 -2
  17. package/.github/workflows/publish.cyberia.ci.yml +5 -16
  18. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -8
  19. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  20. package/CHANGELOG.md +301 -1
  21. package/CLI-HELP.md +71 -6
  22. package/Dockerfile +141 -43
  23. package/Dockerfile.dev +143 -0
  24. package/Dockerfile.test +165 -0
  25. package/README.md +1 -1
  26. package/baremetal/commission-workflows.json +1 -0
  27. package/bin/build.js +31 -0
  28. package/bin/cyberia.js +1080 -184
  29. package/bin/deploy.js +2 -2
  30. package/bin/index.js +1080 -184
  31. package/bump.config.js +1 -0
  32. package/compose.env +131 -0
  33. package/conf.js +18 -1
  34. package/deployment.yaml +2 -2
  35. package/docker-compose.yml +316 -0
  36. package/hardhat/hardhat.config.js +2 -2
  37. package/hardhat/package-lock.json +620 -2041
  38. package/hardhat/package.json +7 -5
  39. package/hardhat/scripts/deployObjectLayerToken.js +18 -18
  40. package/hardhat/test/ObjectLayerToken.js +378 -274
  41. package/ipfs/configure-ipfs.sh +13 -0
  42. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  43. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  44. package/manifests/deployment/dd-cyberia-development/deployment.yaml +2 -2
  45. package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
  46. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +32 -0
  47. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  48. package/mongodb/entrypoint.sh +76 -0
  49. package/nginx.conf +87 -0
  50. package/package.json +31 -19
  51. package/pv-pvc.yaml +32 -0
  52. package/scripts/disk-clean.sh +85 -60
  53. package/scripts/kubeadm-node-setup.sh +317 -0
  54. package/scripts/rocky-kickstart.sh +877 -185
  55. package/scripts/rpmfusion-ffmpeg-setup.sh +26 -50
  56. package/scripts/test-monitor.sh +3 -5
  57. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +43 -7
  58. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +17 -25
  59. package/src/api/cyberia-action/cyberia-action.controller.js +19 -0
  60. package/src/api/cyberia-action/cyberia-action.model.js +21 -29
  61. package/src/api/cyberia-action/cyberia-action.router.js +42 -7
  62. package/src/api/cyberia-action/cyberia-action.service.js +20 -4
  63. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +58 -57
  64. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +37 -6
  65. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +8 -2
  66. package/src/api/cyberia-entity/cyberia-entity.router.js +39 -7
  67. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +74 -0
  68. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
  69. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +63 -0
  70. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
  71. package/src/api/cyberia-instance/cyberia-fallback-world.js +62 -10
  72. package/src/api/cyberia-instance/cyberia-instance.model.js +32 -2
  73. package/src/api/cyberia-instance/cyberia-instance.router.js +6 -6
  74. package/src/api/cyberia-instance/cyberia-world-generator.js +116 -3
  75. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +3 -0
  76. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +39 -7
  77. package/src/api/cyberia-map/cyberia-map.router.js +21 -6
  78. package/src/api/cyberia-quest/cyberia-quest.controller.js +38 -0
  79. package/src/api/cyberia-quest/cyberia-quest.router.js +47 -7
  80. package/src/api/cyberia-quest/cyberia-quest.service.js +59 -4
  81. package/src/api/cyberia-saga/cyberia-saga.controller.js +74 -0
  82. package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
  83. package/src/api/cyberia-saga/cyberia-saga.router.js +63 -0
  84. package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
  85. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +551 -129
  86. package/src/api/cyberia-skill/cyberia-skill.controller.js +74 -0
  87. package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
  88. package/src/api/cyberia-skill/cyberia-skill.router.js +63 -0
  89. package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
  90. package/src/api/ipfs/ipfs.service.js +28 -15
  91. package/src/api/object-layer/object-layer.router.js +25 -15
  92. package/src/api/object-layer/object-layer.service.js +15 -20
  93. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +39 -7
  94. package/src/cli/baremetal.js +717 -16
  95. package/src/cli/cluster.js +80 -5
  96. package/src/cli/deploy.js +127 -11
  97. package/src/cli/docker-compose.js +648 -0
  98. package/src/cli/env.js +11 -2
  99. package/src/cli/fs.js +75 -30
  100. package/src/cli/image.js +129 -51
  101. package/src/cli/index.js +110 -6
  102. package/src/cli/kickstart.js +142 -20
  103. package/src/cli/release.js +46 -4
  104. package/src/cli/repository.js +238 -33
  105. package/src/cli/run.js +520 -114
  106. package/src/cli/secrets.js +82 -48
  107. package/src/cli/ssh.js +234 -0
  108. package/src/cli/static.js +2 -2
  109. package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
  110. package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
  111. package/src/client/components/cyberia/InstanceEngineCyberia.js +219 -13
  112. package/src/client/components/cyberia/MapEngineCyberia.js +154 -71
  113. package/src/client/components/cyberia/ObjectLayerEngineModal.js +40 -63
  114. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +34 -20
  115. package/src/client/components/cyberia/SharedDefaultsCyberia.js +195 -4
  116. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +66 -0
  117. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +8 -0
  118. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -0
  119. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +45 -27
  120. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +3 -3
  121. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +39 -22
  122. package/src/client/public/cyberia-docs/CYBERIA-LORE.md +88 -0
  123. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
  124. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +8 -1
  125. package/src/client/public/cyberia-docs/CYBERIA.md +1 -1
  126. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +5 -5
  127. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  128. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  129. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
  130. package/src/client/services/cyberia-instance/cyberia-instance.management.js +2 -2
  131. package/src/client/services/cyberia-map/cyberia-map.management.js +2 -2
  132. package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
  133. package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
  134. package/src/client/services/object-layer/object-layer.management.js +6 -6
  135. package/src/{server → client-builder}/client-build-docs.js +15 -5
  136. package/src/{server → client-builder}/client-build-live.js +3 -3
  137. package/src/{server → client-builder}/client-build.js +25 -22
  138. package/src/{server → client-builder}/client-dev-server.js +3 -3
  139. package/src/{server → client-builder}/client-icons.js +2 -2
  140. package/src/{server → client-builder}/ssr.js +5 -5
  141. package/src/client.build.js +1 -3
  142. package/src/client.dev.js +1 -1
  143. package/src/db/mongo/MongoBootstrap.js +12 -12
  144. package/src/grpc/cyberia/grpc-server.js +255 -70
  145. package/src/index.js +12 -1
  146. package/src/mailer/EmailRender.js +1 -1
  147. package/src/{server → projects/cyberia}/atlas-sprite-sheet-generator.js +2 -2
  148. package/src/{server → projects/cyberia}/besu-genesis-generator.js +3 -3
  149. package/src/projects/cyberia/catalog-cyberia.js +81 -0
  150. package/src/projects/cyberia/gemini-client.js +175 -0
  151. package/src/projects/cyberia/generate-saga.js +2107 -0
  152. package/src/{server → projects/cyberia}/ipfs-client.js +2 -2
  153. package/src/{server → projects/cyberia}/object-layer.js +12 -108
  154. package/src/{server → projects/cyberia}/semantic-layer-generator-floor.js +1 -1
  155. package/src/{server → projects/cyberia}/semantic-layer-generator-resource.js +1 -1
  156. package/src/{server → projects/cyberia}/semantic-layer-generator-skin.js +1 -1
  157. package/src/{server → projects/cyberia}/semantic-layer-generator.js +2 -2
  158. package/src/{server → projects/cyberia}/shape-generator.js +2 -2
  159. package/src/{server → projects/underpost}/catalog-underpost.js +1 -2
  160. package/src/runtime/cyberia-client/Dockerfile +27 -61
  161. package/src/runtime/cyberia-client/Dockerfile.dev +20 -12
  162. package/src/runtime/cyberia-server/Dockerfile +21 -20
  163. package/src/runtime/cyberia-server/Dockerfile.dev +17 -8
  164. package/src/runtime/engine-cyberia/Dockerfile +143 -0
  165. package/src/runtime/engine-cyberia/Dockerfile.dev +143 -0
  166. package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
  167. package/src/runtime/engine-cyberia/compose.env +131 -0
  168. package/src/runtime/engine-cyberia/docker-compose.yml +316 -0
  169. package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
  170. package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
  171. package/src/runtime/engine-cyberia/nginx.conf +87 -0
  172. package/src/runtime/express/Express.js +2 -2
  173. package/src/runtime/nginx/Nginx.js +250 -0
  174. package/src/server/catalog.js +9 -14
  175. package/src/server/conf.js +3 -6
  176. package/src/server/runtime-status.js +18 -1
  177. package/src/server/start.js +12 -2
  178. package/src/server.js +6 -2
  179. package/test/cyberia-instance-conf-defaults.test.js +140 -0
  180. package/test/deploy-monitor.test.js +26 -10
  181. package/test/shape-generator.test.js +7 -1
  182. package/typedoc.dd-cyberia.json +3 -1
  183. package/typedoc.json +3 -1
  184. /package/src/client/ssr/{Render.js → RootDocument.js} +0 -0
  185. /package/src/{server → client-builder}/client-formatted.js +0 -0
package/Dockerfile CHANGED
@@ -1,45 +1,143 @@
1
- FROM rockylinux:9
2
-
3
- # Update and install required packages
4
- RUN dnf -y update && \
5
- dnf -y install epel-release && \
6
- dnf -y install --allowerasing \
7
- bzip2 \
8
- sudo \
9
- curl \
10
- net-tools \
11
- openssh-server \
12
- nano \
13
- vim-enhanced \
14
- less \
15
- openssl-devel \
16
- wget \
17
- git \
18
- gnupg2 \
19
- libnsl \
20
- perl && \
21
- dnf clean all
22
-
23
-
24
- # Install Node.js
25
- RUN curl -fsSL https://rpm.nodesource.com/setup_24.x | bash -
26
- RUN dnf install nodejs -y
27
- RUN dnf clean all
28
-
29
- # Verify Node.js and npm versions
30
- RUN node --version
31
- RUN npm --version
32
-
33
- # Install underpost ci/cd cli
34
- RUN npm install -g underpost
35
- RUN underpost --version
36
-
37
- # Create working directory
1
+ # syntax=docker/dockerfile:1.7
2
+ #
3
+ # engine-cyberia PRODUCTION image (underpost/engine-cyberia).
4
+ #
5
+ # ---------------------------------------------------------------------------
6
+ # Stage 1 builder: clone the private deploy, build it, then scrub secrets.
7
+ # ---------------------------------------------------------------------------
8
+ FROM rockylinux/rockylinux:9 AS builder
9
+ ARG UNDERPOST_VERSION=3.2.70
10
+ # Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
11
+ # underpost's dependencies require >=24.15.0, so install the official binary.
12
+ ARG NODE_VERSION=24.15.0
13
+ ENV NODE_ENV=production
14
+
15
+ RUN set -eux; \
16
+ # `sudo` is required because underpost's build steps shell out to
17
+ # `sudo cp`/`sudo rm` (src/server/start.js); the build runs as root so sudo
18
+ # is just a passthrough, but the binary must exist.
19
+ dnf install -y git openssl tar xz sudo; \
20
+ arch="$(uname -m)"; \
21
+ case "$arch" in \
22
+ x86_64) node_arch=x64 ;; \
23
+ aarch64) node_arch=arm64 ;; \
24
+ *) echo "unsupported arch: $arch" >&2; exit 1 ;; \
25
+ esac; \
26
+ curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
27
+ | tar -xJ -C /usr/local --strip-components=1; \
28
+ node --version; npm --version; \
29
+ npm install -g underpost@${UNDERPOST_VERSION}; \
30
+ dnf clean all; rm -rf /var/cache/dnf; \
31
+ npm cache clean --force
32
+
38
33
  WORKDIR /home/dd
39
34
 
40
- # Expose necessary ports
41
- EXPOSE 22
42
- EXPOSE 80
43
- EXPOSE 443
44
- EXPOSE 3000-3100
45
- EXPOSE 4000-4100
35
+ RUN --mount=type=secret,id=github_username \
36
+ # --mount=type=secret,id=github_token \
37
+ set -eu; \
38
+ export GITHUB_USERNAME="$(cat /run/secrets/github_username)"; \
39
+ # export GITHUB_TOKEN="$(cat /run/secrets/github_token)"; \
40
+ export ENGINE_CYBERIA_REPO="engine-cyberia"; \
41
+ export INSTANCE_CODE="amethyst-strata-expansion"; \
42
+ cd /home/dd; \
43
+ underpost clone "$GITHUB_USERNAME/$ENGINE_CYBERIA_REPO"; \
44
+ mkdir -p /home/dd/engine; \
45
+ cp -a ./"$ENGINE_CYBERIA_REPO"/. /home/dd/engine/; \
46
+ rm -rf ./"$ENGINE_CYBERIA_REPO"; \
47
+ cd /home/dd; \
48
+ underpost clone "$GITHUB_USERNAME/cyberia-instances"; \
49
+ rm -rf /home/dd/engine/engine-private; \
50
+ mkdir -p /home/dd/engine/engine-private/conf/dd-cyberia; \
51
+ cp -a ./cyberia-instances/conf/dd-cyberia/. /home/dd/engine/engine-private/conf/dd-cyberia/.; \
52
+ cp -a /home/dd/engine/package.json /home/dd/engine/engine-private/conf/dd-cyberia/package.json; \
53
+ mkdir -p /home/dd/engine/engine-private/cyberia-instances; \
54
+ cp -a ./cyberia-instances/instances/"$INSTANCE_CODE" /home/dd/engine/engine-private/cyberia-instances/"$INSTANCE_CODE"; \
55
+ mkdir -p /home/dd/engine/src/client/public/cyberia; \
56
+ cp -a ./cyberia-instances/public/cyberia/. /home/dd/engine/src/client/public/cyberia/.; \
57
+ # The engine gRPC server loads its schema at runtime from
58
+ # cyberia-server/gen/proto/cyberia.proto (src/grpc/cyberia/grpc-server.js);
59
+ # fetch just that file so the engine can bind :50051 / :4005 without the
60
+ # full cyberia-server repo.
61
+ underpost clone "$GITHUB_USERNAME/cyberia-server"; \
62
+ mkdir -p /home/dd/engine/cyberia-server/gen/proto; \
63
+ cp -a ./cyberia-server/gen/proto/cyberia.proto /home/dd/engine/cyberia-server/gen/proto/cyberia.proto; \
64
+ rm -rf ./cyberia-server; \
65
+ cd /home/dd/engine; \
66
+ # --- install deps + env, then replay build-safe itc provisioning ----------
67
+ npm install; \
68
+ node bin env dd-cyberia production; \
69
+ ( cd /home/dd/engine/hardhat && npm install --include=dev ); \
70
+ # --- build the client bundle (assets are now in place) --------------------
71
+ cd /home/dd/engine; \
72
+ node bin client dd-cyberia; \
73
+ # --- CREDENTIAL SCRUB (defense in depth, while secrets are still in scope) -
74
+ # 1) Redact every real secret value from any file it may have reached.
75
+ # for _secret in "$GITHUB_TOKEN" "$CLOUDINARY_API_SECRET" "$CLOUDINARY_API_KEY"; do \
76
+ for _secret in "$GITHUB_USERNAME"; do \
77
+ # for _secret in "$GITHUB_USERNAME" "$GITHUB_TOKEN"; do \
78
+ [ -n "$_secret" ] || continue; \
79
+ grep -rlF --exclude-dir=node_modules --exclude-dir=.git "$_secret" /home/dd/engine 2>/dev/null \
80
+ | xargs -r sed -i "s#${_secret}#__REDACTED__#g" || true; \
81
+ done; \
82
+ # unset GITHUB_TOKEN GITHUB_USERNAME; \
83
+ # unset GITHUB_TOKEN GITHUB_USERNAME CLOUDINARY_CLOUD_NAME CLOUDINARY_API_KEY CLOUDINARY_API_SECRET; \
84
+ unset GITHUB_USERNAME; \
85
+
86
+ # 2) Every .git dir — clone URLs embed the token in .git/config, and the
87
+ # private history itself must not ship.
88
+ find /home/dd/engine -type d -name .git -prune -exec rm -rf {} + 2>/dev/null || true; \
89
+ # 3) User-level credential stores possibly written during the build.
90
+ rm -rf /root/.gitconfig /root/.git-credentials /root/.config/git \
91
+ /root/.netrc /root/.ssh /root/.npm /root/.cache /root/.node-gyp; \
92
+ # 4) The underpost global env store may hold GITHUB_TOKEN.
93
+ rm -f "$(underpost root)/underpost/.env" 2>/dev/null || true; \
94
+ # 5) Build caches, temp, and build-only toolchains. hardhat is contract
95
+ # build/CLI tooling (used only to build the coverage docs above); the
96
+ # runtime server never imports it, so its dev node_modules is pure bloat.
97
+ npm cache clean --force 2>/dev/null || true; \
98
+ rm -rf /home/dd/cyberia-instances \
99
+ /home/dd/engine/src/client/public/itemledger \
100
+ /home/dd/engine/src/client/public/cryptokoyn \
101
+ /home/dd/engine/src/client/components/cryptokoyn \
102
+ /home/dd/engine/src/client/components/itemledger \
103
+ /home/dd/engine/src/client/Itemledger.index.js \
104
+ /home/dd/engine/src/client/Cryptokoyn.index.js \
105
+ /home/dd/engine/hardhat/node_modules \
106
+ /home/dd/engine/.npm /tmp/* /var/tmp/* /var/cache/dnf
107
+
108
+ # ---------------------------------------------------------------------------
109
+ # Stage 2 — runtime: clean base + pinned Node toolchain + scrubbed app tree.
110
+ # ---------------------------------------------------------------------------
111
+ FROM rockylinux/rockylinux:9 AS runtime
112
+ ENV NODE_ENV=production
113
+
114
+ # Node + npm + the underpost CLI (exact pinned version) from the builder — no
115
+ # re-download, no git/build toolchain. libstdc++ is the only runtime lib the
116
+ # prebuilt Node binary needs beyond the base image.
117
+ COPY --from=builder /usr/local/ /usr/local/
118
+ RUN dnf install -y libstdc++ git sudo && dnf clean all && rm -rf /var/cache/dnf && \
119
+ useradd --create-home --home-dir /home/dd --shell /usr/sbin/nologin dd && \
120
+ # The runtime runs as `dd`, but `underpost start --build` shells out to `sudo cp`/`sudo rm`
121
+ # (src/server/start.js). Grant passwordless sudo so those succeed without a TTY/password.
122
+ printf 'dd ALL=(ALL) NOPASSWD:ALL\n' > /etc/sudoers.d/dd && chmod 0440 /etc/sudoers.d/dd && \
123
+ # underpost persists its global env at $(npm root -g)/underpost/.env; the
124
+ # non-root runtime user must be able to write it (fixes EACCES on start).
125
+ chown -R dd:dd /usr/local/lib/node_modules/underpost
126
+
127
+ # Copy ONLY the scrubbed runtime tree — no .git, no token, no caches.
128
+ COPY --from=builder --chown=dd:dd /home/dd/engine /home/dd/engine
129
+
130
+ RUN chmod +x /home/dd/engine/scripts/rpmfusion-ffmpeg-setup.sh && \
131
+ /home/dd/engine/scripts/rpmfusion-ffmpeg-setup.sh
132
+
133
+ # Explicit re-chown: PVC-backed mounts under src/client/public land here at
134
+ # pod start and may override the COPY --chown above with root ownership.
135
+ RUN chown -R dd:dd /home/dd/engine/src/client/public
136
+
137
+ USER dd
138
+ WORKDIR /home/dd/engine
139
+
140
+ EXPOSE 3005
141
+ EXPOSE 50051
142
+
143
+ CMD ["/bin/sh", "-c", "underpost start --run dd-cyberia production"]
package/Dockerfile.dev ADDED
@@ -0,0 +1,143 @@
1
+ # syntax=docker/dockerfile:1.7
2
+ #
3
+ # engine-cyberia — DEVELOPMENT image (underpost/engine-cyberia-dev).
4
+ #
5
+ # ---------------------------------------------------------------------------
6
+ # Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
7
+ # ---------------------------------------------------------------------------
8
+ FROM rockylinux/rockylinux:9 AS builder
9
+ ARG UNDERPOST_VERSION=3.2.70
10
+ # Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
11
+ # underpost's dependencies require >=24.15.0, so install the official binary.
12
+ ARG NODE_VERSION=24.15.0
13
+ ENV NODE_ENV=development
14
+
15
+ RUN set -eux; \
16
+ # `sudo` is required because underpost's build steps shell out to
17
+ # `sudo cp`/`sudo rm` (src/server/start.js); the build runs as root so sudo
18
+ # is just a passthrough, but the binary must exist.
19
+ dnf install -y git openssl tar xz sudo; \
20
+ arch="$(uname -m)"; \
21
+ case "$arch" in \
22
+ x86_64) node_arch=x64 ;; \
23
+ aarch64) node_arch=arm64 ;; \
24
+ *) echo "unsupported arch: $arch" >&2; exit 1 ;; \
25
+ esac; \
26
+ curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
27
+ | tar -xJ -C /usr/local --strip-components=1; \
28
+ node --version; npm --version; \
29
+ npm install -g underpost@${UNDERPOST_VERSION}; \
30
+ dnf clean all; rm -rf /var/cache/dnf; \
31
+ npm cache clean --force
32
+
33
+ WORKDIR /home/dd
34
+
35
+ RUN --mount=type=secret,id=github_username \
36
+ # --mount=type=secret,id=github_token \
37
+ set -eu; \
38
+ export GITHUB_USERNAME="$(cat /run/secrets/github_username)"; \
39
+ # export GITHUB_TOKEN="$(cat /run/secrets/github_token)"; \
40
+ export ENGINE_CYBERIA_REPO="engine-cyberia"; \
41
+ export INSTANCE_CODE="amethyst-strata-expansion"; \
42
+ cd /home/dd; \
43
+ underpost clone "$GITHUB_USERNAME/$ENGINE_CYBERIA_REPO"; \
44
+ mkdir -p /home/dd/engine; \
45
+ cp -a ./"$ENGINE_CYBERIA_REPO"/. /home/dd/engine/; \
46
+ rm -rf ./"$ENGINE_CYBERIA_REPO"; \
47
+ cd /home/dd; \
48
+ underpost clone "$GITHUB_USERNAME/cyberia-instances"; \
49
+ rm -rf /home/dd/engine/engine-private; \
50
+ mkdir -p /home/dd/engine/engine-private/conf/dd-cyberia; \
51
+ cp -a ./cyberia-instances/conf/dd-cyberia/. /home/dd/engine/engine-private/conf/dd-cyberia/.; \
52
+ cp -a /home/dd/engine/package.json /home/dd/engine/engine-private/conf/dd-cyberia/package.json; \
53
+ mkdir -p /home/dd/engine/engine-private/cyberia-instances; \
54
+ cp -a ./cyberia-instances/instances/"$INSTANCE_CODE" /home/dd/engine/engine-private/cyberia-instances/"$INSTANCE_CODE"; \
55
+ mkdir -p /home/dd/engine/src/client/public/cyberia; \
56
+ cp -a ./cyberia-instances/public/cyberia/. /home/dd/engine/src/client/public/cyberia/.; \
57
+ # The engine gRPC server loads its schema at runtime from
58
+ # cyberia-server/gen/proto/cyberia.proto (src/grpc/cyberia/grpc-server.js);
59
+ # fetch just that file so the engine can bind :50051 / :4005 without the
60
+ # full cyberia-server repo.
61
+ underpost clone "$GITHUB_USERNAME/cyberia-server"; \
62
+ mkdir -p /home/dd/engine/cyberia-server/gen/proto; \
63
+ cp -a ./cyberia-server/gen/proto/cyberia.proto /home/dd/engine/cyberia-server/gen/proto/cyberia.proto; \
64
+ rm -rf ./cyberia-server; \
65
+ cd /home/dd/engine; \
66
+ # --- install deps + env, then replay build-safe itc provisioning ----------
67
+ npm install; \
68
+ node bin env dd-cyberia development; \
69
+ ( cd /home/dd/engine/hardhat && npm install --include=dev ); \
70
+ # --- build the client bundle (assets are now in place) --------------------
71
+ cd /home/dd/engine; \
72
+ node bin client dd-cyberia; \
73
+ # --- CREDENTIAL SCRUB (defense in depth, while secrets are still in scope) -
74
+ # 1) Redact every real secret value from any file it may have reached.
75
+ # for _secret in "$GITHUB_TOKEN" "$CLOUDINARY_API_SECRET" "$CLOUDINARY_API_KEY"; do \
76
+ for _secret in "$GITHUB_USERNAME"; do \
77
+ # for _secret in "$GITHUB_USERNAME" "$GITHUB_TOKEN"; do \
78
+ [ -n "$_secret" ] || continue; \
79
+ grep -rlF --exclude-dir=node_modules --exclude-dir=.git "$_secret" /home/dd/engine 2>/dev/null \
80
+ | xargs -r sed -i "s#${_secret}#__REDACTED__#g" || true; \
81
+ done; \
82
+ # unset GITHUB_TOKEN GITHUB_USERNAME; \
83
+ # unset GITHUB_TOKEN GITHUB_USERNAME CLOUDINARY_CLOUD_NAME CLOUDINARY_API_KEY CLOUDINARY_API_SECRET; \
84
+ unset GITHUB_USERNAME; \
85
+
86
+ # 2) Every .git dir — clone URLs embed the token in .git/config, and the
87
+ # private history itself must not ship.
88
+ find /home/dd/engine -type d -name .git -prune -exec rm -rf {} + 2>/dev/null || true; \
89
+ # 3) User-level credential stores possibly written during the build.
90
+ rm -rf /root/.gitconfig /root/.git-credentials /root/.config/git \
91
+ /root/.netrc /root/.ssh /root/.npm /root/.cache /root/.node-gyp; \
92
+ # 4) The underpost global env store may hold GITHUB_TOKEN.
93
+ rm -f "$(underpost root)/underpost/.env" 2>/dev/null || true; \
94
+ # 5) Build caches, temp, and build-only toolchains. hardhat is contract
95
+ # build/CLI tooling (used only to build the coverage docs above); the
96
+ # runtime server never imports it, so its dev node_modules is pure bloat.
97
+ npm cache clean --force 2>/dev/null || true; \
98
+ rm -rf /home/dd/cyberia-instances \
99
+ /home/dd/engine/src/client/public/itemledger \
100
+ /home/dd/engine/src/client/public/cryptokoyn \
101
+ /home/dd/engine/src/client/components/cryptokoyn \
102
+ /home/dd/engine/src/client/components/itemledger \
103
+ /home/dd/engine/src/client/Itemledger.index.js \
104
+ /home/dd/engine/src/client/Cryptokoyn.index.js \
105
+ /home/dd/engine/hardhat/node_modules \
106
+ /home/dd/engine/.npm /tmp/* /var/tmp/* /var/cache/dnf
107
+
108
+ # ---------------------------------------------------------------------------
109
+ # Stage 2 — runtime: clean base + pinned Node toolchain + scrubbed app tree.
110
+ # ---------------------------------------------------------------------------
111
+ FROM rockylinux/rockylinux:9 AS runtime
112
+ ENV NODE_ENV=development
113
+
114
+ # Node + npm + the underpost CLI (exact pinned version) from the builder — no
115
+ # re-download, no git/build toolchain. libstdc++ is the only runtime lib the
116
+ # prebuilt Node binary needs beyond the base image.
117
+ COPY --from=builder /usr/local/ /usr/local/
118
+ RUN dnf install -y libstdc++ git sudo && dnf clean all && rm -rf /var/cache/dnf && \
119
+ useradd --create-home --home-dir /home/dd --shell /usr/sbin/nologin dd && \
120
+ # The runtime runs as `dd`, but `underpost start --build` shells out to `sudo cp`/`sudo rm`
121
+ # (src/server/start.js). Grant passwordless sudo so those succeed without a TTY/password.
122
+ printf 'dd ALL=(ALL) NOPASSWD:ALL\n' > /etc/sudoers.d/dd && chmod 0440 /etc/sudoers.d/dd && \
123
+ # underpost persists its global env at $(npm root -g)/underpost/.env; the
124
+ # non-root runtime user must be able to write it (fixes EACCES on start).
125
+ chown -R dd:dd /usr/local/lib/node_modules/underpost
126
+
127
+ # Copy ONLY the scrubbed runtime tree — no .git, no token, no caches.
128
+ COPY --from=builder --chown=dd:dd /home/dd/engine /home/dd/engine
129
+
130
+ RUN chmod +x /home/dd/engine/scripts/rpmfusion-ffmpeg-setup.sh && \
131
+ /home/dd/engine/scripts/rpmfusion-ffmpeg-setup.sh
132
+
133
+ # Explicit re-chown: PVC-backed mounts under src/client/public land here at
134
+ # pod start and may override the COPY --chown above with root ownership.
135
+ RUN chown -R dd:dd /home/dd/engine/src/client/public
136
+
137
+ USER dd
138
+ WORKDIR /home/dd/engine
139
+
140
+ EXPOSE 4005
141
+ EXPOSE 50051
142
+
143
+ CMD ["/bin/sh", "-c", "underpost start --run dd-cyberia development"]
@@ -0,0 +1,165 @@
1
+ # syntax=docker/dockerfile:1.7
2
+ #
3
+ # engine-cyberia — DEVELOPMENT image (underpost/engine-cyberia-dev).
4
+ #
5
+ # ---------------------------------------------------------------------------
6
+ # Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
7
+ # ---------------------------------------------------------------------------
8
+ FROM rockylinux/rockylinux:9 AS builder
9
+ ARG UNDERPOST_VERSION=3.2.70
10
+ # Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
11
+ # underpost's dependencies require >=24.15.0, so install the official binary.
12
+ ARG NODE_VERSION=24.15.0
13
+ ENV NODE_ENV=development
14
+
15
+ RUN set -eux; \
16
+ # `sudo` is required because underpost's build steps shell out to
17
+ # `sudo cp`/`sudo rm` (src/server/start.js); the build runs as root so sudo
18
+ # is just a passthrough, but the binary must exist.
19
+ dnf install -y git openssl tar xz sudo; \
20
+ arch="$(uname -m)"; \
21
+ case "$arch" in \
22
+ x86_64) node_arch=x64 ;; \
23
+ aarch64) node_arch=arm64 ;; \
24
+ *) echo "unsupported arch: $arch" >&2; exit 1 ;; \
25
+ esac; \
26
+ curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
27
+ | tar -xJ -C /usr/local --strip-components=1; \
28
+ node --version; npm --version; \
29
+ npm install -g underpost@${UNDERPOST_VERSION}; \
30
+ dnf clean all; rm -rf /var/cache/dnf; \
31
+ npm cache clean --force
32
+
33
+ WORKDIR /home/dd
34
+
35
+ # Single hermetic RUN: GitHub credentials are mounted as secrets (readable only
36
+ # here, never persisted), used to clone + build the private dd-cyberia deploy,
37
+ # then every credential/secret/VCS trace is removed BEFORE this layer commits.
38
+ RUN --mount=type=secret,id=github_token \
39
+ --mount=type=secret,id=github_username \
40
+ --mount=type=secret,id=cloudinary_cloud_name \
41
+ --mount=type=secret,id=cloudinary_api_key \
42
+ --mount=type=secret,id=cloudinary_api_secret \
43
+ set -eu; \
44
+ export GITHUB_TOKEN="$(cat /run/secrets/github_token)"; \
45
+ export GITHUB_USERNAME="$(cat /run/secrets/github_username)"; \
46
+ # Cloudinary creds power the `node bin fs --pull` asset downloads below; they
47
+ # are optional (empty when not provided) so builds that don't need assets
48
+ # still work.
49
+ export CLOUDINARY_CLOUD_NAME="$(cat /run/secrets/cloudinary_cloud_name 2>/dev/null || true)"; \
50
+ export CLOUDINARY_API_KEY="$(cat /run/secrets/cloudinary_api_key 2>/dev/null || true)"; \
51
+ export CLOUDINARY_API_SECRET="$(cat /run/secrets/cloudinary_api_secret 2>/dev/null || true)"; \
52
+ \
53
+ # --- fetch sources under our control, then build WITHOUT itc-scripts -----
54
+ # itc-scripts are DEPLOY-time provisioning; the DB-seeding parts (`cyberia
55
+ # ol --drop`, `instance --import`) and the in-cluster .env rewrite cannot run
56
+ # in a hermetic build, so we strip the scripts and replay ONLY the build-safe
57
+ # provisioning steps inline (asset pulls, ffmpeg, hardhat deps, cyberia-server
58
+ # clone). Pre-clone so privateEngineRepoFactory no-ops and --skip-pull-base
59
+ # reuses the tree.
60
+ export ENGINE_CYBERIA_REPO="engine-cyberia"; \
61
+ cd /home/dd; \
62
+ underpost clone "$GITHUB_USERNAME/$ENGINE_CYBERIA_REPO"; \
63
+ mkdir -p /home/dd/engine; \
64
+ cp -a ./"$ENGINE_CYBERIA_REPO"/. /home/dd/engine/; \
65
+ rm -rf ./"$ENGINE_CYBERIA_REPO"; \
66
+ cd /home/dd/engine; \
67
+ rm -rf ./engine-private; \
68
+ underpost clone "$GITHUB_USERNAME/engine-cyberia-private"; \
69
+ mv ./engine-cyberia-private ./engine-private; \
70
+ rm -rf ./engine-private/itc-scripts; \
71
+ \
72
+ # --- install deps + env, then replay build-safe itc provisioning ----------
73
+ npm install; \
74
+ node bin env dd-cyberia development; \
75
+ node bin fs --pull --recursive --deploy-id dd-cyberia --storage-file-path './engine-private/conf/dd-cyberia/storage.engine-cyberia.json'; \
76
+ ( cd /home/dd/engine/hardhat && npm install --include=dev ); \
77
+ ( cd /home/dd/engine && underpost clone underpostnet/cyberia-server ); \
78
+ \
79
+ # --- build the client bundle (assets are now in place) --------------------
80
+ node bin client dd-cyberia; \
81
+ \
82
+ # --- bake NON-secret env (placeholders; real creds come from runtime env) -
83
+ CONF=/home/dd/engine/engine-private/conf/dd-cyberia; \
84
+ cp -a "$CONF/docker-compose/cyberia/compose.env" "$CONF/.env.development"; \
85
+ cp -a "$CONF/docker-compose/cyberia/compose.env" "$CONF/.env.production"; \
86
+ cp -a "$CONF/docker-compose/cyberia/compose.env" "$CONF/.env.test"; \
87
+ cp -a "$CONF/conf.server.dev.dev.json" "$CONF/conf.server.json"; \
88
+ cp -a "$CONF/docker-compose/cyberia/compose.env" /home/dd/engine/.env; \
89
+ \
90
+ # --- drop build-only / non-runtime private material ----------------------
91
+ rm -rf /home/dd/engine/engine-private/itc-scripts; \
92
+ rm -rf /home/dd/engine/engine-private/cyberia-instances/FOREST; \
93
+ rm -rf /home/dd/engine/engine-private/logs; \
94
+ rm -rf "$CONF/build" "$CONF/instances"; \
95
+ rm -rf "$CONF/conf.instances.json"; \
96
+ rm -rf "$CONF/conf.server.dev.underpost.json"; \
97
+ rm -rf "$CONF/storage.bundle.json"; \
98
+ rm -rf "$CONF/storage.json"; \
99
+ rm -rf "$CONF/storage.underpost.json"; \
100
+ \
101
+ # --- CREDENTIAL SCRUB (defense in depth, while secrets are still in scope) -
102
+ # 1) Redact every real secret value from any file it may have reached.
103
+ for _secret in "$GITHUB_TOKEN" "$CLOUDINARY_API_SECRET" "$CLOUDINARY_API_KEY"; do \
104
+ [ -n "$_secret" ] || continue; \
105
+ grep -rlF --exclude-dir=node_modules --exclude-dir=.git "$_secret" /home/dd/engine 2>/dev/null \
106
+ | xargs -r sed -i "s#${_secret}#__REDACTED__#g" || true; \
107
+ done; \
108
+ unset GITHUB_TOKEN GITHUB_USERNAME CLOUDINARY_CLOUD_NAME CLOUDINARY_API_KEY CLOUDINARY_API_SECRET; \
109
+ # 2) Every .git dir — clone URLs embed the token in .git/config, and the
110
+ # private history itself must not ship.
111
+ find /home/dd/engine -type d -name .git -prune -exec rm -rf {} + 2>/dev/null || true; \
112
+ # 3) User-level credential stores possibly written during the build.
113
+ rm -rf /root/.gitconfig /root/.git-credentials /root/.config/git \
114
+ /root/.netrc /root/.ssh /root/.npm /root/.cache /root/.node-gyp; \
115
+ # 4) The underpost global env store may hold GITHUB_TOKEN.
116
+ rm -f "$(underpost root)/underpost/.env" 2>/dev/null || true; \
117
+ # 5) Build caches, temp, and build-only toolchains. hardhat is contract
118
+ # build/CLI tooling (used only to build the coverage docs above); the
119
+ # runtime server never imports it, so its dev node_modules is pure bloat.
120
+ npm cache clean --force 2>/dev/null || true; \
121
+ rm -rf /home/dd/engine/src/client/public/itemledger \
122
+ rm -rf /home/dd/engine/src/client/public/cryptokoyn \
123
+ rm -rf /home/dd/engine/src/client/components/cryptokoyn \
124
+ rm -rf /home/dd/engine/src/client/components/itemledger \
125
+ rm -rf /home/dd/engine/src/client/Itemledger.index.js \
126
+ rm -rf /home/dd/engine/src/client/Cryptokoyn.index.js \
127
+ rm -rf /home/dd/engine/hardhat/node_modules \
128
+ /home/dd/engine/.npm /tmp/* /var/tmp/* /var/cache/dnf
129
+
130
+ # ---------------------------------------------------------------------------
131
+ # Stage 2 — runtime: clean base + pinned Node toolchain + scrubbed app tree.
132
+ # ---------------------------------------------------------------------------
133
+ FROM rockylinux/rockylinux:9 AS runtime
134
+ ENV NODE_ENV=development
135
+
136
+ # Node + npm + the underpost CLI (exact pinned version) from the builder — no
137
+ # re-download, no git/build toolchain. libstdc++ is the only runtime lib the
138
+ # prebuilt Node binary needs beyond the base image.
139
+ COPY --from=builder /usr/local/ /usr/local/
140
+ RUN dnf install -y libstdc++ git sudo && dnf clean all && rm -rf /var/cache/dnf && \
141
+ useradd --create-home --home-dir /home/dd --shell /usr/sbin/nologin dd && \
142
+ # The runtime runs as `dd`, but `underpost start --build` shells out to `sudo cp`/`sudo rm`
143
+ # (src/server/start.js). Grant passwordless sudo so those succeed without a TTY/password.
144
+ printf 'dd ALL=(ALL) NOPASSWD:ALL\n' > /etc/sudoers.d/dd && chmod 0440 /etc/sudoers.d/dd && \
145
+ # underpost persists its global env at $(npm root -g)/underpost/.env; the
146
+ # non-root runtime user must be able to write it (fixes EACCES on start).
147
+ chown -R dd:dd /usr/local/lib/node_modules/underpost
148
+
149
+ # Copy ONLY the scrubbed runtime tree — no .git, no token, no caches.
150
+ COPY --from=builder --chown=dd:dd /home/dd/engine /home/dd/engine
151
+
152
+ RUN chmod +x /home/dd/engine/scripts/rpmfusion-ffmpeg-setup.sh && \
153
+ /home/dd/engine/scripts/rpmfusion-ffmpeg-setup.sh
154
+
155
+ # Explicit re-chown: PVC-backed mounts under src/client/public land here at
156
+ # pod start and may override the COPY --chown above with root ownership.
157
+ RUN chown -R dd:dd /home/dd/engine/src/client/public
158
+
159
+ USER dd
160
+ WORKDIR /home/dd/engine
161
+
162
+ EXPOSE 4005
163
+ EXPOSE 50051
164
+
165
+ CMD ["/bin/sh", "-c", "underpost start --run dd-cyberia development"]
package/README.md CHANGED
@@ -224,7 +224,7 @@ cyberia chain register / mint / transfer / burn / pause / unpause
224
224
 
225
225
  # Named workflows
226
226
  cyberia run-workflow import-default-items
227
- cyberia run-workflow seed-skill-config --instance-code default
227
+ cyberia run-workflow seed-skills
228
228
  cyberia run-workflow seed-dialogues
229
229
  cyberia run-workflow build-manifest
230
230
  cyberia run-workflow build-server-dashboard
@@ -174,6 +174,7 @@
174
174
  "type": "iso-ram",
175
175
  "osIdLike": "rhel centos fedora",
176
176
  "architecture": "amd64",
177
+ "infraSetup": "underpost-kubeadm-contour",
177
178
  "isoUrl": "https://download.rockylinux.org/pub/rocky/9/isos/x86_64/Rocky-9-latest-x86_64-boot.iso",
178
179
  "tftpPrefix": "envy-rocky9",
179
180
  "bootstrapHttpServerPort": 8888,
package/bin/build.js CHANGED
@@ -140,6 +140,7 @@ const buildDeployTemplate = async (confName) => {
140
140
  break;
141
141
  }
142
142
  default:
143
+ for (const path of catalog.templatePaths) fs.copySync(`.${path}`, `${basePath}${path}`);
143
144
  break;
144
145
  }
145
146
 
@@ -153,6 +154,16 @@ const buildDeployTemplate = async (confName) => {
153
154
  if (!fs.existsSync(`${basePath}/images`)) fs.mkdirSync(`${basePath}/images`);
154
155
 
155
156
  fs.copyFileSync(`./.github/workflows/${repoName}.ci.yml`, `${basePath}/.github/workflows/${repoName}.ci.yml`);
157
+ if (fs.existsSync(`./.github/workflows/docker-image.${repoName}.ci.yml`))
158
+ fs.copyFileSync(
159
+ `./.github/workflows/docker-image.${repoName}.ci.yml`,
160
+ `${basePath}/.github/workflows/docker-image.${repoName}.ci.yml`,
161
+ );
162
+ if (fs.existsSync(`./.github/workflows/docker-image.${repoName}.dev.ci.yml`))
163
+ fs.copyFileSync(
164
+ `./.github/workflows/docker-image.${repoName}.dev.ci.yml`,
165
+ `${basePath}/.github/workflows/docker-image.${repoName}.dev.ci.yml`,
166
+ );
156
167
  fs.copyFileSync(`./.github/workflows/${repoName}.cd.yml`, `${basePath}/.github/workflows/${repoName}.cd.yml`);
157
168
 
158
169
  if (fs.existsSync(`./typedoc.${confName}.json`)) {
@@ -178,6 +189,26 @@ const buildDeployTemplate = async (confName) => {
178
189
  `${basePath}/.gitignore`,
179
190
  fs.readFileSync(`.gitignore`, 'utf8').split('# Ignore ERP / CRM custom prototypes src')[0],
180
191
  );
192
+
193
+ // Process catalog copies — each [src, dest] pair is copied from engine root to the template target.
194
+ if (catalog.copies && catalog.copies.length) {
195
+ for (const [src, dest] of catalog.copies) {
196
+ if (fs.existsSync(src)) {
197
+ logger.info(`Build copy`, `${src} -> ${dest}`);
198
+ fs.copySync(src, `${basePath}/${dest.replace(/^\.\//, '')}`);
199
+ }
200
+ }
201
+ }
202
+
203
+ // Process catalog moves — each [src, dest] pair is moved from engine src to template dest.
204
+ if (catalog.moves && catalog.moves.length) {
205
+ for (const [src, dest] of catalog.moves) {
206
+ if (fs.existsSync(src)) {
207
+ logger.info(`Build move`, `${src} -> ${dest}`);
208
+ fs.moveSync(src, `${basePath}/${dest.replace(/^\.\//, '')}`, { overwrite: true });
209
+ }
210
+ }
211
+ }
181
212
  };
182
213
 
183
214
  const program = new Command();