upload

package
v0.5.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: AGPL-3.0 Imports: 25 Imported by: 0

Documentation

Overview

Package upload drives the ingest protocol from the client side, statelessly. The server is authoritative for how many bytes of each file it holds, so the client persists nothing: it announces, reconciles against the server's cursor and content hash, and streams the gap in newline-terminated chunks.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHTTPClient added in v0.5.5

func NewHTTPClient() *http.Client

NewHTTPClient builds the production HTTP client used by sync and watch. The transport bounds connection setup and response headers, while upload bodies use progress deadlines in Client so a large transfer has no wall-clock cap. Redirects are refused; see errIngestRedirectRefused.

Types

type Action

type Action string

Action describes what SyncFile did for a file.

const (
	ActionUpToDate Action = "uptodate" // server already had the whole file
	ActionUploaded Action = "uploaded" // appended new bytes
	ActionReset    Action = "reset"    // diverged, re-uploaded from zero
)

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client talks to one akari server with one bearer token.

func New

func New(httpClient *http.Client, baseURL, token string) *Client

New builds a Client. baseURL is the server root (trailing slash optional).

func (*Client) SyncFile

func (c *Client) SyncFile(ctx context.Context, t Target) (Outcome, error)

SyncFile announces a file, reconciles against the server's cursor, and uploads any new complete lines. It is safe to call repeatedly: an up-to-date file moves no bytes.

A mid-stream offset conflict (HTTP 409) means the server's cursor moved out from under us, so the prefix verified at announce is stale. Rather than trust the conflict's reported cursor blindly (which could append onto a divergent prefix), SyncFile re-announces and re-verifies the prefix from scratch, up to maxConflictRetries times.

type Outcome

type Outcome struct {
	Action        Action
	UploadedBytes int64
	StoredBytes   int64
	// SessionID is the server's id for the synced session, learned at announce. It
	// lets SyncFile address the session after the upload (the finalize refresh), and
	// is carried out to the caller for the same reason.
	SessionID int64
}

Outcome reports the result of syncing one file.

type Target

type Target struct {
	Agent      string
	Path       string
	SourceID   string
	Kind       string
	ProjectKey string
	LocalRoot  string
	GitBranch  string
	Cwd        string
	Machine    string

	// Finalize forces the session's trailing turn to be treated as settled on this
	// sync regardless of how recently the file was written. A Codex session's final
	// turn has no closing user line, so it is normally withheld until the file has
	// been idle for settleWindow (see syncOnce); on an ephemeral host (CI, a cloud
	// sandbox) that idle window never elapses before the host is torn down, so the
	// final turn would never upload. Set by `akari sync --finalize`, an assertion by
	// the caller that every session being synced is terminal.
	Finalize bool
}

Target is everything needed to upload one resolved session file. Kind is the session's classification ("remote", "standalone", or "orphaned"). ProjectKey is set only for a remote session; for standalone and orphaned sessions the server derives the project key from Machine and the local location. LocalRoot, set only for a standalone session in a live worktree, is the repo root shared by every worktree; the server keys on it so a local-only repo's worktrees collapse into one project. When it is empty the server falls back to Cwd.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL