Documentation
¶
Overview ¶
Package lfs provides a pure-HTTP client for the Git LFS Batch API. No git-lfs binary required. Uses the batch API for blob upload/download.
The client implements the Git LFS Batch API spec: https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md
Index ¶
- func ComputeOID(content []byte) string
- func DownloadObject(action *Action) ([]byte, error)
- func FormatPointer(oid string, size int64) string
- func IsPointerFile(path string) bool
- func ParsePointer(content string) (oid string, size int64, err error)
- func UpdateMetaSummary(sessionPath, summary string) error
- func UploadObject(action *Action, content []byte) error
- func WritePointerFile(path string, ref FileRef) error
- func WritePointerFiles(dir string, files map[string]FileRef) ([]string, error)
- func WriteSessionMeta(sessionPath string, meta *SessionMeta) error
- type Action
- type Actions
- type BatchObject
- type BatchResponse
- type BatchResponseObject
- type Client
- type DownloadResult
- type FileRef
- type HydrationStatus
- type ObjectError
- type SessionMeta
- type SessionMetaBuilder
- func (b *SessionMetaBuilder) Build() *SessionMeta
- func (b *SessionMetaBuilder) EntryCount(n int) *SessionMetaBuilder
- func (b *SessionMetaBuilder) Model(m string) *SessionMetaBuilder
- func (b *SessionMetaBuilder) RepoID(id string) *SessionMetaBuilder
- func (b *SessionMetaBuilder) Summary(s string) *SessionMetaBuilder
- func (b *SessionMetaBuilder) Title(t string) *SessionMetaBuilder
- func (b *SessionMetaBuilder) UserID(id string) *SessionMetaBuilder
- func (b *SessionMetaBuilder) WithFiles(f map[string]FileRef) *SessionMetaBuilder
- type UploadResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComputeOID ¶
ComputeOID computes the SHA256 hex digest of content (the LFS OID).
func DownloadObject ¶
DownloadObject downloads a single blob using the action href.
func FormatPointer ¶ added in v0.3.0
FormatPointer returns canonical LFS pointer file content for the given OID and size. OID must include the "sha256:" prefix (matching FileRef.OID convention).
Per spec: version line first, then remaining keys in alphabetical order. "oid" < "size" lexicographically, so the ordering is: version, oid, size. Each line is "key SP value LF" with Unix line endings (\n, not \r\n).
func IsPointerFile ¶ added in v0.3.0
IsPointerFile reports whether the file at path is an LFS pointer. Returns false for missing files, content files, or read errors. Detection is by content format (version + oid + size), not by filename or .gitattributes — matching how git-lfs itself identifies pointers.
func ParsePointer ¶ added in v0.3.0
ParsePointer parses LFS pointer file content and returns the OID and size. Returns an error if the content is not a valid LFS pointer.
Per spec: version line must appear first; remaining keys ("oid", "size") are in alphabetical order. Unknown keys (e.g. "ext-0-*") are silently ignored, allowing forward compatibility with spec extensions.
func UpdateMetaSummary ¶ added in v0.2.0
UpdateMetaSummary reads meta.json from sessionPath, updates the Summary field, and re-writes it atomically. Used by push-summary to replace the local summary with the AI-generated title.
func UploadObject ¶
UploadObject uploads a single blob using the action href from the batch response.
func WritePointerFile ¶ added in v0.3.0
WritePointerFile writes a standard LFS pointer file at path. Replaces any existing file (content is already uploaded to LFS).
func WritePointerFiles ¶ added in v0.3.0
WritePointerFiles writes LFS pointer files for each entry in files. Keys are filenames written as dir/<key>. Returns sorted absolute paths of written files. Both sessions and imports use this to create the standard git-lfs pointer files that prevent garbage collection.
func WriteSessionMeta ¶
func WriteSessionMeta(sessionPath string, meta *SessionMeta) error
WriteSessionMeta writes meta.json to the given session directory. When meta.Files is populated, also replaces content files with LFS pointer files (standard git-lfs naming). Pointer write failures are non-fatal — session data is safe in LFS + meta.json regardless.
Types ¶
type Action ¶
type Action struct {
Href string `json:"href"`
Header map[string]string `json:"header,omitempty"`
ExpiresIn int `json:"expires_in,omitempty"` // seconds
ExpiresAt string `json:"expires_at,omitempty"` // RFC3339
}
Action is a single LFS action with an href and optional headers.
type Actions ¶
type Actions struct {
Upload *Action `json:"upload,omitempty"`
Download *Action `json:"download,omitempty"`
Verify *Action `json:"verify,omitempty"`
}
Actions contains the upload/download actions returned by the batch API.
type BatchObject ¶
type BatchObject struct {
OID string `json:"oid"` // SHA256 hex digest
Size int64 `json:"size"` // bytes
}
BatchObject identifies a single LFS object by its SHA256 OID and size.
type BatchResponse ¶
type BatchResponse struct {
Transfer string `json:"transfer"` // "basic"
Objects []BatchResponseObject `json:"objects"`
}
BatchResponse is the server response from the batch API.
type BatchResponseObject ¶
type BatchResponseObject struct {
OID string `json:"oid"`
Size int64 `json:"size"`
Authenticated bool `json:"authenticated,omitempty"`
Actions *Actions `json:"actions,omitempty"`
Error *ObjectError `json:"error,omitempty"`
}
BatchResponseObject is a single object in the batch response.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client communicates with a Git LFS Batch API server (e.g., GitLab).
func NewClient ¶
NewClient creates an LFS client for the given git repo URL. repoURL should be the git clone URL (e.g., https://git.sageox.io/sageox/ledger.git). Auth uses HTTP Basic per the Git LFS spec: username:token base64-encoded.
func (*Client) BatchDownload ¶
func (c *Client) BatchDownload(objects []BatchObject) (*BatchResponse, error)
BatchDownload requests download URLs for the given objects.
func (*Client) BatchUpload ¶
func (c *Client) BatchUpload(objects []BatchObject) (*BatchResponse, error)
BatchUpload requests upload URLs for the given objects.
type DownloadResult ¶
DownloadResult tracks the outcome of a single download.
func DownloadAll ¶
func DownloadAll(resp *BatchResponse, maxConcurrent int) []DownloadResult
DownloadAll downloads multiple blobs in parallel. Returns results for every object so callers can see all errors, not just the first.
type FileRef ¶
FileRef identifies a content file by its LFS OID and size.
func NewFileRef ¶
NewFileRef creates a FileRef from content bytes.
func ReadPointerFile ¶ added in v0.3.0
ReadPointerFile reads and parses an LFS pointer file, returning the FileRef.
type HydrationStatus ¶
type HydrationStatus string
HydrationStatus describes whether a session's content files are present locally.
const ( // HydrationStatusHydrated means all content files are present locally. HydrationStatusHydrated HydrationStatus = "hydrated" // HydrationStatusDehydrated means no content files are present (only meta.json). HydrationStatusDehydrated HydrationStatus = "dehydrated" // HydrationStatusPartial means some content files are present. HydrationStatusPartial HydrationStatus = "partial" )
func CheckHydrationStatus ¶
func CheckHydrationStatus(sessionPath string, meta *SessionMeta) HydrationStatus
CheckHydrationStatus checks which content files are present as real content (not LFS pointers) for a session. Files that are missing or contain only an LFS pointer are considered dehydrated.
type ObjectError ¶
ObjectError is returned when the server cannot process an object.
type SessionMeta ¶
type SessionMeta struct {
Version string `json:"version"` // "1.0"
SessionName string `json:"session_name"`
Username string `json:"username"` // email of author
UserID string `json:"user_id,omitempty"`
AgentID string `json:"agent_id"`
AgentType string `json:"agent_type"` // "claude-code", "cursor", etc.
Model string `json:"model,omitempty"`
Title string `json:"title,omitempty"`
CreatedAt time.Time `json:"created_at"`
EntryCount int `json:"entry_count,omitempty"`
Summary string `json:"summary,omitempty"`
RepoID string `json:"repo_id,omitempty"`
Files map[string]FileRef `json:"files"` // OID manifest: filename -> ref
}
SessionMeta is the git-tracked metadata + OID manifest for a session. Stored as meta.json in each session folder. When Files is populated, WriteSessionMeta also writes LFS pointer files (standard git-lfs naming) to replace content files, preventing LFS garbage collection.
func ReadSessionMeta ¶
func ReadSessionMeta(sessionPath string) (*SessionMeta, error)
ReadSessionMeta reads meta.json from the given session directory.
type SessionMetaBuilder ¶ added in v0.2.0
type SessionMetaBuilder struct {
// contains filtered or unexported fields
}
SessionMetaBuilder constructs SessionMeta with required fields and optional setters.
func NewSessionMeta ¶ added in v0.2.0
func NewSessionMeta(sessionName, username, agentID, agentType string, createdAt time.Time) *SessionMetaBuilder
NewSessionMeta creates a builder with required fields pre-filled.
func (*SessionMetaBuilder) Build ¶ added in v0.2.0
func (b *SessionMetaBuilder) Build() *SessionMeta
Build returns the constructed SessionMeta.
func (*SessionMetaBuilder) EntryCount ¶ added in v0.2.0
func (b *SessionMetaBuilder) EntryCount(n int) *SessionMetaBuilder
func (*SessionMetaBuilder) Model ¶ added in v0.2.0
func (b *SessionMetaBuilder) Model(m string) *SessionMetaBuilder
func (*SessionMetaBuilder) RepoID ¶ added in v0.2.0
func (b *SessionMetaBuilder) RepoID(id string) *SessionMetaBuilder
func (*SessionMetaBuilder) Summary ¶ added in v0.2.0
func (b *SessionMetaBuilder) Summary(s string) *SessionMetaBuilder
func (*SessionMetaBuilder) Title ¶ added in v0.2.0
func (b *SessionMetaBuilder) Title(t string) *SessionMetaBuilder
func (*SessionMetaBuilder) UserID ¶ added in v0.2.0
func (b *SessionMetaBuilder) UserID(id string) *SessionMetaBuilder
func (*SessionMetaBuilder) WithFiles ¶ added in v0.2.0
func (b *SessionMetaBuilder) WithFiles(f map[string]FileRef) *SessionMetaBuilder
type UploadResult ¶
UploadResult tracks the outcome of a single upload.
func UploadAll ¶
func UploadAll(resp *BatchResponse, files map[string][]byte, maxConcurrent int) []UploadResult
UploadAll uploads multiple blobs in parallel. files maps OID -> content. Uses objects from the batch response to find upload actions.