Skip to main content

Built-in Providers

beachcomber ships 19 built-in providers organized by category.

Each provider declares one or more sources — independent units of execution with their own invalidation strategy and lifecycle. The tables below show each provider's source breakdown. Consumers use comb get provider.field as before; the source is selected automatically by the registry's field → source map.

Source breakdown by provider

ProviderSourceStrategyScopeFields
asdftoolsfseventpathtools (object keyed by tool name)
awsprofilepoll 60sglobalprofile, region, source, expiration
batterystatepoll 30sglobalpercent, charging, status, time_remaining_secs (macOS)
batterylevelpoll 30sglobalpercent, charging, status_raw (Linux)
batteryupowerpoll 60sglobaltime_remaining_secs, status (Linux, requires UPower)
condaenvpoll 30sglobalenv
direnvstatefseventpathstatus, allowed
gcloudconfigpoll 60sglobalproject, account
gitrefsfseventpathbranch, commit, tag, ahead, behind, upstream, detached, state, stash
gitdiffpoll 30spathlines_added, lines_removed, lines_staged_added, lines_staged_removed
gitstatusfsevent_pollpathstaged, unstaged, untracked, conflicted, dirty
hostnamehostfsevent (pure-watch global)globalname, short
kubecontextcontextpoll 30sglobalcontext, namespace
loadloadavgpoll 10sglobalone, five, fifteen
miseglobalfsevent (pure-watch global)globalglobal tool versions (one field per tool)
miseprojectfseventpathproject tool versions (one field per tool)
networkinterfacespoll 10sglobalinterface, ip, vpn_active, vpn_name, ssid, online
opvaultpoll 60sglobalsigned_in, account
pythonvenvfseventpathvenv, venv_name, version
sudostatepoll 30sglobalactive
terraformstatefseventpathworkspace
unamesystemfsevent (pure-watch global)globalsysname, release, version, machine
uptimetimepoll 60sglobalseconds, days, hours, minutes
usernamefsevent (pure-watch global)globalname, uid

Pure-watch global sources execute once on first demand and re-execute only when a registered filesystem path changes. They never decay.

fsevent_poll sources watch files for quick invalidation and also poll on a timer as a backstop.

System

ProviderScopeFieldsInvalidationTypical Latency
hostnameglobalname (string), short (string)once at startup400 ns
userglobalname (string), uid (int)once at startup395 ns
loadglobalone (float), five (float), fifteen (float)poll 10s550 ns
uptimeglobalseconds (int), days (int), hours (int), minutes (int)poll 60s660 ns
batteryglobalpercent (int), charging (bool), time_remaining_secs (int), status (string)poll 30s6 ms
networkglobalinterface (string), ip (string), vpn_active (bool), vpn_name (string), ssid (string), online (bool)poll 10s2 ms
sudoglobalactive (bool)poll 30s< 1 µs
opglobalsigned_in (bool), account (string)poll 60svaries

Platform notes:

  • battery: time_remaining_secs is 0 when the platform can't compute an estimate (battery charged, or state unknown). status takes one of charging / discharging / charged / calculating / unknown. On Linux, the numeric estimate requires UPower; without it, status is calculating.
  • network: SSID detection uses nmcli/iw on Linux (vs airport on macOS).
  • uptime: reads /proc/uptime on Linux (vs sysctl on macOS) — transparent to consumers, same fields.

Example output:

// comb g battery
{
"ok": true,
"data": { "percent": 78, "charging": false, "time_remaining_secs": 7200, "status": "discharging" },
"age_ms": 4200
}

// comb g network
{
"ok": true,
"data": {
"interface": "en0",
"ip": "192.168.1.42",
"vpn_active": true,
"vpn_name": "utun2",
"ssid": "OfficeNet",
"online": true
},
"age_ms": 3100
}

// comb g load
{
"ok": true,
"data": { "one": 2.34, "five": 1.87, "fifteen": 1.42 },
"age_ms": 8900
}

Git

ProviderScopeFieldsInvalidationTypical Latency
gitpath24 fields (see table below)watch .git + fallback poll5.6 ms

