# How PAI's Status Line Indicates Learning Signals and Context Utilization

> Discover how PAI's status line shows learning signals via user feedback counts and context utilization through a real-time token window percentage. Learn more now!

- Repository: [Daniel Miessler 🛡️/Personal_AI_Infrastructure](https://github.com/danielmiessler/personal_ai_infrastructure)
- Tags: deep-dive
- Published: 2026-02-16

---

**PAI's status line displays learning signals as a count of user feedback entries (📈 27) and context utilization as a gradient bar showing percentage of Claude Code's token window consumed, updated in real-time via the [`statusline-command.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/statusline-command.sh) script.**

The Personal AI Infrastructure (PAI) repository by Daniel Miessler provides a dynamic status line that gives users immediate visibility into two critical metrics: how much the system has learned from user feedback (learning signals) and how much of the available AI context window is currently in use. This article explains the technical implementation behind these indicators, referencing the actual source files and data flows within the `danielmiessler/Personal_AI_Infrastructure` codebase.

## Overview of the PAI Status Line Architecture

The status line is generated by the bash script [`statusline-command.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/statusline-command.sh), which Claude Code invokes every time the UI refreshes its bottom bar. The integration point is defined in [`settings.json`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/settings.json) under the `"statusLine"` configuration key. The script aggregates data from three distinct sources: the **Counts cache** (for learning signals), the **Claude Code JSON payload** (for context utilization), and various system helpers (for location, weather, and branding).

## How Learning Signals Are Tracked and Displayed

Learning signals represent quantified user feedback—ratings, corrections, and explicit training inputs—that the system collects to improve future responses. The status line surfaces this as a simple count prefixed with a chart emoji.

### Data Source: GetCounts.ts and the Signals Cache

The raw signal count originates in [`Tools/GetCounts.ts`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/Tools/GetCounts.ts), which aggregates statistics from PAI's memory system and writes them to [`MEMORY/STATE/counts.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/MEMORY/STATE/counts.sh) as a JSON cache. The status line script reads this file and extracts the `.counts.signals` field using `jq`.

```bash

# From statusline-command.sh (v3.0)

learnings_count=$(jq -r '.counts.signals // 0' "$PAI_DIR/MEMORY/STATE/counts.sh")

```

This logic appears around lines 302–315 of the script, ensuring that if no signals exist, the count defaults to zero rather than null.

### Rendering the Learning Indicator

Once extracted, the count is formatted with a non-breaking space and emoji to prevent UI truncation:

```bash
echo "📈 ${learnings_count}"

```

In the final status line output, this appears as `📈 42`, indicating 42 learning signals have been recorded.

## How Context Utilization Is Calculated and Visualized

Context utilization indicates what percentage of Claude Code's available token window is currently occupied by the conversation history, system prompts, and file contents. PAI renders this as both a numeric percentage and a visual gradient bar.

### Extracting Context Metrics from Claude Code

When Claude Code invokes the status line script, it passes a JSON payload via stdin containing a `context_window` object. The script extracts three key fields:

```bash

# Lines 88-92 in statusline-command.sh

context_max=$(jq -r '.context_window.context_window_size // 200000' <<<"$input")
context_pct=$(jq -r '.context_window.used_percentage // 0' <<<"$input")
context_remaining=$(jq -r '.context_window.remaining_percentage // 100' <<<"$input")

```

The script defaults to a 200,000-token window if the field is missing, ensuring robustness across different Claude Code versions.

### Fallback Calculation for Edge Cases

If `used_percentage` reports zero but tokens have actually been transmitted (indicating a payload parsing edge case), the script calculates the percentage manually:

```bash

# Lines 104-106

if [ "$context_pct" = "0" ] && [ "$total_input" -gt 0 ]; then
    context_pct=$((total_tokens * 100 / context_max))
fi

```

This ensures the bar never shows empty when context is actually being consumed.

### The Gradient Bar Visualization

The script converts the percentage into a Unicode block bar using a helper function (around line 667). The bar length adapts to terminal width and uses color coding—typically green for low usage, yellow for medium, and red for high usage—to provide immediate visual feedback.

The final output format is:

```

▉▉▉▉▉▏ 45% | ⧖ 115k/200k (43% remaining)

```

Where:
- `▉▉▉▉▉▏` is the visual bar representing 45% fill
- `⧖ 115k/200k` shows the absolute token count
- `(43% remaining)` confirms the inverse calculation

## Configuration and Integration

To enable the status line, Claude Code's [`settings.json`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/settings.json) must reference the script:

```json
{
  "statusLine": {
    "type": "command",
    "command": "${PAI_DIR}/statusline-command.sh"
  }
}

```

As documented in [`Releases/v2.4/.claude/skills/CORE/USER/STATUSLINE/README.md`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/Releases/v2.4/.claude/skills/CORE/USER/STATUSLINE/README.md), this configuration tells Claude Code to execute the script on every UI refresh, passing the context JSON as stdin.

## Summary

- **Learning signals** are aggregated by [`Tools/GetCounts.ts`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/Tools/GetCounts.ts) and cached in [`MEMORY/STATE/counts.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/MEMORY/STATE/counts.sh); the status line displays them as `📈 <count>` after parsing with `jq`.
- **Context utilization** is extracted from Claude Code's JSON payload (`context_window.used_percentage`) with a fallback calculation using total tokens divided by window size.
- **Visualization** combines a Unicode gradient bar, percentage text, and absolute token counts (`⧖ used/max`) to provide immediate visual feedback on resource consumption.
- The entire system is orchestrated by [`statusline-command.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/statusline-command.sh), invoked via [`settings.json`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/settings.json) on every Claude Code UI refresh.

## Frequently Asked Questions

### How does PAI count learning signals?

PAI counts learning signals by aggregating user feedback entries stored in its memory system. The [`Tools/GetCounts.ts`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/Tools/GetCounts.ts) script traverses the feedback database and writes the total count to `.counts.signals` in the JSON cache at [`MEMORY/STATE/counts.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/MEMORY/STATE/counts.sh). The status line script reads this value using `jq` and renders it as `📈 <number>`.

### What happens if Claude Code doesn't report context usage percentages?

If the Claude Code JSON payload lacks the `used_percentage` field or reports it as zero while tokens are present, [`statusline-command.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/statusline-command.sh) executes a fallback calculation. It multiplies the total token count by 100 and divides by the context window size (defaulting to 200,000 tokens), ensuring the status bar never displays empty utilization when context is actually being consumed.

### Can I customize how the learning signals or context bar appear?

Yes, you can customize the display by creating a wrapper script that sources [`statusline-command.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/statusline-command.sh) and overrides the output formatting. For example, you could modify the `echo` statements that produce the `📈` emoji or the Unicode bar characters. After creating your custom script, update [`settings.json`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/settings.json) to point the `"statusLine.command"` field to your new file path.

### Where is the context utilization data actually calculated?

The primary context utilization percentage is calculated by Claude Code itself and passed to the status line script via stdin in the `context_window.used_percentage` field. However, the script [`statusline-command.sh`](https://github.com/danielmiessler/Personal_AI_Infrastructure/blob/main/statusline-command.sh) performs validation and fallback calculations (lines 88–106 in v3.0) to ensure accuracy, reading the raw token counts from the same JSON payload and computing percentages locally when necessary.