The
apps/bellona/area: twelve Nx applications that make up Bellona's game-development control plane — engine bridges, a build/export/render pipeline, a developer CLI, and the Phase-180 remote creative-control surface (gateway, host, browser extension, and operator Control Room).
What this area is#
Bellona is Oshun's game-development and creative-tooling domain. The
apps/bellona/ directory is not one service but twelve separate Nx
applications (each with its own project.json) that split into three
clusters: engine bridges, the build/export/render pipeline, and the
Phase-180 remote creative-control plane plus its CLI.
The engine-bridge cluster (bellona-bridge-blender, bellona-bridge-godot,
bellona-bridge-unity, bellona-bridge-unreal) are standalone WebSocket
servers. Each one boots a createBridgeServer(...) from the
@bellona/bridge-core library, registers a domain-specific command vocabulary
(Blender scene/asset commands, Godot scene-tree/GDScript, Unity
GameObject/physics, Unreal actor/sequencer), and proxies those commands over
the socket to a connected DCC/engine editor plugin via forwardToEngine(...).
They are real proxies, not simulators: if no engine plugin is connected,
findEngineConnection(...) throws rather than fabricating a response. The
actual engine-side plugins live outside this directory.
The build/export/render cluster (bellona-build-api,
bellona-build-worker, bellona-render-api) is the asset-pipeline backend.
bellona-build-api is a content-addressable build/export cache plus a
cross-domain event consumer; bellona-build-worker is the job processor that
bakes assets, validates them, generates engine projects, and packages exports;
bellona-render-api is a Redis-backed render cache fronting a GPU render queue.
They communicate through Redis queues and the @oshun/event-bus, and emit
@bellona/event-publisher lifecycle events (build.started, export.ready,
etc.).
The remote-control cluster (@bellona/remote-gateway,
@bellona/remote-host, @bellona/remote-extension, @bellona/control-room) is
the Phase-180 "remote creative control plane": an operator drives a controlled
workstation (Blender, Unreal, a managed browser, or macOS desktop fallback)
through an audited, approval-gated gateway. @bellona/cli is the unifying
command-line entry point that exercises both the build/export API and the
remote-control surface.
How the area is shaped#
The clusters depend on shared libs/bellona/* and @oshun/* libraries rather
than on each other directly:
- the four bridges all compose
@bellona/bridge-coreand@bellona/event-publisher; - the build/render services compose
@oshun/cache,@oshun/event-bus,@oshun/logging,@bellona/event-handlers, and@bellona/event-publisher; - the remote-control services are built almost entirely on the
@bellona/remote-protocollibrary, which owns the Zod schemas for devices, commands, sessions, approvals, audit chains, and artifacts — every gateway and host write validates against it.
A recurring honesty caveat applies to the remote-control cluster: the gateway and host READMEs describe themselves as "walking skeleton for Phase 180." That undersells the gateway/host control-plane logic (which is substantial and real) but is accurate about the engine adapters, several of which are deterministic mocks (Unreal) or macOS-only native backends (desktop fallback) rather than universally-live integrations. The per-entity blocks below call out which is which.
How it fits the wider system#
These apps are the runtime surface of the Bellona domain. The bridges are
consumed by DCC/engine plugins on one side and by Bellona's API/agent tooling on
the other. The build/render services are consumed by anything that needs to
bake, package, or render game assets, and they publish onto the Oshun event bus
so other domains can react to build lifecycle events. The remote-control
plane is consumed by a human operator (through @bellona/control-room or the
@bellona/remote-extension popup) and by agents (through @bellona/cli remote
and the gateway's HTTP/WebSocket API), with @bellona/remote-host running on
the controlled workstation. Walk the "used by" edges on any node to see exactly
who depends on it.
Entity catalog (12)#
The 12 tracked Nx projects in bellona, each a code-linked entity node — package, type, source path, declared targets, and its internal dependency graph (depends-on / used-by, resolved from the package manifests, §6/§8), read from the project graph. Grouped by architectural layer; walk the dependency links to travel the system. 12 of these carry an authored deep-dive (what / why / how it fits); the rest are generated scaffolds awaiting one.
client (1)#
Bellona remote-control minimal MV3 browser extension (origin-authenticated, domain-scoped, with a tamper-resistant visible-automation indicator)
A minimal Manifest V3 browser extension for the remote-control surface
(apps/bellona/remote-extension). Its public surface (src/index.ts) is a set
of pure, adversarially-unit-tested security primitives: a closed-by-default
origin allow-list that fails loud on <all_urls> (origin-policy.ts),
extension-origin authentication and per-session token minting
(extension-auth.ts), sensitive-action guards for clipboard/upload/form
(action-guards.ts), a tamper-resistant shadow-DOM automation indicator
(automation-indicator.ts), session teardown (session-lifecycle.ts), and
manifest domain-scoping invariants (manifest-policy.ts). The README is candid
that the Chrome-runtime wiring (background.ts, content-script.ts) is "a thin
shell" that cannot load in CI, so the logic is tested through the pure functions
— a deliberate dependency-boundary approach, not a stub.
service (2)#
Bellona remote gateway service walking skeleton
The remote creative-control plane gateway
(apps/bellona/remote-gateway/src/app.ts), described as a Phase-180 walking
skeleton but in fact a large, real control plane. createRemoteGatewayApp(...)
composes a node http server exposing health/readiness plus /v1 endpoints for
devices, commands, sessions, streams, approvals, artifacts, timeline, audit
export, and pairing exchange, alongside a WS /v1/hosts/connect host channel.
It owns a @bellona/remote-protocol-validated device registry, a command
dispatcher that runs every command through the shared permission policy
(capability scopes, approval gating, fail-closed on audit-store outages except
read-only diagnostics), a hash-chained audit log, an approval service with
deny-by-default expiry, one-time CSPRNG pairing codes, HMAC host tokens,
session-lifecycle and stream registries, and in-memory telemetry. State is
ephemeral by default but can opt into a documented first-stage atomic-JSON
persistent store (schema v3 with forward migration). The honest boundary: it
orchestrates and audits commands but executes nothing itself — real work happens
on the connected host.
Bellona remote host service walking skeleton
The remote host process that runs on the controlled workstation
(apps/bellona/remote-host). It loads a macOS-Keychain-backed device identity,
opens an outbound WebSocket to the gateway with bounded reconnect, and runs a
host command executor that emits protocol-valid progress/result/error events.
Its adapter registry is where the implemented-vs-mocked split is sharpest, and
the README is unusually explicit about it: the Blender adapter is real
(loopback-only discovery of the repo's addon/bridge, then a large canonical
command surface — scene info, object/collection/material/modifier/mesh-edit
mutations, asset import/export — each wrapped with before/after scene-info
evidence and undo checkpoints); the browser adapter really launches
Chrome/Chromium through Playwright bound to loopback CDP with blocked-domain
policy; the desktop fallback adapter is macOS-only and shells real Swift
CoreGraphics/AppKit helpers for screenshot/window/click/type/clipboard with
fail-closed redaction; the Unreal adapter's project.info/world.query/
actor.spawn are deterministic mocks that validate the protocol schemas but
do not yet drive a live editor. The command-policy preflight is honestly named a
...policy-preflight-stub pending the real policy package. Many capabilities
are macOS-specific and report not-applicable elsewhere.
InMemoryRemoteHostAdapterRegistry1RemoteHostAdapterRegistryError1createFakeBlenderAdapterRegistration1createHostDiagnosticsAdapterRegistration1createInMemoryRemoteHostAdapterRegistry1RemoteHostAdapterCommandHandler1RemoteHostAdapterCommandContext1RemoteHostAdapterCommandRouteResult1RemoteHostAdapterHealth1RemoteHostAdapterHealthStatus1RemoteHostAdapterRegistration1RemoteHostAdapterRegistry1RemoteHostAdapterRegistrySnapshot1RemoteHostAdapterStopResult1 +894 moreunclassified (9)#
Command-line interface for Bellona game development platform
The Bellona game-development CLI (apps/bellona/cli/src/index.ts), built on
commander + chalk. The bellona program registers command groups for
build, export, sync (engine sync/push/conflicts), config, health,
project/detect, and remote — the last being the remote creative-control
plane client (pair, devices, sessions, stream, command, approve, diagnose,
artifacts, audit export, unpair). It talks to the build API over HTTP (default
http://localhost:3020) and to the remote gateway through
src/utils/remote-client.ts. Quick aliases (b, e) re-parse into the
canonical subcommands. A real, fully-wired CLI, not a scaffold.
Bellona browser-first remote-control operator Control Room.
The browser-first operator surface for the Phase-180 remote-control MVP
(apps/bellona/control-room, a React + Vite app). It is explicitly scaffolded
behind the VITE_BELLONA_CONTROL_ROOM_ENABLED feature flag (disabled by
default, including production), and the README is clear that "no gateway, host,
desktop, browser, Blender, or Unreal privileges are exposed from this scaffold"
and queued commands record an audit preview rather than dispatching to a live
host. Within that boundary the UI logic is substantial and real: an approval
queue with keyboard shortcuts, a command palette sourced from
REMOTE_COMMAND_NAMESPACE_VALUES, command search, a first-session guided tour,
device permission diagnostics, a mobile-approval PWA route with a service
worker, plus i18n and a11y modules — all fixture-backed
(@bellona/remote-protocol fixtures) and exercised by Vitest + Playwright.
Honest status: real, flag-gated, fixture-driven operator UI; not yet connected
to a live gateway.
Bridge service for Blender integration
A standalone WebSocket bridge service for Blender
(apps/bellona/bridge-blender/src/main.ts). createBlenderBridge() starts a
@bellona/bridge-core server on ws://localhost:9001/blender, registers
handshake/ping plus six Blender commands (blender:get-scene-info,
create-object, import-asset, export-asset, set-frame, render), and
forwards each to a connected blender-plugin client via forwardToEngine(...),
returning the engine's real reply. It is the most fleshed-out bridge: it also
tracks per-connection SessionMetadata and publishes
BellonaSessionStarted/SessionEnded events through
@bellona/event-publisher. Real proxy logic; the Blender-side addon that
answers the commands lives outside this directory.
Bridge service for Godot Engine integration
The Godot Engine WebSocket bridge (apps/bellona/bridge-godot/src/main.ts).
createGodotBridge() listens on ws://localhost:9002/godot and registers nine
Godot-specific commands covering the scene tree, node creation/property/method
calls, scene and resource loading, signal emission, GDScript execution (with a
60s timeout), and project settings — each proxied to a connected godot-plugin
client. Same forward-or-throw contract as the other bridges; it does not yet
wire the event-publisher session tracking that the Blender bridge has.
Bridge service for Unity Engine integration
The Unity Engine WebSocket bridge (apps/bellona/bridge-unity/src/main.ts),
listening on ws://localhost:9004/unity. It registers the largest command set
of the four — fourteen commands spanning GameObject create/destroy, component
add/set, scene load/unload, prefab instantiation, transforms, Animator
play/parameter, Rigidbody force, physics raycast, and SendMessage. Notable
detail: this entrypoint ships its own small LOG_LEVEL-aware logger (routing
through console.warn/console.error) to honour the Bellona logging contract
without pulling a non-Bellona dependency into the standalone process. Commands
are proxied to a connected unity-plugin client.
Bridge service for Unreal Engine integration
The Unreal Engine WebSocket bridge (apps/bellona/bridge-unreal/src/main.ts),
listening on ws://localhost:9003/unreal. It registers eleven commands: world
info, actor spawn/destroy/property, Blueprint function calls, streaming level
load/unload, material parameters, Sequencer control, console-command execution,
and screenshots — all forwarded to a connected unreal-plugin client.
Structurally identical to the Godot/Unity bridges (forward-or-throw, console
logging), specialised to Unreal's actor/level/Sequencer vocabulary.
Build API for Bellona build and export system with content-addressable caching
The build/export API service (apps/bellona/build-api/src/main.ts). It owns a
content-addressable build cache (createBuildCacheService, 100 MB in-memory
tier over a 10 GB Redis tier with compression and deduplication) and wires
cross-domain event handlers via @bellona/event-handlers and
@oshun/event-bus so build/export requests arriving as events are enqueued. Its
build/export queue adapters (createBuildQueueAdapter,
createExportQueueAdapter) use Redis pipelines (hset/zadd/sadd,
priority-scored pending sets) when REDIS_URL is set and fall back to in-memory
Maps otherwise — an honest degraded mode, logged as backend: 'memory', not a
fake. Exposes initialize/shutdown/getHealthStatus with real cache-hit-rate
stats.
initialize8shutdown8getCacheService8isHealthy8getHealthStatus8getBuildCacheService8BuildCacheService18createBuildCacheService18setBuildCacheService18clearBuildCacheService18createBuildJobId82createArtifactId82createProjectId82createAssetId82 +1 moreBackground worker service for asset building and processing
The build worker service (apps/bellona/build-worker/src/main.ts).
BuildWorkerService is a polling job runner: it dequeues from a JobQueue and
dispatches to four real workers — processAssetBakeJob, processValidationJob,
processEngineProjectJob, processExportPackageJob — emitting progress and
publishing BellonaBuildStarted/Progress/Completed and ExportStarted/Ready
events. The work is genuine: asset-bake-worker.ts hashes files with SHA-256
and shells out to real tools (sharp/ImageMagick for textures, ffmpeg for audio,
gltf-pipeline for models) via execFile. The service tracks completed/failed
counts, average duration, heartbeats, retry-on-fail, and graceful shutdown that
drains the in-flight job.
The render API service (apps/bellona/render-api/src/main.ts). It initialises a
Redis-backed render cache (createRenderCacheService) — real
content-addressable storage with pub/sub invalidation, distributed locking, LRU
eviction, and TTL tiers for jobs/outputs/progress/metadata drawn from
@oshun/cache. Behind it sits a GPU render queue (src/queue/gpu-queue.ts)
that tracks GPU devices, memory, priority queuing, concurrent-job limits,
timeouts, retries, and health checks, plus an output validator
(src/validation/). Exposes the same initialize/shutdown/getHealthStatus
lifecycle as the build API. The caching and queue-management logic is real; the
GPU device list is the resource it schedules against.
initialize8shutdown8getCacheService8isHealthy8getHealthStatus8getRenderCacheService8RenderCacheService18createRenderCacheService18setRenderCacheService18clearRenderCacheService18createRenderJobId67createRenderOutputId67OutputValidator70createOutputValidator70 +7 more