Phorge documentation
Phorge gives coding agents a clone-free repository API without replacing Git. The SDK signs short-lived customer JWTs locally and talks to a tenant namespace over HTTPS.
Contents
Install
pnpm add phorge
Create a storage client with your DNS namespace and private key:
import { GitStorage } from "phorge";
const store = new GitStorage({
name: "your-org",
key: env.privateKey,
});
Authentication
Phorge stores an ES256 or RS256 public key for each tenant. The SDK signs narrowly scoped JWTs containing the tenant, actor, repository, permissions, issue time, and expiry. The private key never leaves your process.
Repositories
Repository creation is idempotent. Calling createRepo for a repository you already own returns the existing repository.
const repo = await store.createRepo({
id: "workspace",
ttlSeconds: 86_400,
private: true,
});
idis the repository slug.ttlSecondscontrols its finite lifetime.privaterequires signed reads and defaults totrue.
Commits
Build commits from strings, bytes, deletions, or unified diffs. Set expectedHeadSha when agents may race; a moved ref returns HTTP 412 without changing the branch.
const result = await repo
.createCommit({
targetBranch: "main",
commitMessage: "Add worker",
expectedHeadSha: current.sha,
author: { name: "Agent", email: "agent@example.com" },
})
.addFileFromString("src/worker.ts", source)
.deleteFile("src/old-worker.ts")
.send();
console.log(result.commitSha);
Git over HTTPS
Stock Git works without plugins. The clone helper defaults to a shallow, blob-filtered clone and uses an R2 bundle when one is available.
await repo.clone("./workspace");
const url = await repo.getRemoteURL({
scope: "write",
ttl: 600,
operations: ["no-force-push"],
});
Read without cloning
Repository methods include:
listFiles,getFile,getFileStream, andheadFile.listCommits,getCommit,getCommitDiff, andgetBranchDiff.grep,blame, andgetArchiveStream.
Reads accept a branch, tag, or commit SHA. File streams support byte ranges and ETags.
Errors
Failures use stable machine-readable codes. SDK methods throw typed errors containing the HTTP status, code, message, and structured details.
{
"code": "HEAD_MOVED",
"message": "ref has moved",
"details": { "expected": "…", "actual": "…" }
}
Operations
The production service binds to 127.0.0.1:9948 behind nginx. Its health endpoint is /health. Active repository data and SQLite are stored under /opt/containers/phorge/data.
Cold repositories and clone bundles use separate Cloudflare R2 buckets. B2 backups are optional and disabled by default; enable them with PHORGE_BACKUPS_ENABLED=true and bucket-scoped credentials.