How to Contribute to Lucifer: Your First Pull Request

Cover Image for How to Contribute to Lucifer: Your First Pull Request
AI & Machine Learning5 min read

Building Lucifer: an open-source AI company you can watch · ⭐ GitHub

🚀 Start here: 1. Meet Lucifer · 2. Why I built it · 3. Architecture

📖 Use it: 4. Getting started · 5. Connect an LLM · 6. Office tour

🛠 Build the engine: 7. Org chart in YAML · 8. Real delegation · 9. Sandboxed tools · 10. Simulation brain

🎨 Build the office: 11. 3D office with R3F · 12. WebSocket + zustand · 13. Visualizing workflow

🧭 What's next: 14. Roadmap · 15. Contributing

Lucifer is MIT-licensed and built in the open, and every item on the roadmap is open to contributors. This post gets you from a fresh clone to a merged pull request. It covers the setup, four good first contributions with step-by-step instructions, and the rules that keep the project healthy.

Setup

git clone https://github.com/<you>/lucifer.git     # your fork
cd lucifer
cd lucifer-engine && uv sync && cd ..              # uv installs Python 3.13
cd lucifer-office && pnpm install && cd ..

Run the engine without an API key. The simulation brain lets you develop the whole UI and engine flow without spending a token:

cd lucifer-engine && uv run lucifer-engine serve    # terminal 1
cd lucifer-office && pnpm dev                       # terminal 2

The checks to run before a PR

cd lucifer-engine && uv run pytest                  # engine tests, no API key needed
cd lucifer-office && pnpm test && pnpm build        # office tests + type check + production build

Both should pass before you open a pull request.

Four good first contributions

1. Add a UI language

The office speaks English and Vietnamese. Adding a language takes three steps.

a. Register it in lucifer-office/src/langs.ts:

export const LANGS = [
  { id: "en", name: "English", flag: "🇬🇧" },
  { id: "vi", name: "Tiếng Việt", flag: "🇻🇳" },
  { id: "ja", name: "日本語", flag: "🇯🇵" },
] as const;

It then shows up in the 🌐 menu, and browsers set to Japanese pick it automatically on the first visit.

b. Add a dictionary in lucifer-office/src/i18n.ts and register it in MESSAGES:

export const MESSAGES: Record<Lang, Messages> = { en, vi, ja };

The Messages type is derived from the English dictionary, so TypeScript reports every missing key. You can't ship a half-translated UI by accident.

c. Optionally, translate the company, departments and employees under i18n.ja in the org chart YAML.

Agents need no change, because they reply in the language of the task. If the engine should detect your language explicitly, add a pattern to lucifer-engine/src/lucifer_engine/language.py with a test in tests/test_language.py.

2. Share a company template

Org charts are just YAML, so a new template is a great first PR: an agency, a game studio, a law firm, a newsroom. Put it in lucifer-engine/companies/, then check it:

LUCIFER_COMPANY=companies/newsroom.yaml LUCIFER_BRAIN=sim uv run lucifer-engine serve

The loader validates the file at startup (exactly one head, known departments, valid reportsTo), and the office lays it out automatically. Design your own AI company in YAML covers the format and how to write personas that delegate well. Attach a screenshot of your company on the yacht to the PR.

3. Add an agent tool

Tools are where agents get new abilities. The pattern is always the same:

  1. Add the action to TaskSession (session.py). Validate inputs, call _assert_open() before any write, and log an activity.
  2. Wrap it as a _SessionTool in brains/crew.py, with an args_schema and a description written for the model.
  3. Register it in build_tools.
  4. Test the session method directly, and add it to brains/sim.py if the office should show it without tokens.

Sandboxed agent tools walks through a complete example. Tools that reach outside the workspace, such as the web, a shell or an MCP server, are bigger changes. Open an issue first so we can agree on the boundary.

4. Add something to the world

Want palm trees that sway more, a new beach prop or a better sailboat? The scene is all code in lucifer-office/src/scene/, with no model files. A few tips:

  • Animate in useFrame by mutating objects. Don't put per-frame values in React state.
  • Merge static geometry where you can, so it costs fewer draw calls.
  • Use http://localhost:5173/?lineup for a close-up preview of the characters.
  • Attach a screenshot or GIF to every visual PR.

Bigger visual work, like a whole new world, will go through the planned theme API. Open an issue if you want to help design it.

The rules that keep Lucifer healthy

These come from CONTRIBUTING.md:

  • One change per PR, and explain the why in the description.
  • Follow the surrounding style. The engine uses type hints throughout, and the office uses strict TypeScript.
  • English for code: comments, docstrings, log messages and test names. Other languages belong only in translations (i18n.ts, i18n in org charts) and in test data that exercises them.
  • Protocol changes go on both sides. Update protocol.py and protocol.ts, and check them against uv run lucifer-engine schema.
  • Tests never call a real LLM. Mock at the HTTP layer, like tests/test_crew.py. CI should never need an API key.
  • Never commit .env, data/ or workspace/. They hold secrets and agent output.

Opening a good pull request

A PR that's easy to review has:

  1. A title that says what changes, for example feat(office): Japanese UI.
  2. The reason in the description: the problem, and why this is the right fix.
  3. How you tested it: the commands you ran, and the screenshot or GIF for anything visual.
  4. A small diff. If it grew, split it.

Reporting issues

Include what you did, what you expected and what happened. For engine problems, attach the engine log with API keys removed. Issues go to github.com/siri2moon/lucifer/issues.

Thank you

Lucifer is a story about getting back up and doing honest work, and it's a better project with more hands on deck. Whether you translate the UI, share a company, add a tool or just ⭐ star the repo, welcome aboard.


Lucifer is open source under the MIT license. Clone it, run it for free with the simulation brain, and ⭐ star it if you'd like to follow along: github.com/siri2moon/lucifer.