unoverse 0.1.114 → 0.1.116

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.
@@ -153,7 +153,15 @@ services:
153
153
  # health checks) still reaches it via 127.0.0.1. Never widen to "4101:4101".
154
154
  - "127.0.0.1:4101:4101" # workflow surface (engine in-process)
155
155
  environment:
156
- - NODE_ENV=production
156
+ # PRODUCTION UNLESS THE DEVELOPER SAYS OTHERWISE. This was fixed at "production", and
157
+ # auth-off refuses to boot in production — correctly — so a LOCAL universe running these
158
+ # images could never turn auth off at all: AUTH_ENABLED=false and NODE_ENV=production
159
+ # are a permanent contradiction, and the platform was right to refuse both ways round.
160
+ #
161
+ # The guard is not weakened: unset still means production, and terraform's rendered env
162
+ # never sets this, so a deployed universe cannot drift. Turning it off is a deliberate
163
+ # line in a developer's own .env.
164
+ - NODE_ENV=${NODE_ENV:-production}
157
165
  # Studio is a separate app, launched by the CLI from source. It is not in this image
158
166
  # and has no switch here: the Docker runtime serves MCP + API only.
159
167
  - UNOVERSE_PORT=4105
@@ -169,6 +177,12 @@ services:
169
177
  # containers connect to the container IP); the loopback-only port mappings above and
170
178
  # the Docker network are the boundary here.
171
179
  - UNOVERSE_INTERNAL_BIND=0.0.0.0
180
+ # THE FLAG TRAVELS WITH THE ISSUER. .env could say AUTH_ENABLED=false and no
181
+ # container ever saw it: compose forwarded the issuer and audience and not the flag,
182
+ # so the server defaulted to enabled — correctly — and refused to boot on a local
183
+ # universe with no OIDC. The developer's own setting was invisible to the thing it
184
+ # configures.
185
+ - AUTH_ENABLED=${AUTH_ENABLED:-}
172
186
  - AUTH_ISSUER=${AUTH_ISSUER:-}
173
187
  - AUTH_AUDIENCE=${AUTH_AUDIENCE:-}
174
188
  # WHERE THE MARKETPLACE IS. The catalogue this universe can install from, served as
@@ -267,7 +281,15 @@ services:
267
281
  ports:
268
282
  - "4104:4104"
269
283
  environment:
270
- - NODE_ENV=production
284
+ # PRODUCTION UNLESS THE DEVELOPER SAYS OTHERWISE. This was fixed at "production", and
285
+ # auth-off refuses to boot in production — correctly — so a LOCAL universe running these
286
+ # images could never turn auth off at all: AUTH_ENABLED=false and NODE_ENV=production
287
+ # are a permanent contradiction, and the platform was right to refuse both ways round.
288
+ #
289
+ # The guard is not weakened: unset still means production, and terraform's rendered env
290
+ # never sets this, so a deployed universe cannot drift. Turning it off is a deliberate
291
+ # line in a developer's own .env.
292
+ - NODE_ENV=${NODE_ENV:-production}
271
293
  - PORT=4104
272
294
  - DATABASE_URL=${DATABASE_URL:-}
273
295
  # Connection budget (INFRASTRUCTURE.md) — Terraform-rendered per size.
@@ -277,6 +299,12 @@ services:
277
299
  - REDIS_PASSWORD=${REDIS_PASSWORD:-}
278
300
  - REDIS_TLS=${REDIS_TLS:-}
279
301
  - REDIS_NAMESPACE=${REDIS_NAMESPACE:-}
302
+ # THE FLAG TRAVELS WITH THE ISSUER. .env could say AUTH_ENABLED=false and no
303
+ # container ever saw it: compose forwarded the issuer and audience and not the flag,
304
+ # so the server defaulted to enabled — correctly — and refused to boot on a local
305
+ # universe with no OIDC. The developer's own setting was invisible to the thing it
306
+ # configures.
307
+ - AUTH_ENABLED=${AUTH_ENABLED:-}
280
308
  - AUTH_ISSUER=${AUTH_ISSUER:-}
