# Git Fs API reference

> Exports of @dev-bench/git-fs.

Source: https://gitapp.n.yatsyk.com/docs/git-fs/jsdoc

## Types

### ProviderId

```ts
type ProviderId = "github" | "gitea" | "gitlab"
```

### TokenLookup

```ts
type TokenLookup = { kind?: "absent"; } | { kind?: "present"; token?: string; }
```

### RepoRef

```ts
type RepoRef = { provider?: "github" | "gitea" | "gitlab"; owner?: string; name?: string; branch?: string; proxyBase?: string; }
```

### Author

```ts
type Author = { name?: string; email?: string; timestampISO?: string; }
```

### FileChange

```ts
type FileChange = { kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; } | { kind?: "delete"; path?: string; }
```

### ReadFileResult

```ts
type ReadFileResult = { kind?: "found"; path?: string; content?: Uint8Array<ArrayBuffer>; versionToken?: string; } | { kind?: "missing"; path?: string; }
```

### TreeEntry

```ts
type TreeEntry = { path?: string; type?: "blob" | "tree"; versionToken?: string; }
```

### HeadTreeState

```ts
type HeadTreeState = { kind?: "fresh"; } | { kind?: "at"; treeOid?: string; commitOid?: string; }
```

### CommitInput

```ts
type CommitInput = { message?: string; base?: { kind?: "fresh"; } | { kind?: "at"; treeOid?: string; commitOid?: string; }; changes?: ({ kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; } | { kind?: "delete"; path?: string; })[]; author?: { name?: string; email?: string; timestampISO?: string; }; }
```

### CommitResult

```ts
type CommitResult = { kind?: "ok"; treeOid?: string; commitOid?: string; } | { kind?: "cas-conflict"; currentTreeOid?: string; }
```

### PushResult

```ts
type PushResult = { kind?: "ok"; commitsAhead?: number; } | { kind?: "non-fast-forward"; remoteOid?: string; } | { kind?: "auth"; reason?: string; } | { kind?: "not-found"; } | { kind?: "network"; retriable?: boolean; }
```

### PullResult

```ts
type PullResult = { kind?: "ok"; fastForwarded?: boolean; newHeadOid?: string; } | { kind?: "diverged"; remoteOid?: string; localOid?: string; } | { kind?: "auth"; reason?: string; } | { kind?: "not-found"; } | { kind?: "network"; retriable?: boolean; }
```

### ResetHeadResult

```ts
type ResetHeadResult = { kind?: "ok"; newHeadOid?: string; } | { kind?: "unknown-oid"; oid?: string; }
```

### CloneResult

```ts
type CloneResult = { kind?: "ok"; headOid?: string; } | { kind?: "auth"; reason?: string; } | { kind?: "not-found"; } | { kind?: "network"; retriable?: boolean; } | { kind?: "empty-init"; reason?: string; }
```

### RepoInfo

```ts
type RepoInfo = { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }
```

### RepoLookupResult

```ts
type RepoLookupResult = { kind?: "found"; info?: { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }; } | { kind?: "missing"; } | { kind?: "forbidden"; currentLogin?: string; } | { kind?: "network"; retriable?: boolean; }
```

### CreateRepoArgs

```ts
type CreateRepoArgs = { name?: string; isPrivate?: boolean; }
```

### CreatedRepo

```ts
type CreatedRepo = { owner?: string; name?: string; }
```

### CurrentLoginResult

```ts
type CurrentLoginResult = { kind?: "ok"; login?: string; } | { kind?: "anonymous"; } | { kind?: "network"; retriable?: boolean; }
```

## Interfaces

### GitFs

```ts
interface GitFs
```

- `readFile: (path: string) => Promise<ReadFileResult>` — Read a file by path. Returns missing if absent — never throws.
- `listTree: (prefix: string) => Promise<ReadonlyArray<TreeEntry>>` — List entries under `prefix`. `prefix === ""` lists root.
Returns empty array if prefix points to a non-existent dir.
Recursive flat list (every blob below the prefix), not a one-level dir read.
- `headTreeState: () => Promise<HeadTreeState>` — Current HEAD tree state. Pass directly into `commit({ base, ... })` for
CAS. Discriminated so "no commits yet" is the named `fresh` variant.
- `commit: (input: CommitInput) => Promise<CommitResult>` — Stage + commit `changes` atomically against `input.base`.
Returns cas-conflict (does not commit) if HEAD has advanced past
`input.base`. Caller's responsibility to refresh + retry.

