Gitpulse is a terminal CLI for taking the pulse of development projects. The first implementation focuses on GitHub repositories: it fetches deterministic repository datapoints and presents them as a compact report for developers evaluating whether to contribute to, depend on, compare, or install a project.
Gitpulse is not a replacement for gh. It is a project-health lens: facts first, cautious summaries second, final judgment left to the user.
- Node.js 20 or newer for the published npm CLI.
- Bun 1.3 or newer for development.
- Network access to the GitHub API when cached data is missing or stale.
- Optional:
GITHUB_TOKENfor higher GitHub API rate limits.
For the GitHub pre-release:
git clone https://github.com/shbernal/gitpulse.git
cd gitpulse
bun install
./gitpulse owner/repoAfter the package is published:
npm install -g @shbernal/gitpulseFor local development:
bun installRun from the working tree:
./gitpulse owner/repo
./gitpulse owner/a owner/bOr through Bun:
bun run dev -- owner/repoSingle repository report:
gitpulse cli/cliAfter a repository has appeared in local cache or history, exact bare shorthand is available when it is unambiguous:
gitpulse cli
gitpulse docs cli
gitpulse web cli
gitpulse cli gumBare shorthand is local-only and exact. Gitpulse does not search GitHub for
unknown shorthand, and prefix matching is reserved for shell completion.
Reserved command words such as docs, web, starred, search, history,
cache, config, completions, and user are always treated as commands,
not repository shorthand.
Compare repositories side by side:
gitpulse Jguer/yay Morganamilo/paru
gitpulse OJ/gobuster ffuf/ffufShow documentation signals:
gitpulse docs cli/cliSearch GitHub repositories explicitly:
gitpulse search ripgrep
gitpulse search terminal fuzzy finder
gitpulse search language:rust parser --sort stars
gitpulse search ripgrep --lucky
gitpulse search ripgrep --list
gitpulse search ripgrep --list --jsonShow GitHub user profile signals:
gitpulse user octocatOpen GitHub pages in the browser:
gitpulse web cli/cli
gitpulse user web octocatEmit JSON:
gitpulse cli/cli --json
gitpulse cli/cli charmbracelet/gum --json
gitpulse docs cli/cli --json
gitpulse search ripgrep --list --json
gitpulse user octocat --jsonRefresh and cache controls:
gitpulse cli/cli --refresh
gitpulse cli/cli --offline
gitpulse docs cli/cli --refresh
gitpulse search ripgrep --refresh
gitpulse search ripgrep --offline
gitpulse user octocat --refresh
gitpulse user octocat --offline
gitpulse cli/cli charmbracelet/gum --max-cache-hours 24Manage local files:
gitpulse history
gitpulse cache clear
gitpulse history clear
gitpulse config path
gitpulse config resetGenerate Bash completions:
gitpulse completions bashControl terminal color:
gitpulse cli/cli --color auto
gitpulse cli/cli --color always
gitpulse cli/cli --color never
gitpulse cli/cli --theme tokyo-night
gitpulse cli/cli --theme nordHuman-readable output is the default. Repository reports start with a Repo section that identifies the repository as owner/repo followed by the repository URL on its own muted line, then show explainable composite signals and grouped metric sections. Activity freshness is shown as a score bar; Popularity Score is shown as an open-ended logarithmic score with PU in parentheses. PU means Popularity Units: stars + 8*forks + 5*watchers. Documentation presence is shown through gitpulse docs, not the default repository report. User profile reports show public profile facts and a repository-footprint summary. Comparison reports start with repository descriptions and a scoreboard. Comparison labels use repository names unless owner prefixes are needed to disambiguate matching names.
Gitpulse uses semantic terminal color for repository state, score bands, activity freshness, documentation presence in docs reports, provenance warnings, fetch errors, and common programming languages. Color defaults to --color auto, which enables color for TTY output, disables it for non-TTY output, honors NO_COLOR, and honors FORCE_COLOR. Use --color always to force color or --color never to disable it. Use --theme to choose a terminal palette; supported themes are documented in Terminal Themes.
Repository, docs, user, and comparison reports end with a Data Provenance footer. It discloses fetched/source information first, then any warnings as [warning] lines. Sources show whether each snapshot came from the GitHub API, a fresh cache entry, or stale cache after a failed refresh.
Use --json for scripts and integrations. JSON output is not colorized and includes a stable envelope:
{
"schemaVersion": 5,
"command": "repo",
"source": {
"kind": "cache",
"cachedAt": "2026-05-16T12:00:00.000Z",
"ageHours": 4
},
"result": {
"ok": true
}
}Gitpulse is cache-first by default. It uses a cached snapshot when one exists and is newer than the configured freshness window. If the cache is missing or stale, Gitpulse refreshes from the GitHub API and stores the new snapshot.
gitpulse docs reads from the same repository snapshot cache as gitpulse.
gitpulse docs <repo> --refresh refreshes the full repository snapshot, then
renders only documentation signals.
gitpulse user uses a separate GitHub user profile snapshot cache.
Default config:
{
"cache": {
"enabled": true,
"maxCacheHours": 168,
"staleIfError": true
},
"contributors": {
"fetchLimit": 100
}
}The config file is read from:
${XDG_CONFIG_HOME:-~/.config}/gitpulse/config.json
Snapshots are stored under:
${XDG_CACHE_HOME:-~/.cache}/gitpulse/snapshots/github/
${XDG_CACHE_HOME:-~/.cache}/gitpulse/snapshots/github-users/
Consultation history is appended to:
${XDG_STATE_HOME:-~/.local/state}/gitpulse/history.jsonl
Local repository completion and exact shorthand are derived from the snapshot cache and consultation history. Clearing both local stores removes all shorthand and completion candidates.
Useful overrides:
--refresh: bypass cache reads, fetch from GitHub, and update the cache.--offline: use local cache only, even if stale; fail when no cache entry exists.--max-cache-hours <hours>: overridecache.maxCacheHoursfor one invocation.--contributor-fetch-limit <count>: overridecontributors.fetchLimitfor one repository/report invocation.
A cached snapshot is reused only when it was collected with the same contributor fetch limit, unless --offline is used.
Local file commands:
gitpulse cache clear: remove local cached snapshots.gitpulse history clear: remove the consultation history file.gitpulse config path: print the config file path.gitpulse config reset: create or overwrite the config file with default values.
Gitpulse can print a Bash completion script:
gitpulse completions bashLoad it for the current shell:
eval "$(gitpulse completions bash)"The Bash completion completes top-level and nested Gitpulse commands, shared
flags, --color and --theme values, repository candidates from local
cache/history, and user profile logins from local user profile cache/history.
It includes browser open commands and does not call GitHub while completing.
You do not need a GitHub token for occasional checks against public repositories:
gitpulse cli/cli
gitpulse Jguer/yay Morganamilo/paruGitpulse uses GitHub's unauthenticated public API for refreshes in that case. The tradeoff is that unauthenticated requests have much lower rate limits, and Gitpulse calls several endpoints per repository. For regular use, comparisons, or repeated refreshes, set GITHUB_TOKEN:
export GITHUB_TOKEN=ghp_...Private repositories require a token with access to those repositories. Gitpulse sends the token through Octokit and does not require passing it as a command-line argument.
Phase 1 collects deterministic GitHub API data:
- Repository facts: description, URL, created date, updated date, default branch, primary language, language mix, license, topics, archive/fork/template state, size.
- Adoption signals: stars, forks, watchers, open issues, open pull requests.
- Activity signals: latest push, latest default-branch commit, total default-branch commits, latest release, release count.
- Documentation signals for
gitpulse docs: README, changelog, contributing guide, code of conduct, security policy. - Contributor signals: total contributor count, fetched contributor rows for concentration metrics, top contributor, top contributor share.
- User profile signals for
gitpulse user: public profile facts, account age, follower/following counts, public repo and gist counts, public repository footprint, top repositories, recently pushed repositories, primary languages across fetched public repositories. - Explainable composite signals: activity freshness, Popularity Score.
Watcher counts are sourced from GitHub REST subscribers_count, because GitHub's legacy watchers_count mirrors stargazers_count.
Popularity Score is an open-ended logarithmic score over weighted adoption signals. PU means Popularity Units: stars + 8*forks + 5*watchers. The PU total is shown in parentheses in human-readable output.
Total contributor and total commit counts are inferred from GitHub REST pagination. Contributor collection uses GitHub's anon=true contributor mode so anonymous author identities are included. Contributor concentration metrics use the first contributors.fetchLimit rows returned by GitHub's contributor endpoint, sorted by contribution count.
Composite signals are evidence grouping helpers, not verdicts. The current
formula details are documented in docs/COMPOSITE_METRICS.md.
bun test
bun run typecheck
bun run buildThe npm CLI entrypoint is built from src/bin.ts to dist/cli.js. package.json maps the gitpulse binary to that built Node-compatible file.
Build a standalone executable:
bun run build:bin
install -Dm755 ./dist/gitpulse "$HOME/.local/bin/gitpulse"AGENTS.md: contributor and agent operating guidance.docs/PROJECT_SPEC.md: current product scope, users, signals, and non-goals.docs/DOCS_COMMAND.md: currentgitpulse docsbehavior.docs/COMPOSITE_METRICS.md: current composite metric formulas and caveats.docs/COMPLETIONS.md: shell completion and local shorthand behavior.docs/SEARCH.md: explicit GitHub repository search behavior.docs/STARRED.md: authenticated starred-repository picker behavior.docs/THEMES.md: supported terminal themes and output config.docs/VISUAL_OUTPUT.md: deterministic visual review workflow.docs/next-features/: deferred feature proposals and exploratory notes.