en un clic
clj-repl
// Start or connect to a Clojure/ClojureScript/Babashka nREPL. Detects project type and starts appropriate REPL in background. Use when user wants to evaluate code, start REPL, or needs nREPL connection.
// Start or connect to a Clojure/ClojureScript/Babashka nREPL. Detects project type and starts appropriate REPL in background. Use when user wants to evaluate code, start REPL, or needs nREPL connection.
REPL-driven autonomous development loops for Clojure. Spawns fresh Claude instances per iteration with REPL validation for 10x faster feedback.
Scaffold a new Clojure project with composable modules. Creates hello-world examples only - no assumptions, no custom code.
Experimental: Run Lisa Loop checkpoints via Claude Code Agent Teams. You become team lead, coordinating parallel teammates with REPL-validated gates.
Check and update forj template dependency versions. Use when maintaining forj or when user asks about template versions.
| name | clj-repl |
| description | Start or connect to a Clojure/ClojureScript/Babashka nREPL. Detects project type and starts appropriate REPL in background. Use when user wants to evaluate code, start REPL, or needs nREPL connection. |
Start or connect to an nREPL server for REPL-driven development.
| Command | Action |
|---|---|
/clj-repl | Auto-detect project, start REPL (asks if existing found) |
/clj-repl fresh | Restart all - stop existing, start new (no prompts) |
/clj-repl keep | Use existing REPLs if running (no prompts) |
/clj-repl bb | Start Babashka nREPL |
/clj-repl clj | Start JVM Clojure nREPL |
/clj-repl shadow | Start shadow-cljs nREPL |
/clj-repl status | Check tracked + discovered REPLs |
/clj-repl stop | Stop all tracked REPLs |
/clj-repl --verbose | Show detailed MCP tool output |
Default: Concise - Show brief status updates, final summary table only.
With --verbose - Show MCP tool call details and intermediate output.
Example concise output:
Starting backend + shadow-cljs...
✓ Backend REPL on port 1669
✓ shadow-cljs on port 9630
✓ App server started
| Service | Port | URL |
|---------|------|-----|
| Backend | 1669 | - |
| shadow-cljs | 9630 | http://localhost:9630 |
| Web App | 8080 | http://localhost:8080 |
DO NOT show raw MCP JSON responses or tool call internals unless --verbose is specified.
After REPLs are running, ALWAYS use forj MCP tools instead of bash commands:
| Task | MCP Tool | NOT bash |
|---|---|---|
| Evaluate code | repl_eval | clj-nrepl-eval -p ... |
| Find REPLs | discover_repls | clj-nrepl-eval --discover-ports |
| Reload namespace | reload_namespace | |
| Look up docs | doc_symbol | (doc ...) |
| Eval at line | eval_at | |
| Run tests | run_tests | clj -M:test |
Bash is ONLY for starting/stopping REPL servers. All evaluation should use MCP tools.
Before reporting success, ALL of these must be true:
:dev-http ports (web apps served here!)⚠️ COMMON MISS: The :dev-http port in shadow-cljs.edn!
grep ":dev-http" shadow-cljs.edn
# Example output: :dev-http {8080 "resources/public"}
# This means web app is at http://localhost:8080 - REPORT IT!
Handle flags first:
| Flag | Behavior |
|---|---|
fresh | Skip prompts. Stop all tracked processes, start new ones. |
keep | Skip prompts. Use existing REPLs if found, start only what's missing. |
| (none) | Ask user if existing processes found. |
Check for tracked processes:
list_tracked_processes
discover_repls
With fresh flag:
stop_project # Stop all tracked processes
# Then proceed to start new ones (Step 2+)
With keep flag:
With no flag (default): If there are tracked processes that are still alive:
If processes are tracked but all dead, clean them up silently:
stop_project
Check which config files exist:
| Files Present | What to Start |
|---|---|
deps.edn + shadow-cljs.edn + app.json | Backend + shadow-cljs (check for multiple builds!) + Expo |
deps.edn + shadow-cljs.edn | Backend + shadow-cljs (check for multiple builds!) |
shadow-cljs.edn + app.json | shadow-cljs + Expo |
deps.edn only | Backend REPL |
shadow-cljs.edn only | shadow-cljs |
bb.edn only | Babashka REPL |
⚠️ CHECK FOR MULTIPLE SHADOW BUILDS:
Many projects have BOTH :web and :mobile builds. Check shadow-cljs.edn:
grep -E "^\s+:(web|mobile|app|main)" shadow-cljs.edn
If you see multiple builds (e.g., :web AND :mobile):
bb shadow:web AND bb shadow:mobileExample project with both:
bb dev # Backend REPL
bb shadow:web # Web frontend (port 8080)
bb shadow:mobile # Mobile frontend
bb expo:web # Expo dev server
Do NOT stop after starting REPLs. The app server must also be running.
If bb.edn has relevant tasks, you MUST use them instead of raw commands.
| Task | Use For |
|---|---|
bb dev or bb repl | Backend REPL |
bb shadow:mobile | ClojureScript for Expo (outputs to app/) |
bb shadow:web | ClojureScript for browser |
bb expo / bb expo:android / bb expo:ios / bb expo:web | Expo dev server |
Only fall back to raw commands if NO bb task exists.
Use run_in_background: true for each. Start them all before moving on.
First, create log directory:
mkdir -p .forj/logs
Use setsid -f with tee to daemonize processes (survive terminal close):
# Pattern: setsid -f bash -c 'command 2>&1 | tee .forj/logs/<name>.log' &
setsid -f bash -c 'bb dev 2>&1 | tee .forj/logs/backend.log' &
setsid -f bash -c 'bb shadow:web 2>&1 | tee .forj/logs/shadow.log' & # or shadow:mobile for Expo
IMPORTANT: Track each process after starting!
After each background process starts, call track_process with the PID (from Bash tool output):
track_process with pid=<PID> name="backend-repl" port=<PORT> command="bb dev"
track_process with pid=<PID> name="shadow-cljs" port=9630 command="bb shadow:mobile" # or shadow:web
track_process with pid=<PID> name="expo" port=8081 command="bb expo"
This enables /clj-repl stop to cleanly shut down all processes later.
To view logs later, use the view_repl_logs MCP tool:
view_repl_logs with log: "all" - see all logs at onceview_repl_logs with log: "backend" / "shadow" / "expo" - specific loglines: 50 (default) - number of lines to returnFull-stack with web + mobile (check shadow-cljs.edn for builds!):
mkdir -p .forj/logs
setsid -f bash -c 'bb dev 2>&1 | tee .forj/logs/backend.log' &
# Check shadow-cljs.edn for builds - start ALL that exist:
setsid -f bash -c 'bb shadow:web 2>&1 | tee .forj/logs/shadow-web.log' & # If :web build exists
setsid -f bash -c 'bb shadow:mobile 2>&1 | tee .forj/logs/shadow-mobile.log' & # If :mobile build exists
# Then prompt for device (see Step 4a)
First, check if Expo Web is available:
# Check package.json for react-native-web
grep -q "react-native-web" package.json && echo "WEB_ENABLED"
Ask the user (include Web option only if detected):
"How do you want to run the app?"
- Android emulator (launches automatically)
- iOS simulator (launches automatically)
- Physical device (enter URL in Expo Go)
- Web browser (if react-native-web installed) - great for Playwright/automation testing
Use bb tasks (NOT npx):
Android:
setsid -f bash -c 'bb expo:android 2>&1 | tee .forj/logs/expo.log' &
iOS:
setsid -f bash -c 'bb expo:ios 2>&1 | tee .forj/logs/expo.log' &
Physical Device (Manual URL):
# Get local IP
LOCAL_IP=$(ip route get 1 | awk '{print $7; exit}')
# Start Expo in background with logging (daemonized)
setsid -f bash -c 'bb expo 2>&1 | tee .forj/logs/expo.log' &
# Wait for startup
sleep 3
# Display connection info
echo "Open Expo Go on your device and enter URL:"
echo " exp://${LOCAL_IP}:8081"
Web Browser (if react-native-web installed):
setsid -f bash -c 'bb expo:web 2>&1 | tee .forj/logs/expo.log' &
# Wait for startup
sleep 3
echo "Open http://localhost:8081 in your browser"
Full-stack web:
mkdir -p .forj/logs
setsid -f bash -c 'bb dev 2>&1 | tee .forj/logs/backend.log' &
setsid -f bash -c 'bb shadow:web 2>&1 | tee .forj/logs/shadow.log' &
Backend only:
mkdir -p .forj/logs
setsid -f bash -c 'bb dev 2>&1 | tee .forj/logs/backend.log' &
REPL running ≠ Done. The application server must be started from within the REPL.
Detection priority:
Common functions - Search src/**/core.clj for:
(defn start-server → eval (<namespace>/start-server)(defn start → eval (<namespace>/start)(defn go → eval (<namespace>/go)State management - Check requires:
mount.core → eval (mount.core/start)integrant.core → look for (ig/init ...)component → look for (component/start ...)Comment blocks - Read them for startup examples
Fallback - Read core.clj and figure out how to start it
Example:
repl_eval with code="(require '[myapp.core :as core] :reload)"
repl_eval with code="(core/start-server {:port 3000})"
Wait 2-5 seconds after starting, then:
discover_repls
Test each REPL:
repl_eval with code="(+ 1 2)" port=<backend-port>
repl_eval with code="(+ 1 2)" port=<shadow-port>
Final checklist before reporting:
Check shadow-cljs.edn for dev-http ports:
grep -o ':dev-http {[0-9]*' shadow-cljs.edn
If :dev-http is present (e.g., {8080 "resources/public"}), the web app is served on that port.
Report all services in a table:
| Service | Port | URL |
|---|---|---|
| Backend API | 3000 | http://localhost:3000 |
| Web App (dev-http) | 8080 | http://localhost:8080 |
| Expo Web | 8081 | http://localhost:8081 |
| shadow-cljs UI | 9630 | http://localhost:9630 |
Include only the services actually running for this project type.
Tell the user:
When user asks to evaluate code, ALWAYS use repl_eval MCP tool:
repl_eval with code="(+ 1 2 3)"
The tool auto-discovers ports. Do NOT shell out to clj-nrepl-eval.
/clj-repl status)Run both tools and summarize:
list_tracked_processes
discover_repls
Report to user:
Use the stop_project MCP tool to stop all tracked processes:
stop_project
This kills all REPLs, shadow-cljs, and Expo processes that were tracked with track_process.
To check what's tracked before stopping:
list_tracked_processes
Manual fallback (if processes weren't tracked):
lsof -i :<port>
kill $(lsof -t -i :<port>)
For projects with multiple build files:
discover_repls to see what's runningNo REPLs found:
discover_repls to check what's running/clj-repl bb or /clj-repl cljWrong project context: The nREPL's working directory determines the project. Make sure to start the REPL from the correct directory.
Port conflicts: Each REPL needs a unique port. Use different ports for multiple REPLs.