Vendor chez and jerboa dependencies

ober

e3eccdb4e941fd3cb153574e39a64b3ec759c615

diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..b9cbe49
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,17 @@
+vendor/jerboa/
+vendor/jerboa-shell/
+vendor/jerboa-aws/
+vendor/chez-pcre2/
+vendor/chez-scintilla/
+vendor/chez-qt/
+vendor/chez-ssl/
+vendor/chez-https/
+
+.git/
+*.o
+*.so
+*.dylib
+*.wpo
+*.boot
+jemacs
+jemacs-qt
diff --git a/.gitignore b/.gitignore
index f64a1c3..1a35b1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ src/.jerbuild-hashes
 # Compiled Chez artifacts
 lib/**/*.so
 lib/**/*.wpo
+*.dylib
 
 # Build symlinks / local artifacts
 libjsh-ffi.so
@@ -32,6 +33,13 @@ qt_chez_shim.so
 #7778#
 
 # Vendored repos (cloned, not submodules)
+vendor/jerboa/
 vendor/jerboa-shell/
+vendor/jerboa-aws/
+vendor/chez-pcre2/
+vendor/chez-scintilla/
+vendor/chez-qt/
+vendor/chez-ssl/
+vendor/chez-https/
 vendor/**/*.so
 vendor/**/*.wpo
diff --git a/CLAUDE.md b/CLAUDE.md
index d3417ce..c72d63f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -37,7 +37,7 @@ Common pitfalls when step 3 fails:
 - **`library (std ...) not found`**: The Docker image has a stale jerboa `std/` tree. New modules must be added to the sync list in the `linux-static-qt-docker` Makefile target AND compiled into the WPO step in `build-binary-qt.ss`.
 - **`Dynamic loading not supported`**: Any `load-shared-object` call must be guarded with the `JEMACS_STATIC` env var check (the binary sets `JEMACS_STATIC=1`).
 - **`final:` or other unsupported keywords**: jerbuild doesn't support all Gerbil `defstruct` keywords — remove them.
-- **Dependencies not in gerbil-qt**: This project uses `vendor/chez-qt` (vendored from `github.com/ober/chez-qt`), NOT `~/mine/gerbil-qt`. The `CHEZ_QT_SHIM_DIR` must point to `.` (local project root) for runtime, and `vendor/` for the build header.
+- **Vendored dependencies**: run `make vendor-deps` and use `vendor/chez-*` plus `vendor/jerboa-*` checkouts. Do not rely on developer-local dependency paths or `gerbil-*` shim repos. The Qt shim sources live in this repo's `vendor/` directory.
 
 Do NOT rely on `make run-qt` (interpreted mode) as proof the binary works — the static binary has different constraints (no `load-shared-object`, all libraries must be compiled in).
 
@@ -116,10 +116,10 @@ make stress-burn-static      # Run again
 
 ## jsh Shell Library
 
-The jerboa-shell (jsh) library is a separate project at `~/mine/jerboa-shell`. After modifying any file in `~/mine/jerboa-shell/src/jsh/`, recompile:
+The jerboa-shell (jsh) library is vendored at `vendor/jerboa-shell`. After modifying any file in `vendor/jerboa-shell/src/jsh/`, recompile:
 
 ```bash
-cd ~/mine/jerboa-shell && make jsh-compile
+cd vendor/jerboa-shell && make jsh-compile
 ```
 
 If tests fail with "run-time information for library (jsh ...) has not been loaded", it means jsh needs recompilation.
@@ -195,7 +195,7 @@ Fix: ensure `(only (std srfi srfi-13) string-contains string-prefix?)` is in imp
 
 ### Tests fail: `run-time information for library (jsh ...) not loaded`
 
-Fix: rebuild jsh: `cd ~/mine/jerboa-shell && make jsh-compile`
+Fix: rebuild jsh: `cd vendor/jerboa-shell && make jsh-compile`
 
 ### shell-start! or gsh-capture hangs
 
diff --git a/Dockerfile b/Dockerfile
index c886bfa..b4b146e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -264,7 +264,8 @@ COPY --from=jsh-src . /deps/jsh
 COPY --from=pcre2-src . /deps/chez-pcre2
 COPY --from=sci-src . /deps/chez-scintilla
 COPY --from=qt-src . /deps/chez-qt
-COPY --from=qtshim-src . /deps/gerbil-qt
+RUN mkdir -p /deps/qt-shim
+COPY vendor/qt_shim.cpp vendor/qt_shim.h /deps/qt-shim/
 # qt_chez_shim.c is maintained in vendor/ (not in chez-qt) — copy it in
 COPY vendor/qt_chez_shim.c vendor/qt_shim.h /deps/chez-qt/
 
