Skip to content
/ cp2md Public

Convert GitHub Copilot chat exports to Markdown

License

Notifications You must be signed in to change notification settings

whee/cp2md

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cp2md

Copyright (C) 2025 Brian Hetro whee@smaertness.net

Convert GitHub Copilot chat exports to Markdown.

Highlights

  • Converts GitHub Copilot chat exports (single files or whole directories) to Markdown
  • Shows model, agent, and attached context by default
  • Optional inclusion of tool invocations and timestamps
  • Recurses through directories, processes only JSON exports, and sorts/deduplicates inputs for deterministic output
  • CLI-friendly: cp2md [OPTIONS] -o <OUTPUT> <INPUT>...

Installation

Download a prebuilt binary from GitHub Releases, or build from source:

cargo build --release
./target/release/cp2md --help

Usage

cp2md [OPTIONS] -o <OUTPUT> <INPUT>...

Arguments

  • <INPUT>... - Input JSON files or directories containing exports

Options

  • -o, --output <OUTPUT> - Output directory (or file with --concat, or - for stdout)
  • --concat - Combine all inputs into a single output
  • --heading-offset <N> - Shift heading levels by N (0-5, default: 0)

Notes:

  • Without --concat, -o must point to a directory (or - for stdout) and stdout is only allowed when converting a single input file.
  • With --concat, -o is treated as a single output file (or - for stdout) and is required to combine multiple inputs.

Metadata Display

Use --show-* or --hide-* flags to control what appears in output:

Flag Default Description
--show-timestamps / --hide-timestamps off Timestamps for each message
--show-model / --hide-model on Model identifier (e.g., claude-sonnet-4)
--show-agent / --hide-agent on VS Code agent name (e.g., @workspace)
--show-context / --hide-context on Attached files, selections, folders, and instruction files
--show-tools / --hide-tools off Tool invocations (searches, reads)
--show-edits / --hide-edits off Full code content for file edits

-v, --verbose is an alias for --show-tools.

--compact hides all metadata (model, agent, context, tools, timestamps).

If you pass both show/hide forms for the same field, the last flag wins.

Timestamp Options

When timestamps are enabled (--show-timestamps):

Flag Description
--utc-time Render in UTC (default)
--local-time Render in local timezone
--timestamps-both Render as <local> / <utc>

Other Options

  • -q, --quiet - Suppress progress messages
  • -n, --dry-run - Show what would be processed without writing
  • -f, --force - Overwrite existing output files
  • -h, --help - Print help
  • -V, --version - Print version

Examples

Convert a single chat export:

cp2md chat.json -o output/

Convert all JSON files in a directory:

cp2md ~/copilot-exports/ -o markdown/

Include tool invocations (searches, file reads, etc.):

cp2md chat.json -o output/ --verbose

Minimal output (just messages):

cp2md chat.json -o - --hide-model --hide-agent --hide-context

Preview what would be converted without writing:

cp2md ~/copilot-exports/ -o markdown/ --dry-run

Combine multiple chats into a single file:

cp2md chat1.json chat2.json -o combined.md --concat

Output to stdout (useful for piping):

cp2md chat.json -o - | less

Finding Copilot Exports

Export chat history using the VS Code command palette: Copilot: Export Chat...

Output Format

Each input file foo.json produces foo.md in the output directory. The Markdown includes:

  • Model identifier and agent name in the metadata line (shown by default when present and not hidden)
  • Attached context in a collapsible details block (files, selections, folders, instruction files) when present and not hidden
  • User prompts and assistant responses
  • Timestamps (when --show-timestamps is set)
  • Tool invocations with past-tense messages (when --show-tools / --verbose is set)
  • File modification summaries for edits (with line counts) when a text edit group is present

Headings in user/assistant content are shifted down to prevent them from disrupting document structure. XML-like tags are escaped to render literally.

Example output:

# Copilot Chat

## User

*claude-sonnet-4 · @workspace*

<details>
<summary>📎 Context</summary>

- `main.rs` (file)
- `lib.rs`:10-25 (selection)

</details>

How do I reverse a string in Python?

## Assistant

You can reverse a string using slicing: `[::-1]`

License

This program is free software: you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation.

See LICENSE for the full text.

About

Convert GitHub Copilot chat exports to Markdown

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages