Skip to content

Contributing

Development setup for contributing to Shoji.


Prerequisites

ToolPurpose
miseTool and task manager
Lua 5.4+Runtime (tests require standalone Lua)
LuaRocksLua package manager

Installation

Install mise (if not already installed):

Terminal window
brew install mise

Install Lua and LuaRocks:

Terminal window
brew install lua luarocks

Install project tools and dependencies:

Terminal window
cd Shoji.spoon
mise trust
mise install

This installs Node.js, StyLua, and lua-language-server via mise, then automatically installs the LuaRocks packages (busted, luacheck, luacov) via a post-install hook.

Verification

Terminal window
mise run check

Tasks

Run mise tasks to see all available tasks:

Terminal window
mise run check # Run all checks (format, types, lint, test)
mise run test # Run all tests
mise run test:unit # Run unit tests only
mise run test:integration # Run integration tests only
mise run test:coverage # Run tests with coverage
mise run lint # Run linter
mise run format # Format code
mise run check:format # Check formatting
mise run check:types # Run type checker

Documentation

Terminal window
mise run docs:dev # Start dev server
mise run docs:build # Build for production
mise run docs:preview # Preview production build

Code style

Shoji uses StyLua for formatting and enforces an 80-character line limit. All functions, variables, and modules require EmmyLua type annotations — code that does not type-check cannot be merged. Declare all variables with local (Lua defaults to global scope).

The project’s CLAUDE.md in the repository root contains the full code style guide, including naming conventions, type annotation patterns, and anti-patterns to avoid.

Testing

Tests use busted and follow a TDD workflow (red → green → refactor). Tests should focus on behavior, not implementation details, and include edge cases and boundary conditions.

Terminal window
mise run test # All tests
mise run test:unit # Unit tests only
mise run test:integration # Integration tests only
mise run test:coverage # Tests with coverage report

See TESTING.md in the repository root for the full testing guide, including mock API reference and testing patterns.

Commit conventions

Commit messages use conventional commits format:

type(scope): subject
  • Subject line: 50 characters max, imperative mood
  • Body: Wrap at 72 characters. Explain why the change was needed, how it addresses the problem, and any side effects.
  • Types: feat, fix, refactor, test, docs, style, perf, chore
  • Scopes: Use kebab-case (e.g., focus-history)

Examples:

  • feat(combinators): add IfMax combinator
  • fix(tiling): prevent negative window dimensions
  • docs(readme): update installation instructions

Submitting changes

  1. Fork the repository
  2. Create a feature branch with a descriptive prefix (feature/, fix/, docs/) — for example, feature/add-monocle-layout or fix/focus-cycle-wrap
  3. Make changes and ensure mise run check passes — this runs formatting, type checking, linting, and tests
  4. Commit with a message following the conventions above
  5. Push and open a pull request

For bug reports and feature requests, open an issue on GitHub.