원클릭으로
lisa-loop
// REPL-driven autonomous development loops for Clojure. Spawns fresh Claude instances per iteration with REPL validation for 10x faster feedback.
// REPL-driven autonomous development loops for Clojure. Spawns fresh Claude instances per iteration with REPL validation for 10x faster feedback.
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.
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 | lisa-loop |
| description | REPL-driven autonomous development loops for Clojure. Spawns fresh Claude instances per iteration with REPL validation for 10x faster feedback. |
| commands | [{"name":"lisa-loop","description":"Start an autonomous development loop - spawns fresh Claude instances per checkpoint","args":"<prompt> [--max-iterations N]"},{"name":"lisa-loop watch","description":"Watch the active Lisa loop - spawns background monitor that notifies on completion","args":"[--interval N]"},{"name":"cancel-lisa","description":"Cancel the active Lisa loop"}] |
Lisa Loop is forj's native autonomous development loop. It spawns fresh Claude instances for each iteration, using LISA_PLAN.edn for state and REPL for validation.
Start an autonomous development loop:
/lisa-loop "Build a REST API for users with CRUD operations" --max-iterations 20
Arguments:
<prompt> - The task description (required)--max-iterations N - Maximum iterations before stopping (default: 20)--prd <path> - Path to PRD or specification documentStop the loop:
/cancel-lisa
Monitor the loop and get notified on completion:
/lisa-loop watch
/lisa-loop watch --interval 60
Arguments:
--interval N - Check every N seconds (default: 30)This will:
lisa_watchExample output:
[Lisa Watch] Current Status:
┌────────────┬─────────────────────────────────┬────────┐
│ Checkpoint │ Description │ Status │
├────────────┼─────────────────────────────────┼────────┤
│ 1 │ Create password hashing │ ✅ Done │
│ 2 │ Create JWT tokens │ ✅ Done │
│ 3 │ Create auth middleware │ 🔄 In Progress │
│ 4 │ Integration test │ ⏳ Pending │
└────────────┴─────────────────────────────────┴────────┘
Progress: 2/4 (50%)
Background monitor started (checking every 30s).
You'll be notified when the loop completes.
For live updates, tail the log in another terminal:
tail -f .forj/logs/lisa/orchestrator-20260128-102332.log
On completion, the monitor reports:
Lisa Loop complete!
Final Status: COMPLETE
Checkpoints: 4/4 (100%)
Signs/Learnings: None
All checkpoints:
1. Create password hashing - Done
2. Create JWT tokens - Done
3. Create auth middleware - Done
4. Integration test - Done
When user runs /lisa-loop watch:
Step 1: Show immediate status
lisa_watch → Display current checkpoint table
Step 2: Find orchestrator log
Glob for: .forj/logs/lisa/orchestrator-*.log
Get the most recent one for the tail command
Step 3: Tell user about live tailing option
Tell user:
- For live updates: tail -f <log-path>
- You'll also get periodic status updates here
Step 4: Spawn ONE-SHOT background check agent
IMPORTANT: The agent does ONE check and exits. It does NOT loop internally.
Task({
subagent_type: "general-purpose",
run_in_background: true,
prompt: """
1. Sleep for {interval} seconds using Bash: `sleep {interval}`
2. Read the file LISA_PLAN.edn using Read tool
3. Report: How many checkpoints are :done vs total? What's the current :status? Is it :complete?
That's it - just those 3 steps then exit.
"""
})
Step 5: When agent completes, react
When the background agent completes and notifies you:
:complete → announce "Lisa Loop complete!" and stop:in-progress → spawn another identical agent (go to Step 4)Example flow:
Agent completes → "Status: 5/10 (50%) - wait-30s-6 in progress"
→ Spawn another agent
→ Wait...
Agent completes → "Status: 8/10 (80%) - wait-30s-9 in progress"
→ Spawn another agent
→ Wait...
Agent completes → "Status: 10/10 (100%) - COMPLETE!"
→ Announce completion, stop spawning
Why this approach:
/lisa-loop "Build user auth"
│
▼
┌─────────────────────┐
│ 1. PLANNING PHASE │ ◄── Current Claude session
│ │
│ - Read PRD if exists│
│ - Propose checkpoints│
│ - Get user approval │
│ - Create LISA_PLAN.edn│
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ 2. RUN ORCHESTRATOR │ ◄── Calls lisa_run_orchestrator
│ │
│ Spawns fresh Claude │
│ instance for each │──────┐
│ checkpoint │ │
└─────────────────────┘ │
│
┌────────────────────────┘
│
▼
┌─────────────────────┐
│ ITERATION N │ ◄── Fresh Claude instance
│ (Fresh Context) │
│ │
│ - Read LISA_PLAN.edn│
│ - Read embedded signs│
│ - Work on checkpoint│
│ - Validate via REPL │
│ - Mark done if pass │
└─────────┬───────────┘
│
▼
Checkpoint done?
├── Yes → Next iteration (fresh instance)
└── No → Retry (fresh instance)
│
▼
All done? → COMPLETE
When user runs /lisa-loop:
Check for existing plan:
lisa_get_plan
Check for PRD/documentation:
Glob for: PRD.md, SPEC.md, REQUIREMENTS.md, docs/*.md
Decision tree:
| Situation | Action |
|---|---|
| LISA_PLAN.edn exists with pending checkpoints | Ask: resume or start fresh? |
| PRD exists, no plan | Read PRD, propose checkpoints |
| No plan, no PRD | Create plan from prompt |
ALWAYS show the proposed checkpoints before creating:
I've analyzed the requirements and propose these checkpoints:
1. **Create password hashing module** (src/auth/password.clj)
- Acceptance: `(verify-password "test" (hash-password "test")) => true`
2. **Create JWT token module** (src/auth/jwt.clj)
- Acceptance: `(verify-token (create-token {:user-id 1})) => truthy`
Does this plan look right? I can adjust before starting the loop.
Wait for user approval before proceeding.
After approval, create the plan:
lisa_create_plan with:
title: "Build user authentication"
checkpoints: [
{description: "Create password hashing module",
file: "src/auth/password.clj",
acceptance: "(verify-password \"test\" (hash-password \"test\")) => true"},
...
]
Large plans (>10 checkpoints): Create the plan with the first few checkpoints, then use lisa_add_checkpoint to add the rest individually. This avoids payload size issues with lisa_create_plan.
Then start the orchestrator:
lisa_run_orchestrator with:
max_iterations: 20
This spawns fresh Claude instances for each iteration. The orchestrator:
claude -p <focused-prompt> for that checkpointThe orchestrator logs to .forj/logs/lisa/. When it completes:
Lisa Loop complete!
- Iterations: 8
- All checkpoints: DONE
- Logs: .forj/logs/lisa/
{:title "Build user authentication"
:status :in-progress
:checkpoints
[{:id :password-hashing
:description "Create password hashing module"
:file "src/auth/password.clj"
:acceptance "(verify-password \"test\" (hash-password \"test\")) => true"
:status :done
:completed "2026-01-16T10:30:00Z"}
{:id :jwt-tokens
:description "Create JWT token module"
:file "src/auth/jwt.clj"
:acceptance "(verify-token (create-token {:user-id 1})) => {:user-id 1}"
:status :in-progress
:started "2026-01-16T10:35:00Z"}
{:id :auth-middleware
:description "Create auth middleware"
:file "src/middleware/auth.clj"
:acceptance "Middleware extracts user from valid token"
:status :pending}]
:signs []
:created "2026-01-16T10:00:00Z"}
| Tool | Purpose |
|---|---|
lisa_create_plan | Create LISA_PLAN.edn with checkpoints |
lisa_get_plan | Read current plan status |
lisa_mark_checkpoint_done | Mark checkpoint complete |
lisa_run_orchestrator | Start the loop (spawns fresh instances) |
| Tool | Purpose |
|---|---|
lisa_append_sign | Record a failure/learning |
lisa_get_signs | Read signs from previous iterations |
lisa_clear_signs | Clear signs file |
| Tool | Purpose |
|---|---|
lisa_run_validation | Run validation checks (REPL, Chrome, Judge) |
lisa_check_gates | Check if gates pass before advancing |
| Tool | Purpose |
|---|---|
cancel_loop | Cancel active loop |
loop_status | Check loop iteration count |
Signs record failures that persist across iterations. When something goes wrong in iteration 3, future iterations can read it and avoid the same mistake. Signs are embedded directly in the LISA_PLAN.edn file.
{:title "Build user authentication"
:status :in-progress
:checkpoints [...]
:signs
[{:checkpoint :jwt-tokens
:iteration 3
:timestamp "2026-01-16T10:30:00Z"
:issue "Forgot to require clojure.string"
:fix "Always check requires when adding string functions"
:severity :error}]
:created "2026-01-16T10:00:00Z"}
The spawned Claude instances should append signs when:
Each iteration gets a fresh Claude context:
| Layer | Persists Across Iterations? |
|---|---|
| LISA_PLAN.edn | ✅ Yes - progress tracking & learnings |
| Git/Files | ✅ Yes - code changes |
| REPL state | ✅ Yes - loaded namespaces |
| Claude context | ❌ No - fresh each time |
This prevents context bloat and hallucination from stale memory.
Call:
cancel_loop
Or manually kill the orchestrator process.
> /lisa-loop "Build user authentication per PRD.md"
I found PRD.md. Let me analyze it for checkpoints...
I propose these checkpoints:
1. Create password hashing (src/auth/password.clj)
2. Create JWT tokens (src/auth/jwt.clj)
3. Create auth middleware (src/middleware/auth.clj)
4. Integration test
Does this look right?
> yes
Creating LISA_PLAN.edn and starting orchestrator...
[Lisa] Iteration 1: Checkpoint 1 - Create password hashing
[Lisa] Checkpoint 1 complete
[Lisa] Iteration 2: Checkpoint 2 - Create JWT tokens
[Lisa] Iteration 2 failed - adding sign
[Lisa] Iteration 3: Checkpoint 2 - Create JWT tokens (retry)
[Lisa] Checkpoint 2 complete
...
[Lisa] All checkpoints complete!
Lisa Loop finished in 6 iterations.