@@ -101,6 +101,10 @@ KIND_FWD_BACKEND_PORT ?= $(shell echo $$((12000 + $(KIND_PORT_OFFSET))))
101101KIND_FWD_BACKEND_PORT := $(KIND_FWD_BACKEND_PORT )
102102KIND_FWD_API_SERVER_PORT ?= $(shell echo $$((13000 + $(KIND_PORT_OFFSET ) ) ) )
103103KIND_FWD_API_SERVER_PORT := $(KIND_FWD_API_SERVER_PORT )
104+ KIND_FWD_AMBIENT_UI_PORT ?= $(shell echo $$((14000 + $(KIND_PORT_OFFSET ) ) ) )
105+ KIND_FWD_AMBIENT_UI_PORT := $(KIND_FWD_AMBIENT_UI_PORT )
106+ KIND_FWD_KEYCLOAK_PORT ?= $(shell echo $$((18000 + $(KIND_PORT_OFFSET ) ) ) )
107+ KIND_FWD_KEYCLOAK_PORT := $(KIND_FWD_KEYCLOAK_PORT )
104108# Remote kind host — set to Tailscale IP/hostname of the Linux build machine.
105109# When set, kubeconfig is rewritten so kubectl/port-forward work from Mac.
106110KIND_HOST ?=
@@ -675,9 +679,9 @@ preflight: preflight-cluster ## Validate dev environment (cluster tools + option
675679 p=$$(echo "$$piece" | sed 's/^[[:space:]]*//;s/[[:space:]]*$$//' ) ; \
676680 [ -z " $$ p" ] && continue ; \
677681 case " $$ p" in \
678- frontend) NEED_NODE=1 ;; \
682+ frontend| ambient-ui ) NEED_NODE=1 ;; \
679683 backend) NEED_GO=1 ;; \
680- * ) echo " $( COLOR_RED) ✗$( COLOR_RESET) Unknown COMPONENT: $$ p (use frontend, backend, or frontend,backend )" ; FAILED=1 ;; \
684+ * ) echo " $( COLOR_RED) ✗$( COLOR_RESET) Unknown COMPONENT: $$ p (use frontend, backend, ambient-ui, or comma-separated )" ; FAILED=1 ;; \
681685 esac ; \
682686 done ; \
683687 fi ; \
@@ -753,7 +757,30 @@ dev-env: check-kubectl check-local-context ## Generate components/frontend/.env.
753757 echo " $( COLOR_GREEN) ✓$( COLOR_RESET) Wrote $$ ENV_FILE" ; \
754758 fi
755759
756- dev : # # Local dev: preflight, cluster, dev-env, port-forwards; COMPONENT=frontend|backend|frontend,backend for hot-reload
760+ dev-env-ambient-ui : check-kubectl # # Generate components/ambient-ui/.env.local from cluster state
761+ @kubectl config use-context kind-$(KIND_CLUSTER_NAME ) > /dev/null 2>&1 || true
762+ @set -e; \
763+ SESSION_SECRET=$$(printf '%s-ambient-ui' '$(KIND_CLUSTER_NAME ) ' | sha256sum | cut -c1-32 ) ; \
764+ ENV_FILE=" components/ambient-ui/.env.local" ; \
765+ { \
766+ echo " # Generated by make dev-env-ambient-ui — do not commit" ; \
767+ echo " API_SERVER_URL=http://localhost:$( KIND_FWD_API_SERVER_PORT) " ; \
768+ echo " NEXT_PUBLIC_PREVIEW_ALLOWED_HOSTS=localhost:*,127.0.0.1:*" ; \
769+ echo " SSO_ISSUER_URL=http://localhost:$( KIND_FWD_KEYCLOAK_PORT) /realms/ambient-code" ; \
770+ echo " SSO_CLIENT_ID=ambient-frontend" ; \
771+ echo " SSO_CLIENT_SECRET=dev-secret-do-not-use-in-prod" ; \
772+ echo " SSO_REDIRECT_URI=http://localhost:3001/api/auth/sso/callback" ; \
773+ echo " SESSION_SECRET=$$ SESSION_SECRET" ; \
774+ } > " $$ ENV_FILE.tmp" ; \
775+ if [ -f " $$ ENV_FILE" ] && cmp -s " $$ ENV_FILE.tmp" " $$ ENV_FILE" ; then \
776+ rm -f " $$ ENV_FILE.tmp" ; \
777+ echo " $( COLOR_GREEN) ✓$( COLOR_RESET) $$ ENV_FILE unchanged" ; \
778+ else \
779+ mv " $$ ENV_FILE.tmp" " $$ ENV_FILE" ; \
780+ echo " $( COLOR_GREEN) ✓$( COLOR_RESET) Wrote $$ ENV_FILE" ; \
781+ fi
782+
783+ dev : # # Local dev: preflight, cluster, dev-env, port-forwards; COMPONENT=frontend|backend|ambient-ui for hot-reload
757784 @if [ -z " $( COMPONENT) " ]; then $(MAKE ) --no-print-directory preflight-cluster; else $(MAKE ) --no-print-directory preflight; fi
758785 @set -e; \
759786 if [ " $( CONTAINER_ENGINE) " = " podman" ]; then export KIND_EXPERIMENTAL_PROVIDER=podman; fi ; \
@@ -781,10 +808,10 @@ dev: ## Local dev: preflight, cluster, dev-env, port-forwards; COMPONENT=fronten
781808 kubectl config use-context kind-$(KIND_CLUSTER_NAME ) ; \
782809 fi ; \
783810 COMP=" $( COMPONENT) " ; \
784- HAS_FRONT=0; HAS_BACK=0; \
811+ HAS_FRONT=0; HAS_BACK=0; HAS_AUI=0 ; \
785812 for piece in $$ (echo " $$ COMP" | tr ' ,' ' ' ); do \
786813 p=$$(echo "$$piece" | sed 's/^[[:space:]]*//;s/[[:space:]]*$$//' ) ; \
787- case " $$ p" in frontend) HAS_FRONT=1 ;; backend) HAS_BACK=1 ;; esac ; \
814+ case " $$ p" in frontend) HAS_FRONT=1 ;; backend) HAS_BACK=1 ;; ambient-ui) HAS_AUI=1 ;; esac ; \
788815 done ; \
789816 DEV_LOCAL=0; \
790817 if [ " $$ HAS_FRONT" -eq 1 ] && [ " $$ HAS_BACK" -eq 1 ]; then DEV_LOCAL=1; \
@@ -829,6 +856,33 @@ dev: ## Local dev: preflight, cluster, dev-env, port-forwards; COMPONENT=fronten
829856 (cd components/frontend && npm run dev) & NPM_PID=$$ ! ; \
830857 trap ' kill $$GO_PID $$NPM_PID 2>/dev/null; cleanup' INT TERM; \
831858 wait $$ GO_PID $$ NPM_PID; \
859+ elif [ " $$ HAS_AUI" -eq 1 ]; then \
860+ echo " $( COLOR_BLUE) ▶$( COLOR_RESET) ambient-ui dev: setting up API server + Keycloak..." ; \
861+ pkill -f " port-forward.*ambient-api-server-service" 2> /dev/null || true ; \
862+ pkill -f " port-forward.*keycloak-service" 2> /dev/null || true ; \
863+ WANT_KC=" http://localhost:$( KIND_FWD_KEYCLOAK_PORT) " ; \
864+ CUR_KC=$$(kubectl get deployment keycloak -n $(NAMESPACE ) -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="KC_HOSTNAME" ) ].value}' 2>/dev/null); \
865+ if [ " $$ CUR_KC" != " $$ WANT_KC" ]; then \
866+ echo " $( COLOR_BLUE) ▶$( COLOR_RESET) Patching Keycloak hostname: $$ CUR_KC → $$ WANT_KC" ; \
867+ kubectl set env deployment/keycloak -n $(NAMESPACE ) KC_HOSTNAME=" $$ WANT_KC" > /dev/null 2>&1 ; \
868+ kubectl rollout status deployment/keycloak -n $(NAMESPACE ) --timeout=120s > /dev/null 2>&1 || true ; \
869+ echo " $( COLOR_GREEN) ✓$( COLOR_RESET) Keycloak hostname patched" ; \
870+ else \
871+ echo " $( COLOR_GREEN) ✓$( COLOR_RESET) Keycloak hostname already correct" ; \
872+ fi ; \
873+ kubectl port-forward -n $(NAMESPACE ) svc/ambient-api-server-service $(KIND_FWD_API_SERVER_PORT ) :8000 > /tmp/acp-dev-pf-api.log 2>&1 & PF_PIDS=" $$ PF_PIDS $$ !" ; \
874+ kubectl port-forward -n $(NAMESPACE ) svc/keycloak-service $(KIND_FWD_KEYCLOAK_PORT ) :8080 > /tmp/acp-dev-pf-keycloak.log 2>&1 & PF_PIDS=" $$ PF_PIDS $$ !" ; \
875+ sleep 2; \
876+ echo " $( COLOR_GREEN) ✓$( COLOR_RESET) API server → http://localhost:$( KIND_FWD_API_SERVER_PORT) " ; \
877+ echo " $( COLOR_GREEN) ✓$( COLOR_RESET) Keycloak → http://localhost:$( KIND_FWD_KEYCLOAK_PORT) " ; \
878+ $(MAKE ) --no-print-directory dev-env-ambient-ui; \
879+ echo " " ; \
880+ echo " $( COLOR_BOLD) Access:$( COLOR_RESET) " ; \
881+ echo " Ambient UI: $( COLOR_BLUE) http://localhost:3001$( COLOR_RESET) " ; \
882+ echo " API server: http://localhost:$( KIND_FWD_API_SERVER_PORT) " ; \
883+ echo " Keycloak: http://localhost:$( KIND_FWD_KEYCLOAK_PORT) " ; \
884+ echo " " ; \
885+ cd components/ambient-ui && npm run dev; \
832886 fi
833887
834888# #@ Benchmarking
@@ -969,14 +1023,18 @@ kind-login: check-kubectl check-local-context ## Set kubectl context, port-forwa
9691023kind-port-forward : check-kubectl check-local-context # # Port-forward kind services (for remote Podman)
9701024 @echo " $( COLOR_BOLD) Port forwarding kind services ($( KIND_CLUSTER_NAME) )$( COLOR_RESET) "
9711025 @echo " "
972- @echo " Frontend: http://localhost:$( KIND_FWD_FRONTEND_PORT) "
973- @echo " Backend: http://localhost:$( KIND_FWD_BACKEND_PORT) "
1026+ @echo " Frontend: http://localhost:$( KIND_FWD_FRONTEND_PORT) "
1027+ @echo " Backend: http://localhost:$( KIND_FWD_BACKEND_PORT) "
1028+ @echo " Ambient UI: http://localhost:$( KIND_FWD_AMBIENT_UI_PORT) "
1029+ @echo " Keycloak: http://localhost:$( KIND_FWD_KEYCLOAK_PORT) "
9741030 @echo " "
9751031 @echo " $( COLOR_YELLOW) Press Ctrl+C to stop$( COLOR_RESET) "
9761032 @echo " "
9771033 @trap ' echo ""; echo "$(COLOR_GREEN)✓$(COLOR_RESET) Port forwarding stopped"; exit 0' INT; \
9781034 (kubectl port-forward -n ambient-code svc/frontend-service $( KIND_FWD_FRONTEND_PORT) :3000 > /dev/null 2>&1 & ); \
9791035 (kubectl port-forward -n ambient-code svc/backend-service $( KIND_FWD_BACKEND_PORT) :8080 > /dev/null 2>&1 & ); \
1036+ (kubectl port-forward -n ambient-code svc/ambient-ui-service $( KIND_FWD_AMBIENT_UI_PORT) :3000 > /dev/null 2>&1 & ); \
1037+ (kubectl port-forward -n ambient-code svc/keycloak-service $( KIND_FWD_KEYCLOAK_PORT) :8080 > /dev/null 2>&1 & ); \
9801038 wait
9811039
9821040dev-bootstrap : check-kubectl check-local-context # # Bootstrap developer workspace with API key and integrations
@@ -1169,7 +1227,7 @@ kind-status: check-kind ## Show all kind clusters and their port assignments
11691227 @echo " Cluster: $( KIND_CLUSTER_NAME) "
11701228 @if [ -n " $( KIND_HOST) " ]; then echo " Host: $( KIND_HOST) (remote)" ; else echo " Host: localhost" ; fi
11711229 @echo " NodePort: $( KIND_HTTP_PORT) (HTTP) / $( KIND_HTTPS_PORT) (HTTPS)"
1172- @echo " Forward: $( KIND_FWD_FRONTEND_PORT) (frontend) / $( KIND_FWD_BACKEND_PORT) (backend)"
1230+ @echo " Forward: $( KIND_FWD_FRONTEND_PORT) (frontend) / $( KIND_FWD_BACKEND_PORT) (backend) / $( KIND_FWD_KEYCLOAK_PORT ) (keycloak) "
11731231 @echo " "
11741232 @CLUSTERS=$$($(if $(filter podman,$(CONTAINER_ENGINE ) ) ,KIND_EXPERIMENTAL_PROVIDER=podman) kind get clusters 2>/dev/null) ; \
11751233 if [ -z " $$ CLUSTERS" ]; then \
0 commit comments