---
title: Context Details (see what's filling the agent's context window)
---

# Context Details (see what's filling the agent's context window)

## What it is

Every Claude session has a finite **context window** — the running tally of tokens the agent currently "sees" (system prompt, tool definitions, prior messages, MCP server outputs, attached docs, memory entries, etc.). When that window fills up, the agent loses headroom for new conversation. **Context Details** is a popover that breaks down exactly what's consuming the window right now and how much room is left, so you can decide whether to keep going, `/clear`, start a new session, or trim what's loaded.

The breakdown shows:

- A **summary row** with `used / max` tokens plus the categories that contribute to the used total, biggest-first (e.g. "System prompt 12,234", "MCP tools 8,901", "Conversation 24,156"), an autocompact-buffer line, and free-space remaining.
- A list of **expandable sections** — one per CLI-side source (system prompt, MCP servers, skills, memory, custom agents, etc.). Each section header shows the section name, its total tokens, and a chevron; expanding reveals the per-item rows underneath (individual tool names, memory entries, skill files) with their token counts.
- A **refresh** button (top-right of the header) re-queries the live CLI so you can watch the breakdown move after a long tool call or a `/clear`.

The popover is a real WAI-ARIA modal dialog (focus-trapped, Escape closes, outside click closes). It's read-only — you can't trim individual items from inside it; use slash commands like `/clear` in the session for that.

## Where to find it

Context Details is a popover attached to a session, not a page of its own — you reach it from the
session header. There are two entry points, and the three-dot menu one is always there, so you
never need to turn anything on first.

## How it behaves

### How to open it

There are **two surfaces** that open the same popover:

1. **Three-dot menu → "Context Details"** (always available — the canonical entry point). Click the **⋯** kebab in the session header, scroll to the bottom of the menu — the entry is the last item, separated by a divider, with a gauge icon and a small percent badge (e.g. `42%`) so you can see context fullness without even clicking. Selecting it closes the menu and opens the popover anchored to the kebab.
2. **Donut-ring indicator in the session header** (optional, desktop only). Toggle this on at **Settings → Sessions → "Show context indicator in session header"** (off by default). When on, a small 16×16 donut ring appears at the right edge of the session header — the ring's filled arc tracks current context usage. Click the ring to open the same popover, anchored to the ring.

The three-dot entry exists specifically so the popover is reachable even when the donut ring is hidden — historically the only way in was the ring, so users who left the toggle off had no way to drill into the breakdown. The menu item lives at the very bottom of the menu, below the **More** expansion, so it stays in the same place regardless of whether More is open.

### Empty placeholder when there's no live data

The donut ring **always renders** when the toggle is on — even before any `/context` data has arrived. In the no-data case it shows as an empty neutral-grey track ring (no filled arc) with tooltip `"Context usage — no data yet"`. The placeholder serves as visual confirmation that the feature is active; click it and the popover opens with the appropriate empty/unavailable state.

No-data happens whenever the session-usage Map has no entry for the session. The Map is **in-memory only** (populated by live NDJSON from a running CLI process) and is **not DB-hydrated** on Omniscio restart, so paused / ended / archived sessions, and any session right after Omniscio restart, all start without usage data. Live `running` and `starting` sessions populate the Map within seconds of the first NDJSON event from the CLI; the ring's filled arc + color appear at that point.

### Codex sessions — the ring fills, the drill-in stays Claude-only

The donut **ring** now lights up for **Codex** sessions too, not just Claude. It is fed differently: Claude reports context fullness via its `/context` introspection, but Codex exposes no such command, so Omniscio derives the ring from Codex's own per-turn token report — specifically the **most-recent single model call's input size** (`tokenUsage.last`) measured against the GPT-5 input window (272k tokens). Reading only the latest call (not the cumulative-per-thread total, which grows unbounded across turns, and not a per-turn delta, which over-counts because a tool-loop turn makes many calls each re-sending the context) is what keeps a long Codex session from misreading as ">100% full". If Codex doesn't report that per-call figure, the ring **stays empty rather than showing a wrong number** — an empty ring always beats a misleading one. The ring tooltip shows the raw `used / max` tokens, so the number stays auditable.