@@ -320,7 +321,7 @@ RUN QT_CFLAGS=$(pkg-config --cflags Qt6Widgets 2>/dev/null || \
               -I/opt/qt6-static/include/QtGui -I/opt/qt6-static/include/QtWidgets") && \
     gcc -c -O2 -fPIC -o /deps/chez-qt/qt_chez_shim.o \
         /deps/chez-qt/qt_chez_shim.c \
-        -I/deps/gerbil-qt/vendor $QT_CFLAGS -Wall
+        -I/deps/qt-shim $QT_CFLAGS -Wall
 
 # Build static libqt_shim.a from qt_shim.cpp
 # qt_static_plugins.o must be separate (NOT in archive) — it contains
@@ -333,14 +334,14 @@ RUN QT_CFLAGS=$(pkg-config --cflags Qt6Widgets 2>/dev/null || \
           echo "-I/opt/qt6-static/include -I/opt/qt6-static/include/Qsci")" && \
     g++ -c -fPIC -std=c++17 \
         $QT_CFLAGS $QSCI_FLAGS \
-        /deps/gerbil-qt/vendor/qt_shim.cpp \
-        -o /deps/gerbil-qt/vendor/qt_shim_static.o && \
-    ar rcs /deps/gerbil-qt/vendor/libqt_shim.a \
-        /deps/gerbil-qt/vendor/qt_shim_static.o && \
+        /deps/qt-shim/qt_shim.cpp \
+        -o /deps/qt-shim/qt_shim_static.o && \
+    ar rcs /deps/qt-shim/libqt_shim.a \
+        /deps/qt-shim/qt_shim_static.o && \
     printf '#include <QtPlugin>\nQ_IMPORT_PLUGIN(QXcbIntegrationPlugin)\n' \
-        > /deps/gerbil-qt/vendor/qt_static_plugins.cpp && \
+        > /deps/qt-shim/qt_static_plugins.cpp && \
     g++ -c -fPIC -std=c++17 $QT_CFLAGS \
-        /deps/gerbil-qt/vendor/qt_static_plugins.cpp \
-        -o /deps/gerbil-qt/vendor/qt_static_plugins.o
+        /deps/qt-shim/qt_static_plugins.cpp \
+        -o /deps/qt-shim/qt_static_plugins.o
 
 WORKDIR /src
diff --git a/Dockerfile.qt b/Dockerfile.qt
index db9da7c..4b48db6 100644
--- a/Dockerfile.qt
+++ b/Dockerfile.qt
@@ -275,8 +275,8 @@ COPY --from=qt-shim-alpine /tmp/qt-shim-out/ /opt/qt-shim/
 RUN ln -s /build/chez-musl /opt/chez
 
 # Copy source and run the in-container build
-COPY . /build/mine/jerboa-emacs
-WORKDIR /build/mine/jerboa-emacs
+COPY . /src
+WORKDIR /src
 
 RUN make linux-qt-local
 
@@ -288,5 +288,5 @@ RUN ./jemacs-qt --version && \
 
 # ── Final stage: extract binary ───────────────────────────────────────────────
 FROM ubuntu:24.04
-COPY --from=builder /build/mine/jerboa-emacs/jemacs-qt /out/jemacs-qt
+COPY --from=builder /src/jemacs-qt /out/jemacs-qt
 CMD ["cat", "/out/jemacs-qt"]
diff --git a/Dockerfile.tui b/Dockerfile.tui
index 98b336b..a74914d 100644
--- a/Dockerfile.tui
+++ b/Dockerfile.tui
@@ -11,10 +11,10 @@
 FROM jerboa21/jerboa AS builder
 
 # ── Copy jerboa-emacs source ────────────────────────────────────────────────
-COPY . /build/mine/jerboa-emacs
+COPY . /src
 
 # ── Build jemacs-musl ────────────────────────────────────────────────────────
-WORKDIR /build/mine/jerboa-emacs
+WORKDIR /src
 RUN make linux-tui-local
 
 # ── Verify ───────────────────────────────────────────────────────────────────
@@ -25,5 +25,5 @@ RUN ./jemacs --version && \
 
 # ── Output ───────────────────────────────────────────────────────────────────
 FROM ubuntu:24.04
-COPY --from=builder /build/mine/jerboa-emacs/jemacs /out/jemacs
+COPY --from=builder /src/jemacs /out/jemacs
 CMD ["cat", "/out/jemacs"]
diff --git a/Makefile b/Makefile
index 88d9efd..dd686f6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,39 @@
-JERBOA    ?= $(HOME)/mine/jerboa
+VENDOR    ?= $(CURDIR)/vendor
+
+JERBOA_REPO        ?= https://git.sr.ht/~lisp/jerboa
+JERBOA_SHELL_REPO  ?= https://git.sr.ht/~lisp/jerboa-shell
+CHEZ_PCRE2_REPO    ?= https://git.sr.ht/~lisp/chez-pcre2
+CHEZ_SCINTILLA_REPO ?= https://git.sr.ht/~lisp/chez-scintilla
+CHEZ_QT_REPO       ?= https://git.sr.ht/~lisp/chez-qt
+CHEZ_SSL_REPO      ?= https://git.sr.ht/~lisp/chez-ssl
+CHEZ_HTTPS_REPO    ?= https://git.sr.ht/~lisp/chez-https
+JERBOA_AWS_REPO    ?= https://git.sr.ht/~lisp/jerboa-aws
+
+VENDOR_REPOS := jerboa jerboa-shell chez-pcre2 chez-scintilla chez-qt chez-ssl chez-https jerboa-aws
+
+JERBOA    ?= $(VENDOR)/jerboa
 SCHEME    ?= $(JERBOA)/.chez/bin/scheme
-JSH       = $(if $(wildcard vendor/jerboa-shell/src/jsh),vendor/jerboa-shell/src,$(HOME)/mine/jerboa-shell/src)
-COREUTILS = $(if $(wildcard $(HOME)/mine/jerboa-coreutils/lib),$(HOME)/mine/jerboa-coreutils/lib,$(HOME)/mine/jerboa-shell/vendor/jerboa-coreutils/lib)
-GHERKIN   = $(if $(wildcard vendor/gherkin-runtime),vendor/gherkin-runtime,$(HOME)/mine/gherkin/src)
-JAWS      = $(if $(wildcard vendor/jerboa-aws),vendor/jerboa-aws,$(HOME)/mine/jerboa-aws)
-CSSL      = $(if $(wildcard vendor/chez-ssl/src),vendor/chez-ssl/src,$(HOME)/mine/chez-ssl/src)
-CHTTPS    = $(if $(wildcard vendor/chez-https/src),vendor/chez-https/src,$(HOME)/mine/chez-https/src)
-CQT       = $(if $(wildcard vendor/chez-qt/chez-qt/qt.ss),vendor/chez-qt,$(HOME)/mine/chez-qt)
-LIBDIRS   = --libdirs lib:$(JERBOA)/lib:$(JSH):$(COREUTILS):$(GHERKIN):$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-scintilla/src:$(CQT):$(JAWS):$(CSSL):$(CHTTPS)
+JSH_ROOT  ?= $(VENDOR)/jerboa-shell
+JSH       ?= $(JSH_ROOT)/src
+JSH_VENDOR ?= $(JSH_ROOT)/vendor
+COREUTILS ?= $(JSH_VENDOR)/jerboa-coreutils/lib
+JSH_AWK   ?= $(JSH_VENDOR)/jerboa-awk/lib
+JSH_SED   ?= $(JSH_VENDOR)/jerboa-sed/lib
+CHEZ_SSH  ?= $(JSH_VENDOR)/chez-ssh/src
+CHEZ_SQLITE ?= $(JSH_VENDOR)/chez-sqlite/src
+CHEZ_CRYPTO ?= $(JSH_VENDOR)/chez-crypto/src
+CHEZ_FUSE ?= $(JSH_VENDOR)/chez-fuse/lib
+GHERKIN   ?= $(VENDOR)/gherkin-runtime
+JAWS_ROOT ?= $(VENDOR)/jerboa-aws
+JAWS      ?= $(JAWS_ROOT)/lib
+CHEZ_SSL_ROOT ?= $(VENDOR)/chez-ssl
+CSSL      ?= $(CHEZ_SSL_ROOT)/src
+CHEZ_HTTPS_ROOT ?= $(VENDOR)/chez-https
+CHTTPS    ?= $(CHEZ_HTTPS_ROOT)/src
+CQT       ?= $(VENDOR)/chez-qt
+CHEZ_PCRE2_ROOT ?= $(VENDOR)/chez-pcre2
+CHEZ_SCINTILLA_ROOT ?= $(VENDOR)/chez-scintilla
+LIBDIRS   = --libdirs lib:$(JERBOA)/lib:$(JSH):$(COREUTILS):$(JSH_AWK):$(JSH_SED):$(CHEZ_SSH):$(CHEZ_SQLITE):$(CHEZ_CRYPTO):$(CHEZ_FUSE):$(GHERKIN):$(CHEZ_PCRE2_ROOT):$(CHEZ_SCINTILLA_ROOT)/src:$(CQT):$(JAWS):$(CSSL):$(CHTTPS)
 JERBUILD  = $(SCHEME) --libdirs $(JERBOA)/lib --script $(JERBOA)/jerbuild.ss
 
 # --- Platform detection -------------------------------------------------------
@@ -17,7 +43,7 @@ ifeq ($(UNAME_S),Darwin)
   # -undefined dynamic_lookup: allow symbols resolved at load time from the host process
   SHLIB_FLAGS := -dynamiclib -Wl,-undefined,dynamic_lookup
   PRELOAD_VAR := DYLD_INSERT_LIBRARIES
-  export DYLD_LIBRARY_PATH := .:$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-scintilla:$(HOME)/mine/chez-qt:$(HOME)/mine/jerboa-shell:vendor/jerboa-shell:$(DYLD_LIBRARY_PATH)
+  export DYLD_LIBRARY_PATH := .:$(CHEZ_PCRE2_ROOT):$(CHEZ_SCINTILLA_ROOT):$(CQT):$(JSH_ROOT):$(DYLD_LIBRARY_PATH)
   PTY_LINK    :=
   XVFB_RUN   :=
   export QT_QPA_PLATFORM := cocoa
@@ -29,7 +55,7 @@ else
   SHLIB_EXT   := so
   SHLIB_FLAGS := -shared -fPIC
   PRELOAD_VAR := LD_PRELOAD
-  export LD_LIBRARY_PATH := .:$(HOME)/mine/chez-pcre2:$(HOME)/mine/chez-scintilla:$(HOME)/mine/chez-qt:vendor/jerboa-shell:$(LD_LIBRARY_PATH)
+  export LD_LIBRARY_PATH := .:$(CHEZ_PCRE2_ROOT):$(CHEZ_SCINTILLA_ROOT):$(CQT):$(JSH_ROOT):$(LD_LIBRARY_PATH)
   PTY_LINK    := -lutil
   XVFB_RUN   := xvfb-run -a
   QT_INC_FALLBACK := /usr/include/x86_64-linux-gnu/qt6
@@ -40,16 +66,16 @@ endif
 PRELOAD_ENV := $(PRELOAD_VAR)=./qt_chez_shim.$(SHLIB_EXT):./libjerboa_native.$(SHLIB_EXT):./libjsh-ffi.$(SHLIB_EXT)
 # -----------------------------------------------------------------------------
 
-export CHEZ_SCINTILLA_LIB := $(HOME)/mine/chez-scintilla
-export CHEZ_PCRE2_LIB := $(HOME)/mine/chez-pcre2
-export JSH_FFI_LIB := $(HOME)/mine/jerboa-shell
+export CHEZ_SCINTILLA_LIB := $(CHEZ_SCINTILLA_ROOT)
+export CHEZ_PCRE2_LIB := $(CHEZ_PCRE2_ROOT)
+export JSH_FFI_LIB := $(JSH_ROOT)
 export CHEZ_QT_LIB := .
 export CHEZ_QT_SHIM_DIR := .
 ifeq ($(UNAME_S),Darwin)
   export CHEZ_DIR := $(shell ls -d /opt/homebrew/lib/csv*/tarm64osx 2>/dev/null | head -1)
 endif
 
-.PHONY: all build rebuild run test-tier0 test-tier2 test-tier3 test-tier4 test-tier5 test-org test-extra test clean clean-generated \
+.PHONY: all vendor-deps deps build rebuild run test-tier0 test-tier2 test-tier3 test-tier4 test-tier5 test-org test-extra test clean clean-generated \
         test-org-duration test-org-element test-org-fold test-org-footnote \
         test-org-lint test-org-num test-org-property test-org-src test-org-tempo \
         test-vtscreen test-debug-repl test-qt test-qt-e2e build-qt binary-qt \
@@ -64,6 +90,7 @@ endif
 
 all:
 	@echo "Available targets:"
+	@echo "  vendor-deps    Clone required chez-* and jerboa-* deps into vendor/"
 	@echo "  build          Translate src/*.ss → lib/*.sls (incremental)"
 	@echo "  rebuild        Force full retranslation"
 	@echo "  run            Build and run TUI editor"
@@ -82,12 +109,48 @@ all:
 	@echo "  test-tier5     Full editor commands"
 	@echo "  clean          Remove build artifacts"
 
+vendor-deps:
+	@echo "=== Vendoring chez-* and jerboa-* dependencies into $(VENDOR) ==="
+	@mkdir -p $(VENDOR)
+	@for repo in $(VENDOR_REPOS); do \
+	  case "$$repo" in \
+	    jerboa) url="$(JERBOA_REPO)" ;; \
+	    jerboa-shell) url="$(JERBOA_SHELL_REPO)" ;; \
+	    chez-pcre2) url="$(CHEZ_PCRE2_REPO)" ;; \
+	    chez-scintilla) url="$(CHEZ_SCINTILLA_REPO)" ;; \
+	    chez-qt) url="$(CHEZ_QT_REPO)" ;; \
+	    chez-ssl) url="$(CHEZ_SSL_REPO)" ;; \
+	    chez-https) url="$(CHEZ_HTTPS_REPO)" ;; \
+	    jerboa-aws) url="$(JERBOA_AWS_REPO)" ;; \
+	  esac; \
+	  dest="$(VENDOR)/$$repo"; \
+	  if [ -L "$$dest" ]; then \
+	    echo "  replacing symlink $$dest"; \
+	    rm "$$dest"; \
+	  fi; \
+	  if [ -d "$$dest/.git" ]; then \
+	    echo "  (exists) $$repo"; \
+	  elif [ -e "$$dest" ]; then \
+	    echo "ERROR: $$dest exists but is not a git clone; remove it and rerun make vendor-deps" >&2; \
+	    exit 1; \
+	  else \
+	    echo "  cloning $$repo from $$url"; \
+	    git clone --depth 1 "$$url" "$$dest"; \
+	  fi; \
+	done
+	@echo "=== Vendor complete ==="
+
+deps: vendor-deps
+	$(MAKE) -C $(JSH_ROOT) vendor-deps
+	$(MAKE) -C $(JERBOA) build
+	$(MAKE) -C $(CHEZ_PCRE2_ROOT) SCHEME=$(SCHEME)
+
 # Generate lib/jerboa-emacs/*.sls from src/jerboa-emacs/*.ss (incremental)
-build:
+build: deps
 	$(JERBUILD) src/ lib/
 
 # Force regenerate all
-rebuild:
+rebuild: deps
 	$(JERBUILD) src/ lib/ --force
 
 run: build vterm_shim.$(SHLIB_EXT)
@@ -185,7 +248,7 @@ qt_chez_shim.$(SHLIB_EXT): vendor/qt_chez_shim.c vendor/qt_shim.h
 
 # macOS native binary — compile all modules + link jemacs-qt binary
 macos: build libqt_shim.$(SHLIB_EXT) qt_chez_shim.$(SHLIB_EXT) repl_shim.$(SHLIB_EXT) vterm_shim.$(SHLIB_EXT)
-	cd $(HOME)/mine/chez-pcre2 && make
+	$(MAKE) -C $(CHEZ_PCRE2_ROOT) SCHEME=$(SCHEME)
 	JSH_DIR=$(JSH) $(PRELOAD_ENV) $(SCHEME) $(LIBDIRS) --script build-binary-qt.ss
 	./jemacs-qt --version
 
@@ -259,14 +322,14 @@ build-qt: build
 	@echo "   - Qt modules: 45/45 (100%)"
 	@echo "   - Lines ported: ~48,801"
 	@echo "   - All modules compile successfully"
-	@echo "   - Full feature parity with gerbil-emacs achieved"
+	@echo "   - Full feature parity with the reference editor achieved"
 	@echo ""
 	@echo "🎉 PLAN.MD COMPLETE - READY FOR Qt EXECUTABLE BUILD"
 	@echo "════════════════════════════════════════════════════════════════"
 
 test: build test-tier0 test-tier2 test-tier3 test-tier4 test-tier5 test-org test-extra
 
-test-tier0:
+test-tier0: vterm_shim.$(SHLIB_EXT) repl_shim.$(SHLIB_EXT)
 	$(SCHEME) $(LIBDIRS) --script tests/test-tier0.ss
 
 test-tier2:
@@ -372,28 +435,31 @@ test-term-hang:
 binary-qt: build
 	$(SCHEME) $(LIBDIRS) --script build-binary-qt.ss
 
-# chez-scintilla shim — built from ~/mine/chez-scintilla (requires Scintilla/Lexilla/termbox archives)
-SCI_DIR ?= $(HOME)/mine/chez-scintilla
-GERBIL_SCI_VENDOR ?= $(HOME)/mine/gerbil-emacs/.gerbil/pkg/github.com/ober/gerbil-scintilla/vendor
+# chez-scintilla shim.  The C/C++ Scintilla vendor tree, when needed for TUI
+# binaries, must live under the vendored chez-scintilla checkout.
+SCI_DIR ?= $(CHEZ_SCINTILLA_ROOT)
+SCINTILLA_VENDOR ?= $(SCI_DIR)/vendor
 
 chez_scintilla_shim.$(SHLIB_EXT): $(SCI_DIR)/chez_scintilla_shim.c
+	@test -d $(SCINTILLA_VENDOR) || \
+	  { echo "ERROR: SCINTILLA_VENDOR='$(SCINTILLA_VENDOR)' not found. Populate it from the chez-scintilla dependency or set SCINTILLA_VENDOR."; exit 1; }
 	gcc $(SHLIB_FLAGS) -O2 \
-	  -I$(GERBIL_SCI_VENDOR)/scintilla/include \
-	  -I$(GERBIL_SCI_VENDOR)/scintilla/src \
-	  -I$(GERBIL_SCI_VENDOR)/scintilla/termbox \
-	  -I$(GERBIL_SCI_VENDOR)/scintilla/termbox/termbox_next/src \
-	  -I$(GERBIL_SCI_VENDOR)/lexilla/include \
+	  -I$(SCINTILLA_VENDOR)/scintilla/include \
+	  -I$(SCINTILLA_VENDOR)/scintilla/src \
+	  -I$(SCINTILLA_VENDOR)/scintilla/termbox \
+	  -I$(SCINTILLA_VENDOR)/scintilla/termbox/termbox_next/src \
+	  -I$(SCINTILLA_VENDOR)/lexilla/include \
 	  -o chez_scintilla_shim.$(SHLIB_EXT) \
 	  $(SCI_DIR)/chez_scintilla_shim.c \
 	  -Wl,--whole-archive \
-	  $(GERBIL_SCI_VENDOR)/scintilla/bin/scintilla.a \
-	  $(GERBIL_SCI_VENDOR)/lexilla/bin/liblexilla.a \
-	  $(GERBIL_SCI_VENDOR)/scintilla/termbox/termbox_next/bin/termbox.a \
+	  $(SCINTILLA_VENDOR)/scintilla/bin/scintilla.a \
+	  $(SCINTILLA_VENDOR)/lexilla/bin/liblexilla.a \
+	  $(SCINTILLA_VENDOR)/scintilla/termbox/termbox_next/bin/termbox.a \
 	  -Wl,--no-whole-archive \
 	  -lstdc++ -lpthread -Wall
 
 # pcre2 shim — copied from chez-pcre2 (already built there)
-PCRE2_DIR ?= $(HOME)/mine/chez-pcre2
+PCRE2_DIR ?= $(CHEZ_PCRE2_ROOT)
 
 pcre2_shim.$(SHLIB_EXT): $(PCRE2_DIR)/pcre2_shim.$(SHLIB_EXT)
 	cp $< $@
@@ -413,17 +479,16 @@ ARCH    := $(shell uname -m)
 UID     := $(shell id -u)
 GID     := $(shell id -g)
 
-# Dependency source directories (all ~/mine/* local checkouts)
-JERBOA_SRC   ?= $(HOME)/mine/jerboa
+# Dependency source directories (vendored clones)
+JERBOA_SRC   ?= $(JERBOA)
 GHERKIN_SRC  ?= $(CURDIR)/vendor/gherkin-runtime
-JSH_SRC      ?= $(HOME)/mine/jerboa-shell
-PCRE2_SRC    ?= $(HOME)/mine/chez-pcre2
-SCI_SRC      ?= $(HOME)/mine/chez-scintilla
-QT_SRC       ?= $(CURDIR)/vendor/chez-qt
-QTSHIM_SRC   ?= $(HOME)/mine/gerbil-qt
-JAWS_SRC     ?= $(HOME)/mine/jerboa-aws/lib
-CSSL_SRC     ?= $(HOME)/mine/chez-ssl
-CHTTPS_SRC   ?= $(HOME)/mine/chez-https
+JSH_SRC      ?= $(JSH_ROOT)
+PCRE2_SRC    ?= $(CHEZ_PCRE2_ROOT)
+SCI_SRC      ?= $(CHEZ_SCINTILLA_ROOT)
+QT_SRC       ?= $(CQT)
+JAWS_SRC     ?= $(JAWS)
+CSSL_SRC     ?= $(CHEZ_SSL_ROOT)
+CHTTPS_SRC   ?= $(CHEZ_HTTPS_ROOT)
 # Use stub if the Rust musl build hasn't been compiled yet (regular file check)
 _RUST_COREUTILS := $(JSH_SRC)/rust-coreutils/target/x86_64-unknown-linux-musl/release/libjsh_coreutils.a
 JSH_COREUTILS_LIB ?= $(shell test -f $(_RUST_COREUTILS) && echo $(_RUST_COREUTILS) || echo $(CURDIR)/vendor/libjsh_coreutils_stub.a)
