Spawn one container, return exit code and files.
The execution primitive. Domain-agnostic, zero orchestration. light-run calls down to this for every job.
A thin HTTP server around light-runner. POST inline files, an image and an entrypoint; it runs them in a container and serves back the exit code, logs and any artifacts you asked for. No GitHub fetch, no workflow, no orchestration.
POST /run takes files + image + entrypoint.Send inline files, a Docker image and a command. light-run writes them to a tmpdir, runs them in a container via light-runner, and returns a RunState: id, status, exit code, duration, artifacts.
List container paths in extract; their bytes land in an internal artifact dir, served over GET /runs/:id/artifacts/* with a path-traversal guard. Auto-evicted past a size cap.
Run detached and poll GET /runs/:id, or drive the lifecycle with POST /runs/:id/stop|pause|resume|cancel. Run state is persisted by light-runner, the source of truth.
A remote orchestrator can provision isolated networks (POST /networks), attach runs to them, and sweep orphans (POST /networks/cleanup) - all without shell access to the host.
POST, and your container runs.Start the server (light-run serve), then POST a job. Inline your files, name an image, give a command, list what to extract.
Stateless past the artifact directory. No caching, ever.
npm install -g @enixcode/light-runconst res = await fetch('http://localhost:3000/run', { method: 'POST', headers: { 'content-type': 'application/json', authorization: 'Bearer ...' }, body: JSON.stringify({ image: 'python:3.12-alpine', entrypoint: 'python main.py', files: { 'main.py': 'open("out.json","w").write(...)' }, extract: ['out.json'], }), }); const run = await res.json(); run.status // succeeded | failed | running | cancelled run.exitCode // the container exit code run.artifacts // [{ path, bytes, type }] - fetch via /runs/:id/artifacts
/health requires Authorization: Bearer. No token = open server with a startup warning...and assert the resolved path stays inside the run's artifact directory. A container cannot serve files it never wrote.413 before it can grow the heap.os.tmpdir() and are removed the moment the container exits, success or failure. Files are Zod-validated: no absolute paths, no .. segments.light-process has. This layer stays stateless past the artifact directory.The execution primitive. Domain-agnostic, zero orchestration. light-run calls down to this for every job.
Point a POST endpoint at it, pipe bodies through, fetch artifacts back. Stateless wrapper, same defaults, same guarantees.
When one container is not enough. Composes runs into pipelines with backoff, concurrency limits, and structured outputs. Talks to light-run over HTTP.