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