@@ -444,7 +509,6 @@ docker-deps:
 	  --build-context pcre2-src=$(PCRE2_SRC) \
 	  --build-context sci-src=$(SCI_SRC) \
 	  --build-context qt-src=$(QT_SRC) \
-	  --build-context qtshim-src=$(QTSHIM_SRC) \
 	  --build-context jaws-src=$(JAWS_SRC) \
 	  --build-context chez-ssl-src=$(CSSL_SRC) \
 	  --build-context chez-https-src=$(CHTTPS_SRC) \
@@ -488,12 +552,12 @@ build-jemacs-qt-static: check-root
 	    echo "-I/opt/qt6-static/include -I/opt/qt6-static/include/QtCore \
 	          -I/opt/qt6-static/include/QtGui -I/opt/qt6-static/include/QtWidgets") && \
 	  QSCI_FLAGS="-DQT_SCINTILLA_AVAILABLE -I/opt/qt6-static/include -I/opt/qt6-static/include/Qsci" && \
-	  cp /src/vendor/qt_shim.cpp /deps/gerbil-qt/vendor/qt_shim.cpp && \
+	  cp /src/vendor/qt_shim.cpp /deps/qt-shim/qt_shim.cpp && \
 	  g++ -c -fPIC -std=c++17 -DJEMACS_CHEZ_SMP $$QT_CFLAGS $$QSCI_FLAGS \
-	    /deps/gerbil-qt/vendor/qt_shim.cpp \
-	    -o /deps/gerbil-qt/vendor/qt_shim_static.o && \
-	  ar rcs /deps/gerbil-qt/vendor/libqt_shim.a \
-	    /deps/gerbil-qt/vendor/qt_shim_static.o; \
+	    /deps/qt-shim/qt_shim.cpp \
+	    -o /deps/qt-shim/qt_shim_static.o && \
+	  ar rcs /deps/qt-shim/libqt_shim.a \
+	    /deps/qt-shim/qt_shim_static.o; \
 	fi && \
 	cp -a /src/vendor/chez-qt/. /deps/chez-qt/ && \
 	find /deps/chez-qt -name '*.so' -delete && \
@@ -566,7 +630,7 @@ build-jemacs-qt-static: check-root
 	CHEZ_PCRE2_DIR=/deps/chez-pcre2 \
 	CHEZ_SCINTILLA_DIR=/deps/chez-scintilla/src \
 	CHEZ_QT_DIR=/deps/chez-qt \
-	CHEZ_QT_SHIM_DIR=/deps/gerbil-qt/vendor \
+	CHEZ_QT_SHIM_DIR=/deps/qt-shim \
 	JSH_COREUTILS_LIB=/deps/jsh/libjsh_coreutils.a \
 	JAWS_DIR=/deps/jerboa-aws \
 	CHEZ_SSL_DIR=/deps/chez-ssl \
@@ -578,7 +642,7 @@ build-jemacs-qt-static: check-root
 	TREE_SITTER_QUERIES_OBJ=/tmp/jemacs-build/treesitter_queries.o \
 	PKG_CONFIG_PATH=/opt/qt6-static/lib/pkgconfig \
 	/opt/chez/bin/scheme \
-	  --libdirs lib:/deps/jerboa/lib:/deps/jsh/src:/src/vendor/gherkin-runtime:/deps/chez-pcre2:/deps/chez-scintilla/src:/deps/chez-qt:/deps/jerboa-aws:/deps/chez-ssl/src:/deps/chez-https/src \
+	  --libdirs lib:/deps/jerboa/lib:/deps/jsh/src:/deps/jsh/vendor/jerboa-coreutils/lib:/deps/jsh/vendor/jerboa-awk/lib:/deps/jsh/vendor/jerboa-sed/lib:/deps/jsh/vendor/chez-ssh/src:/deps/jsh/vendor/chez-sqlite/src:/deps/jsh/vendor/chez-crypto/src:/deps/jsh/vendor/chez-fuse/lib:/src/vendor/gherkin-runtime:/deps/chez-pcre2:/deps/chez-scintilla/src:/deps/chez-qt:/deps/jerboa-aws:/deps/chez-ssl/src:/deps/chez-https/src \
 	  --script build-binary-qt.ss
 
 linux-static-qt-docker:
@@ -632,9 +696,10 @@ linux-static-qt-docker:
 # Static TUI binary (Docker-based, Alpine musl)
 # =============================================================================
 
-# gerbil-scintilla vendor source: Scintilla/termbox/Lexilla C/C++ source + headers
-# Used to build static archives inside the Alpine container
-SCI_VENDOR_SRC ?= $(HOME)/mine/gerbil-emacs/.gerbil/pkg/github.com/ober/gerbil-scintilla/vendor
+# Scintilla/termbox/Lexilla C/C++ source + headers used to build static
+# archives inside the Alpine container. Keep this under chez-scintilla's
+# vendored checkout.
+SCI_VENDOR_SRC ?= $(CHEZ_SCINTILLA_ROOT)/vendor
 
 # Fast static TUI binary via Docker (requires deps image from `make docker-deps`).
 # Builds Scintilla+termbox+Lexilla from source, then ./jemacs (~5-10 min).
@@ -699,14 +764,14 @@ build-jemacs-tui-static: check-root
 	SCI_VENDOR_DIR=/deps/sci-vendor \
 	JSH_COREUTILS_LIB=/deps/jsh/libjsh_coreutils.a \
 	/opt/chez/bin/scheme \
-	  --libdirs lib:/deps/jerboa/lib:/deps/jsh/src:/src/vendor/gherkin-runtime:/deps/chez-pcre2:/deps/chez-scintilla/src \
+	  --libdirs lib:/deps/jerboa/lib:/deps/jsh/src:/deps/jsh/vendor/jerboa-coreutils/lib:/deps/jsh/vendor/jerboa-awk/lib:/deps/jsh/vendor/jerboa-sed/lib:/deps/jsh/vendor/chez-ssh/src:/deps/jsh/vendor/chez-sqlite/src:/deps/jsh/vendor/chez-crypto/src:/deps/jsh/vendor/chez-fuse/lib:/src/vendor/gherkin-runtime:/deps/chez-pcre2:/deps/chez-scintilla/src \
 	  --script build-binary.ss
 
 linux-static-tui-docker:
 	@docker image inspect $(DEPS_IMAGE) >/dev/null 2>&1 || \
 	  { echo "ERROR: Deps image '$(DEPS_IMAGE)' not found. Run 'make docker-deps' first."; exit 1; }
 	@test -d $(SCI_VENDOR_SRC) || \
-	  { echo "ERROR: SCI_VENDOR_SRC='$(SCI_VENDOR_SRC)' not found. Set SCI_VENDOR_SRC to gerbil-scintilla vendor/ path."; exit 1; }
+	  { echo "ERROR: SCI_VENDOR_SRC='$(SCI_VENDOR_SRC)' not found. Populate it from the chez-scintilla dependency or set SCI_VENDOR_SRC."; exit 1; }
 	docker run --rm \
 	  --ulimit nofile=8192:8192 \
 	  -v $(CURDIR):/src:z \
@@ -743,6 +808,13 @@ linux-static-tui-docker:
 JERBOA_IMAGE ?= jerboa21/jerboa
 MUSL_CHEZ_DIR = $(shell ls -d /build/chez-musl/lib/csv*/ta6le 2>/dev/null | head -1)
 MUSL_SCHEME = /usr/local/bin/scheme
+MUSL_DEPS ?= $(VENDOR)
+MUSL_JERBOA ?= $(MUSL_DEPS)/jerboa
+MUSL_PCRE2 ?= $(MUSL_DEPS)/chez-pcre2
+MUSL_SCINTILLA ?= $(MUSL_DEPS)/chez-scintilla
+MUSL_JSH_ROOT ?= $(MUSL_DEPS)/jerboa-shell
+MUSL_JSH ?= $(MUSL_JSH_ROOT)/src
+MUSL_SCI_VENDOR ?= /build/sci-vendor
 
 # Docker build: produces ./jemacs static binary
 linux-tui:
@@ -756,74 +828,74 @@ linux-tui:
 	@ls -lh jemacs
 	@file jemacs
 
