Skip to content

Sessions (bnerd sessions)

bnerd sessions lists, inspects, and deletes saved AI chat sessions from the global session store at ~/.bnerd/sessions/<id>/. The TUI (bnerd x / bnerd pa) and bnerd web both save into and restore from this same store, so a session started in one surface shows up here regardless of which surface created it.

Each session is a directory holding:

  • meta.json — identity and bookkeeping (profile, working directory, title, message/token counters, timestamps)
  • history.json — the full conversation history, in the form the AI backend needs to resume it
  • ui.json — surface-owned transcript state

Sessions form a tree: a session may have a parent_id. A successful sub_agent, explore_agent, or kube_agent run inside a conversation is recorded as a child session of that conversation, under the profile name sub-agent, explore-agent, or kube-agent respectively — so a research run the AI spun off is not just a summary in the transcript, it's a session of its own you can inspect. Listing shows only root sessions, so these children never clutter bnerd sessions list — including under --all. To see one conversation's subagent runs, ask for them by parent:

bnerd sessions list --children 20260826-181500-a1b2c3

When recording starts

Child-session recording needs the conversation to already have a session identity in the store. In the TUI that happens on the first exit-save; in bnerd web it happens once the session exists (your first message). A sub_agent/explore_agent/kube_agent call that completes before either happens simply isn't recorded — same as the conversation itself.

Agent-team teammates

A teammate in an agent team — spawned via bnerd team run, bnerd web, or a chat-driven team in the TUI — is also recorded as a child session of the launching conversation, alongside any subagent runs. The profile is the teammate's role slug (e.g. code-reviewer), and the title is teammate: <name>:

bnerd sessions list --children 20260826-181500-a1b2c3
ID                       PROFILE        TITLE                  UPDATED           MSGS  TOKENS
20260826-181812-77bd0e   explore-agent  Find the callers       2026-08-26 18:18  6     2100/700
20260826-182200-4f11ab   code-reviewer  teammate: reviewer-1   2026-08-26 18:30  22    9800/4200

The child record is created on the teammate's first history flush and updated on every later one — including the interrupted flush a team's exit grace runs on quit (see The bnerd team CLI → Exit behavior) — so it's current even for a team that never got to team_finish. One teammate is one record: interrupting and resuming the same team repeatedly keeps updating it rather than adding a row per cycle.

A TUI-launched team adds one more child alongside its teammates, titled teammate: lead under the profile lead. That is the team-level record — paused/resumed/finished, each teammate's completion line with its tool and token counts, stops, and gate mismatches — written when the TUI exits with the team still live. It is not an agent session; nothing was ever sent to a model for it.

This is separate from the team engine's own operational state (~/.bnerd/teams/<team-id>/ — task board, mailbox, lease, and the same teammate histories in the shape team.TeamStore needs to resume or inspect a live run). The two stores serve different purposes and are not kept in sync beyond that shared history snapshot: deleting the conversation (below) cascades over the child session record, but never touches the team's own state directory.

List sessions

bnerd sessions list

By default this lists sessions for the current working directory. Use --all to see every saved session, or narrow with --profile / --workdir:

bnerd sessions list --all
bnerd sessions list --profile pa
bnerd sessions list --workdir /home/bernd/projects/src/git.bnerd.net/cloud/app/cli

Output:

ID                       PROFILE  TITLE                  UPDATED           MSGS  TOKENS
20260826-181500-a1b2c3   chat     Rotate DNS records      2026-08-26 18:15  12    3400/1800
20260825-093012-9f4e21   pa       Slack triage            2026-08-25 09:30  4     900/450

A conversation's subagent runs and teammates

--children <id> lists the child sessions of one parent — the sub_agent/explore_agent/kube_agent runs recorded inside that conversation, plus any agent team teammates it launched (see Agent-team teammates above). Children are never roots, so this is the only listing that reaches them; the other filters don't apply to it.

bnerd sessions list --children 20260826-181500-a1b2c3
ID                       PROFILE        TITLE              UPDATED           MSGS  TOKENS
20260826-181812-77bd0e   explore-agent  Find the callers   2026-08-26 18:18  6     2100/700
20260826-182044-3c9a11   sub-agent      Check the migration 2026-08-26 18:20  4     1500/500

Pass a child's ID to bnerd sessions show to inspect it like any other session.

Show a session

bnerd sessions show 20260826-181500-a1b2c3

Prints the session's meta.json as formatted JSON — profile, working directory, provider/model, timestamps, and message/token counters.

Delete a session

bnerd sessions delete 20260826-181500-a1b2c3

Prompts for confirmation before deleting. Use --yes to skip the prompt (for scripting):

bnerd sessions delete 20260826-181500-a1b2c3 --yes

Deleting cascades to child sessions — but not to a team's own state

Deleting a session also deletes every session that has it as a parent (parent_id) — including the sub-agent/explore-agent/kube-agent and teammate child sessions described above, recursively. Deleting a root session removes its whole research history with it; there's no way to delete just the parent and orphan the children. This cascade is scoped to the global session store only: an agent team's own operational state (~/.bnerd/teams/<team-id>/ — task board, mailbox, lease, teammate histories) lives in a wholly separate tree and is never touched by it, even when the teammate child session it mirrors is deleted.

See also