version

package
v0.22.20 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package version — daemon-side periodic update poller. Every `Interval` ticks (default 1h) the poller calls `CheckForUpdate`; when a transition from no-update → update-available is detected it broadcasts a SystemNotification onto the supplied publisher (typically biam.WatchHub.BroadcastSystem). Connected watchers — orchestrator, dashboard, `task watch`, MCP clients dialling the watch socket — render the inline banner immediately, no polling.

Why daemon-side rather than per-CLI: the CLI is short-lived; the daemon (`clawtool serve`) is the long-running process the operator already keeps up. One canonical poller, single GitHub round-trip per host per hour, push to every active surface.

Telemetry: each transition emits a `clawtool.update_check` event with the same allow-listed payload SessionStart uses, so the operator gets a unified PostHog view of update detection across surfaces.

Package version — update-check primitive. Hits the GitHub Releases API for the latest tag and reports whether the local build is older. Cached for 24h in ~/.cache/clawtool/update.json so a `clawtool doctor` (or any other surface that calls CheckForUpdate) doesn't pay a network roundtrip on every invocation.

No background polling, no telemetry — this is a stateless, user-initiated check. The cache exists purely to avoid being rude to the GitHub API.

Package version exposes the clawtool build version.

Three layers, picked in order:

  1. ldflags override — `go build -ldflags='-X github.com/cogitave/clawtool/internal/version.Version=v…'`. goreleaser sets this on every release tarball, so installed binaries always carry the exact tag.

  2. runtime/debug.ReadBuildInfo — module-cached `go install` binaries surface the tag here. Local `go build` from a working tree returns "(devel)".

  3. The release-please-tracked constant below — fallback for dev workflows where neither (1) nor (2) yields a real version.

`Resolved()` is the single function every caller (overview, upgrade, claude-bootstrap, telemetry) must use to read the effective version. Reading `Version` directly (the constant) will diverge from what the binary actually is when goreleaser stamped a different value via ldflags.

Index

Constants

View Source
const Name = "clawtool"

x-release-please-start-version

View Source
const UpdateCheckURL = "https://api.github.com/repos/cogitave/clawtool/releases/latest"

UpdateCheckURL is the GitHub Releases API endpoint we hit. The public API permits ~60 unauthenticated requests/hour per IP; the 24h cache keeps us well under that even on shared CI runners.

Variables

View Source
var Version = "0.21.7" // x-release-please-version

Version is the build-stamped semver string. Declared as `var` (not `const`) so goreleaser can override it via `-ldflags='-X github.com/cogitave/clawtool/internal/version.Version=…'` at link time. `-X` cannot patch constants; that's why this is a var even though it's effectively immutable at runtime.

Functions

func Resolved added in v0.22.8

func Resolved() string

Resolved returns the authoritative installed-binary version. First-call computation is cached for the process lifetime — the binary's version doesn't change while it's running.

Output strips any leading "v" so callers can pass it straight into Compare() without normalising at every call site.

func String

func String() string

String is the formatted "clawtool X.Y.Z" banner the CLI prints.

Types

type Poller added in v0.22.9

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

Poller wraps the periodic update probe + publisher. Lifetime = daemon process. Stop via ctx cancellation.

func NewPoller added in v0.22.9

func NewPoller(pub PublishFn, cfg PollerConfig, track func(outcome string)) *Poller

NewPoller constructs the poller with the given publisher and optional telemetry tracker. `track` is called on every check with the outcome enum ("up_to_date" | "update_available" | "check_failed"); pass nil to skip telemetry.

func (*Poller) Run added in v0.22.9

func (p *Poller) Run(ctx context.Context)

Run blocks until ctx cancels, ticking once per Interval. The first check fires immediately so a fresh daemon catches an already-pending update without waiting an hour.

type PollerConfig added in v0.22.9

type PollerConfig struct {
	// Interval between checks. Default 1h. Tests pass 50ms.
	Interval time.Duration
	// Timeout per HTTP round-trip. Default 5s.
	Timeout time.Duration
	// Now overrides time.Now for deterministic testing of
	// transitions. Production passes nil.
	Now func() time.Time
}

PollerConfig overrides the defaults — useful for tests that need a tighter tick. Empty struct = production defaults.

type PublishFn added in v0.22.9

type PublishFn func(kind, severity, title, body, actionHint string)

PublishFn is the slim function shape the poller needs from the caller. server.go wraps biam.WatchHub.BroadcastSystem; tests pass a recorder closure. Keeping this as a function instead of an interface avoids dragging biam into the version package's import graph (version stays a leaf).

type UpdateInfo added in v0.9.0

type UpdateInfo struct {
	// HasUpdate is true when the upstream tag is newer than the
	// local build. Defaults to false on any error so we never nag
	// the user about a non-confirmed update.
	HasUpdate bool

	// Latest is the tag string from GitHub (e.g. "v0.10.0"). Empty
	// on error.
	Latest string

	// Current is the local build version (Version package var).
	Current string

	// FetchedAt is when we last asked GitHub. Surfaced so the user
	// knows how stale the answer is. UTC.
	FetchedAt time.Time

	// Err is non-nil when the check itself failed (network, parse,
	// rate-limit). Callers display "could not check" instead of
	// pretending no update exists.
	Err error
}

UpdateInfo is the result a caller surfaces in the UI.

func CheckForUpdate added in v0.9.0

func CheckForUpdate(ctx context.Context) UpdateInfo

CheckForUpdate is the entry point. Returns the cached result when fresh; otherwise hits the API, persists, returns. Never blocks longer than the HTTP client's timeout.

Jump to

Keyboard shortcuts

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