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.

Install on Windows · PowerShell
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

girl
 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.

Terminal
# 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.

Terminal
> girl serve
127.0.0.1:3849
# rate-limit-login streaming
D

you from your phone · 14:02

Also lock the account after 20 failed attempts in an hour.

M

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

Message #rate-limit-login

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.

~\.girl\tools\build_project.lua
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

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.

Girl's build step
> 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

Terminal
> lxe init
> lxe run premain.lua
> lxe install network
> lxe compile . -o game.exe -b gui,audio
main.lua
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.

42 modules and counting

Girl's terminal UI is a module too: tui gives your own apps tabs, markdown, diff cards and a command palette, licensed per seat.

Browse modules