#!/usr/bin/env bash # sx-gitea live server launcher. Loads the FULL forge stack (every substrate # the eight phases compose: git, datalog/acl, dream, smalltalk/content, # relations, scheme/flow, apl/feed, events, haskell/search, fed) into one # sx_server process and calls (gitea/serve! PORT ...) — the native # http-listen loop serving the dream app. Runs in the FOREGROUND, so this # doubles as a container entrypoint and a local launcher. # # Usage: # bash lib/gitea/serve.sh # serve on $HOST_PORT (default 8940) # HOST_PORT=8941 bash lib/gitea/serve.sh # # Env: # SX_INSTANCE instance id baked into AP actor ids (default sx.sx-web.org) # SX_GITEA_ADMIN admin username (default giles) # SX_GITEA_TOKEN admin bearer token (REQUIRED in production) # SX_PERSIST_DIR durable store root (kernel persist ops) # SX_HTTP_HOST bind address (0.0.0.0 in containers) set -uo pipefail cd "${SX_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || echo .)}" SX_SERVER="${SX_SERVER:-hosts/ocaml/_build/default/bin/sx_server.exe}" if [ ! -x "$SX_SERVER" ]; then SX_SERVER="/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe" fi if [ ! -x "$SX_SERVER" ]; then echo "ERROR: sx_server.exe not found." >&2 exit 1 fi PORT="${HOST_PORT:-8940}" INSTANCE="${SX_INSTANCE:-sx.sx-web.org}" ADMIN="${SX_GITEA_ADMIN:-giles}" TOKEN="${SX_GITEA_TOKEN:-dev-token-change-me}" # The full stack, in dependency order — the same lists the conformance # runner uses (base MODULES + every suite's extras), plus the host # native-handler bridge and the serve boot module. MODULES=( # kernel + parser (sx-parse for the wire protocol) "spec/stdlib.sx" "spec/parser.sx" "lib/r7rs.sx" # persist (durable backend rides kernel persist/* ops) "lib/persist/event.sx" "lib/persist/backend.sx" "lib/persist/log.sx" "lib/persist/kv.sx" "lib/persist/durable.sx" # canonical form + sx-git "lib/artdag/dag.sx" "lib/git/object.sx" "lib/git/ref.sx" "lib/git/dag.sx" "lib/git/worktree.sx" "lib/git/diff.sx" "lib/git/merge.sx" "lib/git/porcelain.sx" # datalog + acl (access control) "lib/datalog/tokenizer.sx" "lib/datalog/parser.sx" "lib/datalog/unify.sx" "lib/datalog/db.sx" "lib/datalog/builtins.sx" "lib/datalog/aggregates.sx" "lib/datalog/strata.sx" "lib/datalog/eval.sx" "lib/datalog/api.sx" "lib/datalog/magic.sx" "lib/acl/schema.sx" "lib/acl/facts.sx" "lib/acl/engine.sx" # dream (web) "lib/dream/types.sx" "lib/dream/router.sx" "lib/dream/middleware.sx" "lib/dream/error.sx" "lib/dream/html.sx" "lib/dream/json.sx" "lib/dream/auth.sx" "lib/dream/session.sx" "lib/dream/api.sx" # relations (issue graph) "lib/relations/schema.sx" "lib/relations/engine.sx" "lib/relations/api.sx" # smalltalk + content (markdown issue/PR bodies) "lib/smalltalk/tokenizer.sx" "lib/smalltalk/parser.sx" "lib/guest/reflective/class-chain.sx" "lib/smalltalk/runtime.sx" "lib/guest/reflective/env.sx" "lib/smalltalk/eval.sx" "lib/content/block.sx" "lib/content/doc.sx" "lib/content/render.sx" "lib/content/api.sx" "lib/content/meta.sx" "lib/content/text.sx" "lib/content/section.sx" "lib/content/table.sx" "lib/content/markdown.sx" "lib/content/md-import.sx" # scheme + flow (PR lifecycle, notification delivery) "lib/guest/lex.sx" "lib/guest/reflective/quoting.sx" "lib/scheme/parser.sx" "lib/scheme/eval.sx" "lib/scheme/runtime.sx" "lib/flow/spec.sx" "lib/flow/store.sx" "lib/flow/remote.sx" "lib/flow/host.sx" "lib/flow/api.sx" # apl + feed (timelines) + events notify "lib/apl/runtime.sx" "lib/feed/normalize.sx" "lib/feed/stream.sx" "lib/feed/api.sx" "lib/feed/fanout.sx" "lib/feed/dedupe.sx" "lib/feed/aggregate.sx" "lib/feed/rank.sx" "lib/feed/acl.sx" "lib/feed/mute.sx" "lib/feed/page.sx" "lib/feed/notify.sx" "lib/feed/home.sx" "lib/feed/fed.sx" "lib/events/notify.sx" # haskell + search "lib/haskell/tokenizer.sx" "lib/haskell/layout.sx" "lib/haskell/parser.sx" "lib/haskell/desugar.sx" "lib/haskell/runtime.sx" "lib/haskell/match.sx" "lib/haskell/eval.sx" "lib/haskell/map.sx" "lib/haskell/set.sx" "lib/haskell/testlib.sx" "lib/search/tokenize.sx" "lib/search/index.sx" "lib/search/query.sx" "lib/search/parse.sx" "lib/search/rank.sx" "lib/search/rankq.sx" "lib/search/testlib.sx" # the forge "lib/gitea/repo.sx" "lib/gitea/access.sx" "lib/gitea/web.sx" "lib/gitea/wire.sx" "lib/gitea/issues.sx" "lib/gitea/pr.sx" "lib/gitea/activity.sx" "lib/gitea/search.sx" "lib/gitea/fed.sx" # native http bridge + serve boot "lib/host/server.sx" "lib/gitea/serve.sx" ) EPOCH=1 { for M in "${MODULES[@]}"; do echo "(epoch $EPOCH)"; echo "(load \"$M\")"; EPOCH=$((EPOCH+1)) done # content classes must exist before the first issue/PR page renders echo "(epoch $EPOCH)" echo "(eval \"(begin (st-bootstrap-classes!) (content/bootstrap!) (content-bootstrap-markdown!) (content-bootstrap-table!))\")" EPOCH=$((EPOCH+1)) # boot the durable forge + block in the native server loop echo "(epoch $EPOCH)" echo "(eval \"(gitea/serve! $PORT \\\"$INSTANCE\\\" \\\"$ADMIN\\\" \\\"$TOKEN\\\")\")" } | exec "$SX_SERVER"