asciinema-analyzer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseasciinema-analyzer
asciinema-analyzer
Semantic analysis of converted .txt recordings for Claude Code consumption. Uses tiered analysis: ripgrep (primary, 50-200ms) -> YAKE (secondary, 1-5s) -> TF-IDF (optional).
Platform: macOS, Linux (requires ripgrep, optional YAKE)
针对Claude Code的转换后.txt录屏文件语义分析工具。采用分层分析机制:ripgrep(核心工具,耗时50-200ms)-> YAKE(次要工具,耗时1-5s)-> TF-IDF(可选)。
平台支持: macOS、Linux(需要安装ripgrep,YAKE为可选依赖)
When to Use This Skill
适用场景
Use this skill when:
- Searching for keywords or patterns in converted recordings
- Extracting topics or themes from session transcripts
- Finding specific commands or errors in session history
- Auto-discovering unexpected terms in recordings
- Analyzing session content for documentation or review
在以下场景中使用本工具:
- 在转换后的录屏文件中搜索关键词或模式
- 从会话转录文本中提取主题或核心内容
- 在会话历史中查找特定命令或错误信息
- 自动发现录屏文件中的异常术语
- 分析会话内容用于文档编写或复盘评审
Analysis Tiers
分层分析机制
| Tier | Tool | Speed (4MB) | When to Use |
|---|---|---|---|
| 1 | ripgrep | 50-200ms | Always start here (curated) |
| 2 | YAKE | 1-5s | Auto-discover unexpected terms |
| 3 | TF-IDF | 5-30s | Topic modeling (optional) |
Decision: Start with Tier 1 (ripgrep + curated keywords). Only use Tier 2 (YAKE) when auto-discovery is explicitly requested.
| 层级 | 工具 | 处理速度(4MB文件) | 适用场景 |
|---|---|---|---|
| 1 | ripgrep | 50-200ms | 优先使用(精准匹配预设关键词) |
| 2 | YAKE | 1-5s | 自动发现未预设的异常术语 |
| 3 | TF-IDF | 5-30s | 主题建模(可选功能) |
决策建议:从第1层级开始(ripgrep + 预设关键词集)。仅当明确需要自动发现功能时,才使用第2层级(YAKE)。
Requirements
依赖要求
| Component | Required | Installation | Notes |
|---|---|---|---|
| ripgrep | Yes | | Primary search tool |
| YAKE | Optional | | For auto-discovery tier |
| 组件 | 是否必需 | 安装方式 | 说明 |
|---|---|---|---|
| ripgrep | 是 | | 核心搜索工具 |
| YAKE | 可选 | | 用于自动发现层级的分析 |
Workflow Phases (ALL MANDATORY)
工作流阶段(全部为必填步骤)
IMPORTANT: All phases are MANDATORY. Do NOT skip any phase. AskUserQuestion MUST be used at each decision point.
重要提示:所有阶段均为必填,请勿跳过任何步骤。在每个决策点必须使用AskUserQuestion交互。
Phase 0: Preflight Check
阶段0:前置检查
Purpose: Verify input file exists and check for .txt (converted) format.
bash
/usr/bin/env bash << 'PREFLIGHT_EOF'
INPUT_FILE="${1:-}"
if [[ -z "$INPUT_FILE" ]]; then
echo "NO_FILE_PROVIDED"
elif [[ ! -f "$INPUT_FILE" ]]; then
echo "FILE_NOT_FOUND: $INPUT_FILE"
elif [[ "$INPUT_FILE" == *.cast ]]; then
echo "WRONG_FORMAT: Convert to .txt first with /asciinema-tools:convert"
elif [[ "$INPUT_FILE" == *.txt ]]; then
SIZE=$(ls -lh "$INPUT_FILE" | awk '{print $5}')
LINES=$(wc -l < "$INPUT_FILE" | tr -d ' ')
echo "READY: $INPUT_FILE ($SIZE, $LINES lines)"
else
echo "UNKNOWN_FORMAT: Expected .txt file"
fi
PREFLIGHT_EOFIf no .txt file found, suggest running first.
/asciinema-tools:convert目的:验证输入文件是否存在,并检查是否为.txt(转换后)格式。
bash
/usr/bin/env bash << 'PREFLIGHT_EOF'
INPUT_FILE="${1:-}"
if [[ -z "$INPUT_FILE" ]]; then
echo "NO_FILE_PROVIDED"
elif [[ ! -f "$INPUT_FILE" ]]; then
echo "FILE_NOT_FOUND: $INPUT_FILE"
elif [[ "$INPUT_FILE" == *.cast ]]; then
echo "WRONG_FORMAT: Convert to .txt first with /asciinema-tools:convert"
elif [[ "$INPUT_FILE" == *.txt ]]; then
SIZE=$(ls -lh "$INPUT_FILE" | awk '{print $5}')
LINES=$(wc -l < "$INPUT_FILE" | tr -d ' ')
echo "READY: $INPUT_FILE ($SIZE, $LINES lines)"
else
echo "UNKNOWN_FORMAT: Expected .txt file"
fi
PREFLIGHT_EOF如果未找到.txt文件,建议先运行进行格式转换。
/asciinema-tools:convertPhase 1: File Selection (MANDATORY)
阶段1:文件选择(必填)
Purpose: Discover .txt files and let user select which to analyze.
目的:发现当前目录下的.txt文件,并让用户选择要分析的文件。
Step 1.1: Discover .txt Files
步骤1.1:发现.txt文件
bash
/usr/bin/env bash << 'DISCOVER_TXT_EOF'bash
/usr/bin/env bash << 'DISCOVER_TXT_EOF'Find .txt files that look like converted recordings
查找看起来是转换后录屏的.txt文件
for file in $(fd -e txt . --max-depth 3 2>/dev/null | head -10); do
SIZE=$(ls -lh "$file" 2>/dev/null | awk '{print $5}')
LINES=$(wc -l < "$file" 2>/dev/null | tr -d ' ')
BASENAME=$(basename "$file")
echo "FILE:$file|SIZE:$SIZE|LINES:$LINES|NAME:$BASENAME"
done
DISCOVER_TXT_EOF
undefinedfor file in $(fd -e txt . --max-depth 3 2>/dev/null | head -10); do
SIZE=$(ls -lh "$file" 2>/dev/null | awk '{print $5}')
LINES=$(wc -l < "$file" 2>/dev/null | tr -d ' ')
BASENAME=$(basename "$file")
echo "FILE:$file|SIZE:$SIZE|LINES:$LINES|NAME:$BASENAME"
done
DISCOVER_TXT_EOF
undefinedStep 1.2: Present File Selection (MANDATORY AskUserQuestion)
步骤1.2:展示文件选择选项(必须使用AskUserQuestion)
Question: "Which file would you like to analyze?"
Header: "File"
Options:
- Label: "{filename}.txt ({size})"
Description: "{line_count} lines"
- Label: "{filename2}.txt ({size2})"
Description: "{line_count2} lines"
- Label: "Enter path"
Description: "Provide a custom path to a .txt file"
- Label: "Convert first"
Description: "Run /asciinema-tools:convert before analysis"问题: "你想分析哪个文件?"
标题: "文件选择"
选项:
- 标签: "{filename}.txt ({size})"
描述: "{line_count} 行"
- 标签: "{filename2}.txt ({size2})"
描述: "{line_count2} 行"
- 标签: "输入路径"
描述: "提供自定义的.txt文件路径"
- 标签: "先转换格式"
描述: "在分析前运行 /asciinema-tools:convert 转换格式"Phase 2: Analysis Type (MANDATORY)
阶段2:分析类型选择(必填)
Purpose: Let user choose analysis depth.
Question: "What type of analysis do you need?"
Header: "Type"
Options:
- Label: "Curated keywords (Recommended)"
Description: "Fast search (50-200ms) with domain-specific keyword sets"
- Label: "Auto-discover keywords"
Description: "YAKE unsupervised extraction (1-5s) - finds unexpected patterns"
- Label: "Full analysis"
Description: "Both curated + auto-discovery for comprehensive results"
- Label: "Density analysis"
Description: "Find high-concentration sections (peak activity windows)"目的:让用户选择分析的深度。
问题: "你需要哪种类型的分析?"
标题: "分析类型"
选项:
- 标签: "预设关键词分析(推荐)"
描述: "基于领域专属关键词集的快速搜索(耗时50-200ms)"
- 标签: "自动发现关键词"
描述: "YAKE无监督提取(耗时1-5s)- 发现未预设的模式"
- 标签: "全面分析"
描述: "同时进行预设关键词分析和自动发现,获取完整结果"
- 标签: "密度分析"
描述: "查找关键词浓度最高的段落(活跃峰值区间)"Phase 3: Domain Selection (MANDATORY)
阶段3:领域选择(必填)
Purpose: Let user select which keyword domains to search.
Question: "Which domain keywords to search?"
Header: "Domain"
multiSelect: true
Options:
- Label: "Trading/Quantitative"
Description: "sharpe, sortino, calmar, backtest, drawdown, pnl, cagr, alpha, beta"
- Label: "ML/AI"
Description: "epoch, loss, accuracy, sota, training, model, validation, inference"
- Label: "Development"
Description: "iteration, refactor, fix, test, deploy, build, commit, merge"
- Label: "Claude Code"
Description: "Skill, TodoWrite, Read, Edit, Bash, Grep, iteration complete"See Domain Keywords Reference for complete keyword lists.
目的:让用户选择要搜索的关键词领域。
问题: "你想搜索哪个领域的关键词?"
标题: "领域选择"
支持多选: 是
选项:
- 标签: "交易/量化金融"
描述: "sharpe、sortino、calmar、backtest、drawdown、pnl、cagr、alpha、beta"
- 标签: "机器学习/人工智能"
描述: "epoch、loss、accuracy、sota、training、model、validation、inference"
- 标签: "软件开发"
描述: "iteration、refactor、fix、test、deploy、build、commit、merge"
- 标签: "Claude Code"
描述: "Skill、TodoWrite、Read、Edit、Bash、Grep、iteration complete"完整关键词列表请参考 领域关键词参考文档。
Phase 4: Execute Curated Analysis
阶段4:执行预设关键词分析
Purpose: Run Grep searches for selected domain keywords.
目的:针对选中的领域运行Grep搜索。
Step 4.1: Trading Domain
步骤4.1:交易领域
bash
/usr/bin/env bash << 'TRADING_EOF'
INPUT_FILE="${1:?}"
echo "=== Trading/Quantitative Keywords ==="
KEYWORDS="sharpe sortino calmar backtest drawdown pnl cagr alpha beta roi volatility"
for kw in $KEYWORDS; do
COUNT=$(rg -c -i "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
done
TRADING_EOFbash
/usr/bin/env bash << 'TRADING_EOF'
INPUT_FILE="${1:?}"
echo "=== 交易/量化金融关键词分析 ==="
KEYWORDS="sharpe sortino calmar backtest drawdown pnl cagr alpha beta roi volatility"
for kw in $KEYWORDS; do
COUNT=$(rg -c -i "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
done
TRADING_EOFStep 4.2: ML/AI Domain
步骤4.2:机器学习/人工智能领域
bash
/usr/bin/env bash << 'ML_EOF'
INPUT_FILE="${1:?}"
echo "=== ML/AI Keywords ==="
KEYWORDS="epoch loss accuracy sota training model validation inference tensor gradient"
for kw in $KEYWORDS; do
COUNT=$(rg -c -i "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
done
ML_EOFbash
/usr/bin/env bash << 'ML_EOF'
INPUT_FILE="${1:?}"
echo "=== 机器学习/人工智能关键词分析 ==="
KEYWORDS="epoch loss accuracy sota training model validation inference tensor gradient"
for kw in $KEYWORDS; do
COUNT=$(rg -c -i "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
done
ML_EOFStep 4.3: Development Domain
步骤4.3:软件开发领域
bash
/usr/bin/env bash << 'DEV_EOF'
INPUT_FILE="${1:?}"
echo "=== Development Keywords ==="
KEYWORDS="iteration refactor fix test deploy build commit merge debug error"
for kw in $KEYWORDS; do
COUNT=$(rg -c -i "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
done
DEV_EOFbash
/usr/bin/env bash << 'DEV_EOF'
INPUT_FILE="${1:?}"
echo "=== 软件开发关键词分析 ==="
KEYWORDS="iteration refactor fix test deploy build commit merge debug error"
for kw in $KEYWORDS; do
COUNT=$(rg -c -i "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
done
DEV_EOFStep 4.4: Claude Code Domain
步骤4.4:Claude Code领域
bash
/usr/bin/env bash << 'CLAUDE_EOF'
INPUT_FILE="${1:?}"
echo "=== Claude Code Keywords ==="
KEYWORDS="Skill TodoWrite Read Edit Bash Grep Write"
for kw in $KEYWORDS; do
COUNT=$(rg -c "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
donebash
/usr/bin/env bash << 'CLAUDE_EOF'
INPUT_FILE="${1:?}"
echo "=== Claude Code关键词分析 ==="
KEYWORDS="Skill TodoWrite Read Edit Bash Grep Write"
for kw in $KEYWORDS; do
COUNT=$(rg -c "$kw" "$INPUT_FILE" 2>/dev/null || echo "0")
if [[ "$COUNT" -gt 0 ]]; then
echo " $kw: $COUNT"
fi
doneSpecial patterns
特殊模式匹配
ITERATION=$(rg -c "iteration complete" "$INPUT_FILE" 2>/dev/null || echo "0")
echo " 'iteration complete': $ITERATION"
CLAUDE_EOF
---ITERATION=$(rg -c "iteration complete" "$INPUT_FILE" 2>/dev/null || echo "0")
echo " 'iteration complete': $ITERATION"
CLAUDE_EOF
---Phase 5: YAKE Auto-Discovery (if selected)
阶段5:YAKE自动发现分析(若选中)
Purpose: Run unsupervised keyword extraction.
bash
/usr/bin/env bash << 'YAKE_EOF'
INPUT_FILE="${1:?}"
echo "=== Auto-discovered Keywords (YAKE) ==="
uv run --with yake python3 -c "
import yake
kw = yake.KeywordExtractor(
lan='en',
n=2, # bi-grams
dedupLim=0.9, # dedup threshold
top=20 # top keywords
)
with open('$INPUT_FILE') as f:
text = f.read()
keywords = kw.extract_keywords(text)
for score, keyword in keywords:
print(f'{score:.4f} {keyword}')
"
YAKE_EOF目的:运行无监督关键词提取。
bash
/usr/bin/env bash << 'YAKE_EOF'
INPUT_FILE="${1:?}"
echo "=== YAKE自动发现关键词 ==="
uv run --with yake python3 -c "
import yake
kw = yake.KeywordExtractor(
lan='en',
n=2, # 提取双词组合
dedupLim=0.9, # 去重阈值
top=20 # 提取前20个关键词
)
with open('$INPUT_FILE') as f:
text = f.read()
keywords = kw.extract_keywords(text)
for score, keyword in keywords:
print(f'{score:.4f} {keyword}')
"
YAKE_EOFPhase 6: Density Analysis (if selected)
阶段6:密度分析(若选中)
Purpose: Find sections with highest keyword concentration.
bash
/usr/bin/env bash << 'DENSITY_EOF'
INPUT_FILE="${1:?}"
KEYWORD="${2:-sharpe}"
WINDOW_SIZE=100 # lines
echo "=== Density Analysis: '$KEYWORD' ==="
echo "Window size: $WINDOW_SIZE lines"
echo ""
TOTAL_LINES=$(wc -l < "$INPUT_FILE" | tr -d ' ')
TOTAL_MATCHES=$(rg -c -i "$KEYWORD" "$INPUT_FILE" 2>/dev/null || echo "0")
echo "Total matches: $TOTAL_MATCHES in $TOTAL_LINES lines"
echo "Overall density: $(echo "scale=4; $TOTAL_MATCHES / $TOTAL_LINES * 1000" | bc) per 1000 lines"
echo ""目的:查找关键词浓度最高的段落。
bash
/usr/bin/env bash << 'DENSITY_EOF'
INPUT_FILE="${1:?}"
KEYWORD="${2:-sharpe}"
WINDOW_SIZE=100 # 窗口大小(行数)
echo "=== 密度分析: '$KEYWORD' ==="
echo "窗口大小: $WINDOW_SIZE 行"
echo ""
TOTAL_LINES=$(wc -l < "$INPUT_FILE" | tr -d ' ')
TOTAL_MATCHES=$(rg -c -i "$KEYWORD" "$INPUT_FILE" 2>/dev/null || echo "0")
echo "总匹配次数: $TOTAL_MATCHES 次,共 $TOTAL_LINES 行"
echo "整体密度: $(echo "scale=4; $TOTAL_MATCHES / $TOTAL_LINES * 1000" | bc) 次/千行"
echo ""Find peak windows
查找峰值窗口
echo "Top 5 densest windows:"
awk -v ws="$WINDOW_SIZE" -v kw="$KEYWORD" '
BEGIN { IGNORECASE=1 }
{
lines[NR] = $0
if (tolower($0) ~ tolower(kw)) matches[NR] = 1
}
END {
for (start = 1; start <= NR - ws; start += ws/2) {
count = 0
for (i = start; i < start + ws && i <= NR; i++) {
if (matches[i]) count++
}
if (count > 0) {
printf "Lines %d-%d: %d matches (%.1f per 100)\n", start, start+ws-1, count, count*100/ws
}
}
}
' "$INPUT_FILE" | sort -t: -k2 -rn | head -5
DENSITY_EOF
---echo "关键词密度最高的5个窗口:"
awk -v ws="$WINDOW_SIZE" -v kw="$KEYWORD" '
BEGIN { IGNORECASE=1 }
{
lines[NR] = $0
if (tolower($0) ~ tolower(kw)) matches[NR] = 1
}
END {
for (start = 1; start <= NR - ws; start += ws/2) {
count = 0
for (i = start; i < start + ws && i <= NR; i++) {
if (matches[i]) count++
}
if (count > 0) {
printf "第 %d-%d 行: %d 次匹配 (每百行 %.1f 次)\n", start, start+ws-1, count, count*100/ws
}
}
}
' "$INPUT_FILE" | sort -t: -k2 -rn | head -5
DENSITY_EOF
---Phase 7: Report Format (MANDATORY)
阶段7:报告格式选择(必填)
Purpose: Let user choose output format.
Question: "How should results be presented?"
Header: "Output"
Options:
- Label: "Summary table (Recommended)"
Description: "Keyword counts + top 5 peak sections"
- Label: "Detailed report"
Description: "Full analysis with timestamps and surrounding context"
- Label: "JSON export"
Description: "Machine-readable output for further processing"
- Label: "Markdown report"
Description: "Save formatted report to file"目的:让用户选择结果的展示格式。
问题: "你希望结果以什么格式展示?"
标题: "输出格式"
选项:
- 标签: "汇总表格(推荐)"
描述: "关键词统计结果 + 前5个密度峰值段落"
- 标签: "详细报告"
描述: "包含时间戳和上下文的完整分析结果"
- 标签: "JSON导出"
描述: "机器可读格式,便于后续处理"
- 标签: "Markdown报告"
描述: "保存为格式化的Markdown文件"Phase 8: Follow-up Actions (MANDATORY)
阶段8:后续操作选择(必填)
Purpose: Guide user to next action.
Question: "Analysis complete. What's next?"
Header: "Next"
Options:
- Label: "Jump to peak section"
Description: "Read the highest-density section in the file"
- Label: "Search for specific keyword"
Description: "Grep for a custom term with context"
- Label: "Cross-reference with .cast"
Description: "Map findings back to original timestamps"
- Label: "Done"
Description: "Exit - no further action needed"目的:引导用户进行后续操作。
问题: "分析完成。接下来要做什么?"
标题: "后续操作"
选项:
- 标签: "跳转至峰值段落"
描述: "查看文件中关键词密度最高的段落"
- 标签: "搜索自定义关键词"
描述: "使用Grep搜索自定义术语并展示上下文"
- 标签: "与.cast文件关联"
描述: "将分析结果映射回原始录屏的时间戳"
- 标签: "完成"
描述: "退出 - 无需进一步操作"TodoWrite Task Template
TodoWrite任务模板
1. [Preflight] Check input file exists and is .txt format
2. [Preflight] Suggest /convert if .cast file provided
3. [Discovery] Find .txt files with line counts
4. [Selection] AskUserQuestion: file to analyze
5. [Type] AskUserQuestion: analysis type (curated/auto/full/density)
6. [Domain] AskUserQuestion: keyword domains (multi-select)
7. [Curated] Run Grep searches for selected domains
8. [Auto] Run YAKE if auto-discovery selected
9. [Density] Calculate density windows if requested
10. [Format] AskUserQuestion: report format
11. [Next] AskUserQuestion: follow-up actions1. [前置检查] 验证输入文件存在且为.txt格式
2. [前置检查] 若提供的是.cast文件,建议先运行/convert进行转换
3. [发现] 查找带行数统计的.txt文件
4. [选择] 询问用户:要分析的文件
5. [类型] 询问用户:分析类型(预设/自动/全面/密度)
6. [领域] 询问用户:关键词领域(支持多选)
7. [预设分析] 针对选中领域运行Grep搜索
8. [自动分析] 若选中自动发现,则运行YAKE
9. [密度分析] 若请求则计算密度窗口
10. [格式] 询问用户:报告格式
11. [后续] 询问用户:后续操作Post-Change Checklist
修改后检查清单
After modifying this skill:
- All bash blocks use heredoc wrapper
- Curated keywords match references/domain-keywords.md
- Analysis tiers match references/analysis-tiers.md
- YAKE invocation uses
uv run --with yake - All AskUserQuestion phases are present
- TodoWrite template matches actual workflow
在修改本工具后,请检查以下内容:
- 所有bash代码块均使用heredoc包装
- 预设关键词与保持一致
references/domain-keywords.md - 分层分析机制与保持一致
references/analysis-tiers.md - YAKE调用使用命令
uv run --with yake - 所有AskUserQuestion交互阶段均已包含
- TodoWrite模板与实际工作流一致
Reference Documentation
参考文档
- Domain Keywords Reference
- Analysis Tiers Reference
- ripgrep Manual
- YAKE Documentation
- 领域关键词参考文档
- 分层分析机制参考文档
- ripgrep官方手册
- YAKE官方文档
Troubleshooting
故障排查
| Issue | Cause | Solution |
|---|---|---|
| "WRONG_FORMAT" error | .cast file provided | Run /asciinema-tools:convert first to create .txt |
| ripgrep not found | Not installed | |
| YAKE import error | Package not installed | |
| No keywords found | Wrong domain selected | Try different domain or auto-discovery mode |
| Density analysis empty | Keyword not in file | Use curated search first to find valid keywords |
| File too large for YAKE | Memory constraints | Use Tier 1 (ripgrep) only for large files |
| Zero matches in all domains | File is binary or corrupted | Verify file is plain text with |
| fd command not found | Not installed | |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 出现"WRONG_FORMAT"错误 | 提供了.cast格式文件 | 先运行/asciinema-tools:convert转换为.txt格式 |
| 找不到ripgrep | 未安装ripgrep | 执行 |
| YAKE导入错误 | 未安装YAKE依赖 | |
| 未找到任何关键词 | 选择的领域不正确 | 尝试更换领域或使用自动发现模式 |
| 密度分析结果为空 | 文件中无该关键词 | 先使用预设搜索找到有效的关键词 |
| YAKE处理大文件失败 | 内存限制 | 仅使用第1层级(ripgrep)处理大文件 |
| 所有领域均无匹配结果 | 文件为二进制或已损坏 | 使用 |
| 找不到fd命令 | 未安装fd | 执行 |