The **drill-in breakdown popover** (the per-section/per-item list) remains **Claude-only**: it shells out to the Claude CLI's context-introspection command, which a Codex session has no equivalent of. So on a Codex session the ring shows fullness, but clicking it opens the "Unavailable" empty state rather than a category breakdown. Full invariants: [provider-registry-contract.md](../../.claude/memory/contracts/provider-registry-contract.md).

### When the popover shows nothing useful

`CONTEXT_DETAILS_GET` returns `data: null` (which the popover renders as an "Unavailable" empty state) in any of these cases:

- The session is in a **terminal status** (`ended`, `error`, `archived`, `paused`) — there's no live CLI to query.
- The session has **no `cliSessionId` yet** — typically the first few hundred ms before the CLI emits its session-init event.
- The owning **project row was soft-deleted** (rare — the session would normally be gone too).
- The CLI query itself failed (network, CLI crash, etc.) — the popover renders an Error state with a Retry button.

If the session is healthy and the popover is genuinely empty (no sections, no summary), the underlying `claude context` command returned nothing — you'll see the "No context loaded" empty state.

## For agents

### Data shape

The popover is fed by `IPC.CONTEXT_DETAILS_GET` (handler in `src/main/ipc/context-handlers.ts`), which calls `queryContextDetails(cliSessionId, workingDir, accountId?)` from `src/main/services/context-query.ts` (the middle argument is the session's working directory, not a project-folder path). That service shells out to the Claude CLI's context-introspection command and parses the result into:

```ts
interface ContextBreakdown {
  summary: ContextSummary | null
  sections: ContextSection[]
  skillsFrontmatterTotal: number | null // always-on per-skill frontmatter token cost; null when unavailable
}

interface ContextSummary {
  used: number // sum of all category rows (excludes autocompact + free)
  reserved: number // autocompact buffer
  free: number // remaining headroom
  categories: Array<{ name: string; tokens: number }> // biggest-first
  maxTokens: number // nominal capacity
}

interface ContextSection {
  name: string
  command: string | null // slash command to manage this section, if any
  note: string | null
  totalTokens: number | null
  items: ContextItem[]
}

interface ContextItem {
  name: string
  tokens: number | null
  group: string | null
}
```

The "percent" shown on the **Context Details** menu badge is the same value the donut ring draws — it comes from `sessionUsage.contextInfo.percent` on the session-usage push channel, not from the heavier `CONTEXT_DETAILS_GET` call. So opening the menu costs nothing extra; the full breakdown fetch only fires when you click the entry.

### Source files

- `src/renderer/src/features/sessions/ContextDetailsPopover.tsx` — the popover component (focus-trap, escape-close, outside-click, refresh)
- `src/renderer/src/components/ui/ContextBar.tsx` — the optional donut-ring trigger in the session header (renders even with no data — see "Empty placeholder" above)
- `src/renderer/src/features/sessions/SessionOverflowMenu.tsx` — the three-dot menu, including the always-visible **Context Details** entry at the bottom
- `src/main/ipc/context-handlers.ts` — IPC handler that gates on session status and dispatches to the query service
- `src/main/services/context-query.ts` — the CLI shell-out + parser
- `src/shared/types/context-window.ts` — `ContextBreakdown` / `ContextSummary` / `ContextSection` / `ContextItem` types

## Related

The warning you get when a session is getting close to the ceiling — and what Omniscio does about
it — is on the [context warnings](context-warnings.md) page, and the self-healing path for a turn
that runs clean out of room is on [out-of-context stall recovery](context-stall-recovery.md). What
happens to the conversation when it does fill up is described on the
[compaction summary](compaction-summary.md) page. Codex's own differences are on the
[Codex provider](codex-provider.md) page.
