Using with AI Agents
Integrate Coregit into your AI coding agent workflow — from repo creation to commit and clone.
Why Coregit for AI Agents?
Traditional Git requires a filesystem, a git binary, and SSH keys. AI agents running in serverless environments don't have these. Coregit replaces all of that with a REST API:
- No containers, no git binary, no cold starts
- Multi-file commits in a single HTTP call
- Instant rollback via snapshots
- Standard
git clonefor the final result
Full Workflow
1. Create a Repository
const res = await fetch('https://api.coregit.dev/v1/repos', {
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
slug: 'agent-output',
visibility: 'private',
}),
});
const repo = await res.json();
// { id: "repo_abc", slug: "agent-output", ... }2. Generate Code and Commit
Your agent generates files, then commits them all at once:
const commitRes = await fetch(
'https://api.coregit.dev/v1/repos/agent-output/commits',
{
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
branch: 'main',
message: 'feat: implement user authentication',
changes: [
{
path: 'src/auth.ts',
content: `import { hash, verify } from './crypto';
export async function authenticate(email: string, password: string) {
const user = await db.users.findByEmail(email);
if (!user) throw new Error('User not found');
const valid = await verify(password, user.passwordHash);
if (!valid) throw new Error('Invalid password');
return { id: user.id, email: user.email };
}`,
},
{
path: 'src/middleware.ts',
content: `import { authenticate } from './auth';
export async function authMiddleware(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token' });
try {
req.user = await verifyToken(token);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}`,
},
{
path: 'src/index.ts',
content: `import { authMiddleware } from './middleware';
app.use('/api', authMiddleware);
app.listen(3000);`,
},
],
}),
}
);
const commit = await commitRes.json();
// { sha: "7f3b...", tree_sha: "a1c2...", parent_sha: "0000..." }3. Create a Snapshot Before Risky Changes
await fetch('https://api.coregit.dev/v1/repos/agent-output/snapshots', {
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'before-refactor',
branch: 'main',
}),
});4. Roll Back if Something Breaks
await fetch(
'https://api.coregit.dev/v1/repos/agent-output/snapshots/before-refactor/restore',
{
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ target_branch: 'main' }),
}
);5. Clone the Result
The user (or CI) clones with standard Git:
git clone https://myorg:cgk_live_KEY@api.coregit.dev/myorg/agent-output.gitLazy Edits — Stop Rewriting Whole Files
Once a file exists, rewriting it to change three lines is wasteful: your agent burns 5 000 output tokens to regenerate 4 997 that were already correct. action: "lazy_edit" lets the agent send only the diff in its head, marked with // ... existing code ... placeholders, and Coregit merges it server-side inside the same atomic commit.
await fetch('https://api.coregit.dev/v1/repos/agent-output/commits', {
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
branch: 'main',
message: 'fix: null-check user before session',
parent_sha: currentHead,
changes: [
{
path: 'src/auth.ts',
action: 'lazy_edit',
instruction: 'Add user null check before session creation',
edit_snippet:
'// ... existing code ...\n' +
' const user = db.find(email);\n' +
' if (!user) throw new Error("User not found");\n' +
' const session = createSession(user);\n' +
'// ... existing code ...',
},
],
}),
});When to use it — any edit where > 80% of the file is unchanged. For a 1-line fix in a 5 000-token file, you're sending ~100 tokens instead of 5 000 — 50× fewer output tokens from your agent's LLM, which is usually the single biggest cost in an agent loop.
Full reference: Commits → Lazy Edits.
Finding Code with Agentic Search
Before you edit a file, your agent usually needs to locate the right spot. Instead of running N shell commands in a sandbox to grep/read/list, hand the question to Coregit:
const res = await fetch(
'https://api.coregit.dev/v1/repos/agent-output/agentic-search',
{
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
q: 'Where is the JWT verification middleware and what does it check?',
ref: 'main',
}),
}
);
const { answer, locations } = await res.json();
// answer: "JWT verification lives in src/auth/middleware.ts, line 42..."
// locations: [{ path: "src/auth/middleware.ts", start_line: 42, end_line: 58 }]Coregit materializes the repo at ref, runs an upstream model through a 3–6 step grep/read/glob loop inside a sandboxed filesystem, and returns an answer + file pointers. Your agent gets one clean fact instead of 30 tool calls.
Set stream: true to receive per-turn SSE events (turn_start, tool_call, tool_result, finish) if you want to show progress.
Full reference: Agentic Search.
Conflict Detection
When multiple agents work on the same repo, use parent_sha to detect conflicts:
// Get current branch head
const branchRes = await fetch(
'https://api.coregit.dev/v1/repos/agent-output/branches/main',
{ headers: { 'x-api-key': process.env.COREGIT_API_KEY } }
);
const { sha: currentHead } = await branchRes.json();
// Commit with CAS check
const commitRes = await fetch(
'https://api.coregit.dev/v1/repos/agent-output/commits',
{
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
branch: 'main',
message: 'update config',
parent_sha: currentHead, // Will return 409 if branch moved
changes: [
{ path: 'config.json', content: '{"v": 2}' },
],
}),
}
);
if (commitRes.status === 409) {
// Branch was updated by another agent — re-read and retry
}Branching and Merging
For multi-step tasks, agents can work on feature branches and merge when ready:
// Create a feature branch
await fetch('https://api.coregit.dev/v1/repos/agent-output/branches', {
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'agent-task-42', from: 'main' }),
});
// Agent works on the branch (multiple commits)...
// Check if it can be merged cleanly
const compareRes = await fetch(
'https://api.coregit.dev/v1/repos/agent-output/compare?base=main&head=agent-task-42',
{ headers: { 'x-api-key': process.env.COREGIT_API_KEY } }
);
const comparison = await compareRes.json();
if (comparison.mergeable) {
// Merge into main
await fetch(
'https://api.coregit.dev/v1/repos/agent-output/branches/agent-task-42/merge',
{
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
target: 'main',
strategy: 'squash',
message: 'feat: implement user auth (agent-task-42)',
}),
}
);
} else {
console.log('Conflicts:', comparison.conflicts);
// Handle conflicts or retry with a different approach
}Cherry-Pick for Stacked Changes
When multiple agents work in sequence, use cherry-pick to replay changes:
// Agent A worked on commits base..headA on branch-a
// Agent B needs to replay those onto a different branch
const cherryPickRes = await fetch(
'https://api.coregit.dev/v1/repos/agent-output/cherry-pick',
{
method: 'POST',
headers: {
'x-api-key': process.env.COREGIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
base: mergeBase, // start of range (exclusive)
head: agentAHead, // end of range (inclusive)
onto: 'dev', // replay onto dev branch
branch: 'dev', // update dev branch with result
expected_sha: devHead, // CAS — fail if dev moved
}),
}
);
const result = await cherryPickRes.json();
if (result.success) {
console.log('Replayed onto dev:', result.head_sha);
} else {
console.log('Conflicts:', result.conflicts);
}Helper Function
Wrap the API in a reusable function:
class CoregitClient {
constructor(private apiKey: string, private baseUrl = 'https://api.coregit.dev/v1') {}
private async request(path: string, options?: RequestInit) {
const res = await fetch(`${this.baseUrl}${path}`, {
...options,
headers: {
'x-api-key': this.apiKey,
'Content-Type': 'application/json',
...options?.headers,
},
});
if (!res.ok) throw new Error(`Coregit API error: ${res.status}`);
return res.json();
}
createRepo(slug: string, visibility: 'private' | 'public' = 'private') {
return this.request('/repos', {
method: 'POST',
body: JSON.stringify({ slug, visibility }),
});
}
commit(repoSlug: string, branch: string, message: string, changes: any[]) {
return this.request(`/repos/${repoSlug}/commits`, {
method: 'POST',
body: JSON.stringify({ branch, message, changes }),
});
}
compare(repoSlug: string, base: string, head: string) {
return this.request(`/repos/${repoSlug}/compare?base=${base}&head=${head}`);
}
cherryPick(repoSlug: string, base: string, head: string, onto: string, branch?: string) {
return this.request(`/repos/${repoSlug}/cherry-pick`, {
method: 'POST',
body: JSON.stringify({ base, head, onto, branch }),
});
}
merge(repoSlug: string, source: string, target: string, strategy: string = 'fast-forward') {
return this.request(`/repos/${repoSlug}/branches/${source}/merge`, {
method: 'POST',
body: JSON.stringify({ target, strategy }),
});
}
snapshot(repoSlug: string, name: string, branch: string) {
return this.request(`/repos/${repoSlug}/snapshots`, {
method: 'POST',
body: JSON.stringify({ name, branch }),
});
}
restore(repoSlug: string, snapshotName: string, targetBranch: string) {
return this.request(`/repos/${repoSlug}/snapshots/${snapshotName}/restore`, {
method: 'POST',
body: JSON.stringify({ target_branch: targetBranch }),
});
}
readFile(repoSlug: string, ref: string, path: string) {
return this.request(`/repos/${repoSlug}/blob/${ref}/${path}`);
}
}
// Usage
const git = new CoregitClient(process.env.COREGIT_API_KEY!);
await git.createRepo('my-project');
await git.commit('my-project', 'main', 'init', [
{ path: 'README.md', content: '# Hello' },
]);
// Compare and merge
const diff = await git.compare('my-project', 'main', 'feature');
if (diff.mergeable) {
await git.merge('my-project', 'feature', 'main', 'squash');
}