Skip to content

desktop: /export offers only JSON — expose the Markdown format the TUI already has #55542

Open

Description

@ssearles

Summary

/export offers a Markdown format in the TUI, but the desktop app only offers JSON. Same command, different formats depending on which client you're in.

Current behaviour

In the TUI, /export presents a dialog with two formats — Markdown (human-readable, opens in $EDITOR) and JSON (structured, re-importable). This is described in #48105.

In the desktop app, the command palette describes /export as "Export the full session transcript as JSON", and no Markdown option is offered.

So a user who wants to read a conversation, or paste it somewhere, has to work in the TUI — or open the JSON and convert it by hand. For a long session that JSON is several megabytes.

Related, and deliberately not duplicated here

This is not about the truncation bug. #50014 and #50732 both cover it, and the Markdown export there is built from the UI's loaded window rather than full storage. That is a separate fix with someone already on it, and this request should not compete with that work.

It does affect the desktop app equally — a desktop user exporting a long session gets whatever the TUI produces, truncated or not.

A note on scope, offered as an observation rather than a direction: #50014 and #50732 look like two reports of one underlying cause — the Markdown transcript being assembled from the UI's loaded window instead of from storage, which is presumably why the JSON path is unaffected. Fixing that at the source would close both issues at once. Leaving that decision to whoever is picking them up.

Why I think it belongs in core rather than a plugin

I built a plugin that reads the session store directly and writes Markdown, which sidesteps both the format gap and the truncation. That works, but it means:

  • a second, divergent implementation of session export that will drift from whatever the built-in eventually does
  • users needing an extra dependency to read their own conversations

The desktop Markdown format is a parity gap, not a missing feature — the implementation already exists in this repo.

Proposal

Expose the existing Markdown format in the desktop app's /export, ideally through the same format choice the TUI offers.

If there is a reason the desktop app deliberately ships JSON-only, I'd like to understand it — I couldn't find one in #48105 or elsewhere.

Environment

  • OpenCode 2.0.24 (desktop)
  • Observed on the session list in the desktop app; /export in the command palette is described as JSON

Activity

  1. opencode-agent commented on Oct 14, 2026

    @opencode-agent
    Contributor

    Thanks for the clear write-up, and for keeping it separate from the truncation issue. If I understand it right, you'd like the desktop app's /export to offer the same Markdown format the TUI already has, ideally through the same format choice, instead of only JSON.

    I checked the code: the desktop command is set up as JSON-only, and the Markdown formatting currently lives in the TUI package. I couldn't find a documented reason the desktop leaves it out. Maintainers will consider this as a feature request.

    Related issues:

  2. crxusb-dev commented on Oct 22, 2026

    @crxusb-dev

    I completely agree with this request. I have exactly the same need.

    I use the OpenCode desktop app extensively and want to export my conversations as readable Markdown files for archiving, searching, and reviewing later. Having to use the TUI or manually convert large JSON files is inconvenient.

    Please bring the existing Markdown export functionality to the desktop app, ideally with the same format selection as the TUI. It would also be great if the export could include the complete session history without truncation.

    Thanks for raising this and for working on improving OpenCode!

  3. ssearles commented on Oct 22, 2026

    @ssearles
    Author
  4. ssearles commented on Oct 22, 2026

    @ssearles
    Author
  5. Dante-dan commented on Oct 23, 2026

    @Dante-dan
    Contributor

    I can take this on. I propose a focused first step for desktop /export:

    • Add a Markdown/JSON choice, keeping JSON as the default and preserving its existing export behavior.
    • For Markdown, offer the TUI’s thinking/tool inclusion switches and save a .md file through the existing native save dialog (or browser download fallback).
    • Extract the TUI’s formatSessionTranscript and its small text-only dependencies into a browser-safe shared module, so both clients use the same transcript projection without the app importing TUI code. Preserve the existing TUI output in that extraction.

    The current app path in packages/app/src/session/commands/export.ts already walks message pages; I would keep that data source rather than serialize the visible chat. use-session-commands.tsx currently passes the resulting data straight to the JSON save helper. The TUI formatter lives in packages/tui/src/routes/session/index.tsx and also depends on its local toolDisplayContent helper, so sharing it needs that small extraction rather than a cross-UI import.

    Validation would cover Markdown content and thinking/tool switches, multi-page message ordering, .md filename/content type, save cancellation, and unchanged JSON/TUI output, followed by the relevant package checks and desktop export flow. This stays separate from #50014/#50732 and does not claim to address their truncation behavior.

    Could a maintainer approve this design, particularly keeping JSON as the default and limiting the first change to file export?

  6. magiccodelab commented on Nov 3, 2026

    @magiccodelab

    +1. For AI handoff, a conversation-only preset would be more useful than turning tools/thinking off in the full formatter.

    Suggested preset:

    • include only user and assistant text;
    • exclude reasoning, tool calls and results, shell messages, and system/synthetic notices;
    • keep a small header with the session title, ID, and created/updated timestamps;
    • one Markdown file per session.

    The TUI formatter (packages/tui/src/routes/session/index.tsx:3741) is close, but thinking=false, tools=false still includes shell messages, so this needs either a conversation preset or includeShell / includeNotices options.

    Desktop already pages the entire transcript in fetchSessionExport (not only the loaded portion), so a shared formatter driven by that payload would avoid the loaded-history limitation discussed in #50014 / #50732. Moving the formatter into shared code would also serve the CLI request in #59904.

    Related: #61335 covers saving the export into the remote SSH workspace and exposing the path for copying.

  7. Eldorado-ling commented on Nov 5, 2026

    @Eldorado-ling

    For the conversation-only handoff preset, there is a file-only converter preview for already saved exports in the documented v2 JSON format. It keeps user/assistant text and omits reasoning, tools, shell/system notices and attachment data:

    python scripts/extract_opencode_export.py session.json --out conversation.md

    The conversion needs Python 3.10+ and no running server. It omits the requested title/ID/time header and leaves any secrets in visible text unchanged. This is an interim saved-file workaround; it does not add a desktop export option. Workflow feedback can use a description or invented example rather than raw sessions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions