Your backlog, delivered as fixed-price bounties.
Write a bounty or import it from Jira, price it, and slice a sandbox a contributor or coding agent can work in.
The work is accepted when tests it never saw pass, and comes back as a pull request.
How it flows • Run it • Develop it • Versions • Docs • lunox.work
A bounty is a proposal, which specifies and prices the work, and a sandbox, which contributors do it in; both work on their own. Jira and GitHub connections enrich them with issue tracking and repository context, and neither is required.
- Propose. Write the bounty, or import a Jira issue. It is sized and priced against a rubric before anyone starts.
- Slice. For a connected repository, carveout cuts the files the change needs into one folder that installs, builds and tests on its own; the rest of the codebase stays private.
- Work. A contributor opens the sandbox in the VS Code extension; a coding agent reaches it over the API's MCP tools. Either runs the public tests and submits a patch.
- Judge. The build writes and calibrates hidden tests from the spec with duediligence. A submission passes only when every test in both suites does.
- Merge back. Accepted work returns to the client's repository as a pull request, followed through its CI until it merges.
| Workspace | What it is |
|---|---|
packages/core |
Shared domain rules. The publishable package |
packages/shared |
Zod schemas for the wire format |
packages/client |
Typed API client, used by web and extension |
packages/jira |
Atlassian OAuth and the Jira REST client |
packages/github |
The GitHub App: tokens, REST client, webhooks |
packages/db |
Drizzle schema, migrations, Postgres and S3 store |
apps/api |
Hono HTTP API |
apps/worker |
Private repository analysis and sandbox builds |
apps/web |
Vite + React dashboard |
apps/extension |
VS Code extension |
tooling/tsconfig |
The shared TypeScript strictness contract |
Needs Docker and Make. Nothing else — not even Node.
git clone https://github.com/lunox-work/sandbox-factory.git
cd sandbox-factory
cp .env.example .env.development # then fill in the auth section, see below
make upOpen http://localhost:5173. The first make up installs dependencies inside
the containers, so give it a minute. make down stops it.
Sign-in is Google, GitHub and Atlassian only, and the API will not boot until
all three are configured. In .env.development, set a signing secret
(openssl rand -base64 32), then register a client with each provider and
paste in its id and secret:
| Provider | Where | Redirect URI |
|---|---|---|
| console.cloud.google.com → OAuth client ID → Web application | http://localhost:4000/api/auth/callback/google |
|
| GitHub | github.com/settings/developers → New OAuth App | http://localhost:4000/api/auth/callback/github |
| Atlassian | developer.atlassian.com → OAuth 2.0 integration | http://localhost:4000/api/auth/callback/atlassian |
The redirect URI must match exactly. A mismatch is rejected on the provider's
page, not in your logs. Atlassian needs a little more setup — see the notes in
.env.example.
Connecting a client's repositories is optional and needs a GitHub App of its
own, separate from the sign-in OAuth app above. Without its six GITHUB_APP_*
values everything else runs and the GitHub tab says it is not set up. How to
register one is in docs/github-apps.md.
Just looking around? npm run verify runs the whole test suite and needs none
of this.
make extThen open this repo in VS Code and press F5. A second window opens
with the extension loaded; its commands are under Lunox in the command
palette. For a local stack, set sandboxFactory.platformUrl to
http://localhost:5173 in that window's user settings.
The extension is a bundle the editor loads, so it runs on your machine rather
than in Docker and make ext needs Node 22.12+ within 22.x, or 24+. A
contributor signs in with a contributor token, opens a contribution (download
and unpack), runs its install, app and test commands in VS Code terminals in a
trusted workspace, and previews and submits the folder with the verdict in the
status bar. Show Version reports the extension's and the API's builds.
Needs Node.js 22.12+ within 22.x, or 24+. make dev runs the API and web app
directly on your machine — faster than the containers, and what you want day to
day. It still needs Postgres: make migrate starts it and applies the schema.
| Command | What it does |
|---|---|
make dev |
API on :4000, web on :5173, hot reload |
make ext |
Rebuild the extension on save |
make ext-package |
Produce a .vsix |
make verify |
Everything CI runs — the gate before pushing |
make test |
Test every workspace with coverage thresholds |
make build |
Build every workspace, in dependency order |
make lint |
Type-check every workspace |
make format |
Apply formatting |
make up / down |
Dev containers — source mounted, hot reload intact |
make up-prod |
Built images behind nginx on :8080 |
make build-images |
Build the production images without starting them |
make logs / ps |
Follow logs, show status |
make db-up |
Start Postgres and SeaweedFS, wait for both |
make migrate |
Apply the schema |
make psql |
Open a psql shell against the local database |
make reset |
Stop everything and delete the data volumes |
Run make on its own for the full list. Every target delegates to an npm
script or to docker compose, so make test and npm test cannot drift apart.
Scope a check to one workspace:
npx turbo run lint test --filter=@sandbox-factory/apiNotes:
make up-prodserves one origin through nginx with/apiproxied, matching the dev server, so cookie and CORS behaviour does not differ between the two.- Ports are overridable:
API_PORT,WEB_PORT,WEB_PROD_PORT,POSTGRES_PORT. - SeaweedFS' S3 gateway is on :8333 and its filer browser on :8888.
Credentials in
docker-compose.ymlare development values only. - The extension host reloads on every rebuild
(
debug.extensionHost.autoReloadin.vscode/settings.json), so its in-memory state is lost and the tree refetches. - The test suite needs no services:
npm run verifypasses with Docker stopped.
Dependency-free, and runs in a browser, in Node, or inside an editor extension.
It is not on npm yet. Consume it through the workspace, or from the tarball attached to a release. The import below is what publishing would enable:
import { checkHandle, normalizeHandle, toHandleStem } from "sandbox-factory";
normalizeHandle(" Acme-Corp "); // { status: "ok", handle: "acme-corp" }
normalizeHandle("no spaces!"); // { status: "invalid", reason: "…" }
toHandleStem("dana@example.test"); // "dana"
checkHandle("ok-name"); // { status: "ok", handle: "ok-name" }Users and organizations draw handles from one namespace, so what counts as a valid handle is decided here and nowhere else.
Every surface reports <version>+<short sha>, e.g. 1.4.2+7f3a9c1: the web
app in its footer, the API at GET /version, the extension through its Show
Version command.
That string identifies a build but proves nothing — the running code only repeats what the build stamped into it. What proves something is the signature: every deployment attests the image it runs and every file it publishes, so anyone can check that the live site serves code built from this repository, without trusting us:
./scripts/verify-production.shSee docs/versioning.md for how this is wired, what it deliberately does not prove, and why the commit sha rather than the version is the real identifier.
Start with the documentation index to find the smallest relevant reading set for your task.
| Document | Covers |
|---|---|
| CONTRIBUTING.md | Dev setup and pull request process |
| AGENTS.md | Rules for coding agents |
| docs/architecture.md | Dependencies, auth, bounties, pricing, analysis |
| docs/ci.md | Workflows, branch protection, releases |
| docs/versioning.md | Build provenance, and verifying a release |
| docs/github-apps.md | Installed apps and settings that live outside files |
| scripts/README.md | ship.sh and rotate-token.sh |
| infra/README.md | The AWS deployment |
| apps/worker/README.md | Analysis tools, artifacts, evaluation limits |
See CONTRIBUTING.md; by participating you agree to the Code of Conduct. Report vulnerabilities privately — see SECURITY.md — never in a public issue.
MIT © feversoul