Skip to content

Documentation

Repo Maintainer

Repo Maintainer gives a coding agent one focused task in a temporary clone of your repository. When the agent proposes a change, the patch is applied to a fresh checkout and your project's own checks run against it. Each run ends with a patch, a report and one of three results: changed, unchanged or blocked.

It is an open-source Rust engine with a command line and SDKs for Python, TypeScript and Rust, running on macOS or Linux. Configuration can live in a YAML file or be passed in from code. A reusable GitHub Actions workflow runs the same pipeline on a schedule and opens a pull request when the checks pass. Nothing is merged, deployed or released automatically.

Engine
Rust · MIT licensed
Interfaces
CLI · Python · TypeScript · Rust
Runs on
macOS · Linux · GitHub Actions
Checks
Your commands, in a fresh checkout
Results
changed unchanged blocked
Publishes
Nothing merged, deployed or released for you

Contents

  • Get started Install the executable, write .maintainer.yml and run one task locally.
  • Agent setup prompts Paste one prompt into your coding agent to prepare a working setup.
  • Run a specific task Hand over a bug, small feature or missing test as a task file.
  • Templates and setup prompts Starting points you give to your coding agent to adapt to a repository.
  • Use cases How the Prism, Slack report and vulnerability-fix workflows fit together.
  • Web context Supply official changelogs, API references or advisories as evidence.
  • Command line Commands, JSON output, exit codes and script-generated requests.
  • SDKs: Python, TypeScript, Rust Run the engine from your own code and read a typed result.
  • Self-hosting Self-hosted runners, Docker images with your tools, cron and custom stages.

Reference: Configuration · Result contract · Architecture · Networking · Troubleshooting

How a run works

  1. The engine clones your repository's committed HEAD into a temporary directory. Uncommitted edits are not included, and your working tree is never modified.
  2. The agent receives the task, the paths it is allowed to edit and excerpts from any configured web sources.
  3. Its edits are exported as a patch. Files outside the permitted paths, hidden paths, symlinks and executable files are rejected, and a patch is limited to 25 files and 500 KB.
  4. A changed patch is applied to a fresh checkout, where your configured setup and check commands run.
  5. The result, report, patch, event log and the agent's brief are written to .maintainer-output/<run>/.
Result Meaning Next step
changed A permitted patch passed your checks in a fresh checkout Review proposal.patch, apply it on a branch and run your checks
unchanged No patch was produced Read the assessment in report.json
blocked The task or its checks could not complete; a partial patch may be kept Read the blockers, fix the task, configuration or access, and rerun

Passing checks is evidence, not proof. The default configuration only checks whitespace, so replace it with the tests, linters and builds that cover the behavior you care about. Field-by-field detail is in the result contract.

Install and run a task

You need Rust 1.89 or newer, Git, a coding agent and whatever tools your project's checks use.

cargo install --git https://github.com/djsydney04/repo_maintainer --locked
cd /path/to/your-repository
repo-maintainer init       # writes .maintainer.yml, keeping any existing file
repo-maintainer check      # validates configuration without calling a model
repo-maintainer validate   # runs your setup and check commands once
repo-maintainer run --task task.md

New configurations use the Codex CLI, which signs in with its own login or CODEX_API_KEY. The built-in agent can call Groq, Google, OpenAI or Anthropic instead. Codex and paid provider profiles require agent.allow_paid: true; free provider profiles do not. Keys stay in the environment, never in configuration. Get started also covers Docker and GitHub Actions.

Configure with YAML or from code

A checked-in .maintainer.yml suits recurring work, but it is optional. The SDKs accept the same configuration as an object, and any script can pipe a JSON request to the command line. All three use the same schema, editing boundaries and checks.

# .maintainer.yml
version: 2
agent:
  allow_paid: true
instructions: Repair one reproducible bug and add a regression test.
editable:
  source_dirs: [src, tests]
  extensions: [.ts, .tsx]
validation:
  profile: custom
  checks:
    - name: tests
      command: [npm, test]
repo-maintainer run

Every field is described in the configuration reference.

from repo_maintainer import Maintainer

client = Maintainer(".", config={
    "version": 2,
    "agent": {"allow_paid": True},
    "editable": {"source_dirs": ["src", "tests"], "extensions": [".py"]},
    "validation": {"checks": [
        {"name": "tests", "command": ["python3", "-m", "unittest", "discover"]}
    ]},
})
client.check()
result = client.run("Repair one reproducible bug and add a regression test.")
print(result.status, result.artifacts.patch)