-# In-container build target (called inside jerboa21/jerboa)
-# All deps are pre-installed in the image at /build/mine/ and /build/sci-vendor/
-linux-tui-local:
+# In-container build target (called inside jerboa21/jerboa).
+# Dependency sources use the same vendor/ clones as local builds.
+linux-tui-local: vendor-deps
 	@echo "=== Building jemacs static TUI (in-container) ==="
 	rm -f src/.jerbuild-hashes
 	find lib -name '*.so' -o -name '*.wpo' | xargs rm -f 2>/dev/null; true
 	find src/jerboa-emacs -name '*.ss' | sed 's|src/|lib/|; s|\.ss$$|.sls|' | xargs rm -f 2>/dev/null; true
-	find /build/mine/jerboa/lib -name '*.so' -delete 2>/dev/null; true
-	find /build/mine/jerboa/lib -name '*.wpo' -delete 2>/dev/null; true
-	find /build/mine/chez-scintilla -name '*.so' -delete 2>/dev/null; true
-	find /build/mine/chez-pcre2 -name '*.so' -delete 2>/dev/null; true
-	find /build/mine/jerboa-shell -name '*.wpo' -delete 2>/dev/null; true
+	find $(MUSL_JERBOA)/lib -name '*.so' -delete 2>/dev/null; true
+	find $(MUSL_JERBOA)/lib -name '*.wpo' -delete 2>/dev/null; true
+	find $(MUSL_SCINTILLA) -name '*.so' -delete 2>/dev/null; true
+	find $(MUSL_PCRE2) -name '*.so' -delete 2>/dev/null; true
+	find $(MUSL_JSH_ROOT) -name '*.wpo' -delete 2>/dev/null; true
 	find vendor/gherkin-runtime -name '*.so' -delete 2>/dev/null; true
 	find vendor/gherkin-runtime -name '*.wpo' -delete 2>/dev/null; true
 	find vendor/jerboa-shell -name '*.so' -delete 2>/dev/null; true
 	find vendor/jerboa-shell -name '*.wpo' -delete 2>/dev/null; true
 	@echo "Recompiling jerboa core + prelude..."
 	echo '(import (chezscheme)) (compile-imported-libraries #t) (import (jerboa core)) (import (jerboa prelude))' \
-	  | $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib -q
-	rm -f /build/mine/jerboa/lib/jerboa/*.wpo
-	$(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib --script /build/mine/jerboa/jerbuild.ss src/ lib/
-	cp vendor/chez-pcre2-ffi-static.ss /build/mine/chez-pcre2/chez-pcre2/ffi.ss
-	$(MUSL_SCHEME) --libdirs /build/mine/chez-pcre2 \
+	  | $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib -q
+	rm -f $(MUSL_JERBOA)/lib/jerboa/*.wpo
+	$(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib --script $(MUSL_JERBOA)/jerbuild.ss src/ lib/
+	cp vendor/chez-pcre2-ffi-static.ss $(MUSL_PCRE2)/chez-pcre2/ffi.ss
+	$(MUSL_SCHEME) --libdirs $(MUSL_PCRE2) \
 	  --compile-imported-libraries --script vendor/chez-pcre2-compile-libs.ss
-	rm -f /build/mine/chez-pcre2/chez-pcre2/*.wpo
-	cp vendor/chez-scintilla-ffi-static.sls /build/mine/chez-scintilla/src/chez-scintilla/ffi.sls
-	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /build/mine/chez-scintilla/src \
+	rm -f $(MUSL_PCRE2)/chez-pcre2/*.wpo
+	cp vendor/chez-scintilla-ffi-static.sls $(MUSL_SCINTILLA)/src/chez-scintilla/ffi.sls
+	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs $(MUSL_SCINTILLA)/src \
 	  --compile-imported-libraries --script vendor/chez-scintilla-compile-libs.ss
-	rm -f /build/mine/chez-scintilla/src/chez-scintilla/*.wpo
-	cp vendor/jerboa-net-tcp-static.sls /build/mine/jerboa/lib/std/net/tcp.sls
-	cp vendor/jerboa-net-tcp-raw-static.sls /build/mine/jerboa/lib/std/net/tcp-raw.sls
-	cp vendor/jerboa-net-uri.sls /build/mine/jerboa/lib/std/net/uri.sls
-	cp vendor/jerboa-net-tls-rustls-static.sls /build/mine/jerboa/lib/std/net/tls-rustls.sls
-	rm -f /build/mine/jerboa/lib/std/net/*.wpo /build/mine/jerboa/lib/std/net/*.so
-	cp vendor/jerboa-crypto-native-static.sls /build/mine/jerboa/lib/std/crypto/native.sls
-	rm -f /build/mine/jerboa/lib/std/crypto/*.wpo /build/mine/jerboa/lib/std/crypto/*.so
-	mkdir -p /build/mine/jerboa/lib/std/security
-	cp vendor/jerboa-security-capsicum-static.sls /build/mine/jerboa/lib/std/security/capsicum.sls
-	rm -f /build/mine/jerboa/lib/std/security/*.wpo /build/mine/jerboa/lib/std/security/*.so
-	cp vendor/jerboa-os-landlock-static.sls /build/mine/jerboa/lib/std/os/landlock.sls
-	rm -f /build/mine/jerboa/lib/std/os/landlock.wpo /build/mine/jerboa/lib/std/os/landlock.so
-	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	rm -f $(MUSL_SCINTILLA)/src/chez-scintilla/*.wpo
+	cp vendor/jerboa-net-tcp-static.sls $(MUSL_JERBOA)/lib/std/net/tcp.sls
+	cp vendor/jerboa-net-tcp-raw-static.sls $(MUSL_JERBOA)/lib/std/net/tcp-raw.sls
+	cp vendor/jerboa-net-uri.sls $(MUSL_JERBOA)/lib/std/net/uri.sls
+	cp vendor/jerboa-net-tls-rustls-static.sls $(MUSL_JERBOA)/lib/std/net/tls-rustls.sls
+	rm -f $(MUSL_JERBOA)/lib/std/net/*.wpo $(MUSL_JERBOA)/lib/std/net/*.so
+	cp vendor/jerboa-crypto-native-static.sls $(MUSL_JERBOA)/lib/std/crypto/native.sls
+	rm -f $(MUSL_JERBOA)/lib/std/crypto/*.wpo $(MUSL_JERBOA)/lib/std/crypto/*.so
+	mkdir -p $(MUSL_JERBOA)/lib/std/security
+	cp vendor/jerboa-security-capsicum-static.sls $(MUSL_JERBOA)/lib/std/security/capsicum.sls
+	rm -f $(MUSL_JERBOA)/lib/std/security/*.wpo $(MUSL_JERBOA)/lib/std/security/*.so
+	cp vendor/jerboa-os-landlock-static.sls $(MUSL_JERBOA)/lib/std/os/landlock.sls
+	rm -f $(MUSL_JERBOA)/lib/std/os/landlock.wpo $(MUSL_JERBOA)/lib/std/os/landlock.so
+	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-tcp.ss
-	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-tcp-raw.ss
-	$(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	$(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-uri.ss
-	rm -f /build/mine/jerboa/lib/std/net/*.wpo
-	cp vendor/jerboa-repl-static.sls /build/mine/jerboa/lib/std/repl.sls
-	rm -f /build/mine/jerboa/lib/std/repl.wpo /build/mine/jerboa/lib/std/repl.so
-	cd /build/mine/jerboa/lib && $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	rm -f $(MUSL_JERBOA)/lib/std/net/*.wpo
+	cp vendor/jerboa-repl-static.sls $(MUSL_JERBOA)/lib/std/repl.sls
+	rm -f $(MUSL_JERBOA)/lib/std/repl.wpo $(MUSL_JERBOA)/lib/std/repl.so
+	cd $(MUSL_JERBOA)/lib && $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script $(CURDIR)/vendor/jerboa-compile-repl.ss
-	rm -f /build/mine/jerboa/lib/std/repl.wpo
+	rm -f $(MUSL_JERBOA)/lib/std/repl.wpo
 	rm -f lib/jerboa/*.wpo lib/jerboa/*.so
 	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-repl-socket.ss
 	rm -f lib/jerboa/*.wpo
-	find /build/mine/jerboa-shell -name '*.wpo' -delete 2>/dev/null; true
+	find $(MUSL_JSH_ROOT) -name '*.wpo' -delete 2>/dev/null; true
 	JEMACS_STATIC=1 \
 	CHEZ_DIR=$(MUSL_CHEZ_DIR) \
-	JERBOA_DIR=/build/mine/jerboa/lib \
-	JSH_DIR=vendor/jerboa-shell/src \
-	GHERKIN_DIR=vendor/gherkin-runtime \
-	CHEZ_PCRE2_DIR=/build/mine/chez-pcre2 \
-	CHEZ_SCINTILLA_DIR=/build/mine/chez-scintilla/src \
-	SCI_VENDOR_DIR=/build/sci-vendor \
+	JERBOA_DIR=$(MUSL_JERBOA)/lib \
+	JSH_DIR=$(MUSL_JSH) \
+	GHERKIN_DIR=$(GHERKIN) \
+	CHEZ_PCRE2_DIR=$(MUSL_PCRE2) \
+	CHEZ_SCINTILLA_DIR=$(MUSL_SCINTILLA)/src \
+	SCI_VENDOR_DIR=$(MUSL_SCI_VENDOR) \
 	$(MUSL_SCHEME) \
-	  --libdirs lib:/build/mine/jerboa/lib:vendor/jerboa-shell/src:vendor/gherkin-runtime:/build/mine/chez-pcre2:/build/mine/chez-scintilla/src \
+	  --libdirs lib:$(MUSL_JERBOA)/lib:$(MUSL_JSH):$(COREUTILS):$(JSH_AWK):$(JSH_SED):$(CHEZ_SSH):$(CHEZ_SQLITE):$(CHEZ_CRYPTO):$(CHEZ_FUSE):$(GHERKIN):$(MUSL_PCRE2):$(MUSL_SCINTILLA)/src \
 	  --script build-binary.ss
 	@echo ""
 	@echo "=== jemacs static TUI binary built ==="
@@ -851,16 +923,16 @@ linux-qt:
 # Tree-sitter is at /opt/tree-sitter-* (copied from Alpine stage).
 # Pre-compiled libqt_shim.a is at /opt/qt-shim/ (Alpine-musl g++, ABI-compatible).
 # /opt/chez → /build/chez-musl symlink provides musl Chez Scheme.
-linux-qt-local:
+linux-qt-local: vendor-deps
 	@echo "=== Building jemacs-qt static (in-container) ==="
 	rm -f src/.jerbuild-hashes
 	find lib -name '*.so' -o -name '*.wpo' | xargs rm -f 2>/dev/null; true
 	find src/jerboa-emacs -name '*.ss' | sed 's|src/|lib/|; s|\.ss$$|.sls|' | xargs rm -f 2>/dev/null; true
-	find /build/mine/jerboa/lib -name '*.so' -delete 2>/dev/null; true
-	find /build/mine/jerboa/lib -name '*.wpo' -delete 2>/dev/null; true
-	find /build/mine/chez-scintilla -name '*.so' -delete 2>/dev/null; true
-	find /build/mine/chez-pcre2 -name '*.so' -delete 2>/dev/null; true
-	find /build/mine/jerboa-shell -name '*.wpo' -delete 2>/dev/null; true
+	find $(MUSL_JERBOA)/lib -name '*.so' -delete 2>/dev/null; true
+	find $(MUSL_JERBOA)/lib -name '*.wpo' -delete 2>/dev/null; true
+	find $(MUSL_SCINTILLA) -name '*.so' -delete 2>/dev/null; true
+	find $(MUSL_PCRE2) -name '*.so' -delete 2>/dev/null; true
+	find $(MUSL_JSH_ROOT) -name '*.wpo' -delete 2>/dev/null; true
 	find vendor/gherkin-runtime -name '*.so' -delete 2>/dev/null; true
 	find vendor/gherkin-runtime -name '*.wpo' -delete 2>/dev/null; true
 	find vendor/jerboa-shell -name '*.so' -delete 2>/dev/null; true
@@ -873,9 +945,9 @@ linux-qt-local:
 	find vendor/jerboa-aws -name '*.wpo' -delete 2>/dev/null; true
 	@echo "Recompiling jerboa core + prelude..."
 	echo '(import (chezscheme)) (compile-imported-libraries #t) (import (jerboa core)) (import (jerboa prelude))' \
-	  | $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib -q
-	rm -f /build/mine/jerboa/lib/jerboa/*.wpo
-	$(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib --script /build/mine/jerboa/jerbuild.ss src/ lib/
+	  | $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib -q
+	rm -f $(MUSL_JERBOA)/lib/jerboa/*.wpo
+	$(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib --script $(MUSL_JERBOA)/jerbuild.ss src/ lib/
 	# Set up writable chez-qt copy from vendor (compile Scheme library)
 	mkdir -p /tmp/jemacs-build/chez-qt
 	cp -a vendor/chez-qt/. /tmp/jemacs-build/chez-qt/
@@ -884,50 +956,50 @@ linux-qt-local:
 	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /tmp/jemacs-build/chez-qt \
 	  --compile-imported-libraries --script /tmp/jemacs-build/chez-qt/compile-libs.ss
 	rm -f /tmp/jemacs-build/chez-qt/chez-qt/*.wpo
-	cp vendor/chez-pcre2-ffi-static.ss /build/mine/chez-pcre2/chez-pcre2/ffi.ss
-	$(MUSL_SCHEME) --libdirs /build/mine/chez-pcre2 \
+	cp vendor/chez-pcre2-ffi-static.ss $(MUSL_PCRE2)/chez-pcre2/ffi.ss
+	$(MUSL_SCHEME) --libdirs $(MUSL_PCRE2) \
 	  --compile-imported-libraries --script vendor/chez-pcre2-compile-libs.ss
-	rm -f /build/mine/chez-pcre2/chez-pcre2/*.wpo
-	cp vendor/chez-scintilla-ffi-static.sls /build/mine/chez-scintilla/src/chez-scintilla/ffi.sls
-	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /build/mine/chez-scintilla/src \
+	rm -f $(MUSL_PCRE2)/chez-pcre2/*.wpo
+	cp vendor/chez-scintilla-ffi-static.sls $(MUSL_SCINTILLA)/src/chez-scintilla/ffi.sls
+	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs $(MUSL_SCINTILLA)/src \
 	  --compile-imported-libraries --script vendor/chez-scintilla-compile-libs.ss
-	rm -f /build/mine/chez-scintilla/src/chez-scintilla/*.wpo
-	cp vendor/jerboa-net-tcp-static.sls /build/mine/jerboa/lib/std/net/tcp.sls
-	cp vendor/jerboa-net-tcp-raw-static.sls /build/mine/jerboa/lib/std/net/tcp-raw.sls
-	cp vendor/jerboa-net-uri.sls /build/mine/jerboa/lib/std/net/uri.sls
-	cp vendor/jerboa-net-tls-rustls-static.sls /build/mine/jerboa/lib/std/net/tls-rustls.sls
-	rm -f /build/mine/jerboa/lib/std/net/*.wpo /build/mine/jerboa/lib/std/net/*.so
-	cp vendor/jerboa-crypto-native-static.sls /build/mine/jerboa/lib/std/crypto/native.sls
-	rm -f /build/mine/jerboa/lib/std/crypto/*.wpo /build/mine/jerboa/lib/std/crypto/*.so
-	mkdir -p /build/mine/jerboa/lib/std/security
-	cp vendor/jerboa-security-capsicum-static.sls /build/mine/jerboa/lib/std/security/capsicum.sls
-	rm -f /build/mine/jerboa/lib/std/security/*.wpo /build/mine/jerboa/lib/std/security/*.so
-	cp vendor/jerboa-os-landlock-static.sls /build/mine/jerboa/lib/std/os/landlock.sls
-	rm -f /build/mine/jerboa/lib/std/os/landlock.wpo /build/mine/jerboa/lib/std/os/landlock.so
-	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	rm -f $(MUSL_SCINTILLA)/src/chez-scintilla/*.wpo
+	cp vendor/jerboa-net-tcp-static.sls $(MUSL_JERBOA)/lib/std/net/tcp.sls
+	cp vendor/jerboa-net-tcp-raw-static.sls $(MUSL_JERBOA)/lib/std/net/tcp-raw.sls
+	cp vendor/jerboa-net-uri.sls $(MUSL_JERBOA)/lib/std/net/uri.sls
+	cp vendor/jerboa-net-tls-rustls-static.sls $(MUSL_JERBOA)/lib/std/net/tls-rustls.sls
+	rm -f $(MUSL_JERBOA)/lib/std/net/*.wpo $(MUSL_JERBOA)/lib/std/net/*.so
+	cp vendor/jerboa-crypto-native-static.sls $(MUSL_JERBOA)/lib/std/crypto/native.sls
+	rm -f $(MUSL_JERBOA)/lib/std/crypto/*.wpo $(MUSL_JERBOA)/lib/std/crypto/*.so
+	mkdir -p $(MUSL_JERBOA)/lib/std/security
+	cp vendor/jerboa-security-capsicum-static.sls $(MUSL_JERBOA)/lib/std/security/capsicum.sls
+	rm -f $(MUSL_JERBOA)/lib/std/security/*.wpo $(MUSL_JERBOA)/lib/std/security/*.so
+	cp vendor/jerboa-os-landlock-static.sls $(MUSL_JERBOA)/lib/std/os/landlock.sls
+	rm -f $(MUSL_JERBOA)/lib/std/os/landlock.wpo $(MUSL_JERBOA)/lib/std/os/landlock.so
+	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-tcp.ss
-	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-tcp-raw.ss
-	$(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	$(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-uri.ss
-	rm -f /build/mine/jerboa/lib/std/net/*.wpo
-	cp vendor/jerboa-repl-static.sls /build/mine/jerboa/lib/std/repl.sls
-	rm -f /build/mine/jerboa/lib/std/repl.wpo /build/mine/jerboa/lib/std/repl.so
-	cd /build/mine/jerboa/lib && $(MUSL_SCHEME) --libdirs /build/mine/jerboa/lib \
+	rm -f $(MUSL_JERBOA)/lib/std/net/*.wpo
+	cp vendor/jerboa-repl-static.sls $(MUSL_JERBOA)/lib/std/repl.sls
+	rm -f $(MUSL_JERBOA)/lib/std/repl.wpo $(MUSL_JERBOA)/lib/std/repl.so
+	cd $(MUSL_JERBOA)/lib && $(MUSL_SCHEME) --libdirs $(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries --script $(CURDIR)/vendor/jerboa-compile-repl.ss
-	rm -f /build/mine/jerboa/lib/std/repl.wpo
+	rm -f $(MUSL_JERBOA)/lib/std/repl.wpo
 	rm -f lib/jerboa/*.wpo lib/jerboa/*.so
 	JEMACS_STATIC=1 $(MUSL_SCHEME) --libdirs lib \
 	  --compile-imported-libraries --script vendor/jerboa-compile-repl-socket.ss
 	rm -f lib/jerboa/*.wpo
 	# Compile SSL/HTTPS/AWS
 	cp vendor/chez-ssl-static.sls vendor/chez-ssl/src/chez-ssl.sls
-	cp vendor/jerboa-aws-crypto-native.sls vendor/jerboa-aws/jerboa-aws/crypto.sls
+	cp vendor/jerboa-aws-crypto-native.sls $(JAWS)/jerboa-aws/crypto.sls
 	find vendor/chez-ssl -name '*.so' -delete; find vendor/chez-ssl -name '*.wpo' -delete
 	find vendor/chez-https -name '*.so' -delete; find vendor/chez-https -name '*.wpo' -delete
 	find vendor/jerboa-aws -name '*.so' -delete; find vendor/jerboa-aws -name '*.wpo' -delete
 	JEMACS_STATIC=1 $(MUSL_SCHEME) \
-	  --libdirs vendor/chez-ssl/src:/build/mine/jerboa/lib \
+	  --libdirs vendor/chez-ssl/src:$(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries -q --script vendor/chez-ssl-compile-libs.ss
 	find vendor/chez-ssl -name '*.wpo' -delete
 	JEMACS_STATIC=1 $(MUSL_SCHEME) \
@@ -935,7 +1007,7 @@ linux-qt-local:
 	  --compile-imported-libraries -q --script vendor/chez-https-compile-libs.ss
 	find vendor/chez-https -name '*.wpo' -delete
 	JEMACS_STATIC=1 $(MUSL_SCHEME) \
-	  --libdirs vendor/jerboa-aws:vendor/chez-https/src:vendor/chez-ssl/src:/build/mine/jerboa/lib \
+	  --libdirs $(JAWS):$(CHTTPS):$(CSSL):$(MUSL_JERBOA)/lib \
 	  --compile-imported-libraries -q --script vendor/jerboa-aws-compile-libs.ss
 	find vendor/jerboa-aws -name '*.wpo' -delete
 	# Build tree-sitter C shim objects
@@ -947,17 +1019,17 @@ linux-qt-local:
 	# Run the main Qt build script
 	JEMACS_STATIC=1 \
 	CHEZ_DIR=$(MUSL_CHEZ_DIR) \
-	JERBOA_DIR=/build/mine/jerboa/lib \
-	JSH_DIR=vendor/jerboa-shell/src \
-	GHERKIN_DIR=vendor/gherkin-runtime \
-	CHEZ_PCRE2_DIR=/build/mine/chez-pcre2 \
-	CHEZ_SCINTILLA_DIR=/build/mine/chez-scintilla/src \
+	JERBOA_DIR=$(MUSL_JERBOA)/lib \
+	JSH_DIR=$(MUSL_JSH) \
+	GHERKIN_DIR=$(GHERKIN) \
+	CHEZ_PCRE2_DIR=$(MUSL_PCRE2) \
+	CHEZ_SCINTILLA_DIR=$(MUSL_SCINTILLA)/src \
 	CHEZ_QT_DIR=/tmp/jemacs-build/chez-qt \
 	CHEZ_QT_SHIM_DIR=/opt/qt-shim \
 	JSH_COREUTILS_LIB=vendor/libjsh_coreutils_stub.a \
-	JAWS_DIR=vendor/jerboa-aws \
-	CHEZ_SSL_DIR=vendor/chez-ssl \
-	CHEZ_HTTPS_DIR=vendor/chez-https/src \
+	JAWS_DIR=$(JAWS) \
+	CHEZ_SSL_DIR=$(CHEZ_SSL_ROOT) \
+	CHEZ_HTTPS_DIR=$(CHTTPS) \
 	TREE_SITTER_INCLUDE=/opt/tree-sitter-include \
 	TREE_SITTER_LIB=/opt/tree-sitter-lib \
 	TREE_SITTER_GRAMMARS=/opt/tree-sitter-grammars \
@@ -965,7 +1037,7 @@ linux-qt-local:
 	TREE_SITTER_QUERIES_OBJ=/tmp/jemacs-build/treesitter_queries.o \
 	PKG_CONFIG_PATH=/opt/qt6-static/lib/pkgconfig \
 	$(MUSL_SCHEME) \
-	  --libdirs lib:/build/mine/jerboa/lib:vendor/jerboa-shell/src:vendor/gherkin-runtime:/build/mine/chez-pcre2:/build/mine/chez-scintilla/src:/tmp/jemacs-build/chez-qt:vendor/jerboa-aws:vendor/chez-ssl/src:vendor/chez-https/src \
+	  --libdirs lib:$(MUSL_JERBOA)/lib:$(MUSL_JSH):$(COREUTILS):$(JSH_AWK):$(JSH_SED):$(CHEZ_SSH):$(CHEZ_SQLITE):$(CHEZ_CRYPTO):$(CHEZ_FUSE):$(GHERKIN):$(MUSL_PCRE2):$(MUSL_SCINTILLA)/src:/tmp/jemacs-build/chez-qt:$(JAWS):$(CSSL):$(CHTTPS) \
 	  --script build-binary-qt.ss
 	@echo ""
 	@echo "=== jemacs-qt static binary built ==="
diff --git a/README.md b/README.md
index 9382419..3d0ec01 100644
--- a/README.md
+++ b/README.md
@@ -19,11 +19,11 @@ The TUI backend runs in a terminal using Scintilla's text model. The Qt backend 
 | Dependency | Purpose | Location |
 |------------|---------|----------|
 | Chez Scheme ≥ 9.6 | Scheme runtime | system |
-| jerboa | Gerbil-compat stdlib | `~/mine/jerboa` |
-| jerboa-shell (jsh) | Shell interpreter | `~/mine/jerboa-shell` |
-| gherkin | Scheme dialect library | `~/mine/gherkin` |
-| chez-scintilla | Scintilla editor FFI | `~/mine/chez-scintilla` |
-| chez-pcre2 | PCRE2 regex FFI | `~/mine/chez-pcre2` |
+| jerboa | Gerbil-compat stdlib | `vendor/jerboa` |
+| jerboa-shell (jsh) | Shell interpreter | `vendor/jerboa-shell` |
+| gherkin runtime | Scheme dialect runtime | `vendor/gherkin-runtime` |
+| chez-scintilla | Scintilla editor FFI | `vendor/chez-scintilla` |
+| chez-pcre2 | PCRE2 regex FFI | `vendor/chez-pcre2` |
 
 ### Additional (Qt backend)
 
@@ -31,12 +31,20 @@ The TUI backend runs in a terminal using Scintilla's text model. The Qt backend 
 |------------|---------|----------|
 | Qt 5 or Qt 6 | GUI framework | system |
 | QScintilla | Qt Scintilla widget | system |
-| chez-qt | Qt FFI bindings | `~/mine/chez-qt` |
+| chez-qt | Qt FFI bindings | `vendor/chez-qt` |
 
 ## Build
 
 All commands run from the project root.
 
+### Vendor dependencies
+
+```bash
+make vendor-deps
+```
+
+This clones required `chez-*` and `jerboa-*` repositories into `vendor/` from their SourceHut remotes. The default `make build` target runs this first.
+
 ### Build library modules
 
 ```bash
@@ -56,7 +64,7 @@ make rebuild
 The shell interpreter must be compiled separately:
 
 ```bash
-cd ~/mine/jerboa-shell
+cd vendor/jerboa-shell
 make jsh-compile
 ```
 
@@ -112,9 +120,9 @@ This runs: test-tier0, test-tier2, test-tier3, test-tier4, test-tier5, test-org,
 The Makefile sets these automatically:
 
 ```
-LD_LIBRARY_PATH = ~/mine/chez-pcre2:~/mine/chez-scintilla:~/mine/chez-qt:~/mine/jerboa-shell
-CHEZ_SCINTILLA_LIB = ~/mine/chez-scintilla
-CHEZ_PCRE2_LIB = ~/mine/chez-pcre2
+LD_LIBRARY_PATH = vendor/chez-pcre2:vendor/chez-scintilla:vendor/chez-qt:vendor/jerboa-shell
+CHEZ_SCINTILLA_LIB = vendor/chez-scintilla
+CHEZ_PCRE2_LIB = vendor/chez-pcre2
 ```
 
 ## Source Layout
@@ -182,10 +190,10 @@ The Gerbil form `(with-output-to-string "" thunk)` is not valid in Chez.
 
 | Variable | Default | Description |
 |----------|---------|-------------|
-| `SCHEME` | `scheme` | Chez Scheme executable |
-| `JERBOA` | `~/mine/jerboa` | jerboa library path |
-| `JSH` | `~/mine/jerboa-shell/src` | jsh source path |
-| `GHERKIN` | `~/mine/gherkin/src` | gherkin library path |
+| `SCHEME` | `vendor/jerboa/.chez/bin/scheme` | Chez Scheme executable |
+| `JERBOA` | `vendor/jerboa` | jerboa checkout |
+| `JSH` | `vendor/jerboa-shell/src` | jsh source path |
+| `GHERKIN` | `vendor/gherkin-runtime` | gherkin runtime path |
 
 Override on the command line: `make SCHEME=/usr/local/bin/chez build`
 
diff --git a/build-binary-qt.ss b/build-binary-qt.ss
index 7b2ea92..238e8dc 100644
--- a/build-binary-qt.ss
+++ b/build-binary-qt.ss
@@ -7,8 +7,8 @@
 ;;
 ;; All boot files are embedded as C byte arrays via Sregister_boot_file_bytes.
 ;; FFI shims are compiled into the binary (pcre2_shim, qt_chez_shim).
-;; libqt_shim.so (from gerbil-qt vendor) is loaded at runtime — it must
-;; be in the same directory as the binary or on LD_LIBRARY_PATH.
+;; libqt_shim.so is loaded at runtime — it must be in the same directory as
+;; the binary or on LD_LIBRARY_PATH.
 ;;
 ;; Qt system libraries (Qt6Widgets, Qt6Core, etc.) are linked dynamically
 ;; from the system install. The binary requires Qt6 to be installed.
@@ -60,37 +60,43 @@
   (exit 1))
 
 ;; --- Locate dependent library directories ---
-(define home (getenv "HOME"))
+(define repo-dir (current-directory))
+(define (repo-path rel)
+  (if (and (> (string-length repo-dir) 0)
+           (char=? (string-ref repo-dir (- (string-length repo-dir) 1)) #\/))
+      (string-append repo-dir rel)
+      (string-append repo-dir "/" rel)))
+
 (define jerboa-dir
   (or (getenv "JERBOA_DIR")
-      (format "~a/mine/jerboa/lib" home)))
+      (repo-path "vendor/jerboa/lib")))
 (define gherkin-dir
   (or (getenv "GHERKIN_DIR")
-      (format "~a/mine/gherkin/src" home)))
+      (repo-path "vendor/gherkin-runtime")))
 (define jsh-dir
   (or (getenv "JSH_DIR")
-      (format "~a/mine/jerboa-emacs/vendor/jerboa-shell/src" home)))
+      (repo-path "vendor/jerboa-shell/src")))
 (define pcre2-dir
   (or (getenv "CHEZ_PCRE2_DIR")
-      (format "~a/mine/chez-pcre2" home)))
+      (repo-path "vendor/chez-pcre2")))
 (define sci-dir
   (or (getenv "CHEZ_SCINTILLA_DIR")
-      (format "~a/mine/chez-scintilla/src" home)))
+      (repo-path "vendor/chez-scintilla/src")))
 (define qt-dir
   (or (getenv "CHEZ_QT_DIR")
-      (format "~a/mine/chez-qt" home)))
+      (repo-path "vendor/chez-qt")))
 (define qt-shim-dir
   (or (getenv "CHEZ_QT_SHIM_DIR")
-      (format "~a/mine/gerbil-qt/vendor" home)))
+      (repo-path "vendor")))
 (define jaws-dir
   (or (getenv "JAWS_DIR")
-      (format "~a/mine/jerboa-aws/lib" home)))
+      (repo-path "vendor/jerboa-aws/lib")))
 (define chez-ssl-dir
   (or (getenv "CHEZ_SSL_DIR")
-      (format "~a/mine/chez-ssl" home)))
+      (repo-path "vendor/chez-ssl")))
 (define chez-https-dir
   (or (getenv "CHEZ_HTTPS_DIR")
-      (format "~a/mine/chez-https/src" home)))
+      (repo-path "vendor/chez-https/src")))
 
 ;; Static build detection (needed before dep checks)
 (define jemacs-static?
diff --git a/build-binary.ss b/build-binary.ss
index f1de191..ecf22ca 100644
--- a/build-binary.ss
+++ b/build-binary.ss
@@ -72,27 +72,33 @@
   (exit 1))
 
 ;; --- Locate dependent library directories ---
-(define home (getenv "HOME"))
+(define repo-dir (current-directory))
+(define (repo-path rel)
+  (if (and (> (string-length repo-dir) 0)
+           (char=? (string-ref repo-dir (- (string-length repo-dir) 1)) #\/))
+      (string-append repo-dir rel)
+      (string-append repo-dir "/" rel)))
+
 (define jerboa-dir
   (or (getenv "JERBOA_DIR")
-      (format "~a/mine/jerboa/lib" home)))
+      (repo-path "vendor/jerboa/lib")))
 (define gherkin-dir
   (or (getenv "GHERKIN_DIR")
-      (format "~a/mine/gherkin/src" home)))
+      (repo-path "vendor/gherkin-runtime")))
 (define jsh-dir
   (or (getenv "JSH_DIR")
-      (format "~a/mine/jerboa-emacs/vendor/jerboa-shell/src" home)))
+      (repo-path "vendor/jerboa-shell/src")))
 (define pcre2-dir
   (or (getenv "CHEZ_PCRE2_DIR")
-      (format "~a/mine/chez-pcre2" home)))
+      (repo-path "vendor/chez-pcre2")))
 (define sci-dir
   (or (getenv "CHEZ_SCINTILLA_DIR")
-      (format "~a/mine/chez-scintilla/src" home)))
-;; gerbil-scintilla vendor dir: contains scintilla.a, liblexilla.a, termbox.a
-;; and the C header files needed to compile chez_scintilla_shim.c
+      (repo-path "vendor/chez-scintilla/src")))
+;; Scintilla vendor dir: contains scintilla.a, liblexilla.a, termbox.a and the
+;; C header files needed to compile chez_scintilla_shim.c.
 (define sci-vendor-dir
   (or (getenv "SCI_VENDOR_DIR")
-      (format "~a/mine/gerbil-emacs/.gerbil/pkg/github.com/ober/gerbil-scintilla/vendor" home)))
+      (repo-path "vendor/chez-scintilla/vendor")))
 
 ;; Static build detection
 (define jemacs-static?
diff --git a/docs/jemacs-vs-emacs.md b/docs/jemacs-vs-emacs.md
index bc9c90c..7384f65 100644
--- a/docs/jemacs-vs-emacs.md
+++ b/docs/jemacs-vs-emacs.md
@@ -1146,7 +1146,7 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features 
 
 ## Personal Workflow Gap Analysis
 
-> *Based on review of the user's Doom Emacs configuration at `~/mine/emacs/`*
+> *Based on review of the user's local Doom Emacs configuration.*
 
 ### What the User Actually Uses Daily
 
diff --git a/docs/repl-server.md b/docs/repl-server.md
index 6bea66f..1ffdb88 100644
--- a/docs/repl-server.md
+++ b/docs/repl-server.md
@@ -103,7 +103,7 @@ Connection closed.
 
 ### Step 1: New Module `debug-repl.ss`
 
-Create `/home/jafourni/mine/jerboa-emacs/debug-repl.ss`:
+Create `debug-repl.ss` in the repository root:
 
 ```scheme
 (export start-debug-repl! stop-debug-repl! debug-repl-port)
diff --git a/docs/shell.md b/docs/shell.md
index ceeb974..d28b9b6 100644
--- a/docs/shell.md
+++ b/docs/shell.md
@@ -41,23 +41,17 @@ jsh is a complete POSIX shell with bash compatibility, built from first principl
 
 ## Phase 1: Add jsh as a Dependency
 
-### 1a. Link jerboa-shell locally
+### 1a. Vendor jerboa-shell locally
 
 ```bash
-jerboa pkg link jerboa-shell ~/mine/jerboa-shell
+make vendor-deps
 ```
 
-This makes `:jsh/...` modules importable via `GERBIL_LOADPATH`.
+This clones `vendor/jerboa-shell` and makes `:jsh/...` modules importable through the project Makefile's `--libdirs`.
 
-### 1b. Update `gerbil.pkg`
+### 1b. Use vendored Chez/Jerboa dependencies
 
-```scheme
-(package: jemacs)
-(depend: (github: "ober/gerbil-pcre2")