mcpField
T
transcript-viewer

transcript-viewer

github.com/rysweetAgent 工作流7667 次安装21 周前更新
代码仓库

关于 transcript-viewer

transcript-viewer 是用于查看 Claude Code 和 GitHub Copilot CLI 会话记录的技能,适合需要回顾当前或历史会话的开发者。它支持按会话、后台 Agent 输出或日期范围浏览,并可将记录呈现为 Markdown 或 HTML。

主要功能

  1. 01自动识别 Claude Code 与 Copilot CLI
  2. 02查看当前或指定会话记录
  3. 03浏览后台 Agent 任务输出
  4. 04按日期范围筛选会话
  5. 05导出为 Markdown 或 HTML

适用场景

  1. 01回顾当前编码会话
  2. 02查找特定 ID 的历史记录
  3. 03检查后台 Agent 任务输出
  4. 04筛选一段日期内的会话

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rysweet/amplihack --skill transcript-viewer

安装后在 Claude Code 中输入/transcript-viewer确认已加载。

附带文件tests/test_transcript_viewer.sh

详细介绍

Transcript Viewer 技能

用途

此技能可转换和浏览来自两种受支持工具的会话记录:

  • Claude Code — 自动保存到 ~/.claude/projects/ 的 JSONL 日志
  • GitHub Copilot CLI — 自动保存到 ~/.copilot/session-state/*/events.jsonl 的 JSONL 日志

它提供四种浏览模式:

  1. 当前会话 — 查看活动会话的记录
  2. 指定会话 — 按会话 ID 查看会话
  3. Agent 输出 — 查看子 Agent 生成的后台任务输出文件
  4. 所有会话 — 浏览项目的所有会话,可按日期范围筛选

工具上下文自动检测

浏览前,检测当前使用的工具,以设置默认日志路径。 优先使用基于目录的检测(比环境变量更可靠);如果目录不存在,则回退到 src/amplihack/hooks/launcher_detector.py 中的环境变量:

# Primary: directory-based detection (most reliable)
if [[ -d "$HOME/.copilot/session-state" ]]; then
  # Check if there are any sessions present
  COPILOT_SESSIONS=$(ls -d "$HOME/.copilot/session-state/"*/ 2>/dev/null | wc -l)
  CLAUDE_SESSIONS=$(ls "$HOME/.claude/projects/"*/*.jsonl 2>/dev/null | wc -l)
  if [[ "$COPILOT_SESSIONS" -gt 0 && "$CLAUDE_SESSIONS" -eq 0 ]]; then
    TOOL_CONTEXT="copilot"
    DEFAULT_LOG_DIR="$HOME/.copilot/session-state"
  elif [[ "$CLAUDE_SESSIONS" -gt 0 ]]; then
    TOOL_CONTEXT="claude-code"
    DEFAULT_LOG_DIR="$HOME/.claude/projects"
  else
    # Both dirs exist but empty — use env vars to decide
    TOOL_CONTEXT="claude-code"
    DEFAULT_LOG_DIR="$HOME/.claude/projects"
  fi
elif [[ -d "$HOME/.claude/projects" ]]; then
  TOOL_CONTEXT="claude-code"
  DEFAULT_LOG_DIR="$HOME/.claude/projects"
# Fallback: env var detection (same vars as launcher_detector.py)
elif [[ -n "${CLAUDE_CODE_SESSION:-}${CLAUDE_SESSION_ID:-}${ANTHROPIC_API_KEY:-}" ]]; then
  TOOL_CONTEXT="claude-code"
  DEFAULT_LOG_DIR="$HOME/.claude/projects"
elif [[ -n "${GITHUB_COPILOT_TOKEN:-}${COPILOT_SESSION:-}" ]]; then
  # Note: GITHUB_TOKEN is intentionally excluded — it's too generic and
  # appears in non-Copilot CI contexts, causing false positives.
  TOOL_CONTEXT="copilot"
  DEFAULT_LOG_DIR="$HOME/.copilot/session-state"
else
  # Default to claude-code — safe fallback (most users)
  TOOL_CONTEXT="claude-code"
  DEFAULT_LOG_DIR="$HOME/.claude/projects"
fi

如果 ~/.copilot/session-state/ 和 ~/.claude/projects/ 都存在会话, 请向用户提供选择:“找到 Claude Code 和 GitHub Copilot CLI 的会话。 您想浏览哪一种?[1] Claude Code [2] GitHub Copilot CLI”

用户始终可以通过指定路径覆盖默认设置。

日志格式自动检测

收到文件路径时,处理前先检测其格式:

detect_log_format() {
  local file="$1"
  if [[ "$file" == *.jsonl ]]; then
    echo "jsonl"
  elif [[ "$file" == *.md ]]; then
    # Check for Copilot /share export signature — specific header only
    # Note: do NOT match on "/share" alone (too generic — appears in docs, READMEs)
    if grep -q "Copilot Session Export\|copilot-session" "$file" 2>/dev/null; then
      echo "copilot-markdown"
    else
      echo "markdown"
    fi
  elif [[ "$file" == *.log ]]; then
    # .log files may be plain text or agent JSONL; check content
    local first_char
    first_char=$(head -c 1 "$file" 2>/dev/null)
    if [[ "$first_char" == "{" ]]; then
      echo "jsonl"
    else
      echo "plain-log"
    fi
  else
    # Inspect first byte for other extensions
    local first_char
    first_char=$(head -c 1 "$file" 2>/dev/null)
    if [[ "$first_char" == "{" ]]; then
      echo "jsonl"
    else
      echo "unknown"
    fi
  fi
}
格式处理方式
jsonl传递给 claude-code-log
copilot-markdown内嵌显示(已是易读的 Markdown)
markdown内嵌显示
unknown发出警告并显示原始内容

工具检测

运行任何命令前,检查 claude-code-log 是否可用:

# Step 1: direct install check
which claude-code-log 2>/dev/null

# Step 2: npx fallback
npx --yes claude-code-log --version 2>/dev/null

将解析出的命令设为 CCL:

if which claude-code-log &>/dev/null; then
  CCL="claude-code-log"
elif npx --yes claude-code-log --version &>/dev/null 2>&1; then
  CCL="npx claude-code-log"
else
  CCL=""
fi
缺少工具 — 优雅处理错误

如果 CCL 为空,显示此消息并停止:

claude-code-log is not installed.

To install it globally:
  npm install -g claude-code-log

Or run without installing (requires npx):
  npx claude-code-log --help

After installing, retry your request.

不要尝试自动安装。

模式

模式 1:当前会话

触发短语:“查看当前记录”、“显示我的当前会话”、“当前日志”

操作:

对于 Claude Code(TOOL_CONTEXT="claude-code"):

  1. 查找 ~/.claude/projects/ 下最近修改的 JSONL 文件:
    ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -1
    
  2. 运行:
    $CCL <path-to-jsonl> --format markdown
    
  3. 内嵌显示 Markdown 输出。

对于 GitHub Copilot CLI(TOOL_CONTEXT="copilot"):

  1. 查找 ~/.copilot/session-state/ 下最近修改的会话目录:
    ls -dt ~/.copilot/session-state/*/ 2>/dev/null | head -1
    
  2. 读取其 events.jsonl:
    LATEST_SESSION=$(ls -dt ~/.copilot/session-state/*/ 2>/dev/null | head -1)
    $CCL "${LATEST_SESSION}events.jsonl" --format markdown
    
  3. 内嵌显示 Markdown 输出。

输出示例:

# Session: 2025-11-23 19:32
**Model**: claude-sonnet-4-6
**Messages**: 42

---

**User**: Fix the authentication bug in login.py
**Assistant**: I'll examine the file...
...
模式 2:按 ID 指定会话

触发短语:“查看会话 ”、“显示记录 ”、“打开日志 ”

操作:

对于 Claude Code(TOOL_CONTEXT="claude-code"):

  1. 搜索与会话 ID 匹配的 JSONL 文件:
    find ~/.claude/projects -name "*.jsonl" | xargs grep -l "<SESSION_ID>" 2>/dev/null | head -1
    
    或者,如果 ID 看起来像文件名片段,则使用:
    ls ~/.claude/projects/*/ | grep "<SESSION_ID>"
    
  2. 运行:
    $CCL <path-to-jsonl> --format markdown
    
  3. 显示输出。如果没有匹配的文件,则报告:
    No session found with ID: <SESSION_ID>
    Available sessions: run "view all sessions" to list them.
    

对于 GitHub Copilot CLI(TOOL_CONTEXT="copilot"):

  1. 会话 ID 是 ~/.copilot/session-state/ 下的目录名。直接检查:
    SESSION_DIR="$HOME/.copilot/session-state/<SESSION_ID>"
    if [[ -d "$SESSION_DIR" ]]; then
      EVENTS_FILE="$SESSION_DIR/events.jsonl"
    fi
    
    如果不知道完整 ID,则搜索部分匹配项:
    ls -d ~/.copilot/session-state/*/ 2>/dev/null | grep "<SESSION_ID>"
    
  2. 运行:
    $CCL "$EVENTS_FILE" --format markdown
    
  3. 显示输出。如果没有匹配的目录,则报告:
    No Copilot session found with ID: <SESSION_ID>
    Available sessions: run "browse all sessions" to list them.
    
模式 3:Agent 后台任务输出

触发短语:“查看 Agent 输出”、“显示后台任务输出”、“Agent 日志”

操作:

  1. 查找后台 Agent 任务创建的 .log 或 .jsonl 文件。这些文件 通常写入当前工作目录或临时路径,名称与 .agent-step-*.log 或类似模式匹配:
    ls -t .agent-step-*.log 2>/dev/null
    ls -t /tmp/*.agent*.log 2>/dev/null
    
  2. 对找到的每个文件,运行 detect_log_format <file> 进行分类:
    • jsonl → 运行 $CCL <file> --format markdown
    • plain-log → 使用 cat 直接显示
  3. 这样可以确保 JSONL 格式的 .log 文件(虽然少见,但有可能出现)得到正确渲染。
  4. 如果未找到 Agent 输出文件:
    No agent background task output files found in the current directory.
    Background agents write their output to files named .agent-step-<ID>.log.
    
模式 4:所有会话(浏览)

触发短语:“浏览所有会话”、“列出对话记录”、“查看所有会话”、 “显示会话历史记录”

操作:

对于 Claude Code(TOOL_CONTEXT="claude-code"):

  1. 列出 ~/.claude/projects/ 下的所有 JSONL 文件:
    find ~/.claude/projects -name "*.jsonl" -printf "%T@ %p\n" 2>/dev/null \
      | sort -rn | awk '{print $2}'
    
  2. 对于每个文件,提取会话日期和第一条用户消息:
    $CCL <file> --format markdown --summary
    # If --summary flag is not supported, just show filename and date
    head -1 <file> | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d.get('timestamp',''))"
    
  3. 打印摘要表格:
    Available Sessions (Claude Code)
    =================================
    #   Date                  Session ID / File
    1   2025-11-23 19:32:36   ~/.claude/projects/foo/abc123.jsonl
    2   2025-11-22 14:10:05   ~/.claude/projects/foo/def456.jsonl
    ...
    
  4. 提供打开特定会话的选项:“输入编号以查看该会话。”

对于 GitHub Copilot CLI(TOOL_CONTEXT="copilot"):

  1. 按修改时间排序,列出 ~/.copilot/session-state/ 下的所有会话目录:
    ls -dt ~/.copilot/session-state/*/ 2>/dev/null
    
  2. 对于每个会话目录,读取其 events.jsonl 以提取时间戳:
    for session_dir in $(ls -dt ~/.copilot/session-state/*/); do
      session_id=$(basename "$session_dir")
      events_file="$session_dir/events.jsonl"
      if [[ -f "$events_file" ]]; then
        timestamp=$(head -1 "$events_file" | python3 -c \
          "import sys,json; d=json.loads(sys.stdin.read()); print(d.get('timestamp',''))" 2>/dev/null)
        echo "$timestamp  $session_id"
      fi
    done
    
  3. 打印摘要表格:
    Available Sessions (GitHub Copilot CLI)
    ========================================
    #   Date                  Session ID
    1   2025-11-23 19:32:36   abc1234567890abcdef1234567890abcd
    2   2025-11-22 14:10:05   def4567890abcdef1234567890abcdef
    ...
    
  4. 提供打开特定会话的选项:“输入编号以查看该会话。”
日期范围筛选

当用户指定日期范围时(例如,“最近 7 天”、“2025-11-01 到 2025-11-30 之间”):

# Filter by modification time (last N days)
find ~/.claude/projects -name "*.jsonl" -mtime -7

# Filter by date range using find -newer
find ~/.claude/projects -name "*.jsonl" \
  -newer /tmp/start_date_ref \
  ! -newer /tmp/end_date_ref

使用 touch -d 创建参考文件:

touch -d "2025-11-01" /tmp/start_date_ref
touch -d "2025-11-30" /tmp/end_date_ref

输出格式

Markdown(默认)

向 claude-code-log 传入 --format markdown。输出会直接显示在对话中。适合在终端或 Claude Code 中快速阅读。

HTML

向 claude-code-log 传入 --format html。将输出写入文件并打开:

$CCL <file> --format html > /tmp/transcript-view.html
open /tmp/transcript-view.html 2>/dev/null \
  || xdg-open /tmp/transcript-view.html 2>/dev/null \
  || echo "HTML saved to /tmp/transcript-view.html — open it in your browser."

用户可以明确要求 HTML:“以 HTML 格式查看对话记录”或“导出为 HTML”。

GitHub Copilot CLI 支持

自动持久化日志

GitHub Copilot CLI 会自动将会话数据保存到磁盘上的:

~/.copilot/session-state/{session-id}/

每个会话目录包含:

  • events.jsonl — JSONL 会话历史记录(格式与 Claude Code 日志类似)
  • workspace.yaml — 会话元数据(工作目录、会话 ID 等)
  • plan.md — 会话的实施计划
  • checkpoints/ — 压缩历史记录(较早的事件快照)

旧版会话也可能位于 ~/.copilot/history-session-state/。

JSONL 格式

Copilot 的 events.jsonl 每行包含一个 JSON 对象,格式与 Claude Code 类似:

{"type":"user","message":{"role":"user","content":[{"type":"text","text":"Fix the bug"}]},"timestamp":"2025-11-23T19:32:36Z","sessionId":"abc1234567890"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"I'll examine the file..."}]},"timestamp":"2025-11-23T19:32:40Z","sessionId":"abc1234567890"}

由于格式兼容,claude-code-log 可以解析这些文件。

查看 Copilot 会话

当用户想要查看 Copilot 会话时(通过目录检测或明确指定路径):

  1. 找到该会话的 events.jsonl:
    # Current session (most recent)
    LATEST_SESSION=$(ls -dt ~/.copilot/session-state/*/ 2>/dev/null | head -1)
    EVENTS_FILE="${LATEST_SESSION}events.jsonl"
    
    # Specific session by ID
    EVENTS_FILE="$HOME/.copilot/session-state/<SESSION_ID>/events.jsonl"
    
  2. 运行:
    $CCL "$EVENTS_FILE" --format markdown
    
  3. 在对话中直接显示输出。
检测可用会话

要检查是否存在 Copilot 会话:

if [[ -d "$HOME/.copilot/session-state" ]]; then
  SESSION_COUNT=$(ls -d "$HOME/.copilot/session-state/"*/ 2>/dev/null | wc -l)
  if [[ "$SESSION_COUNT" -gt 0 ]]; then
    echo "Found $SESSION_COUNT Copilot session(s)"
  fi
fi

完整工作流

用户调用此技能时,遵循以下决策树:

0. Detect tool context (directory-based first, then env var fallback):
   - ~/.copilot/session-state/ exists with sessions → copilot
   - ~/.claude/projects/ exists with sessions       → claude-code
   - Both exist with sessions → offer user a choice
   - Directory detection fails, use env vars:
     - CLAUDE_CODE_SESSION / CLAUDE_SESSION_ID / ANTHROPIC_API_KEY set → claude-code
     - GITHUB_COPILOT_TOKEN / COPILOT_SESSION set → copilot
   - Neither → default to claude-code (safe fallback)

1. Detect CCL (which claude-code-log / npx fallback)
   → If missing: show install instructions and STOP
   → Required for ALL modes (both Claude Code and Copilot use JSONL format)

2. If user provides an explicit file path:
   a. Detect its format (detect_log_format function above)
   b. jsonl or events.jsonl → pass to $CCL
   c. unknown → warn and display raw

3. Determine mode from user message:
   - mentions "current" or no session specified → Mode 1 (Current Session)
   - mentions a session ID or hash             → Mode 2 (Specific Session)
   - mentions "agent" or "background"          → Mode 3 (Agent Output)
   - mentions "all", "browse", "list"          → Mode 4 (All Sessions)

4. Determine output format:
   - "as HTML" or "export HTML" → html
   - default                    → markdown

5. Execute the appropriate mode (using TOOL_CONTEXT to choose correct paths) and display results.

错误处理

情况响应
未安装 claude-code-log显示安装说明,然后停止
未找到 JSONL 文件“在 处未找到会话文件”
未找到会话 ID“未找到 ID 为 的会话。运行 'browse all sessions' 以列出可用会话。”
没有 Agent 输出文件“在当前目录中未找到 Agent 后台任务输出。”
JSONL 文件为空“会话文件为空 — 没有可显示的消息。”
日期范围内没有结果“在 和 之间未找到会话。”
claude-code-log 返回非零退出码显示 stderr 并建议使用 --help
~/.copilot/session-state/ 存在但为空“未找到 Copilot 会话。使用 GitHub Copilot CLI 启动会话以创建日志。”
Copilot 会话目录存在,但没有 events.jsonl“已找到会话目录,但 处缺少 events.jsonl”
文件格式未知警告用户并显示原始内容

实现说明

检测会话 ID

Claude Code 会话 ID 是类似 UUID 的字符串。如果用户输入类似“查看会话 abc123”或“显示日志 def456”的内容,则将最后一个词视为会话 ID,并搜索匹配的 JSONL 文件名。

JSONL 结构(Claude Code)

Claude Code 会话 JSONL 文件每行包含一个 JSON 对象:

{"type":"user","message":{"role":"user","content":[{"type":"text","text":"..."}]},"timestamp":"...","sessionId":"..."}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"..."}]},"timestamp":"..."}