Does NOT push. Push is a separate explicit step.
- `clone: (ref: RepoRef, token: TokenLookup) => Promise<CloneResult>` — Initialise the local working tree from `ref`. Idempotent — if the local
tree is already cloned for `ref`, returns ok with the existing HEAD.
If the remote returns 404 AND `init.allowEmptyOnMissing` is implied
(adapter-internal default), MAY init an empty repo locally and return
empty-init so the caller can write + push to materialise the remote.
- `push: (ref: RepoRef, token: TokenLookup) => Promise<PushResult>` — Push current HEAD to `ref.branch`.
- `pull: (ref: RepoRef, token: TokenLookup) => Promise<PullResult>` — Fetch + fast-forward HEAD from `ref.branch`. If divergent
(local commits not on remote), does NOT auto-merge — returns diverged.
- `resetLocal: () => Promise<void>` — Drop all local state (working tree + git db + clone metadata).
Used by the "Reset local repo" affordance. Idempotent. After this,
`clone()` re-initialises from scratch.
- `resetHead: (oid: string) => Promise<ResetHeadResult>` — Rewinds local HEAD to `oid`. Discards local commits not on the path
to `oid`. Working-tree state == tree of `oid` after this returns.

Idempotent: `resetHead(currentHeadOid)` returns ok with no observable
change.

Returns `{kind:"unknown-oid"}` (without mutating HEAD) if `oid` is
not present in the local object store. This indicates a programmer
error or a stale reference — callers that hold a HeadTreeState.commitOid
just observed should never see this branch.

Caller contract: ONLY `transaction-runner.handleNonFastForward` should
call this. It's destructive (local commits between `oid` and current
HEAD are unreachable from any ref afterwards), and there is no
general-purpose reason to discard local commits — sync conflict
recovery is the sole legitimate use case.

Adapter implementers MUST also support this from the contract suite
(see __tests__/contract/git-fs.contract.ts → describe("resetHead", …)).

### RepoManagement

```ts
interface RepoManagement
```

- `id: "github" | "gitea" | "gitlab"`
- `label: string`
- `listMyRepos: (token: TokenLookup) => Promise<ReadonlyArray<RepoInfo>>` — List repos the authenticated user can write to (page 1, ≤100 results).
Returns repos sorted by most-recently-pushed.
- `createRepo: (token: TokenLookup, args: CreateRepoArgs) => Promise<CreatedRepo>` — Create a repo owned by the authenticated user. Initialises with README.
- `getRepo: (token: TokenLookup, owner: string, name: string) => Promise<RepoLookupResult>` — Probe a specific repo's visibility to the current token.
  found     → exists + visible
  missing   → does not exist AND token's owner == `owner` (creatable)
  forbidden → exists but invisible to this token (private/wrong-org)
  network   → transient network error
- `currentLogin: (token: TokenLookup) => Promise<CurrentLoginResult>` — Resolve the login the token belongs to.

## Constants

### ProviderIdSchema

```ts
const ProviderIdSchema: z.ZodEnum<["github", "gitea", "gitlab"]>
```

### TokenLookupSchema

```ts
const TokenLookupSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"absent">; }, "strip", z.ZodTypeAny, { kind?: "absent"; }, { kind?: "absent"; }>, z.ZodObject<{ kind: z.ZodLiteral<"present">; token: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "present"; token?: string; }, { kind?: "present"; token?: string; }>]>
```

### tokenAbsent

```ts
const tokenAbsent: () => TokenLookup
```

### tokenPresent

```ts
const tokenPresent: (token: string) => TokenLookup
```

### RepoRefSchema

```ts
const RepoRefSchema: z.ZodObject<{ provider: z.ZodEnum<["github", "gitea", "gitlab"]>; owner: z.ZodString; name: z.ZodString; branch: z.ZodString; proxyBase: z.ZodString; }, "strip", z.ZodTypeAny, { provider?: "github" | "gitea" | "gitlab"; owner?: string; name?: string; branch?: string; proxyBase?: string; }, { provider?: "github" | "gitea" | "gitlab"; owner?: string; name?: string; branch?: string; proxyBase?: string; }>
```

### AuthorSchema

```ts
const AuthorSchema: z.ZodObject<{ name: z.ZodString; email: z.ZodString; timestampISO: z.ZodString; }, "strip", z.ZodTypeAny, { name?: string; email?: string; timestampISO?: string; }, { name?: string; email?: string; timestampISO?: string; }>
```

### FileChangeSchema

```ts
const FileChangeSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"write">; path: z.ZodString; content: z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>; }, "strip", z.ZodTypeAny, { kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; }, { kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; }>, z.ZodObject<{ kind: z.ZodLiteral<"delete">; path: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "delete"; path?: string; }, { kind?: "delete"; path?: string; }>]>
```

