Skip to content

Trail

A conversation produces things that outlive it: pull requests, often in more than one repository, tickets created or moved, a deploy, a page. Today the only record is the chat. Trail keeps it, per conversation, and answers both ways: what did this conversation make? and which conversation made PR #33 — take me there.

Terminal window
opencode plugin @opencode-cockpit/trail@0.9.0 --global --force # OpenCode 1
opencode plugin add @opencode-cockpit/trail@0.9.0 # OpenCode 2

Or through the bundle, where it is on by default (features.trail: false turns it off).

There is nothing to set up. People reach the same systems in different ways — gh, an MCP server, a company CLI — and the agent always knows what it just did. So the agent writes the trail and Cockpit keeps, orders and shows it. Trail has no GitHub or Jira client and stores no credentials.

  • The agent records them with trail_add, right after it creates or changes something outside the repository’s files. Its system prompt says so on every request, subagents included. A subagent’s records belong to the conversation and name the subagent.
  • A safety net, never automatic. A PR or issue link in the output of something the agent ran — a shell command, an MCP call — that it has not recorded is put to it on its next request as a choice: seen in output — record it if you created or changed it. Links in files it read or pages it fetched never count. Nothing is added without the agent or you.
  • You add one with /link, then paste the link, and a note if you like.

The same link again updates its record — the actions become a history, created → updated — and a better title replaces the old one. Which system a thing belongs to comes from its link: GitHub, Jira, Confluence, Claude, Linear, or else its domain. Query parameters that look like secrets are dropped before anything is stored, and only http(s) links are ever opened.

On by default, after Shells. What this conversation made, grouped by the ticket it was for, newest work first: its name, its title, its system, what this conversation last did and when — now, 12m ago, 2h ago. A record with no ref gives its title the ref’s column.

Trail 9
COM-1801
a1b2c3d Bump the pr… 12m ago
ENG-42 Retry the s… Linear 15m ago ↗
COM-1736 Bundle desy… Jira 2h ago ↗
PR #33 0.8: Trust,… GitHub 1h ago ↗
PR #12 Landing: Tr… GitHub 2h ago ↗
+ 4 more · /trail

There is no status — where a PR stands now belongs to GitHub, one click away; a trail that said “open” for a merged PR would be worse than none.

  • A row with ↗ opens the page in your browser.
  • A row without a page opens /trail on it; + N more opens /trail.
  • Empty, the block says none yet; hideWhenEmpty hides it until there is something to show.

/trail, ctrl+x f, or the palette (“cockpit trail”): This conversation and All conversations in the project (tab), grouped the same way. Under a thing several conversations touched, each one is listed — a deleted conversation keeps its records, marked.

key
enteropen the page
ggo to the conversation that made it
ccopy the link
xremove it from the trail
mcopy the trail as a markdown list
/search title, ref, kind and system
escclose
tool
trail_addtitle, and url or ref; optional kind, action, for, note — all free text
trail_listthis conversation’s trail, or with all the project’s and which conversation made each; query filters

trail_list answers with the same facts in the same order as /trail. What the conversation produced is also rebuilt into its system prompt on every request, from the trail itself, so the agent still knows after a long conversation is compacted.

// ~/.config/opencode-cockpit/config.json, or a project's .cockpit.json
{
"trail": { "sidebar": true, "sidebarRows": 5, "hideWhenEmpty": false }
}

enabled and keybinds work as in every bay; the block’s place is the top-level "sidebar" list’s to say. See Configuration.

Optional. A few lines in your AGENTS.md shape what gets recorded — they do not make it happen. /cockpit-setup’s second phase offers your ticket prefix, read from your branch names and commits, and writes it there for you (how); or by hand:

## Trail
- Tickets are Jira keys like COM-1234: pass the PR's ticket as `for`.
- Put the Confluence space in a page's title: "WEB · Release notes 0.8".

One append-only file per project, outside it, under ~/.local/share/opencode-cockpit/trail/. Every window and the agent append to it; nothing is ever rewritten.