claude-code-log 会负责解析;此技能不会重新实现解析功能。

Copilot JSONL 结构(GitHub Copilot CLI)

Copilot CLI 的 events.jsonl 文件每行包含一个 JSON 对象,存储在 ~/.copilot/session-state/{session-id}/events.jsonl:

{"type":"user","message":{"role":"user","content":[{"type":"text","text":"..."}]},"timestamp":"...","sessionId":"..."}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"..."}]},"timestamp":"...","sessionId":"..."}

此格式兼容 claude-code-log。每个会话还包含以下文件:

  • workspace.yaml — 会话元数据
  • plan.md — 实施计划
  • checkpoints/ — 压缩历史记录(较早的快照)

旧版会话可能存储在 ~/.copilot/history-session-state/ 中,结构相同。

理念契合
  • 轻量封装:所有 JSONL(Claude Code 和 Copilot)操作均委托给 claude-code-log
  • 优雅降级:工具缺失或找不到会话时,提供明确的错误消息
  • 单一职责:仅查看和转换对话记录,不对其进行修改
  • 无隐藏状态:向用户显示所有文件路径

限制

  • 需要 claude-code-log(npm)或 npx 才能将 JSONL(Claude Code 和 Copilot)转换为 HTML/Markdown
  • 无法查看远程计算机上的对话记录
  • 日期筛选依据文件系统修改时间,而非会话时间戳
  • --summary 标志是否可用取决于 claude-code-log 版本
  • 不会自动发现 ~/.copilot/history-session-state/ 中的旧版 Copilot 会话(必须使用显式路径)
  • 如果 Claude Code 和 Copilot 会话同时存在,该技能会提示用户选择,而不会将它们合并