### ReadFileResultSchema

```ts
const ReadFileResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"found">; path: z.ZodString; content: z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>; versionToken: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "found"; path?: string; content?: Uint8Array<ArrayBuffer>; versionToken?: string; }, { kind?: "found"; path?: string; content?: Uint8Array<ArrayBuffer>; versionToken?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"missing">; path: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "missing"; path?: string; }, { kind?: "missing"; path?: string; }>]>
```

### TreeEntrySchema

```ts
const TreeEntrySchema: z.ZodObject<{ path: z.ZodString; type: z.ZodEnum<["blob", "tree"]>; versionToken: z.ZodString; }, "strip", z.ZodTypeAny, { path?: string; type?: "blob" | "tree"; versionToken?: string; }, { path?: string; type?: "blob" | "tree"; versionToken?: string; }>
```

### HeadTreeStateSchema

```ts
const HeadTreeStateSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"fresh">; }, "strip", z.ZodTypeAny, { kind?: "fresh"; }, { kind?: "fresh"; }>, z.ZodObject<{ kind: z.ZodLiteral<"at">; treeOid: z.ZodString; commitOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "at"; treeOid?: string; commitOid?: string; }, { kind?: "at"; treeOid?: string; commitOid?: string; }>]>
```

### CommitInputSchema

```ts
const CommitInputSchema: z.ZodObject<{ base: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"fresh">; }, "strip", z.ZodTypeAny, { kind?: "fresh"; }, { kind?: "fresh"; }>, z.ZodObject<{ kind: z.ZodLiteral<"at">; treeOid: z.ZodString; commitOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "at"; treeOid?: string; commitOid?: string; }, { kind?: "at"; treeOid?: string; commitOid?: string; }>]>; changes: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"write">; path: z.ZodString; content: z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>; }, "strip", z.ZodTypeAny, { kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; }, { kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; }>, z.ZodObject<{ kind: z.ZodLiteral<"delete">; path: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "delete"; path?: string; }, { kind?: "delete"; path?: string; }>]>, "many">; message: z.ZodString; author: z.ZodObject<{ name: z.ZodString; email: z.ZodString; timestampISO: z.ZodString; }, "strip", z.ZodTypeAny, { name?: string; email?: string; timestampISO?: string; }, { name?: string; email?: string; timestampISO?: string; }>; }, "strip", z.ZodTypeAny, { message?: string; base?: { kind?: "fresh"; } | { kind?: "at"; treeOid?: string; commitOid?: string; }; changes?: ({ kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; } | { kind?: "delete"; path?: string; })[]; author?: { name?: string; email?: string; timestampISO?: string; }; }, { message?: string; base?: { kind?: "fresh"; } | { kind?: "at"; treeOid?: string; commitOid?: string; }; changes?: ({ kind?: "write"; path?: string; content?: Uint8Array<ArrayBuffer>; } | { kind?: "delete"; path?: string; })[]; author?: { name?: string; email?: string; timestampISO?: string; }; }>
```

### CommitResultSchema

```ts
const CommitResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"ok">; commitOid: z.ZodString; treeOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "ok"; treeOid?: string; commitOid?: string; }, { kind?: "ok"; treeOid?: string; commitOid?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"cas-conflict">; currentTreeOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "cas-conflict"; currentTreeOid?: string; }, { kind?: "cas-conflict"; currentTreeOid?: string; }>]>
```

### PushResultSchema

```ts
const PushResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"ok">; commitsAhead: z.ZodNumber; }, "strip", z.ZodTypeAny, { kind?: "ok"; commitsAhead?: number; }, { kind?: "ok"; commitsAhead?: number; }>, z.ZodObject<{ kind: z.ZodLiteral<"non-fast-forward">; remoteOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "non-fast-forward"; remoteOid?: string; }, { kind?: "non-fast-forward"; remoteOid?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"auth">; reason: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "auth"; reason?: string; }, { kind?: "auth"; reason?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"not-found">; }, "strip", z.ZodTypeAny, { kind?: "not-found"; }, { kind?: "not-found"; }>, z.ZodObject<{ kind: z.ZodLiteral<"network">; retriable: z.ZodBoolean; }, "strip", z.ZodTypeAny, { kind?: "network"; retriable?: boolean; }, { kind?: "network"; retriable?: boolean; }>]>
```

### PullResultSchema

