Skip to content

Canonical source: CONTRIBUTING.md This page is generated for the docs site from the repository root document.

Contributing to Shoal

Shoal is a personal-first project. Contributions are welcome, but the default scope is the maintainer's workflow: fish + tmux + pi.

Scope and Compatibility

  • Fish shell is the only actively supported shell integration right now.
  • Claude and Gemini are supported as secondary tool profiles.
  • Broad compatibility changes should be optional, isolated, and non-disruptive to default workflows.

Development Setup

We use uv for dependency management.

# Clone and install in editable mode for development
git clone https://github.com/TheShoal/shoal-cli.git
cd shoal-cli
uv sync --extra dev --extra mcp

Quick Start

After installing, set up the local development hooks:

# Install pre-commit hooks (or: just setup)
pre-commit install
pre-commit install --hook-type commit-msg

A justfile provides all common dev commands. Run just --list to see them:

Command What it does
just ci Run all CI checks (lint, typecheck, test, fish-check, security)
just lint Lint with ruff
just fmt Auto-format with ruff
just typecheck Type check with mypy
just test Run tests (exclude integration)
just test-all Run all tests including integration
just cov Run tests with coverage report
just fish-check Validate fish template syntax
just security Run Bandit security scan
just release X.Y.Z Bump version, commit, and tag
just setup Install pre-commit hooks

Standards

Code Style

We use ruff for linting and formatting:

just lint
just fmt

Type Checking

We use mypy for static type analysis:

just typecheck

Testing

All new features should include tests. Run the test suite with:

just test

Workflow

  1. Branch: Create a feature branch (or use shoal new -w my-feature -b).
    • New worktrees do not inherit the parent venv. Run uv sync --extra dev --extra mcp in the worktree before starting work, or apply the uv-dev session mixin which runs this automatically before the agent launches.
  2. Commit: Follow the Conventional Commits format:
    • feat: for new features
    • fix: for bug fixes
    • docs: for documentation changes
    • test: for test additions or corrections
    • refactor: for code restructuring
    • chore: for maintenance tasks
  3. PR: Open a PR to the main branch.
  4. Review: Ensure CI passes and wait for a review from a maintainer.

Commit Messages

We follow Conventional Commits for all commit messages. Commit messages are validated by gitlint via pre-commit hooks.

Format: <type>: <description>

Example:

feat: add session name validation at all entry points

- Validate session names in models and API endpoints
- Add CLI validation for new/fork/rename commands
- Include comprehensive test coverage

See COMMIT_GUIDELINES.md for full details and examples.

Branch Protection

The main branch is protected with the following rules:

  • All CI checks must pass before merging
  • At least one review is required for PRs from external contributors
  • Force pushes to main are blocked

Code Reviews

Run a standing code review pass periodically, especially after major milestones or before releases. Focus on observability, logging, security, workflow regressions, and documentation drift, and record the findings in the review artifact you are using for that cycle.

Release Process

Releases are automated via just release X.Y.Z, which bumps the version in pyproject.toml, commits, and creates a git tag. Pushing the tag triggers a GitHub Actions workflow that creates a GitHub Release with auto-generated notes.

For maintainers: see RELEASE_PROCESS.md for full versioning details.