Usage Analytics
dot usage records local-first analytics for the dot CLI so you can see which features are actually used, split human from agent from automated calls, and decide whether a feature earns its keep. Its optional history backfill can also observe selected standalone CLI invocations without requiring those projects to integrate with dotfiles.
Recording stays local: each dispatched dot command appends one NDJSON event under $XDG_STATE_HOME/tool-usage. Live events store the timestamp, machine, canonical subcommand path, recognised flag names, exit status, duration, source, and invoker. They do not store positional values such as paths, ids, or note text. Help and unresolved invocations exit before the recording hook.
How it works
Section titled “How it works”dot installs a best-effort exit hook that appends one event when the process exits, capturing the real exit code and duration:
{"ts":"2026-07-08T20:45:30Z","machine":"desktop","tool":"dot","invokedAs":"dot","command":["git-diff"],"flags":["--raw"],"exitCode":0,"durationMs":63,"source":"live","invoker":"human"}Events are written per machine and per day:
$XDG_STATE_HOME/tool-usage/events/<machine>/YYYY-MM-DD.ndjsoninvoker is one of human, agent (an AI coding agent was detected), or automation (a status-bar poll, detected from --bar-json), so Waybar polling does not drown out genuine feature usage.
Reporting
Section titled “Reporting”dot usage summary # per-feature table (last 90 days)dot usage summary --days 30 # narrow the windowdot usage summary --format json # machine-readabledot usage summary --format agent-context # compact, for feeding an agentdot usage stale --days 90 # features not used recently + dot commands never seendot usage path # print the event rootThe summary groups by tool and command, showing total, human, agent, automation, failure count, median duration, and last-seen date.
Backfill from shell history
Section titled “Backfill from shell history”Prefill from existing shell history. Only whitelisted binaries (dot, context, notes, note, handoff, handoffs) are observed, and only from shells that timestamp history (fish and zsh extended history); bash is skipped because its history is undated. This is a dot-owned observation layer: the standalone projects remain independent and do not write dot usage events.
The backfill parser splits history on whitespace and does not interpret shell quoting. dot history entries keep only flags declared by the matched command, but standalone tools have no command-specific flag allowlist. Review the dry run and source history before applying if standalone arguments may include sensitive text beginning with -.
dot usage backfill --history # dry run: counts by tool, writes nothingdot usage backfill --history --apply # write the imported eventsBackfilled events are attributed to human, marked source: "history", and have a null exit code and duration. Re-running is safe: exact history duplicates are removed, and matching history events at or after the first live event for the same machine, tool, command, and flags are suppressed.
Two machines
Section titled “Two machines”Each machine writes its own per-machine files, so nothing conflicts when the directory is synced (Syncthing, a shared folder, or a private repo). Combine roots at read time for summary and stale:
dot usage summary --root ~/synced/other-machine/tool-usage--root does not change where backfill --apply writes; imports always use the local DOT_USAGE_DIR root.
Configuration
Section titled “Configuration”DOT_USAGE_DIR- relocate the event root (default$XDG_STATE_HOME/tool-usage).DOT_USAGE_DISABLE=1- stop automatic live dot recording. Explicitbackfill --applystill writes.OMARCHY_HOST- overrides the machine identifier used to partition event files (falls back to the system hostname).