LocalCI for coding agents
LocalCI runs a project's existing checks
on the machine that is doing the work and reports the verdict against
the commit those checks ran on. This is the authoritative procedure for
“Set up LocalCI in example_proj/ per https://gittrove.com/packages/localci”.
Read the target project's instructions and record its starting
git status --porcelain before changing files.
Default completion contract
Unless the user requests more, setup means:
- Make LocalCI available in an isolated tool environment outside
project dependencies and record
localci --version. - Preserve existing TOML and LocalCI settings, configuring the project's full existing check command for checkout execution.
- Run those checks once through
localci --no-githuband verify failure propagation with a harmless command override. - Leave a short instruction in
AGENTS.mdorCONTRIBUTING.md, preferring the existing file and creatingAGENTS.mdif neither exists. Report the project root, installed version, selected command, verification results, changed files, and remaining prerequisites.
GitHub reporting and committed execution profiles are opt-in. Preserve existing reporting settings, but disable reporting during setup verification. Follow the target repository's policy and user authorization for committing and pushing; setup itself does not authorize either.
Installation policy
Check localci --version first. If it is missing, check
for an existing isolated installation outside PATH before reinstalling.
uv tool dir --bin locates tool executables; the
installation guide explains shell recovery.
An adoption request authorizes installation using an existing
credential the user has authorized you to retrieve from their secret
manager. Follow the installation
guide: Python 3.13, the private index, and isolated
uv tool install. Apply the user's release-selection policy
and pin an eligible version when required. LocalCI has no runtime
dependencies. Keep the key in the installer's environment with shell
tracing disabled, never in arguments, output, history, or files. Do not
search unrelated secret stores or create keys without authorization.
If the credential or retrieval permission is missing, ask for that specific prerequisite. If no subscription exists, explain that purchasing and authorizing payment require the user. Report denied download access without substituting a public package. Preserve useful configuration work, but mark installation and verification incomplete until the tool works. Never add installer configuration or a private index URL to the target project.
1. Find the command the project already runs
LocalCI does not install dependencies, prepare an environment, or invent checks. It runs the command the project already has, from the repository root. Look for a recipe that runs everything and exits nonzero when any part fails:
| Where | What to look for |
|---|---|
justfile |
just check, or whatever recipe CI calls |
Makefile |
check, test, or ci |
package.json |
the scripts entry CI calls |
tox.ini, noxfile.py |
the default environment or the session list |
.github/workflows/* |
the step that gates a pull request |
Prefer repository instructions and the aggregate command used by CI. Preserve all required lint, type checks, tests, and builds. Use an existing task or a small project-owned wrapper when CI has several steps. Ask when competing commands leave coverage unclear. The agent may prepare the project's documented environment using its existing lockfile; LocalCI itself installs no dependencies. Run checks during verification without a duplicate manual run.
2. Write the configuration
Add a [tool.localci] table to the root
pyproject.toml, creating the file with only this table when
the project has none. This works for non-Python projects too.
[tool.localci]
command = ["just", "check"]- Every element is one argument. There is no shell, so
&&,|, globs, and$VARIABLEare not expanded. Compose several checks in the project's own task runner and point LocalCI at that. - An unknown option name is a configuration error, so a typo cannot quietly select the defaults.
repository = "owner/name"is needed only whenorigincannot supply it.timeout_seconds = 900stops a check that hangs instead of holding the terminal.- Leave
githubunset (false) for a new adoption unless reporting is requested. Preserve an existing reporting choice. github = trueposts the verdict to GitHub, andgithub_pending = trueposts a pending status before the checks start. Reporting needs a token and a clean tree; the GitHub setup guide covers both.
3. Verify the adoption
Verify locally while configuration and documentation edits are uncommitted. These commands do not need reporting credentials.
Run
localci --no-githubonce from the target root and record the verdict and exit code. Checkout execution is the default, including on a dirty tree. A passing run exits 0.Verify failure propagation without changing configuration:
localci --no-github --command python --command=-c --command='raise SystemExit(7)'Expect exit 1 and
failed (exit 7). Substitute an available Python executable when necessary. The override affects only this invocation.Compare
git status --porcelainwith the starting state. Preserve unrelated edits and report intentional adoption changes. Investigate files written by checks; use check modes or ignore disposable artifacts as appropriate.
--dry-run executes checks; it is not a preflight and
needs no separate run. Ordinary adoption does not require repeating the
suite from a subdirectory. If checks fail, report configuration complete
and verification failed, with the command, exit code, and useful error
evidence. Distinguish missing project tools or environment from failing
checks. Repair routine setup per project instructions, but do not expand
adoption into unrequested project repairs or claim success without
passing verification.
The exit codes are 0 passed, 1 checks
failed or timed out, 2 the checkout is misconfigured,
3 nothing was published, and 130 interrupted.
A check outcome wins over a reporting problem, so a failing run exits 1
even when its status could not be posted.
4. Leave a note for the next agent
Add a section like this to the project's AGENTS.md or
CONTRIBUTING.md, with the command changed to the one you
configured.
## Checks
This project runs its checks with LocalCI. The command lives in `[tool.localci]`
in `pyproject.toml`.
localci --no-github # run configured checks locally
The configured command is `just check`. LocalCI uses the project's environment
and PATH. GitHub reporting is optional; enable it only when requested, following
the GitHub setup guide.
Exit codes: 0 passed, 1 failed or timed out, 2 misconfigured, 3 not published,
130 interrupted. Reporting to GitHub needs a clean tree, untracked files
included, so use --no-github while work is in progress. Do not add LocalCI to
`[project].dependencies`, and never commit a GitTrove key.What not to do
- Do not add LocalCI to
[project].dependenciesor to a dependency group. It is a tool a developer runs, not a library the project imports. - Do not commit a license key, an index URL, or installer
configuration such as
UV_DEFAULT_INDEXorPIP_INDEX_URL. - Do not make running the checks require a GitTrove credential. Only installing the tool, and reporting to GitHub, need one.
- Do not put secrets in
commandarguments. Those arguments appear in the description of the status LocalCI posts. - Do not let LocalCI manage the project environment. It resolves and installs nothing, so a missing project tool is the project's own problem to fix.
- Do not remove hosted CI. A LocalCI status is a developer's report from their own machine, not independent validation.
Upgrading a project that already uses LocalCI
- 0.5.0: nothing is required.
timeout_secondsandgithub_pendingare new and both default to off. Add the first where a check can hang, and the second where a reviewer should see a run start. - 0.4.0: GitTrove run recording was removed. A
urloption in[tool.localci]is now an error, and--recordand--no-recorddo not exist. Take the verdict from the exit code and the GitHub status.
If a project sets github = true, the commit status is
named by github_context, which defaults to
LocalCI. That name is what a branch protection rule lists
as a required check.