Skip to content

Get started

Repo Maintainer runs a coding agent against committed repository source, checks its proposed changes, and saves a patch for review. Start with one local task. Add a schedule or PR publishing only after that task and its checks work.

Prefer to have your coding agent do the setup? Copy the local setup prompt. It discovers your project's tools and writes the configuration without starting a paid run.

Choose how to run

Your goal Start here Where work runs Result
Try one task Native executable Your Mac or Linux machine Patch and report
Supply a project runtime in a container Local Docker Your Docker host Patch and report
Run from Python, TypeScript or Rust SDK examples · Script prompt The machine running your script Structured result and artifacts
Open reviewable PRs on demand or on a schedule GitHub Actions GitHub-hosted Linux or your runner PR, unchanged assessment or blocker report
Use the website Hosted preview Cloudflare when execution is enabled Currently a demo; real hosted runs are not enabled

The GitHub Actions workflow is usable independently of the hosted website. A ChatGPT subscription does not supply an OpenAI API key. The self-hosted Codex runner uses the Codex account configured on its worker or CODEX_API_KEY; the website preview's planned first version uses a user-supplied API key.

Native executable

You need Git, Rust 1.89+ to build the engine, your selected coding agent, and the runtime/tools used by your project's checks. Docker is not required for this path. Install the engine from a terminal:

cargo install --git https://github.com/djsydney04/repo_maintainer --locked
repo-maintainer --version

The second command should print the installed version. If the command is missing, check that Cargo's binary directory is on your PATH. When you need a reproducible installation, add --rev FULL_COMMIT_SHA to cargo install, replacing the placeholder with the revision you reviewed.

For development from an existing Repo Maintainer checkout, use cargo install --locked --path . there instead.

Your first task

1. Initialize in the repository you want to maintain

Replace the path below with your project, not the Repo Maintainer source checkout:

cd /path/to/your-repository
git status --short
repo-maintainer init

init creates .maintainer.yml if needed and preserves an existing one. Add .maintainer-output/ to this project's .gitignore. Do not discard existing changes: later runs inspect committed HEAD, so decide which source changes should be committed before asking the agent to work on them.

2. Configure one task and the checks that prove it works

Edit .maintainer.yml. Set a focused instruction, narrow editable paths and commands that actually exist in your project. The generated whitespace check alone does not prove application behavior. Use a language example or the setup prompt to adapt the configuration.

For example, this validation section fits a Node project only if it uses an npm lockfile and defines test and lint scripts. Replace those commands for pnpm, yarn, Python, Rust or another runtime:

validation:
  profile: custom
  setup:
    - name: dependencies
      command: [npm, ci]
      timeout_seconds: 600
  checks:
    - name: tests
      command: [npm, test]
    - name: lint
      command: [npm, run, lint]

Checks are argument arrays, not shell command strings. Write a trusted script when you need shell pipelines or several dependent operations.

New configurations select Codex. Install and authenticate the Codex CLI on the same machine, or provide CODEX_API_KEY in its environment. Set agent.allow_paid: true to permit use of that account. This is an opt-in, not a dollar spending cap. For other agents/providers, use the configuration reference. Never put credential values in .maintainer.yml, task text or Git. The native command inherits your shell environment; it does not automatically load .env.

3. Check setup before making a model request

repo-maintainer check
repo-maintainer validate
Command What it checks Calls the agent?
check Configuration and supported settings No
validate Configured setup and project checks in the target directory No
run Agent proposal, followed by independent checks for a changed patch Yes

validate executes project commands and may install dependencies. A passing configuration check is not evidence that the project builds. If the baseline fails, record the failure and fix setup first—or make repairing that known failure the explicit task. See diagnosis by stage.

4. Write the task and run it once

Create task.md in the target repository. Replace this example with one result your checks can verify:

When a search succeeds with no matches, render the existing empty-state component
instead of a blank list. Preserve loading and error behavior. Add a regression
test for an empty successful response and run the search tests and lint.

Confirm the source you want inspected is committed, then run:

repo-maintainer run --task task.md --json

This step uses the configured agent account and can incur charges. The task is appended to the configured instructions; it does not override allowed paths, budgets or checks. The engine works in temporary checkouts and saves results to a new .maintainer-output/run-* directory without applying changes to your working tree.

5. Review the result

Use the output directory reported by the command. A run retains structured results, a report, the patch and evidence; a successful changed proposal also has validation.json. See the result contract for field meanings.

Status Meaning Next action
changed A proposed patch passed the configured independent checks Review the patch and test coverage before applying
unchanged No patch was produced Read the assessment; this does not by itself prove a requested feature is already complete
blocked Work could not complete within its constraints or validation failed Keep the artifacts, diagnose the blocker, then use a new output directory for a retry

With --json, exit code 0 means success, 2 means a blocked result with retained artifacts, and 1 means an operational error. Do not treat a nonzero exit as a successful run just because a patch file exists.

