Skip to content

Instantly share code, notes, and snippets.

@j1cs
Created October 9, 2025 22:58
Show Gist options
  • Save j1cs/744bf16ece7b0a5fd8cf07e1090f3caa to your computer and use it in GitHub Desktop.
Save j1cs/744bf16ece7b0a5fd8cf07e1090f3caa to your computer and use it in GitHub Desktop.

Revisions

  1. j1cs created this gist Oct 9, 2025.
    85 changes: 85 additions & 0 deletions export-copilot-chat.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    #!/usr/bin/env bash
    # export-copilot-chat.sh
    # Interactive script to list and export VSCode Copilot chat sessions to Markdown

    # --- Detect default baseDir depending on OS ---
    detect_default_basedir() {
    case "$(uname -s)" in
    Linux)
    echo "$HOME/.config/Code/User/workspaceStorage"
    ;;
    Darwin)
    echo "$HOME/Library/Application Support/Code/User/workspaceStorage"
    ;;
    CYGWIN* | MINGW* | MSYS*)
    # Windows Git Bash / WSL
    echo "$(wslpath "$(wslvar APPDATA)")/Code/User/workspaceStorage"
    ;;
    *)
    echo "$HOME/.config/Code/User/workspaceStorage"
    ;;
    esac
    }

    # --- Main ---
    baseDir="${1:-$(detect_default_basedir)}"
    keyword="$2"

    if [[ ! -d "$baseDir" ]]; then
    echo "❌ Base directory not found: $baseDir"
    exit 1
    fi

    echo "πŸ“‚ Using base directory: $baseDir"

    # 1. Collect sessions (optionally filter by keyword)
    sessions=$(rg -l --fixed-strings --glob '*.json' "${keyword:-}" "$baseDir"/*/chatSessions 2>/dev/null |
    xargs -I {} jq -rc '
    try (
    {
    sessionId: .sessionId,
    creationDate: (.creationDate | strftime("%F %T")),
    lastMessageDate: (.lastMessageDate | strftime("%F %T")),
    firstRequest: .requests[0].message.text[:120]
    }
    ) catch empty
    ' {} | jq -s 'sort_by(.lastMessageDate)')

    if [[ -z "$sessions" || "$sessions" == "[]" ]]; then
    echo "❌ No sessions found."
    exit 1
    fi

    # 2. Show sessions in a numbered list
    echo "πŸ“‹ Available sessions:"
    echo "$sessions" | jq -r 'to_entries[] | "\(.key+1)) [\(.value.lastMessageDate)] \(.value.sessionId)\n β†’ \(.value.firstRequest)"'

    # 3. Ask user to choose
    echo -n "πŸ‘‰ Enter the number of the session to export: "
    read choice

    sessionId=$(echo "$sessions" | jq -r ".[$((choice - 1))].sessionId")

    if [[ -z "$sessionId" || "$sessionId" == "null" ]]; then
    echo "❌ Invalid selection."
    exit 1
    fi

    # 4. Locate the actual JSON file
    targetSession=$(fd -t f "$sessionId.json" "$baseDir"/*/chatSessions)

    if [[ -z "$targetSession" ]]; then
    echo "❌ Could not find file for session $sessionId"
    exit 1
    fi

    # 5. Export to Markdown
    outFile="chat-$sessionId.md"
    jq -r '
    .requests[]
    | "**Request:**\n" + .message.text
    + "\n\n**Response:**\n" + (.response[0].value // "")
    + "\n\n---\n"
    ' "$targetSession" >"$outFile"

    echo "βœ… Exported to $outFile"