Repositories
Native Git hosting in ProxifAI — bare-git repositories, branches, browse, archive download, branch protection, and a full REST surface.
ProxifAI’s forge is a built-in Git host. Repositories live as bare git directories on disk, and every operation — clone, browse, push, PR — is served by the same proxifai binary that serves the rest of the platform. There’s no external git server to operate.
How the forge fits in
Native repositories are stored under $DATA_DIR/repos/<owner>/<repo>.git and managed by internal/forge/native/, which implements a ~90-method Forge interface (forge.go). HTTP routes are mounted at:
| Concern | Mount point |
|---|---|
| Git smart-HTTP protocol | /git/{owner}/{repo}.git/{git-upload-pack,git-receive-pack} |
| REST API | /api/v1/forge/{owner}/{repo}/... |
| Branch protection | /api/v1/branch-protection/{owner}/{repo} |
| Container registry | /v2/... (OCI Distribution Spec) |
Anything served on port PORT (default 3000) handles all four — a single binary, a single endpoint.
Creating a repository
From the UI
Click Code → New Repository. Set the name, description, visibility (public or private), and default branch (typically main). You can initialize with a README or leave it empty.
From the CLI
pfai repo create my-repo --private --description "Shiny new project" From the API
curl -X POST http://localhost:3000/api/v1/forge/repos \
-H "Authorization: Bearer $PFAI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"my-repo","private":true,"description":"Shiny new project"}' To migrate an existing repository from elsewhere, use POST /api/v1/forge/repos/import with a clone URL — the importer mirrors all branches, tags, and history.
Visibility
Two levels:
| Level | Behavior |
|---|---|
| Public | Listed in the org’s public repos page; clone and browse without authentication |
| Private | Visible only to org members with read access; auth required for every git protocol request |
Switch from Repository Settings → General.
Cloning and pushing
The git smart-HTTP protocol is served at http(s)://<your-proxifai-host>/git/<owner>/<repo>.git. Use a pfai token as the password:
# Read-only clone
git clone http://localhost:3000/git/my-org/my-repo.git
# Authenticated push (use your pfai token as the password)
git clone http://<user>:<pfai_token>@localhost:3000/git/my-org/my-repo.git
cd my-repo
git push
The Repository API response includes a server-resolved cloneUrl so client tools get the correct host without hard-coding it.
SSH push is available via the separate sshing service (/sshing in the platform repo). It runs alongside the main binary and authenticates with the same JWT subsystem; the OSS Docker Compose deploy doesn’t include it by default.
Browsing and editing
The forge serves these read endpoints — every one of them backs both the web UI’s repo browser and the pfai file / pfai compare CLI commands:
| Endpoint | Returns |
|---|---|
GET /api/v1/forge/{owner}/{repo}/tree?path=...&ref=... | Directory listing |
GET /api/v1/forge/{owner}/{repo}/tree-info | Tree with last-commit info per entry |
GET /api/v1/forge/{owner}/{repo}/all-files | Flat file list (used for code intelligence indexing) |
GET /api/v1/forge/{owner}/{repo}/file?path=&ref= | Decoded file contents |
GET /api/v1/forge/{owner}/{repo}/raw?path=&ref= | Raw bytes |
GET /api/v1/forge/{owner}/{repo}/readme | The repo’s README rendered to HTML |
GET /api/v1/forge/{owner}/{repo}/blame?path=&ref= | Per-line author + commit info |
GET /api/v1/forge/{owner}/{repo}/archive/{ref}.{zip,tar.gz} | Source snapshot |
Files can also be edited from the web UI or via API. Commit-via-API uses POST /api/v1/forge/{owner}/{repo}/commits with an array of {path, content, mode} entries — the forge composes a single commit and updates the target ref atomically.
Branches and tags
| Operation | UI | API |
|---|---|---|
| List branches | Repo → Branches tab | GET /branches[/detailed] |
| Create branch | Branch dropdown → New | POST /branches with {name, ref} |
| Delete branch | Branches tab → ⋯ → Delete | DELETE /branches/<name> |
| Compare two refs | Compare tab | GET /compare?base=&head= |
| List tags | Tags tab | GET /tags |
| List commits | Commits tab | GET /commits?ref= |
| Diff for a commit | Click any commit | GET /commits/{sha}/diff |
Annotated tags carry a message, tagger, and date; lightweight tags only have a SHA. Both surface through the same Tag type in the API.
Branch protection
Rules live in the BranchProtectionRule table and apply to any branch matching the rule’s branchPattern (a glob like main or release/*). The full schema, from models.go:
| Field | Effect |
|---|---|
requireApprovals | Minimum approvals before merging |
requiredReviewers | Specific users or teams whose approval is required ([{type:"user"|"team", id:"…"}]) |
requireStatusChecks + requiredStatusChecks | Named CI checks must pass |
dismissStaleReviews | Reviews invalidated when new commits land |
requireLinearHistory | Reject merge commits — squash or rebase only |
allowForcePush | Permit --force updates (default: false) |
allowDeletion | Permit branch deletion (default: false) |
allowedPushUsers / allowedPushTeams | Restrict direct pushes |
allowedMergeUsers / allowedMergeTeams | Restrict who can merge PRs |
lockBranch | Read-only — no pushes accepted from anyone |
requireCodeOwnerReview | Flag exists; CODEOWNERS file parsing not yet implemented |
requireSignedCommits | Require GPG/SSH signature |
Manage rules at Repository Settings → Branch Protection, via pfai branch-protection, or directly through /api/v1/branch-protection/{owner}/{repo}.
Org-level push rules at /api/v1/org/push-rules complement branch protection — they enforce constraints (commit message format, file size limits, blocked file paths) across every repo in the org and can’t be overridden per-repo.
requireCodeOwnerReview toggles the flag but the CODEOWNERS file parser isn’t wired up yet — no automatic reviewer assignment from path patterns. Track via the linked GitHub issue in the platform repo.
Deploy keys
Repository-scoped SSH keys for CI/CD and deploy tooling. Configure under Repository Settings → Deploy Keys or via pfai deploy-key. Each key has read-only or read-write access and is scoped to a single repository — even with the key, holders can’t reach other repos.
Linking to projects
A repo can be linked to a project under Plan so commits, PRs, and releases surface on the project dashboard. Done via the UI’s project picker, or:
curl -X PUT http://localhost:3000/api/v1/forge/{owner}/{repo}/link \
-H "Authorization: Bearer $PFAI_TOKEN" \
-d '{"projectId":"proj_42"}'
pfai project repos add <project-id> <owner>/<repo> does the same from the CLI.
Other features
- Language detection — the repo overview shows a language breakdown bar based on a file-extension scan
- Starring —
pfai starred add <owner>/<repo>(or click the star); starred repos appear in your sidebar - Activity feed — recent commits, PRs, issues, releases on the repo overview
- Code intelligence — every native repo can be indexed for search, blast-radius analysis, and community detection. Trigger with
pfai codeintel index <owner>/<repo>or callPOST /api/v1/forge/{owner}/{repo}/intel/index. See Knowledge Base for the broader RAG story.
See also
Review, approve, and merge changes — three states + draft flag, four review verdicts.
Pipelines that run on push and PR, defined in .proxifai/workflows/.
Tagged releases with downloadable assets and the integrated OCI container registry.
pfai repo / branch / commit / file / compare / branch-protection — every web action is scriptable.