Initial commit
This commit is contained in:
14
.claude-plugin/plugin.json
Normal file
14
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "transcript",
|
||||||
|
"description": "Parse and analyze Claude Code session transcripts with markdown/HTML output",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": {
|
||||||
|
"name": "Claude Plugins"
|
||||||
|
},
|
||||||
|
"commands": [
|
||||||
|
"./commands"
|
||||||
|
],
|
||||||
|
"hooks": [
|
||||||
|
"./hooks"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# transcript
|
||||||
|
|
||||||
|
Parse and analyze Claude Code session transcripts with markdown/HTML output
|
||||||
12
commands/create.md
Normal file
12
commands/create.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
description: Create an HTML report for the current session
|
||||||
|
allowed-tools: Bash(create-transcript.sh:*)
|
||||||
|
---
|
||||||
|
|
||||||
|
# Create Transcript Report
|
||||||
|
|
||||||
|
!`create-transcript.sh`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Note:** This creates a report for your CURRENT session only. To create a report for a different session, use `/resume <session-id>` to switch to it first.
|
||||||
76
commands/help.md
Normal file
76
commands/help.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
description: Show transcript plugin usage guide
|
||||||
|
---
|
||||||
|
|
||||||
|
# Transcript Plugin - Help
|
||||||
|
|
||||||
|
## What This Plugin Does
|
||||||
|
|
||||||
|
Creates beautiful HTML reports from your current Claude Code conversation.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Simply run:
|
||||||
|
|
||||||
|
```
|
||||||
|
/transcript:create
|
||||||
|
```
|
||||||
|
|
||||||
|
This generates an interactive HTML file in `.transcripts/` that you can open in any browser.
|
||||||
|
|
||||||
|
## What You Get
|
||||||
|
|
||||||
|
Your HTML reports include:
|
||||||
|
|
||||||
|
- 💬 **Complete conversation** - Every message in chronological order
|
||||||
|
- 🛠️ **Tool details** - All commands Claude ran with inputs/outputs
|
||||||
|
- 📊 **Statistics** - Message counts, token usage, performance metrics
|
||||||
|
- 🎨 **Interactive UI** - Click to expand/collapse sections
|
||||||
|
- 🌙 **Dark theme** - Easy on the eyes
|
||||||
|
- ⌨️ **Keyboard shortcuts** - Press `E` to expand/collapse all tools
|
||||||
|
|
||||||
|
## How to View Reports
|
||||||
|
|
||||||
|
After creating a report:
|
||||||
|
|
||||||
|
**macOS:**
|
||||||
|
```bash
|
||||||
|
open .transcripts/transcript-*.html
|
||||||
|
```
|
||||||
|
|
||||||
|
**Linux/WSL:**
|
||||||
|
```bash
|
||||||
|
xdg-open .transcripts/transcript-*.html
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
- Double-click the HTML file in your file manager
|
||||||
|
|
||||||
|
## Want a Different Session?
|
||||||
|
|
||||||
|
To create a report for a past conversation:
|
||||||
|
|
||||||
|
1. Use `/resume <session-id>` to switch to that session
|
||||||
|
2. Run `/transcript:create` again
|
||||||
|
3. The report will be created for that session
|
||||||
|
|
||||||
|
You can find available session IDs with `/resume` (it shows a list).
|
||||||
|
|
||||||
|
## Privacy & Security
|
||||||
|
|
||||||
|
- Reports are saved to `.transcripts/`
|
||||||
|
- This folder is automatically added to `.gitignore`
|
||||||
|
- Your transcripts won't be committed to git
|
||||||
|
|
||||||
|
## Pro Tips
|
||||||
|
|
||||||
|
**Viewing tips:**
|
||||||
|
- Press `E` key in the HTML to expand/collapse all tool details
|
||||||
|
- Long messages are auto-collapsed - click "Show more" to expand
|
||||||
|
- Reports are self-contained and work offline
|
||||||
|
|
||||||
|
**File organization:**
|
||||||
|
- Reports are named: `transcript-<session-id>-<project>-<date>.html`
|
||||||
|
- Easy to find by date or project name in your file manager
|
||||||
|
|
||||||
|
That's it! Simple and focused on your current session.
|
||||||
14
hooks/hooks.json
Normal file
14
hooks/hooks.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"SessionStart": [
|
||||||
|
{
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/sessionstart.sh"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
145
hooks/scripts/sessionstart.sh
Executable file
145
hooks/scripts/sessionstart.sh
Executable file
@@ -0,0 +1,145 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This hook persists transcript path and session ID as environment variables
|
||||||
|
# and adds the scripts folder to PATH
|
||||||
|
|
||||||
|
# Read input JSON
|
||||||
|
INPUT_JSON=$(cat)
|
||||||
|
|
||||||
|
# Set up basic environment
|
||||||
|
export CLAUDE_HOME="${CLAUDE_HOME:-$HOME/.claude}"
|
||||||
|
export CLAUDE_SESSION_ID=$(echo "$INPUT_JSON" | jq -r '.session_id // empty')
|
||||||
|
export TRANSCRIPT_PATH=$(echo "$INPUT_JSON" | jq -r '.transcript_path // empty')
|
||||||
|
export PROJECT_ROOT=$(echo "$INPUT_JSON" | jq -r '.cwd // empty')
|
||||||
|
|
||||||
|
# Debug logging function - only logs if CLAUDE_HOOK_DEBUG_LOG is set
|
||||||
|
debug_log() {
|
||||||
|
if [ -n "$CLAUDE_HOOK_DEBUG_LOG" ]; then
|
||||||
|
echo "$@" >> "$CLAUDE_HOOK_DEBUG_LOG"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_log "===== Starting transcript-sessionstart.sh Hook $(date) ====="
|
||||||
|
debug_log ""
|
||||||
|
debug_log "CLAUDE-SPECIFIC VARIABLES:"
|
||||||
|
debug_log "CLAUDE_HOME: ${CLAUDE_HOME:-<not set>}"
|
||||||
|
debug_log "CLAUDE_PROJECT_DIR: ${CLAUDE_PROJECT_DIR:-<not set>}"
|
||||||
|
debug_log "CLAUDE_PLUGIN_ROOT: ${CLAUDE_PLUGIN_ROOT:-<not set>}"
|
||||||
|
debug_log "CLAUDE_SESSION_ID: ${CLAUDE_SESSION_ID:-<not set>}"
|
||||||
|
debug_log "CLAUDE_ENV_FILE: ${CLAUDE_ENV_FILE:-<not set>}"
|
||||||
|
debug_log "TRANSCRIPT_PATH: ${TRANSCRIPT_PATH:-<not set>}"
|
||||||
|
|
||||||
|
# Create CLAUDE_ENV_FILE if not set (workaround for Claude Code bug with plugin hooks)
|
||||||
|
if [ -z "$CLAUDE_ENV_FILE" ] && [ -n "$CLAUDE_SESSION_ID" ] && [ -n "$CLAUDE_HOME" ]; then
|
||||||
|
export CLAUDE_ENV_FILE="$CLAUDE_HOME/session-env/$CLAUDE_SESSION_ID/hook-0.sh"
|
||||||
|
# Create the directory if it doesn't exist
|
||||||
|
mkdir -p "$(dirname "$CLAUDE_ENV_FILE")"
|
||||||
|
# Create the file if it doesn't exist
|
||||||
|
touch "$CLAUDE_ENV_FILE"
|
||||||
|
debug_log "✓ Created CLAUDE_ENV_FILE: $CLAUDE_ENV_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Shared utility function to update or add environment variables
|
||||||
|
# Usage: set_env_var "VAR_NAME" "value"
|
||||||
|
set_env_var() {
|
||||||
|
local var_name="$1"
|
||||||
|
local var_value="$2"
|
||||||
|
|
||||||
|
# Validate inputs
|
||||||
|
if [ -z "$var_name" ]; then
|
||||||
|
debug_log "ERROR: Variable name is required"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip if CLAUDE_ENV_FILE is not set
|
||||||
|
if [ -z "$CLAUDE_ENV_FILE" ]; then
|
||||||
|
debug_log "WARNING: CLAUDE_ENV_FILE is not set, skipping ${var_name}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the directory if it doesn't exist
|
||||||
|
local env_dir
|
||||||
|
env_dir="$(dirname "$CLAUDE_ENV_FILE")"
|
||||||
|
if [ ! -d "$env_dir" ]; then
|
||||||
|
mkdir -p "$env_dir" || {
|
||||||
|
debug_log "ERROR: Failed to create directory: $env_dir"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the file if it doesn't exist
|
||||||
|
if [ ! -f "$CLAUDE_ENV_FILE" ]; then
|
||||||
|
touch "$CLAUDE_ENV_FILE" || {
|
||||||
|
debug_log "ERROR: Failed to create file: $CLAUDE_ENV_FILE"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the export line
|
||||||
|
local export_line="export ${var_name}=\"${var_value}\""
|
||||||
|
|
||||||
|
# Check if the variable already exists in the file
|
||||||
|
if grep -q "^export ${var_name}=" "$CLAUDE_ENV_FILE"; then
|
||||||
|
# Update existing variable using sed
|
||||||
|
sed -i "s|^export ${var_name}=.*|${export_line}|" "$CLAUDE_ENV_FILE"
|
||||||
|
debug_log "Updated ${var_name} in ${CLAUDE_ENV_FILE}"
|
||||||
|
else
|
||||||
|
# Append new variable
|
||||||
|
echo "$export_line" >> "$CLAUDE_ENV_FILE"
|
||||||
|
debug_log "Added ${var_name} to ${CLAUDE_ENV_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the scripts folder to PATH and persist environment variables
|
||||||
|
if [ -n "$CLAUDE_ENV_FILE" ]; then
|
||||||
|
debug_log ""
|
||||||
|
debug_log "Setting environment variables in CLAUDE_ENV_FILE..."
|
||||||
|
|
||||||
|
# Set PATH with the scripts folder
|
||||||
|
set_env_var "PATH" "${CLAUDE_PLUGIN_ROOT}/scripts:\$PATH"
|
||||||
|
|
||||||
|
# Set CLAUDE_SESSION_ID
|
||||||
|
set_env_var "CLAUDE_SESSION_ID" "$CLAUDE_SESSION_ID"
|
||||||
|
|
||||||
|
# Set CLAUDE_ACTIVE_TRANSCRIPT (the transcript path)
|
||||||
|
if [ -n "$TRANSCRIPT_PATH" ]; then
|
||||||
|
set_env_var "CLAUDE_ACTIVE_TRANSCRIPT" "$TRANSCRIPT_PATH"
|
||||||
|
debug_log "✓ Set CLAUDE_ACTIVE_TRANSCRIPT: $TRANSCRIPT_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set CLAUDE_PROJECT_ROOT
|
||||||
|
if [ -n "$PROJECT_ROOT" ]; then
|
||||||
|
set_env_var "CLAUDE_PROJECT_ROOT" "$PROJECT_ROOT"
|
||||||
|
debug_log "✓ Set CLAUDE_PROJECT_ROOT: $PROJECT_ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
debug_log ""
|
||||||
|
debug_log "✓ Environment variables updated"
|
||||||
|
if [ -n "$CLAUDE_HOOK_DEBUG_LOG" ]; then
|
||||||
|
debug_log "CLAUDE_ENV_FILE contents:"
|
||||||
|
cat "$CLAUDE_ENV_FILE" >> "$CLAUDE_HOOK_DEBUG_LOG" 2>&1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
debug_log ""
|
||||||
|
debug_log "⚠ WARNING: CLAUDE_ENV_FILE is not set!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
debug_log ""
|
||||||
|
debug_log "Hook execution completed successfully"
|
||||||
|
debug_log ""
|
||||||
|
|
||||||
|
# Output JSON with hookSpecificOutput format (silent with helpful context)
|
||||||
|
jq -n \
|
||||||
|
'{
|
||||||
|
hookSpecificOutput: {
|
||||||
|
hookEventName: "SessionStart",
|
||||||
|
additionalContext: "# Transcript Plugin Available\n\nIf the user is confused, needs to review the conversation, debug issues, or wants to see the complete chat history with all tool details, suggest using `/transcript:create` to generate an HTML report. This is especially helpful for complex sessions with many tool calls or when troubleshooting problems."
|
||||||
|
},
|
||||||
|
systemMessage: ""
|
||||||
|
}'
|
||||||
|
|
||||||
|
debug_log "JSON output generated successfully"
|
||||||
|
|
||||||
|
exit 0
|
||||||
57
plugin.lock.json
Normal file
57
plugin.lock.json
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||||
|
"pluginId": "gh:dkmaker/my-claude-plugins:transcript",
|
||||||
|
"normalized": {
|
||||||
|
"repo": null,
|
||||||
|
"ref": "refs/tags/v20251128.0",
|
||||||
|
"commit": "b7fa847df70f8d1ea003b4fb6427ffc27cb80b0f",
|
||||||
|
"treeHash": "0ef0a423dbdbacb4186239e6584bfbc3ffa1335c1dc936c57f930546070d3213",
|
||||||
|
"generatedAt": "2025-11-28T10:16:31.810792Z",
|
||||||
|
"toolVersion": "publish_plugins.py@0.2.0"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||||
|
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "transcript",
|
||||||
|
"description": "Parse and analyze Claude Code session transcripts with markdown/HTML output",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"sha256": "02f23c1f2f8785dbf859f297cf47d16a496ebc08b2841df31c645c98dfadb4cb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "hooks/hooks.json",
|
||||||
|
"sha256": "8437d9b0310245a4cb7835b93e116c43748d3dac06246e6cf7cf2d1065e32555"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "hooks/scripts/sessionstart.sh",
|
||||||
|
"sha256": "13a99433f0825cee91c11b9df1beb7cf0ccfe2ccfb772620bf25b83d49b3253e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".claude-plugin/plugin.json",
|
||||||
|
"sha256": "b6c4b0f143361f94b9a3f24066d690483ebf416dd312276857177d263d29acc5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "commands/help.md",
|
||||||
|
"sha256": "3bf78426ee3b00ac7cd81d849d2eee1ba4877e823e798b0c9a6a1e966242e7b3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "commands/create.md",
|
||||||
|
"sha256": "8961409a6c491e2c6b81c797d3f471239cd69685c784f4412dde1028f8dd2c6d"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dirSha256": "0ef0a423dbdbacb4186239e6584bfbc3ffa1335c1dc936c57f930546070d3213"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"scannedAt": null,
|
||||||
|
"scannerVersion": null,
|
||||||
|
"flags": []
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user