Skip to main content

Project Pulse

The activity strip on the empty panel grid: a collapsed peek at your commit rhythm that expands into a heatmap, coach line, summary row and repository health signals.

Reviewed

What Project Pulse is

Project Pulse reads your local git log and turns it into a picture of how the project has been moving. It lives on the empty panel grid (the canvas you see when the active worktree has no panels open), and it is, by default, one quiet line rather than a dashboard.

The heatmap itself is entirely local: commit history is read with git log and never leaves your machine. The repository health chips at the bottom of the expanded card are the one part that talks to a forge, and only when one is connected.

The strip

What appears on the empty grid is a collapsed one-line strip: an activity icon, the label Project pulse, an 18-cell mini ribbon of recent days, then your active-day count and, if you have one, a streak flame with its day count.

It leads with active days, not commits. The strip's accessible name reads "Show project activity: 47 active days, 6 day streak", and before any pulse has been fetched it reads simply View activity.

The strip populates itself on load rather than waiting for you to open it, so the peek is there from the first frame. That fetch is a bounded git-log scan, deduped while in flight and cheap on repeat behind a short cache.

Expanding it

Clicking the strip expands the full card in place; a Collapse button below it closes the card again. Expansion is deliberately ephemeral: it resets to collapsed every time the empty grid mounts. Pulse is designed as something you click to peek at, never a permanent dashboard competing with the launcher above it.

Expanding kicks a fresh fetch, so the card opens on a skeleton rather than a blank frame and the peek reflects the latest activity when it collapses again.

The card

The expanded card is titled <Project name> Project Pulse and stacks, top to bottom: the heatmap, its legend, the coach line, the repository health row, and the summary row with an Updated <relative time> control that doubles as the manual refresh.

Activity heatmap

The heatmap renders commit history as a grid of one-day cells, oldest to newest. There are five levels: one empty level for no commits, plus four heat levels for increasing commit density.

A radiogroup in the card header, labelled Activity range, offers 60 days (default), 120 days and 180 days. It's a global preference, not per worktree. Days before the repository's first commit are filtered out, so the grid starts where the project does. The most recent day with commits carries a subtle neutral ring (text-tinted, not accent) to help you orient. Hovering any cell gives the date and either the commit count or No commits.

Below the heatmap sits a legend: Less, five swatches spanning the exact fills the cells use, and More. The swatches route through the same function the cells do, so a theme that omits the opaque heat stops still gets a legend that covers the range actually on screen. Under forced-colors mode both cells and swatches fall back to size-graded shapes rather than color.

Note

A day with no commits is just quiet. Every zero cell renders and reads identically, whatever its neighbors did, and its tooltip is simply No commits. The heatmap has no way to express failure, and a regression test keeps it that way.

Coach line

One sentence sits under the legend. It is framed around what landed rather than how many commits you made: a commit count in Daintree mostly measures how busy the agents were, while a merged change is the outcome you actually care about.

Four branches, in evaluation order:

WhenWhat it says
Merged changes in the selected range"7 changes landed in the last 60 days." (the range follows the toggle: 60, 120 or 180)
At least one commit today"There's activity today."
Activity within the last seven days"There's been activity in the last seven days."
Neither"It's been quiet lately."

The design constraint is explicit in the source: the coach line states what happened. Never asks for anything, never praises, and never frames a quiet stretch as a shortfall. No branch here can express failure, and a test bans a list of words (streak, missed, keep, maintain, must, should, need to, make, ship, win, momentum, nice, tiny) from ever appearing in the copy.

The wording is provider-neutral on purpose: "change" and "landed", not "pull request" and "shipped". A merge means it reached the base branch, not that it reached anyone's machine.

Only a positive merge count is claimed, because zero is ambiguous: a forge can zero-fill when its velocity query fails. The coach line and the health chips are filtered through one shared check, so they can never disagree about whether forge data is usable.

Summary row

  • Commits in the selected range.
  • Active days, as a ratio: 47/312 active days. The denominator is the project's age in days, not the selected range.
  • Streak, with a flame and day count, when it is longer than one day.
  • Uncommitted files with insertion and deletion counts, when the working tree is dirty.
  • Branch delta against the base branch (ahead, behind, files changed, insertions and deletions) on a non-default branch.

Streak

The streak counts consecutive days with at least one commit, computed over the project's full commit history rather than the selected range. (It is capped at 50,000 commits, so a very high-volume repository can undercount.) The flame's color shifts through seven tiers as the streak grows:

DaysTier color
1–7Amber
8–14Light orange
15–29Orange
30–59Red
60–119Deep red
120–239Fuchsia
240+Violet

All seven stops are theme-overridable tokens with the ramp above baked in as fallbacks, so a theme that never authors them renders exactly this. The flame is a static icon: there is no milestone animation and no celebration state.

Tip

The streak is a nudge, not a target. It tracks your natural rhythm and is visible only to you. If the gamification isn't your thing, turning Project Pulse off removes the streak along with the rest of it.

Repository health

When the project has a connected remote, a row of chips renders under the coach line. The data comes from the Code Forge layer and is provider-neutral:

  • CI status: success, failure, pending, or none configured. Links to the workflow runs.
  • Open issues count.
  • Open pull requests count.
  • Latest release tag, with relative publish time.
  • Security alerts count, when the provider exposes them and there are any.
  • Merged in range: 7 merged (60d), matching whatever range the heatmap is showing.

Each chip opens the corresponding page in your browser. Where health is unavailable, the row swaps in one of two hints rather than collapsing: Connect a git remote for CI status, issues, and PRs when there is no remote, and Offline: repository status unavailable when there is one but it can't be reached.

Loading, empty and error states

While fetching, the card shows a skeleton at the same height as the loaded card, so nothing below it shifts. A repository with no commits yet reads "New repository: make your first commit to start tracking activity". On failure the card shows the error with a Retry now control and, while automatic retries are in flight, a Retrying (n/3) status line. The Updated <relative time> control in the summary row refetches both the heatmap and the health signals on demand.

Settings and gating

Pulse is on by default. Turn it off at Settings > General > Display, under Project pulse ("Show activity heatmap on the empty panel grid").

Three conditions all have to hold for the strip to appear, which is worth knowing when it doesn't:

  • The setting is on.
  • The project has a launchable agent. A project with none shows no Pulse regardless of the setting.
  • There is an active worktree. A lightweight (non-git) workspace has none, so its empty grid never carries Pulse at all.