```ts
const PullResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"ok">; fastForwarded: z.ZodBoolean; newHeadOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "ok"; fastForwarded?: boolean; newHeadOid?: string; }, { kind?: "ok"; fastForwarded?: boolean; newHeadOid?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"diverged">; localOid: z.ZodString; remoteOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "diverged"; remoteOid?: string; localOid?: string; }, { kind?: "diverged"; remoteOid?: string; localOid?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"auth">; reason: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "auth"; reason?: string; }, { kind?: "auth"; reason?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"not-found">; }, "strip", z.ZodTypeAny, { kind?: "not-found"; }, { kind?: "not-found"; }>, z.ZodObject<{ kind: z.ZodLiteral<"network">; retriable: z.ZodBoolean; }, "strip", z.ZodTypeAny, { kind?: "network"; retriable?: boolean; }, { kind?: "network"; retriable?: boolean; }>]>
```

### ResetHeadResultSchema

```ts
const ResetHeadResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"ok">; newHeadOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "ok"; newHeadOid?: string; }, { kind?: "ok"; newHeadOid?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"unknown-oid">; oid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "unknown-oid"; oid?: string; }, { kind?: "unknown-oid"; oid?: string; }>]>
```

### CloneResultSchema

```ts
const CloneResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"ok">; headOid: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "ok"; headOid?: string; }, { kind?: "ok"; headOid?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"auth">; reason: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "auth"; reason?: string; }, { kind?: "auth"; reason?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"not-found">; }, "strip", z.ZodTypeAny, { kind?: "not-found"; }, { kind?: "not-found"; }>, z.ZodObject<{ kind: z.ZodLiteral<"network">; retriable: z.ZodBoolean; }, "strip", z.ZodTypeAny, { kind?: "network"; retriable?: boolean; }, { kind?: "network"; retriable?: boolean; }>, z.ZodObject<{ kind: z.ZodLiteral<"empty-init">; reason: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "empty-init"; reason?: string; }, { kind?: "empty-init"; reason?: string; }>]>
```

### RepoInfoSchema

```ts
const RepoInfoSchema: z.ZodObject<{ owner: z.ZodString; name: z.ZodString; isPrivate: z.ZodBoolean; defaultBranch: z.ZodString; pushedAt: z.ZodString; }, "strip", z.ZodTypeAny, { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }, { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }>
```

### RepoLookupResultSchema

```ts
const RepoLookupResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"found">; info: z.ZodObject<{ owner: z.ZodString; name: z.ZodString; isPrivate: z.ZodBoolean; defaultBranch: z.ZodString; pushedAt: z.ZodString; }, "strip", z.ZodTypeAny, { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }, { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }>; }, "strip", z.ZodTypeAny, { kind?: "found"; info?: { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }; }, { kind?: "found"; info?: { owner?: string; name?: string; isPrivate?: boolean; defaultBranch?: string; pushedAt?: string; }; }>, z.ZodObject<{ kind: z.ZodLiteral<"missing">; }, "strip", z.ZodTypeAny, { kind?: "missing"; }, { kind?: "missing"; }>, z.ZodObject<{ kind: z.ZodLiteral<"forbidden">; currentLogin: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "forbidden"; currentLogin?: string; }, { kind?: "forbidden"; currentLogin?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"network">; retriable: z.ZodBoolean; }, "strip", z.ZodTypeAny, { kind?: "network"; retriable?: boolean; }, { kind?: "network"; retriable?: boolean; }>]>
```

### CreateRepoArgsSchema

```ts
const CreateRepoArgsSchema: z.ZodObject<{ name: z.ZodString; isPrivate: z.ZodBoolean; }, "strip", z.ZodTypeAny, { name?: string; isPrivate?: boolean; }, { name?: string; isPrivate?: boolean; }>
```

### CreatedRepoSchema

```ts
const CreatedRepoSchema: z.ZodObject<{ owner: z.ZodString; name: z.ZodString; }, "strip", z.ZodTypeAny, { owner?: string; name?: string; }, { owner?: string; name?: string; }>
```

### CurrentLoginResultSchema

```ts
const CurrentLoginResultSchema: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{ kind: z.ZodLiteral<"ok">; login: z.ZodString; }, "strip", z.ZodTypeAny, { kind?: "ok"; login?: string; }, { kind?: "ok"; login?: string; }>, z.ZodObject<{ kind: z.ZodLiteral<"anonymous">; }, "strip", z.ZodTypeAny, { kind?: "anonymous"; }, { kind?: "anonymous"; }>, z.ZodObject<{ kind: z.ZodLiteral<"network">; retriable: z.ZodBoolean; }, "strip", z.ZodTypeAny, { kind?: "network"; retriable?: boolean; }, { kind?: "network"; retriable?: boolean; }>]>
```
