-
-
Notifications
You must be signed in to change notification settings - Fork 7
Statusline
What bastra-recall shows while it works — the persistent statusline segment and the live phrases under a running tool call. Was bastra-recall während der Arbeit anzeigt — das persistente Statusline-Segment und die Live-Phrasen unter einem laufenden Tool-Call.
bastra-recall surfaces its activity in two live channels inside Claude Code:
- the statusline segment — the persistent powerline at the very bottom.
- the progress line — the text under a running tool call (
Calling bastra-recall …).
Package @bastra-recall/statusline (owloops/claude-powerline vendored + a native bastra segment). It reads a per-session feed that the daemon's MCP forwarder writes to ~/.bastra/statusline/<claude-session-pid>.json, and renders one of three states:
| State | Looks like | When |
|---|---|---|
| idle | bastra · 182 memories |
no bastra tool call this turn |
| done (loads only) | ✓ bastra · 2 calls · 12ms · Krame im Gedächtnis … |
tool calls finished, no recall |
| done (with recall) | ✓ bastra · 3 calls · 14 hits · 142ms · Da, bitte. |
a recall ran this turn |
-
calls — every bastra tool call this turn (
recall+load_memory/save_memory/find_document/ …). - hits — recalls only; omitted when 0.
- ms — summed duration of all bastra calls this turn (e.g. two ~6 ms loads → ~12 ms; a recall ~120 ms).
- the trailing phrase persists for ~10 s (TTL), then the banner drops back to the bare stats.
The feed is namespaced by the claude ancestor PID — Claude Code sends no session id to MCP servers (anthropics/claude-code#41836) — so concurrent sessions never clobber each other's counters. The turn boundary is detected via a turn_id the prompt-hook stamps, so recall_count stays correct even across parallel recalls.
Setup (bastra install claude-code wires this for you):
"statusLine": {
"type": "command",
"command": "node …/packages/statusline/dist/index.mjs --style=powerline",
"refreshInterval": 1
}refreshInterval is in seconds, minimum 1.
The "parts" of the statusline are segments, and they can only be changed through a config file (CLI flags / env vars only set theme, style and charset). The first file that exists wins:
-
--config <path>flag, or theCLAUDE_POWERLINE_CONFIGenv var (~is expanded) <projectDir>/.claude-powerline.json<cwd>/.claude-powerline.json-
~/.claude/claude-powerline.json← the usual place for a global config ~/.config/claude-powerline/config.json
The file is deep-merged onto the built-in defaults, so you only list what you want to change. One exception: display.lines is an array — if you set it, it replaces the default lines wholesale, so list every segment you want on that line.
⚠️ display.style/theme/charsetset in the file are overridden by the CLI flag in yourstatusLine.command(--style=…), which has the highest priority. The segments are unaffected — they come only from the file.
Default-on: directory, git, model, weekly, context, agent, bastra.
Default-off: session, today, block, version, tmux, sessionId, metrics, thinking, cacheTimer, env.
Every segment takes enabled: true|false plus its own options:
| Key | Part | Options (beyond enabled) |
|---|---|---|
directory |
working dir | style: basename | fish |
git |
git status | showSha, showWorkingTree, showOperation, showTag, showTimeSinceCommit, showStashCount, showUpstream, showRepoName |
model |
active model | — |
session |
session cost/tokens |
type: tokens | cost | both, costSource, showUnits
|
today |
today's cost |
type: cost | tokens | both | breakdown, showUnits
|
block |
5h billing block | type, burnType, displayStyle |
weekly |
weekly usage | displayStyle |
context |
context usage | showPercentageOnly, displayStyle, autocompactBuffer, percentageMode: remaining | used |
metrics |
turn metrics | showResponseTime, showLastResponseTime, showDuration, showMessageCount, showLinesAdded, showLinesRemoved |
agent |
sub-agent | showLabel |
thinking |
thinking status | showEnabled, showEffort |
cacheTimer |
prompt-cache TTL | displayMode: elapsed | remaining, ttlSeconds |
bastra |
bastra-recall status | — |
version / tmux / sessionId / env
|
misc |
sessionId.showIdLabel, env.variable (required), env.prefix
|
Minimal example — drop the cost segments, show the git SHA, split across two lines:
{
"display": {
"lines": [
{ "segments": {
"directory": { "enabled": true, "style": "basename" },
"git": { "enabled": true, "showSha": true },
"model": { "enabled": true },
"context": { "enabled": true },
"bastra": { "enabled": true }
} },
{ "segments": {
"weekly": { "enabled": true },
"agent": { "enabled": true }
} }
]
}
}Changes apply on the next render (a new prompt) — no rebuild needed. For the full set of themeable colors and display styles see the upstream engine, owloops/claude-powerline.
During a tool call the forwarder sends MCP notifications/progress with a banter phrase; Claude Code renders it under the collapsed tool call, e.g. └ Krame im Gedächtnis … (100%).
-
recall streams one phrase per pipeline stage (
query.parse → bm25.search → vector.search → …), so the line changes as the recall progresses — phrase-first, e.g.Stichwörter durchforsten … · 15ms. -
non-streaming tools (
load_memory,save_memory, …) emit one phrase per call; a series of them shows changing banter. - Requires Claude Code ≥ 2.1.153 — earlier versions did not render MCP progress in the collapsed tool view (anthropics/claude-code#51713).
| env var | values | effect |
|---|---|---|
BASTRA_BANTER |
on (default) · terse · off
|
terse/off → no phrases (statusline falls back to the raw stage name) |
BASTRA_BANTER_LANG |
en (default) · de
|
language of the phrases |
Set these in the MCP server's env block in ~/.claude.json (the forwarder reads them). Phrases live in @bastra-recall/core (recall-banter.ts): per-stage pools for recall, plus per-tool pools for load_memory & co.
- The statusline refreshes at most ~1×/s plus on events, with a hardcoded ~300 ms debounce — enough for the done-banner, not for animating a sub-second recall. The live, changing phrases therefore appear in the progress line, not the statusline; the statusline's job is the persistent per-turn summary.
-
hits/msare entangled only at render time:hitsshow only with a recall,mswhenever any tool ran — so aload_memory-only turn reads2 calls · 12mswith no misleading0 hits.
bastra-recall zeigt seine Aktivität in zwei Live-Kanälen innerhalb von Claude Code:
- das Statusline-Segment — die persistente Powerline ganz unten.
- die Progress-Zeile — der Text unter einem laufenden Tool-Call (
Calling bastra-recall …).
Paket @bastra-recall/statusline (owloops/claude-powerline vendored + ein natives bastra-Segment). Es liest einen Per-Session-Feed, den der MCP-Forwarder des Daemons nach ~/.bastra/statusline/<claude-session-pid>.json schreibt, und rendert einen von drei Zuständen:
| Zustand | Sieht so aus | Wann |
|---|---|---|
| idle | bastra · 182 memories |
kein bastra-Tool-Call in diesem Turn |
| done (nur Loads) | ✓ bastra · 2 calls · 12ms · Krame im Gedächtnis … |
Tool-Calls fertig, kein recall |
| done (mit recall) | ✓ bastra · 3 calls · 14 hits · 142ms · Da, bitte. |
ein recall lief in diesem Turn |
-
calls — jeder bastra-Tool-Call dieses Turns (
recall+load_memory/save_memory/find_document/ …). - hits — nur recalls; bei 0 weggelassen.
- ms — Summe der Dauern aller bastra-Calls dieses Turns (z. B. zwei ~6 ms-Loads → ~12 ms; ein recall ~120 ms).
- die abschließende Phrase bleibt ~10 s stehen (TTL), danach fällt der Banner auf die nackten Stats zurück.
Der Feed wird über die claude-Vorfahren-PID namespaced — Claude Code sendet keine Session-ID an MCP-Server (anthropics/claude-code#41836) — sodass parallele Sessions sich nicht gegenseitig die Zähler überschreiben. Die Turn-Grenze wird über eine turn_id erkannt, die der Prompt-Hook stempelt; so bleibt recall_count auch bei parallelen Recalls korrekt.
Einrichtung (bastra install claude-code erledigt das für dich):
"statusLine": {
"type": "command",
"command": "node …/packages/statusline/dist/index.mjs --style=powerline",
"refreshInterval": 1
}refreshInterval ist in Sekunden, Minimum 1.
Die „Parts" der Statusline sind Segmente, und die lassen sich nur über eine Config-Datei anpassen (CLI-Flags / Env-Variablen setzen nur Theme, Style und Charset). Die erste existierende Datei gewinnt:
-
--config <pfad>-Flag oder die Env-VariableCLAUDE_POWERLINE_CONFIG(~wird expandiert) <projektDir>/.claude-powerline.json<cwd>/.claude-powerline.json-
~/.claude/claude-powerline.json← der übliche Ort für eine globale Config ~/.config/claude-powerline/config.json
Die Datei wird per Deep-Merge über die eingebauten Defaults gelegt — du gibst also nur an, was du ändern willst. Eine Ausnahme: display.lines ist ein Array — wenn du es setzt, ersetzt es die Default-Zeilen komplett; liste also jedes Segment auf, das auf dieser Zeile erscheinen soll.
⚠️ display.style/theme/charsetaus der Datei werden vom CLI-Flag in deinemstatusLine.command(--style=…) übersteuert, das die höchste Priorität hat. Die Segmente sind davon nicht betroffen — die kommen ausschließlich aus der Datei.
Standardmäßig an: directory, git, model, weekly, context, agent, bastra.
Standardmäßig aus: session, today, block, version, tmux, sessionId, metrics, thinking, cacheTimer, env.
Jedes Segment nimmt enabled: true|false plus eigene Optionen:
| Key | Part | Optionen (über enabled hinaus) |
|---|---|---|
directory |
Arbeitsverzeichnis | style: basename | fish |
git |
Git-Status | showSha, showWorkingTree, showOperation, showTag, showTimeSinceCommit, showStashCount, showUpstream, showRepoName |
model |
aktives Modell | — |
session |
Session-Kosten/Tokens |
type: tokens | cost | both, costSource, showUnits
|
today |
Tageskosten |
type: cost | tokens | both | breakdown, showUnits
|
block |
5h-Abrechnungsblock | type, burnType, displayStyle |
weekly |
Wochenverbrauch | displayStyle |
context |
Kontext-Auslastung | showPercentageOnly, displayStyle, autocompactBuffer, percentageMode: remaining | used |
metrics |
Turn-Metriken | showResponseTime, showLastResponseTime, showDuration, showMessageCount, showLinesAdded, showLinesRemoved |
agent |
Sub-Agent | showLabel |
thinking |
Thinking-Status | showEnabled, showEffort |
cacheTimer |
Prompt-Cache-TTL | displayMode: elapsed | remaining, ttlSeconds |
bastra |
bastra-recall-Status | — |
version / tmux / sessionId / env
|
div. |
sessionId.showIdLabel, env.variable (Pflicht), env.prefix
|
Minimal-Beispiel — Kosten-Segmente raus, Git-SHA zeigen, auf zwei Zeilen aufgeteilt:
{
"display": {
"lines": [
{ "segments": {
"directory": { "enabled": true, "style": "basename" },
"git": { "enabled": true, "showSha": true },
"model": { "enabled": true },
"context": { "enabled": true },
"bastra": { "enabled": true }
} },
{ "segments": {
"weekly": { "enabled": true },
"agent": { "enabled": true }
} }
]
}
}Änderungen greifen beim nächsten Render (neuer Prompt) — kein Rebuild nötig. Für die komplette Palette an Theme-Farben und Display-Styles siehe die Upstream-Engine, owloops/claude-powerline.
Während eines Tool-Calls sendet der Forwarder MCP-notifications/progress mit einer Banter-Phrase; Claude Code rendert sie unter dem collapsed Tool-Call, z. B. └ Krame im Gedächtnis … (100%).
-
recall streamt eine Phrase pro Pipeline-Stage (
query.parse → bm25.search → vector.search → …), die Zeile wechselt also mit dem Recall-Fortschritt — Phrase zuerst, z. B.Stichwörter durchforsten … · 15ms. -
nicht-streamende Tools (
load_memory,save_memory, …) feuern eine Phrase pro Call; eine Serie zeigt wechselnde Banter. - Benötigt Claude Code ≥ 2.1.153 — frühere Versionen rendern MCP-Progress nicht im collapsed Tool-View (anthropics/claude-code#51713).
| env-Variable | Werte | Wirkung |
|---|---|---|
BASTRA_BANTER |
on (Default) · terse · off
|
terse/off → keine Phrasen (Statusline fällt auf den rohen Stage-Namen zurück) |
BASTRA_BANTER_LANG |
en (Default) · de
|
Sprache der Phrasen |
Im env-Block des MCP-Servers in ~/.claude.json setzen (der Forwarder liest sie). Die Phrasen liegen in @bastra-recall/core (recall-banter.ts): Pro-Stage-Pools für recall plus Pro-Tool-Pools für load_memory & Co.
- Die Statusline rendert höchstens ~1×/s plus bei Events, mit einem hartcodierten ~300 ms-Debounce — genug für den Done-Banner, nicht für eine Animation eines Sub-Sekunden-Recalls. Die lebendigen, wechselnden Phrasen erscheinen deshalb in der Progress-Zeile, nicht in der Statusline; die Statusline liefert die persistente Pro-Turn-Zusammenfassung.
-
hits/mssind nur beim Rendern entkoppelt:hitserscheinen nur mit einem recall,mssobald irgendein Tool lief — ein reinerload_memory-Turn liest sich also2 calls · 12msohne irreführende0 hits.
The statusline engine is owloops/claude-powerline, MIT-licensed, vendored into packages/statusline. The upstream license is kept verbatim at packages/statusline/LICENSE:
MIT License — Copyright (c) 2025 Owloops
bastra-recall's own additions (the native bastra segment, the per-session feed, the banter integration) are likewise MIT. Under the MIT terms, using and redistributing the statusline only requires keeping that LICENSE file and its copyright notice intact — which the package and every release tarball already do ("files": ["dist", "bin", "src", "LICENSE"] in package.json, and the engine is credited in the package description). No further obligation applies.
Die Statusline-Engine ist owloops/claude-powerline, MIT-lizenziert, nach packages/statusline vendored. Die Upstream-Lizenz liegt unverändert unter packages/statusline/LICENSE:
MIT License — Copyright (c) 2025 Owloops
Die eigenen Ergänzungen von bastra-recall (das native bastra-Segment, der Per-Session-Feed, die Banter-Integration) sind ebenfalls MIT. Nach den MIT-Bedingungen erfordert Nutzung und Weitergabe der Statusline lediglich, dass diese LICENSE-Datei samt Copyright-Hinweis erhalten bleibt — was Package und jedes Release-Tarball bereits tun ("files": ["dist", "bin", "src", "LICENSE"] in der package.json, und die Engine ist in der Package-description genannt). Keine weitere Pflicht.