Fields:

FieldTypeDescription
branchstringCurrent branch name
commitstringShort SHA of HEAD
detachedboolWhether HEAD is detached
upstreamstringUpstream tracking branch (e.g., "origin/main")
tagstringNearest tag (empty if none)
dirtyboolWhether working tree has changes
stagedintNumber of staged files
unstagedintNumber of unstaged modified files
untrackedintNumber of untracked files
conflictedintNumber of conflicted files
aheadintCommits ahead of upstream
behindintCommits behind upstream
stashintNumber of stash entries
lines_addedintLines added in working tree (unstaged)
lines_removedintLines removed in working tree (unstaged)
lines_staged_addedintLines added in index (staged)
lines_staged_removedintLines removed in index (staged)
statestringRepo state: "clean", "merge", "rebase", "cherry-pick", "bisect", "revert"
state_stepintCurrent step in rebase/cherry-pick (0 if not in progress)
state_totalintTotal steps in rebase/cherry-pick (0 if not in progress)
last_commit_age_secsintSeconds since last commit
commit_summarystringFirst line of the HEAD commit message
push_aheadintCommits ahead of the push remote
push_behindintCommits behind the push remote

Example output:

// comb g git .
{
"ok": true,
"data": {
"branch": "feature/fast-cache",
"commit": "a1b2c3d",
"detached": false,
"upstream": "origin/main",
"tag": "v0.3.1",
"dirty": true,
"staged": 3,
"unstaged": 1,
"untracked": 0,
"conflicted": 0,
"ahead": 2,
"behind": 0,
"stash": 1,
"lines_added": 47,
"lines_removed": 12,
"lines_staged_added": 23,
"lines_staged_removed": 5,
"state": "clean",
"state_step": 0,
"state_total": 0,
"last_commit_age_secs": 3420,
"commit_summary": "feat: add synchronous cache miss",
"push_ahead": 2,
"push_behind": 0
},
"age_ms": 234
}

// comb g git.branch . (g = get, text is the default format)
feature/fast-cache

Cloud and DevOps

ProviderScopeFieldsInvalidationTypical Latency
kubecontextglobalcontext (string), namespace (string)poll 30s749 ns
gcloudglobalproject (string), account (string)poll 60s1.08 µs
awsglobalprofile (string), region (string), source (string), expiration (string)poll 60s< 1 µs
terraformpathworkspace (string)watch .terraform< 1 µs

kubecontext reads ~/.kube/config directly (respecting $KUBECONFIG) — no kubectl subprocess. gcloud reads ~/.config/gcloud/properties directly — no Python CLI subprocess.

Example output:

// comb g kubecontext
{
"ok": true,
"data": { "context": "prod-cluster", "namespace": "default" },
"age_ms": 15200
}

// comb g aws
{
"ok": true,
"data": { "profile": "work-prod", "region": "us-east-1", "source": "profile", "expiration": "2026-05-30T12:00:00Z" },
"age_ms": 42100
}

Development Tools

ProviderScopeFieldsInvalidationTypical Latency
pythonpathvenv (bool), venv_name (string), version (string)watch .venv, pyproject.toml< 1 µs
condaglobalenv (string)poll 30s< 1 µs
miseglobal/pathone string field per tool name (e.g. node, rust) — global source (Global scope) and project source (PathScoped)watch .mise.toml, mise.tomlvaries
asdfpathtools (object keyed by tool name)watch .tool-versions< 1 µs
direnvpathstatus (string), allowed (bool)watch .envrcvaries

Example output:

// comb g mise .              (project tools for the current directory)
{
"ok": true,
"data": { "node": "20.11.0", "python": "3.12.1" },
"age_ms": 890
}

// comb g mise (global tools — no path context)
{
"ok": true,
"data": { "rust": "1.75.0" },
"age_ms": 890
}

// comb g python .
{
"ok": true,
"data": { "venv": true, "venv_name": ".venv", "version": "3.12.1" },
"age_ms": 120
}