feat(mavweb): /ecosystem page consuming Nexus/Praxis/Hexis + shell fixes

Add a read-only /ecosystem page that consumes the sibling services'
JSON APIs (Nexus entities, Praxis attention, Hexis capabilities),
fetched concurrently with honest per-panel error states. Siblings stay
headless — mavweb is their human surface (arch §16). Wired via mavweb
-nexus/-praxis/-hexis flags; mavweb joins the ecosystem compose network.

Fix mobile horizontal overflow across all pages: .content is a flex
child with default min-width:auto, so it refused to shrink below the
tables' intrinsic width. min-width:0 lets wide tables pan inside .scroll
instead of dragging the page sideways. Verified via CDP geometry check
(scrollWidth === clientWidth at 430px).

Also includes in-progress Ethos UI redesign, ecosystem deploy compose,
and planning docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kami
2026-07-19 22:04:23 +04:00
parent 6c92f85d10
commit 5fe8f228c1
43 changed files with 1782 additions and 668 deletions
+54
View File
@@ -0,0 +1,54 @@
# Nexus / Praxis / Hexis — the three sibling services Maven coordinates.
# One container each, built from the sibling repos (siblings of the Maven repo
# on the same mount). HTTP is published to 127.0.0.1 so the host nginx can
# reverse-proxy the *.subdomains; container-to-container (Maven → sibling) goes
# over the shared `ecosystem` network by service name, no host round-trip.
#
# docker compose -f deploy/ecosystem/docker-compose.yml up -d --build
#
# Maven's own compose joins this same network (add `ecosystem` as an external
# network there) to reach nexus:9740 / praxis:8989 / hexis:9741 directly.
name: ecosystem
services:
nexus:
build: ../../../nexus
restart: unless-stopped
ports: ["127.0.0.1:9740:9740"] # host nginx → nexus.<domain>
volumes:
- nexus-data:/data
- sockets:/run/ecosystem # nexus.sock, shared with Maven
networks: [ecosystem]
praxis:
build: ../../../praxis
restart: unless-stopped
ports: ["127.0.0.1:8989:8989"] # host nginx → praxis.<domain>
volumes:
- praxis-data:/data
networks: [ecosystem]
hexis:
build: ../../../hexis
restart: unless-stopped
ports: ["127.0.0.1:9741:9741"] # host nginx → hexis.<domain> (MCP moved off hexis.*)
environment:
# hexis fronts the workspace MCP; point at wherever it listens on the
# host/network. Empty ⇒ workspace provider disabled (systemd-only).
- WORKSPACE_MCP_URL=${WORKSPACE_MCP_URL:-http://192.168.1.104:9930}
volumes:
- hexis-data:/data
- sockets:/run/ecosystem
# required when WORKSPACE_MCP_URL is set — hexisd fatals without it.
- ../../../hexis/etc/workspace-allowlist.yaml:/data/workspace-allowlist.yaml:ro
networks: [ecosystem]
volumes:
nexus-data:
praxis-data:
hexis-data:
sockets:
networks:
ecosystem:
name: ecosystem # stable name so Maven's compose can reference it as external
+42
View File
@@ -0,0 +1,42 @@
# Reverse-proxy the three sibling admin UIs. Drop into your nginx sites (or the
# nginx-panel app) and reload. Assumes the compose publishes each service on
# 127.0.0.1:<port>. Add TLS (certbot / your existing cert block) per server.
#
# NOTE: hexis.<domain> previously pointed at the MCP tool — repoint that
# elsewhere first (the app now owns hexis.*).
server {
listen 80;
server_name nexus.kvmx.ru;
location / {
proxy_pass http://127.0.0.1:9740;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name praxis.kvmx.ru;
location / {
proxy_pass http://127.0.0.1:8989;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name hexis.kvmx.ru;
location / {
proxy_pass http://127.0.0.1:9741;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
+4
View File
@@ -18,6 +18,10 @@
"chat_id": "${TELEGRAM_CHAT_ID}"
},
"nexus": { "url": "http://nexus:9740" },
"praxis": { "url": "http://praxis:8989" },
"hexis": { "url": "http://hexis:9741" },
"voice": {
"enabled": true,
"bind": "0.0.0.0:9100",