> For the complete documentation index, see [llms.txt](https://fleet.hackmap.win/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fleet.hackmap.win/meta/contributing.md).

# Contributing

## Comment style — enforced

The repo enforces a strict comment style (no module docstrings, no multi-line comment paragraphs, no banner lines, function/method docstrings one short line max). Two scripts live in `scripts/`:

```bash
python scripts/check_comment_style.py        # exits 1 on violations
python scripts/strip_comments.py --write     # auto-fix
```

A shared pre-commit hook at `.githooks/pre-commit` runs the check on every commit. Wire it up after cloning:

```bash
git config core.hooksPath .githooks
```

The repo is open source, MIT-licensed, but pre-alpha. Contributions are welcome with a few caveats:

The public API is still moving. A pull request that adds a new feature is much more likely to be accepted if it doesn't lock the framework into a design decision before the design is settled. New examples and documentation are always welcome.

Tests run with `pytest tests/` (the suite is at the repo root; CI runs it against memory, redis, and sqlite backends).

## Setup

```bash
git clone https://github.com/sarperavci/fleet
cd fleet
python3 -m venv .venv && source .venv/bin/activate
pip install -e '.[browser,test]'
pip install -e examples/hello-world
pip install -e examples/echo-consumer
```

Run the smoke test to confirm everything works:

```bash
# in one terminal
redis-server --port 6379 --appendonly no --save ""

# in another
FLEET_ADMIN_TOKEN=t FLEET_WORKER_TOKEN=t fleet master --port 8000

# in another
MASTER_URL=http://localhost:8000 FLEET_WORKER_TOKEN=t fleet worker --type hello-world --id smoke

# in another, enable it
curl -X PATCH http://localhost:8000/api/v1/automations/hello-world/workers/smoke/config \
  -H "Authorization: Bearer t" -H "Content-Type: application/json" \
  -d '{"enabled": true, "slots": 1}'

# check the stream
curl -X POST http://localhost:8000/api/v1/automations/hello-world/output/pop \
  -H "Authorization: Bearer t" -H "Content-Type: application/json" \
  -d '{"n": 3}'
```

If you get three entries, the install works.

## Code style

The codebase is informal. The conventions that matter:

No `"""docstring"""` blocks. Comments are short, lowercase, and explain why something is the way it is, not what the code does. If the code needs a paragraph to explain itself, that's a sign the code is wrong.

No `# TODO: ...` for things you're not actually going to do. Either fix it or open an issue.

Lines up to \~100 characters. `ruff format` is fine if you want consistency, but it's not enforced.

Imports sorted (`ruff check --select I --fix`).

`from __future__ import annotations` at the top of any module that uses 3.10+ union syntax. This is a deliberate choice — it lets the framework run on 3.11 while still using `X | Y` typing.

## Patterns

Async everywhere. The master and worker are both `asyncio`-based. Blocking I/O goes through `loop.run_in_executor(None, ...)`. The browser code is async-first (Playwright via cloakbrowser); only the SmartRouter subprocess (mitmdump) and pyvirtualdisplay shell out to sync child processes.

Generic Pydantic models for configs. `BaseConfig` is parameterized via `ContinuousAutomation[MyConfig]` so the type system can follow.

No singletons except the automation registry. Tests should be able to create a `Store(url)`, a `Broadcaster()`, a worker `Agent(...)` and not have them collide.

No global state in the worker except for the registry. Each `Agent` instance owns its own state — you should be able to run two in the same process if you wanted.

## Adding an automation type

If you're contributing a new example, put it in `examples/<name>/` with the same shape as `examples/hello-world/`:

```
examples/my-automation/
  pyproject.toml
  README.md
  my_automation/
    __init__.py
```

The `pyproject.toml` should declare `dependencies = ["fleet-framework"]` and an entry-point. The base dependency already carries the browser pool and anti-bot helpers, so a plugin that drives a browser needs nothing extra.

## Adding a feature to fleet core

Open an issue first. The core (`src/fleet/`) is small on purpose; new features there raise the bar for everything else. Most "new feature" requests are better solved as a plugin.

Things that are unambiguously in-scope for the core:

Reconcile bug fixes.

Protocol additions that are needed across multiple plugins.

Dashboard improvements.

Performance work on the master.

Better tests.

Things that are out of scope:

Specific automation types (those are plugins).

External integrations (Kafka, Postgres, k8s operator) — separate repos.

Multi-language client SDKs — separate repos.

## Pull requests

Keep them small. One feature or one fix per PR. If you're touching documentation alongside code, that's fine — it counts as one change.

Branch off `main`. The `docs` branch is documentation-only and exists for the GitBook integration; don't open code PRs against it.

Tests where applicable. The test framework is `pytest` with `pytest-asyncio` in auto mode. Aim for at least one test per non-trivial new function. The bar isn't 100% coverage; the bar is "the test exists and would fail if the code regressed".


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://fleet.hackmap.win/meta/contributing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