快速参考

用户说工具模式命令
“查看当前对话记录”Claude Code当前会话$CCL <latest.jsonl> --format markdown
“显示会话 abc123”Claude Code指定会话$CCL ~/.claude/projects/**/*abc123*.jsonl --format markdown
“查看 Agent 输出”Claude CodeAgent 输出cat .agent-step-*.log 或 $CCL *.jsonl
“浏览所有会话”Claude Code所有会话列出并汇总所有 ~/.claude/projects/**/*.jsonl
“以 HTML 查看对话记录”Claude Code任意会话 + HTML$CCL <file> --format html > /tmp/view.html
“最近 7 天”(与浏览一起使用)Claude Code日期筛选find ... -mtime -7
“查看当前 Copilot 会话”Copilot当前会话$CCL ~/.copilot/session-state/<latest>/events.jsonl --format markdown
“显示 Copilot 会话 abc123”Copilot指定会话$CCL ~/.copilot/session-state/abc123/events.jsonl --format markdown
“浏览 Copilot 会话”Copilot所有会话列出 ~/.copilot/session-state/ 中的目录并显示会话 ID
“以 HTML 查看 Copilot 会话”Copilot任意会话 + HTML$CCL <events.jsonl> --format html > /tmp/view.html

评论

支持 Markdown