281
309
  - AUTH_AUDIENCE=${AUTH_AUDIENCE:-}
282
310
  - OPENAI_API_KEY=${OPENAI_API_KEY:-}
@@ -151,10 +151,19 @@ cmd_start() {
151
151
  local running=0
152
152
  local total=0
153
153
  i=0
154
+ # A RESTARTING CONTAINER IS NOT A RUNNING ONE. `--filter status=running` counts a container
155
+ # that is crash-looping, because between crashes it genuinely is running — so `start`
156
+ # announced "All 5 services running" while unoverse and memory were dying on boot every few
157
+ # seconds, and the developer went looking at their browser instead of the logs.
158
+ #
159
+ # Counting restarts as failures also means the loop keeps waiting instead of breaking early
160
+ # on a lie, which gives a slow-but-healthy boot the time it needs.
161
+ local restarting=0
154
162
  while [ $attempts -lt 15 ]; do
155
163
  running=$(docker compose -f "$ROOT/docker-compose.yml" ps --format "{{.Name}}" --filter "status=running" 2>/dev/null | wc -l | tr -d ' ')
164
+ restarting=$(docker compose -f "$ROOT/docker-compose.yml" ps -a --format "{{.Status}}" 2>/dev/null | grep -ci "restarting" | tr -d ' ')
156
165
  total=$(docker compose -f "$ROOT/docker-compose.yml" ps --format "{{.Name}}" 2>/dev/null | wc -l | tr -d ' ')
157
- if [ "$running" -eq "$total" ] && [ "$total" -gt 0 ]; then
166
+ if [ "$running" -eq "$total" ] && [ "$total" -gt 0 ] && [ "$restarting" -eq 0 ]; then
158
167
  break
159
168
  fi
160
169
  local c="${spin:i%${#spin}:1}"
@@ -165,6 +174,29 @@ cmd_start() {
165
174
  done
166
175
 
167
176
  echo ""
177
+ # NAME WHAT IS CRASHING, AND WHY. A restart loop is the one failure whose cause is always
178
+ # in the logs and never on screen, so print the last line of each one rather than leaving
179
+ # the developer to find `docker compose logs` themselves.
180
+ if [ "${restarting:-0}" -gt 0 ]; then
181
+ printf "\r ${RED}✗${NC} $restarting service(s) crashing on boot \n"
182
+ echo ""
183
+ # ASK COMPOSE FOR THE SERVICE NAME. `${svc##*-}` on a container called
184
+ # unoversedevtest-unoverse-1 yields "1", so the log lookup asked for a service that does
185
+ # not exist and printed nothing — the crash was named and its cause silently dropped.
186
+ # `ps --format {{.Service}}` gives compose's own name for it.
187
+ docker compose -f "$ROOT/docker-compose.yml" ps -a --format "{{.Service}}\t{{.Status}}" 2>/dev/null \
188
+ | grep -i restarting | awk -F'\t' '{print $1}' | while read -r svc; do
189
+ reason=$(docker compose -f "$ROOT/docker-compose.yml" logs --tail=60 "$svc" 2>/dev/null \
190
+ | grep -iE "error" | grep -viE "at [A-Za-z_]+ \(|node:internal" | tail -1 \
191
+ | sed -E 's/^[^|]*\| *//')
192
+ echo -e " ${RED}•${NC} ${BOLD}$svc${NC}"
193
+ [ -n "$reason" ] && echo -e " ${DIM}${reason}${NC}"
194
+ done
195
+ echo ""
196
+ info "Full output: ${BOLD}unoverse logs <service>${NC}"
197
+ echo ""
198
+ return 1
199
+ fi
168
200
  if [ "$running" -eq "$total" ] && [ "$total" -gt 0 ]; then
169
201
  printf "\r ${GREEN}✓${NC} ${DIM}Health checks passed${NC} \n"
170
202
  echo ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unoverse",
3
- "version": "0.1.114",
3
+ "version": "0.1.116",
4
4
  "description": "The Unoverse front door — create a Studio project, a universe, or a client app, and launch Studio.",
5
5
  "license": "SEE LICENSE IN README.md",
6
6
  "type": "module",