Complete reference for Repatch's tools, steps, and core interfaces.
All tools are defined in src/tools/registry.ts and registered with Zod schemas for validation.
interface Tool {
name: string;
description: string;
parameters: Record<string, unknown>; // Zod schema
handler: (args: any) => Promise<any>;
}| Tool | Steps Available | Description |
|---|---|---|
list_files |
UNDERSTAND, EXPLORE, REPRODUCE, PLAN, VERIFY | List files recursively |
read_file |
EXPLORE, REPRODUCE, PLAN, EXECUTE, VERIFY, SUBMIT | Read file with line numbers |
grep_search |
EXPLORE, REPRODUCE, PLAN | Search pattern in files |
run_command |
REPRODUCE, VERIFY, SUBMIT | Run command in Docker sandbox |
run_local_command |
REPRODUCE, VERIFY, SUBMIT | Run command locally (Nixpacks) |
write_file |
EXECUTE | Create/overwrite file |
edit_file |
EXECUTE | Surgical snippet replacement |
create_reproduction_test |
REPRODUCE | Create dedicated test file |
Purpose: List files in a directory recursively with optional pattern filter.
Parameters:
{
"dirPath": "string (required)",
"pattern": "string (optional, glob pattern)"
}Returns: FileResult[]
interface FileResult {
path: string;
isDirectory: boolean;
size?: number;
}Example:
{ "dirPath": "/repo", "pattern": "*.ts" }Purpose: Read a file and return content with line numbers.
Parameters:
{
"filePath": "string (required)"
}Returns: FileResult
interface FileResult {
path: string;
content: string;
lineCount: number;
}Example:
{ "filePath": "/repo/src/auth.ts" }Purpose: Search for a pattern in files within a directory.
Parameters:
{
"pattern": "string (required)",
"dirPath": "string (required)",
"extensions": "string[] (optional)"
}Returns: GrepResult[]
interface GrepResult {
file: string;
line: number;
match: string;
context: string; // surrounding lines
}Example:
{ "pattern": "authenticate", "dirPath": "/repo/src", "extensions": [".ts", ".js"] }Purpose: Execute a command inside a Docker sandbox container.
Parameters:
{
"imageTag": "string (required)",
"cmd": "string (required)",
"repoPath": "string (optional)"
}Returns: CommandResult
interface CommandResult {
stdout: string;
stderr: string;
exitCode: number;
}Example:
{
"imageTag": "repatch-sandbox:abc123",
"cmd": "npm test",
"repoPath": "/repo"
}Purpose: Execute a command locally using Nixpacks-detected environment.
Parameters:
{
"cmd": "string (required)",
"repoPath": "string (required)"
}Returns: CommandResult
Example:
{ "cmd": "npm test", "repoPath": "/repo" }Purpose: Create or overwrite a file with content.
Parameters:
{
"filePath": "string (required)",
"content": "string (required)"
}Returns:
{ "success": true, "path": "string" }Example:
{
"filePath": "/repo/src/new-file.ts",
"content": "export function hello() { return 'world'; }"
}Purpose: Surgically replace a code snippet using fuzzy matching.
Parameters:
{
"filePath": "string (required)",
"oldSnippet": "string (required)",
"newSnippet": "string (required)"
}Returns:
{ "success": true, "path": "string" }Matching Algorithm:
- Exact match (whitespace-normalized)
- Sliding window search (±5 lines)
- Token-based similarity (if enabled)
Example:
{
"filePath": "/repo/src/auth.ts",
"oldSnippet": "if (user.email === '') { return false; }",
"newSnippet": "if (!user.email || user.email === '') { return false; }"
}Purpose: Create a dedicated test file to reproduce a bug.
Parameters:
{
"dirPath": "string (required)",
"content": "string (required)",
"fileName": "string (optional, default: 'reproduce.test.ts')"
}Returns:
{ "success": true, "path": "string" }Example:
{
"dirPath": "/repo/tests",
"content": "import { authenticate } from '../src/auth';\ntest('empty email fails', () => { expect(authenticate('', 'pass')).toBe(false); });",
"fileName": "auth-reproduction.test.ts"
}All steps are in src/orchestrator/steps/ and implement the BaseStep interface.
interface BaseStep {
readonly name: Step; // "UNDERSTAND" | "EXPLORE" | "REPRODUCE" | "PLAN" | "EXECUTE" | "VERIFY" | "SUBMIT"
execute(state: AgentState): Promise<StepResult>;
}
interface StepResult {
nextStep: Step;
state: AgentState;
cost?: number;
}
interface StepDependencies {
model: string;
maxIterations: number;
isLocal?: boolean;
sandboxImageTag?: string;
executeTool(toolCall: ToolCall, state: AgentState): Promise<unknown>;
onLLMResponse?(response: LLMResponse): void;
}File: src/orchestrator/steps/understand.ts
Purpose: Analyze issue, build context, identify keywords and references.
Tools: list_files
Input State: issueText, repoUrl, hint?
Output State: fileTree, references?, history entry
Prompt Template:
You are a Senior Software Engineer triaging a bug report.
REPO: {repoUrl}
ISSUE: {issueText}
MAP OF TRUTH (File Tree): {fileTree}
Task:
1. Summarize the bug with technical precision
2. Identify authoritative source (MDN, Unicode, Wikipedia, etc.)
3. Determine keywords and likely files
Respond with JSON:
{"summary": "...", "references": ["url1"], "keywords": [...], "analysis": "..."}
File: src/orchestrator/steps/explore.ts
Purpose: LLM-guided search for relevant files using grep/read.
Tools: list_files, read_file, grep_search
Input State: issueText, fileTree, visitedFiles, hint?, keywords?
Output State: visitedFiles (updated), history entry
Behavior:
- Iterative: LLM calls tools until satisfied or max iterations
- Tracks visited files to avoid re-reading
- Parallel batching for multiple grep searches
File: src/orchestrator/steps/reproduce.ts
Purpose: Generate minimal failing test that proves the bug exists.
Tools: list_files, read_file, grep_search, run_command, create_reproduction_test
Input State: issueText, visitedFiles, fileTree, hint?
Output State: reproductionTest, reproductionFailureOutput, history entry
Behavior:
- Writes test file via
create_reproduction_test - Runs test via
run_command/run_local_command - Captures failure output for PLAN step
- Falls back to EXPLORE if no reproduction found
File: src/orchestrator/steps/plan.ts
Purpose: Create surgical fix plan with line-level changes.
Tools: list_files, read_file, grep_search
Input State: issueText, visitedFiles, reproductionFailureOutput, fileTree, hint?
Output State: fixPatch (JSON plan), history entry
Prompt Template:
You are a Senior Engineer planning a fix.
ISSUE: {issueText}
REPRODUCTION FAILURE: {reproductionFailureOutput}
VISITED FILES: {visitedFiles}
MAP OF TRUTH: {fileTree}
Create a fix plan with:
{
"rootCause": "...",
"changes": [
{"file": "path", "oldSnippet": "...", "newSnippet": "..."}
],
"testStrategy": "..."
}
File: src/orchestrator/steps/execute.ts
Purpose: Apply fixes using fuzzy surgical matching.
Tools: read_file, edit_file, write_file
Input State: fixPatch, visitedFiles
Output State: history entry, errorLogs (if any)
Behavior:
- Iterates through
fixPatch.changes - Uses fuzzy matching (exact → sliding window → token similarity)
- Logs each edit attempt
- Backtracks to PLAN on failure
File: src/orchestrator/steps/verify.ts
Purpose: Run tests + linters in sandbox to confirm fix works.
Tools: run_command, list_files
Input State: repoPath, sandboxImageTag, isLocal, fixPatch
Output State: verificationSuccessOutput, lintOutput, history entry
Behavior:
- Detects test command (package.json, pyproject.toml, etc.)
- Runs tests in sandbox
- Runs linter if configured
- Backtracks to PLAN on test/lint failure (max 2 retries)
File: src/orchestrator/steps/submit.ts
Purpose: Open PR with fix and engineering narrative.
Tools: read_file, run_command
Input State: All previous state
Output State: prUrl (in result), history entry
Behavior:
- Generates branch name:
repatch/fix-{issueHash} - Creates commit with conventional message
- Pushes to fork/remote
- Opens PR via GitHub API
- Includes engineering narrative in PR body
interface AgentState {
currentStep: Step;
repoUrl: string;
issueUrl: string;
issueText: string;
repoPath: string;
fileTree?: string;
monologue?: string;
visitedFiles: string[];
reproductionTest?: string;
reproductionFailureOutput?: string;
verificationSuccessOutput?: string;
lintOutput?: string;
hint?: string;
references?: string[];
fixPatch?: string;
errorLogs: string[];
history: HistoryEntry[];
totalCost: number;
}interface HistoryEntry {
step: Step;
action: string;
result: string;
timestamp: number;
}interface LLMMessage {
role: "system" | "user" | "assistant";
content: string;
}interface LLMResponse {
content: string;
toolCalls?: ToolCall[];
cost: number;
usage: {
promptTokens: number;
completionTokens: number;
totalTokens: number;
};
}interface ToolCall {
id: string;
name: string;
arguments: Record<string, unknown>;
}All providers implement LLMProvider interface in src/inference/provider.ts.
interface LLMProvider {
complete(messages: LLMMessage[], tools?: Tool[]): Promise<LLMResponse>;
streamComplete?(messages: LLMMessage[], tools?: Tool[]): AsyncGenerator<LLMResponse>;
}| Provider | Class | Models | Notes |
|---|---|---|---|
| OpenAI | OpenAIProvider |
gpt-4o, gpt-4o-mini, o1 | Official API |
| Anthropic | AnthropicProvider |
claude-3-5-sonnet-latest | Official API |
| Gemini | GeminiProvider |
gemini-1.5-pro, gemini-1.5-flash | API + CLI fallback |
| Mimo | MimoProvider |
mimo-v2.5-pro | Gitlab OpenGateway |
- Retry Logic: Exponential backoff (3 attempts default)
- Cost Tracking: Returns
costin USD per response - Secret Redaction:
safeLogError()redacts API keys in logs - Prompt Sanitization: User data wrapped via
wrapUserData()
Two execution modes in src/sandbox/:
// src/sandbox/docker.ts
interface SandboxExecutor {
buildImage(repoPath: string): Promise<string>; // returns imageTag
runCommand(imageTag: string, cmd: string, repoPath: string): Promise<CommandResult>;
cleanup(imageTag: string): Promise<void>;
}Build Process:
- Nixpacks detects language → generates Dockerfile
docker buildcreates image taggedrepatch-sandbox:{hash}- Image cached for subsequent runs
Resource Limits (configurable):
- Memory: 4GB default
- CPUs: 2 default
- Network: disabled default
- Timeout: 300s default
// src/sandbox/local.ts
interface LocalExecutor {
setupLocalEnvironment(repoPath: string): Promise<LocalExecutionContext>;
runLocalCommand(context: LocalExecutionContext, cmd: string): Promise<CommandResult>;
getLocalTestCommand(context: LocalExecutionContext): string;
getLocalLintCommand(context: LocalExecutionContext): string;
}Language Detection (Nixpacks + fallback):
| Language | Detection File | Install Command |
|---|---|---|
| Node.js | package.json | npm install |
| Python | requirements.txt / pyproject.toml | pip install -r requirements.txt |
| Go | go.mod | go mod download |
| Rust | Cargo.toml | cargo build |
| Java | pom.xml / build.gradle | mvn install / gradle build |
| Ruby | Gemfile | bundle install |
| PHP | composer.json | composer install |
const ConfigSchema = z.object({
model: z.string().default("gpt-4o"),
openai: z.object({
apiKey: z.string().optional(),
baseUrl: z.string().url().optional()
}).optional(),
anthropic: z.object({
apiKey: z.string().optional()
}).optional(),
gemini: z.object({
apiKey: z.string().optional()
}).optional(),
mimo: z.object({
apiKey: z.string().optional(),
baseUrl: z.string().url().optional()
}).optional(),
github: z.object({
token: z.string().optional()
}).optional(),
sandbox: z.object({
memory: z.string().default("4g"),
cpus: z.number().default(2),
network: z.boolean().default(false)
}).optional()
});| Variable | Config Equivalent | Required |
|---|---|---|
OPENAI_API_KEY |
openai.apiKey |
One of |
ANTHROPIC_API_KEY |
anthropic.apiKey |
One of |
GEMINI_API_KEY |
gemini.apiKey |
One of |
MIMO_API_KEY |
mimo.apiKey |
One of |
GH_TOKEN |
github.token |
For PR submit |
AI_MODEL |
model |
Optional |
| Flag | Description |
|---|---|
-i, --issue <text> |
Issue description or GitHub issue URL |
-h, --hint <text> |
Hint for the agent |
--model <name> |
Override default model |
--budget <usd> |
Max cost budget |
--local |
Run without Docker |
--resume |
Resume from checkpoint |
--parallel <n> |
Parallel workers (fix-multi) |
--max-retries <n> |
Max retries per issue |
--good-first |
Filter good first issues (triage) |
--json |
JSON output |
- Add to
src/tools/registry.ts:
{
name: "my_tool",
description: "What it does",
parameters: { /* Zod schema */ },
handler: async (args) => { /* implementation */ }
}- Declare availability in steps via
availableInSteps(if using step-gating)
- Create
src/orchestrator/steps/my-step.ts:
export class MyStep implements BaseStep {
readonly name = "MY_STEP" as Step;
constructor(private deps: StepDependencies) {}
async execute(state: AgentState): Promise<StepResult> { ... }
}- Register in
src/orchestrator/machine.tsstep order.
- Create
src/inference/my-provider.tsimplementingLLMProvider. - Register in
src/inference/provider.tsfactory functioncreateProvider().
| Code | Context | Meaning |
|---|---|---|
SANDBOX_BUILD_FAILED |
Docker build | Nixpacks/Dockerfile issue |
SANDBOX_TIMEOUT |
Command execution | Command exceeded timeout |
TOOL_VALIDATION_ERROR |
Tool call | Args don't match schema |
LLM_RATE_LIMIT |
Provider call | 429 from API |
LLM_TOKEN_LIMIT |
Provider call | Context too large |
GITHUB_AUTH_FAILED |
PR submit | Invalid/missing GH_TOKEN |
FUZZY_MATCH_FAILED |
Edit step | Could not locate snippet |
CHECKPOINT_CORRUPT |
Resume | Invalid checkpoint file |
| Repatch Version | Node.js | TypeScript | Docker |
|---|---|---|---|
| 0.1.x | 20+ | 5.x | 24+ |