A coding agent, built with LuaXE
Girl, the coding agent you script in Lua.
Girl plans, implements and reviews changes in your repository from a fast terminal UI. Its config, hooks, commands and tools are all Lua, and all of it ships as one file that LuaXE runs.
PS> irm https://luaxe.dev/install.ps1 | iex Installs girl and lxe to ~\.girl\bin and adds it to your PATH · read the script
v0.18.0 · Windows x64 · free for non-commercial use · girl.lef 12.29 MB · md5 d1e0bec0d589ff9902a42b0d140dd9f3
rate limit login api docs + ❯︎ Rate limit failed logins on /login ●︎ I'll check how the routes are wired, then wrap the login handler. ✓︎ read_file src/routes/login.lua 0.20s ✓︎ search src 0.20s ╭─ ✎︎ Edit ·︎ src/routes/login.lua ──────────────────────────────────────────────╮ │ 8│local users = require("users") │ │ +9│local attempts = require("limiter").new(5, 60) -- 5 tries a minute │ │ -│router.post("/login", login) │ │ +10│router.post("/login", attempts:guard(login)) │ │ │router.post("/logout", logout) │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ ⠙ cmd ·︎ lxe run tests/run.lua ──────────────────────────────────────────────╮ │ routes/login ok rejects a wrong password │ │ routes/login ok locks out after 5 attempts │ │ routes/login ok resets the counter after a minute │ │ routes/signup ok hashes new passwords │ │ lib/limiter ok shares a window across workers │ │ lib/limiter .. │ ╰──────────────────────────────────────────────────────────────────────────────╯ │ Rate limit │ │ [x] Map the login routes │ │ [x] Wrap the login handler │ │ […︎] Run the tests │ ╭ input ───────────────────────────────────────────────────────────────────────╮ │> │ ╰──────────────────────────────────────────────────────────────────────────────╯ implement •︎ gpt-5.5 •︎ (medium) ↑︎ 18.2k ·︎ 2.3k ↓︎ $0.042 ⠋ running D:\projects\shop ⎇︎ main ~1 ◇︎ ask •︎ session rate-limit-login
Quick start
From a chat to a reviewed change.
Point Girl at a model with your API key or an existing Codex or Claude login, then work interactively, or script it in CI with machine-readable output.
# one terminal, a tab per task, all of them working at once
> girl chat
# implement with an independent review gate after every milestone
> girl exec --guard --yes "Split billing.lua into invoices and payments"
# keep going while earlier milestones are reviewed in the background
> girl exec --race --yes "Move the tests to the new runner"
# a read-only reviewer for CI, JSON in and out
> git diff origin/main | girl -p --read-only --format json "Find bugs in this diff"
# every running session, in your browser
> girl serve Why Girl
The things other agents leave out.
Reviews that keep pace
--ship adds an independent review at the end, --guard gates every milestone, and --race reviews finished milestones in the background while work continues.
It writes its own tools
Girl can author a Lua tool, save it for the project or for good, and call it from then on. No plugin API to learn, no restart.
Scripts itself in Lua
run_lua exposes every tool as a Lua function, so one script can sweep 200 files instead of 200 model turns. Each call still passes your permission rules.
A second opinion on permissions
In auto mode the ask-level decisions go to a model you pick instead of interrupting you. Deny rules stay absolute.
Steer it mid-flight
Type while it works: your message waits for the next safe boundary instead of cancelling the turn. Subagents take steering the same way.
Every session in a tab
Open workspaces side by side, each with its own sessions. Background tabs keep working, and flag you when they need an answer.
Comments become tasks
With file watching on, an AI! comment in your editor starts the change it describes, and AI? asks a question about the code around it.
Undo and branch anything
Every turn is checkpointed for /undo, /git-undo reverts auto-commits without rewriting history, and Esc Esc branches the conversation.
Know what it costs
girl stats turns your local session journals into a dashboard: cost, cache hits, latency and errors per model and project.
girl serve
All your agents, in one browser tab.
girl serve mirrors every running Girl on your machine into a chat app. Nothing to deploy, it's built into the same exe.
> girl serve you from your phone · 14:02
Also lock the account after 20 failed attempts in an hour.
Mira 14:02
On it. I'll add a second limiter window and a lockout flag on the user record.
✓ read_file src/models/user.lua
✓ spawn_subagent Nova · map every login entry point
○ edit_file src/routes/login.lua
implement · gpt-5.5 · ↑ 24.1k · 3.0k ↓ · $0.058
Every session, one tab
Each folder is a server, each running girl chat a channel. Switch between them without hunting for terminal windows.
Talk to it from anywhere
Send messages and slash commands, answer permission prompts, and follow tool calls as they stream, on a laptop or a phone.
See the whole team
The member list shows the session and every subagent it spawned, with what each one is doing right now.
Start work remotely
Open any folder as a new girl chat from the browser, it spawns and registers itself.
It listens on 127.0.0.1 without authentication. To reach it from another device, put it behind a firewall or an authenticating proxy, see the docs.
Community tools
Teach Girl new tricks in a few lines of Lua.
A tool is one Lua file that registers functions the model can call. Drop it into ~\.girl\tools, or ask Girl to write and save one for you. Install one from luaxe.dev with girl install <name>, and share yours here too.
return function(registry)
registry:register {
name = "build_project",
description = "Run this project's build",
permission = "lua.execute",
run = function(args, context)
return "built " .. context.workspace
end,
}
end idalib_mcp_launcher
VerifiedAutomates launching the idalib mcp (uv run idalib-mcp)
browser_shot
VerifiedAutomates browser screenshots
How Girl is built
46,000 lines of Lua. One 12.29 MB .lef.
Girl is plain Lua compiled by LuaXE. Model requests, tools and subagents run on LuaXE's native threads so the interface never blocks, HTTPS streaming and the local dashboards use its network module, and Win32 calls go straight through the LuaJIT FFI. No Node, no Python, no runtime to install.
> lxe compile src -m main.lua -o bin\girl.lef -s -b win32 LuaXE
Compile Lua into .exe with LuaXE.
Write games, tools and apps in LuaJIT, pull in native modules from the registry and ship a single executable. Because Lua is awesome.
Windows: irm https://luaxe.dev/install.ps1 | iex
Linux x86_64: curl -fsSL https://luaxe.dev/install | sh · lxe.exe 1.25 MB · md5 692c1211bd65adc98dd95c32d41fefaf
> lxe init
> lxe run premain.lua
> lxe install network
> lxe compile . -o game.exe -b gui,audio local network = import "network"
local add = `(a, b) => a + b`
local total = 0
for i = 1, 10 do
if i % 2 == 0 then continue end
total += add(i, 1)
end One exe, no runtime
lxe compile bundles your scripts and the modules they import into a single Windows executable.
LuaJIT with batteries
LuaJIT and its FFI, plus native modules for networking, threads, the filesystem, crypto and more.
Real threads
Isolated Lua states on native threads, with buffers, locks and cancellation, for work that must not block.
A module registry
lxe install pulls modules and their dependencies from luaxe.dev, import loads them.