After reviewing a successful patch, check that your current source still matches the revision recorded in request.json. Replace run-EXAMPLE below with the actual output directory; angle-bracket placeholders are not shell commands.

git apply --check .maintainer-output/run-EXAMPLE/proposal.patch
git apply .maintainer-output/run-EXAMPLE/proposal.patch
repo-maintainer validate

If you selected a custom config, pass the same --config to validation. Review and commit the change through your normal process. Local runs do not open PRs, merge changes or install a schedule. For more task examples, see run a specific work item.

Local Docker runs

You need Git and Docker with the Compose plugin. Clone this project beside the repository you want to maintain:

git clone https://github.com/djsydney04/repo_maintainer.git
cd /path/to/your-repository
/path/to/repo_maintainer/maintainer init

Edit the generated .maintainer.yml: describe the maintenance task, select the agent, set project checks, and review the editable paths. External documentation sources are optional. Supply the selected agent's key in your shell environment or in the shared checkout's ignored .env file, using .env.example as the starting point. Keep real keys out of your repository and Dockerfile.

/path/to/repo_maintainer/maintainer check
/path/to/repo_maintainer/maintainer run

check validates configuration without inference or an API key. run works from the target repository's committed HEAD: commit the source changes you want it to consider first. The target mount is read-only; the wrapper handles user IDs and creates .maintainer-output/<run>/ for the report and patch.

Review report.json and proposal.patch. To apply a changed proposal yourself, run from the target repository. Replace run-EXAMPLE with your actual run directory:

git apply --check .maintainer-output/run-EXAMPLE/proposal.patch
git apply .maintainer-output/run-EXAMPLE/proposal.patch

Add .maintainer-output/ to the target repository's .gitignore. A local run generates a proposal; it does not open a GitHub PR or install a schedule.

Direct Compose or Docker

From the shared checkout, provide explicit paths:

REPOSITORY_PATH=/path/to/your-repository \
MAINTAINER_OUTPUT_PATH=/path/to/output \
MAINTAINER_UID=$(id -u) MAINTAINER_GID=$(id -g) \
  docker compose run --build --rm maintainer check

Create the output directory first. Use run to generate a proposal, or smoke to exercise a live repair fixture with your selected provider. The wrapper is the convenient way to handle paths and permissions automatically.

For a direct image, build Dockerfile and mount the target at /repository read-only and a writable directory at /output. Pass keys at runtime; do not add them to image layers. The default command is check. The default image includes native Codex; set MAINTAINER_RUNTIME_IMAGE to a Debian-based Node/Python/Go image when needed. See container configuration.

Weekly cloud maintenance

Copy the GitHub Actions setup prompt to have an agent prepare a caller for your project. Start with manual dispatch; add the schedule below only after reviewing a successful run. A workflow dry_run can still incur inference charges; it skips publication, not proposal generation.

The workflow runs on GitHub-hosted Linux. Your Mac or other development computer can be off. The consuming repository owns its schedule and keys.

  1. Commit .maintainer.yml in the repository to maintain.
  2. Add the selected API key in that repository's Settings → Secrets and variables → Actions → Secrets. See provider/key names.
  3. Allow GitHub Actions to create pull requests in the consuming repository's Actions settings. The bot creates PRs; it never approves or merges them.
  4. Add a caller such as .github/workflows/maintenance.yml:
name: Weekly maintenance
on:
  schedule:
    - cron: '0 9 * * 1'
      timezone: America/Los_Angeles
  workflow_dispatch:
permissions:
  contents: read
jobs:
  maintain:
    permissions:
      contents: write
      pull-requests: write
      issues: write
      actions: write
    uses: djsydney04/repo_maintainer/.github/workflows/maintain.yml@bb53d51b6ec4e7140a5d8d7aed2a78c44899488c
    with:
      maintainer_ref: bb53d51b6ec4e7140a5d8d7aed2a78c44899488c
      config_path: .maintainer.yml
      install_codex: true
    secrets:
      CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }}
      MAINTENANCE_API_KEY: ${{ secrets.MAINTENANCE_API_KEY }}
      GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
      GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      SDK_MAINTENANCE_API_KEY: ${{ secrets.SDK_MAINTENANCE_API_KEY }}

Both references pin the same implementation commit. Review it before enabling a schedule, and keep uses and maintainer_ref on the same full SHA when updating. A change to the shared repository only affects your bot after you update that pin.

The example runs Mondays at 9 AM Pacific, including DST. Change the cron and timezone to suit your repository. GitHub can delay scheduled runs.

Merge the configuration and caller, manually start Weekly maintenance once, and review its result. The bot runs only from the repository's default branch. Enable GitHub assignment/mention notifications to receive new blocker issues. Its owner workflow input defaults to the repository owner and can be changed.

The CI workflow named in configuration must exist in the target repository. When configured, rust.package_check must be an executable there, with its own interpreter or compiled binary. For unpublished workspace crates, use your repository's existing packaging verifier. See Rust settings.