Requires Python 3.9+ and the command-line executable. The package installs from Git; it is not yet on PyPI. Python SDK

import { Maintainer } from "@djsydney04/repo-maintainer";

const client = new Maintainer({
  repo: ".",
  config: {
    version: 2,
    agent: { allow_paid: true },
    editable: { source_dirs: ["src", "tests"], extensions: [".ts", ".tsx"] },
    validation: { checks: [{ name: "tests", command: ["npm", "test"] }] },
  },
});
await client.check();
const result = await client.run("Repair one reproducible bug and add a regression test.");
console.log(result.status, result.artifacts.patch);

Requires Node 22+ on a server and the command-line executable. The package is built from a checkout; it is not yet on npm. TypeScript SDK

use repo_maintainer::Maintainer;
use serde_json::json;

fn main() -> anyhow::Result<()> {
    let client = Maintainer::new(".").configuration(json!({
        "version": 2,
        "agent": {"allow_paid": true},
        "validation": {"checks": [
            {"name": "tests", "command": ["cargo", "test"]}
        ]}
    }));
    client.check()?;
    let result = client.run("Repair one reproducible bug and add a regression test.")?;
    println!("{}: {}", result.status, result.summary);
    Ok(())
}

Add the crate as a Git dependency. It embeds the engine, so no separate executable is needed. Rust SDK

python make_request.py | repo-maintainer run --request - --json
{
  "config": {
    "version": 2,
    "agent": {"allow_paid": true},
    "validation": {"checks": [{"name": "tests", "command": ["npm", "test"]}]}
  },
  "task": "Repair one reproducible bug and add a regression test."
}

The engine parses the JSON; it never executes a configuration file as code. Script-generated requests

Templates

The repository's templates/ directory holds editable starting points. Each includes a SETUP.md prompt to give your coding agent inside the target repository. The prompt asks the agent to adapt the template to that repository's real paths, tests and build. There is also a general prompt you can copy.

SDK upkeep, modeled on Prism

Prism contains independent Rust SDKs for OpenAI, Gemini and Groq. Use a weekly GitHub Actions run to read the providers' official changelogs, find a documented compatibility gap and propose a fix with offline contract tests as a pull request. The template allows an unchanged result when no fix is needed.

Setup prompt · YAML · Details

Maintenance from a script

A Python or Node script supplies the configuration and task directly, with no YAML file, and receives the checked patch and structured result. The SDKs do not schedule or publish anything themselves.

Setup prompt · Python · JavaScript · Details

Vulnerability reports to Slack

Scanner findings arrive through an authenticated dispatch and are posted as a concise list to a Slack channel through an incoming webhook. This path makes no model calls, labels findings as scanner claims and does not start remediation.

Setup prompt · Report payload · Details

Vulnerability fixes as GitHub pull requests

A dispatch for one finding asks the agent to reproduce it, add a regression test and repair the root cause, which may be application logic that a dependency bump would not touch. A checked patch is published as a pull request, and Slack receives the outcome with a link to the run. Findings that do not apply return unchanged; uncertain ones return blocked. The agent job is kept apart from GitHub write access and Slack delivery.

Setup prompt · Fix payload · Workflow · Details

The security templates do not include a public webhook receiver. Your gateway verifies signatures, deduplicates deliveries and sends the GitHub dispatch.

Web context

List official pages under sources to give the agent something specific to compare the code against:

sources:
  - https://developers.openai.com/api/docs/changelog
official_hosts:
  - developers.openai.com

Each page is fetched over HTTPS on every run, only from allowed hosts, and a bounded text excerpt goes into the agent's brief. When sources are configured, a changed result must cite reference evidence. Pages are treated as evidence, not instructions, and there is no JavaScript rendering or signed-in browsing. Web context

On GitHub Actions

The reusable workflow runs on GitHub-hosted Linux, on a schedule or when started manually. Proposing, validating and publishing are separate jobs: the model key is only present while proposing. Publication runs separately with the permissions needed to push a branch and open a PR. A validated patch opens or updates one pull request; a new blocker opens an assigned issue. The bot never approves or merges. Weekly cloud maintenance · Architecture

What it does not do

  • Merge, deploy or release anything.
  • Open pull requests or schedule work from local runs or the SDKs. Your scheduler decides when work runs.
  • Discover issues, claim tasks or manage a backlog. Each task is an explicit brief.