Conversation history

Every chat message in a card's modal is persisted. This page explains where it lives, what's kept, and what's not.

Storage

Conversations are stored in the local SQLite database, in a conversations table. Columns:

ColumnWhat it is
idMessage UUID
cardIdWhich card the message belongs to
sectionTypedetail / opinion / solution / tests — which tab's chat it belongs to
roleuser / assistant
contentThe rendered message text (HTML)
mentionsJSON array of @skill / @mcp / @card / @document mentions used in the message
toolCallsJSON array of MCP tool calls the agent made during this turn
createdAtISO timestamp

A separate chatSessions table maps (cardId, sectionType) to a CLI session ID so you can resume a chat instead of starting a new one every time.

Per-section scoping

The thread you see when you open the Detail tab is not the same thread as Opinion, Solution, or Tests. Each tab has its own independent conversation history. This is deliberate:

  • It keeps context small — the agent doesn't re-read the plan discussion when you're in the tests tab
  • It lets you hold four parallel conversations about the same card without noise
  • It matches the mental model: "talk about what's on screen"

If you want a conversation that spans sections, put it in Detail. Detail is the default/overview tab, and the agent will pick up the other sections naturally as it reads the card.

What's kept

  • Every user and assistant message, indefinitely
  • Full mentions and toolCalls JSON alongside each message
  • Tool inputs and outputs — so you can audit what an agent did on a card after the fact

Conversations are never auto-cleared or compressed. They grow. For most users this is fine (cards have bounded lifespans), but if a specific card gets a hundred messages across months, the database grows accordingly.

What's not synced

In the Team edition, the local database syncs to Supabase for pool collaboration — but conversations are not part of the sync. Your chat history stays on your machine. A teammate pulling the same card from the pool gets the card state (plan, tests, opinion) but not the thread you had with the agent while writing them.

This is intentional. Conversations are often long, verbose, and personal to the writer. Syncing them would blow up payloads for no shared benefit.

If you need to hand off the thinking, copy the relevant messages into the card body — or use save_plan / save_tests / save_opinion to capture the conclusions in structured form. That's the whole point of those tools.

Accessing conversations outside the modal

There's an API: GET /api/cards/[id]/conversations returns the full thread for a card (all sections). You can use it for:

  • Export before deleting a card
  • Bulk analysis of which tools got called most on which cards
  • Building a custom dashboard on top of local state

There's no built-in export button in the UI today. If you need one, open an issue or build it against the API.

Pruning by hand

If you do need to prune, the conversations table is just SQLite. Open the database, delete rows where createdAt is older than some cutoff, and the next time you open the card the history starts from whatever's left. Don't do this while the app is running — take a backup first.


Prev: Interactive CLI sessions Next: Prompting patterns Up: User guide index

Last updated: 2026-04-13