Documentation
¶
Overview ¶
Package wire defines ClipBeam's FROZEN Envelope v1 over-the-wire JSON shapes plus the byte-ceiling math. It is a byte-for-behavior re-implementation of the Swift app's Models.swift (the literal source of truth, PLAN §3.0); a Mac running ClipBeam.app and a box running clipbeam must interoperate over POST /clip.
Optional fields are POINTERs with omitempty so Go's encoder matches Swift's nil-omission AND a present-but-empty string is emitted as &"" rather than dropped (the load-bearing &"" rule, PLAN §3.5). On decode, pointer fields tolerate both a missing key and an explicit JSON null.
Index ¶
Constants ¶
const DefaultMaxBytes = 52_428_800
DefaultMaxBytes is the default DECODED-payload cap: 52_428_800 = 50 MB (Swift Config.defaults.maxBytes, PLAN §3.8).
const HardCeilingHeaderBytes = 64 * 1024
HardCeilingHeaderBytes is the HTTP header-section ceiling that maps to 431 (mirrors Swift's 64 KB header cap, PLAN §3.3).
Variables ¶
This section is empty.
Functions ¶
func DecodedLength ¶
DecodedLength returns the decoded byte length of a base64 string without allocating the decoded buffer — a cheap sender pre-flight that replicates Swift Sender.swift decodedLength(ofBase64:). It counts non-whitespace, non-pad chars, counts '=' padding separately, then groups=(chars+pad)/4, decoded=groups*3-pad, clamped ≥ 0 (PLAN §3.8).
func EmptyString ¶
func EmptyString() *string
EmptyString returns a pointer to "" so callers can emit the present-but-empty &"" form (PLAN §3.5) without a local addressable variable.
func HardCeiling ¶
HardCeiling returns the raw-wire byte ceiling for the base64-JSON /clip wire, derived from the DECODED cap. base64 inflates by ~33%, plus 64 KB header slack.
The exact formula is `maxBytes*4/3 + 64*1024` with Go INTEGER division and MULTIPLY-FIRST — `maxBytes/3*4` or float math would change the truncation and accept/reject a payload the Mac app would reject/accept. For the default maxBytes (52428800) this is exactly 69970602 (PLAN §3.8; a unit test asserts the literal). This ceiling applies ONLY to the base64-JSON /clip wire — the raw-bytes CB01 SSH frame caps decoded-sum ≤ maxBytes directly (raw==decoded, PLAN §5.1).
func MarshalEnvelope ¶
MarshalEnvelope encodes an Envelope to wire JSON. It is a thin wrapper over encoding/json; key order is unspecified (Swift's wire encoder does not sort keys), so interop tests assert semantic (decode-then-compare) equality, never raw bytes (PLAN §3.5).
Types ¶
type AgentItem ¶
type AgentItem struct {
Type string // "image" | "file" | "text"
Sender string // the envelope's sender host (informational)
Path *string // set for image/file (abs path in the agent inbox)
Text *string // set for text only (never written to disk)
}
AgentItem is a dequeued agent-channel item (Models.swift AgentItem). It lives in memory only: file/image items reference a saved path under the agent inbox; text items carry their text and are never written to disk. Drained one-at-a-time by GET /recv (PLAN §3.10, §7.5).
type ClipResponse ¶
type ClipResponse struct {
OK bool `json:"ok"`
Saved []string `json:"saved"`
Count int `json:"count"`
}
ClipResponse is the 200 body for POST /clip: ok, the absolute saved paths in item order, and the item count. Byte-shape-frozen against Swift ClipResponse.
type Envelope ¶
type Envelope struct {
Version int `json:"version"`
Sender string `json:"sender"`
Items []Item `json:"items"`
Channel *string `json:"channel,omitempty"`
}
Envelope is the top-level POST /clip body. Version is a bare integer that MUST equal 1 forever (the protocol version, decoupled from CLI SemVer, PLAN §10.8). Channel is an optional routing channel: nil or "clipboard" → the clipboard channel; "agent" → the agent inbox channel (PLAN §3.4, Models.swift:25-30).
func UnmarshalEnvelope ¶
UnmarshalEnvelope decodes wire JSON into an Envelope. Pointer optionals tolerate both a missing key and an explicit null.
type HealthResponse ¶
type HealthResponse struct {
OK bool `json:"ok"`
App string `json:"app"`
Version string `json:"version"`
Host string `json:"host"`
Platform string `json:"platform"`
}
HealthResponse is the GET /health 200 body. The KEY NAMES are frozen and shared with the Swift app; the VALUES are the CLI's own (app:"clipbeam", platform:"linux <kernel>") — a liveness check must test ok==true, never the app/platform strings (PLAN §3.3, §8.9).
type Item ¶
type Item struct {
Kind string `json:"kind"`
Name *string `json:"name,omitempty"`
Uti *string `json:"uti,omitempty"`
Mime *string `json:"mime,omitempty"`
BytesB64 *string `json:"bytesB64,omitempty"`
Text *string `json:"text,omitempty"`
}
Item is one wire item. kind ∈ {image,file,text}. For text, name/uti/mime/bytesB64 are nil and text carries the UTF-8 string; for image/file, bytesB64 carries the base64 payload and text is nil. Mirrors Swift Models.swift Item exactly (PLAN §3.5).
type SendRequest ¶
SendRequest is the unified input to the loopback send/control surface. It mirrors Swift SendRequest: POST /push (bare) → {channel:"clipboard", kind:"clipboard"}; POST /agent-send builds one from the X-ClipBeam-* headers + body (PLAN §3.4).
channel ∈ {"agent","clipboard"}
kind ∈ {"file","text","clipboard"}
File absolute path for kind=="file" (nil otherwise)
Text raw UTF-8 body for kind=="text" (nil otherwise)