Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:02:31 +08:00
commit 866f3dbf18
34 changed files with 8341 additions and 0 deletions

View File

@@ -0,0 +1,189 @@
---
name: local-research
description: "This skill should be used when performing codebase research with markdown documentation persistence. Triggered by phrases like [local research], [quick research], [load local research], [init local research], [read local research ...]."
---
# Local Research
## Overview
Perform comprehensive codebase research with persistent markdown documentation stored in `~/workspace/llm/research/`. This skill integrates multiple research tools including fast-repo-context skill, knowledge graph queries, and external resources to create structured research documentation.
Use absolute file path in research document for easy share across different projects/repos.
### Automation Script
The skill includes an automation script at `~/.claude/skills/local-research/scripts/research_ops.py` that handles:
- Generating descriptive research names from user queries
- Creating research directories and markdown files with timestamps
- Listing and locating existing research files by keywords
- Providing CLI interface for all research operations
## When to Use This Skill
Use this skill when:
- Need to research and analyze codebase structure and patterns
- Want to create persistent research documentation
- Need to load previous research findings
- User says "local research", "quick research", or "load local research"
## Core Workflow
### Research Generation Process (when user explicitly requests new research)
1. **Generate Research Name**: Create descriptive research name based on user input as `<user-query>`, user input may contain typos, improve it.
2. **Create Research File**: `python3 ~/.claude/skills/local-research/scripts/research_ops.py create "<user-query>"`
3. **Ask Clarifying Questions**: Ask user for more details about research scope
4. **Execute Research Workflow**: Use integrated tools to gather information
5. **Document Findings**: Write results to research markdown file, use absolute file path when writting, do not use `~` path abbreviation.
### Loading Research Process (when user mention load or update doc, or provided doc keywords)
When user requests to "load local research" or similar:
1. **List Research Files**: `python3 ~/.claude/skills/local-research/scripts/research_ops.py list`
2. **Identify Target**: `python3 ~/.claude/skills/local-research/scripts/research_ops.py locate <keywords>`
3. **Load Content**: Read and display the summary of relevant research markdown file
## Research Tools and Methods
### Primary Research Tools
1. **Fast Context Skill** (`fast-repo-context`):
- load fast-repo-context skill
- Use for comprehensive codebase understanding
- Leverages repomix-generated XML for efficient searching
2. **Knowledge Graph** (`kg`):
- Query related keywords and existing research
- Use `mcp__kg__query_graph` with semantic search
- Set `group_id` to organize research by project/topics
3. **External Resources**:
- **Brightdata**: Use `mcp__brightdata__search_engine` for web research
- **GitHub**: Use `mcp__github__search_code` or `mcp__github__search_repositories` for external code reference
### Research Execution Order
1. **Initialize Research Environment**:
```bash
python3 ~/.claude/skills/local-research/scripts/research_ops.py create "<user-query>"
```
2. **Fast Context Analysis**:
- Extract code structure, patterns, and key files
- Document findings in research file
3. **Knowledge Graph Integration**:
- Query `kg` for related information
- Use semantic search with research keywords
- Integrate findings into research documentation
4. **External Research** (if needed):
- Use Brightdata for web research on related topics
- Use GitHub tools for external examples and best practices
- Add external insights to research file
## Research Documentation Structure
Each research markdown file should follow this structure:
```markdown
# <Research Name>
- **Created**: <timestamp>
- **Research Query**: <original user input>
## Executive Summary
<brief overview of findings>
## Codebase Analysis
<findings from fast-repo-context>
## Knowledge Graph Insights
<related information from kg queries>
## External Research
<findings from web/github research if applicable>
## Key Findings
<important discoveries and insights>
## Recommendations
<actionable recommendations based on research>
## Files Referenced
<list of key files analyzed>
## Next Steps
<suggested follow-up actions>
```
- Note: file path in the research doc must use absolute path, do not use `~` abbreviation, because this doc will be shared across different project/repos.
## Loading Research
When user wants to load existing research:
1. **Available Research**: List all research files with timestamps
2. **Search Matching**: Match user keywords to research names/content
3. **Display Findings**: Present the complete research file content
### Script Commands
```bash
# Create new research file
python3 ~/.claude/skills/local-research/scripts/research_ops.py create "<user-query>"
# List all research files (sorted by timestamp)
python3 ~/.claude/skills/local-research/scripts/research_ops.py list
# Locate research file by keywords
python3 ~/.claude/skills/local-research/scripts/research_ops.py locate <keywords...>
# Read specific research file
cat ~/workspace/llm/research/<research-name>-<timestamp>.md
```
## Integration with Other Skills
### Fast Context Integration
- Always invoke `fast-repo-context` skill for codebase analysis
- Follow its mandatory checklist: check repomix freshness, search XML, then optionally KG
- Document steps completed in research file
### Knowledge Graph Integration
- Use consistent `group_id` for related research projects
- Store research summaries in KG for future retrieval
- Query KG before starting new research to avoid duplication
## Research Naming Conventions
Generate descriptive research names:
- Convert user input to kebab-case
- Include domain/technology focus
- Example inputs to names:
- "analyze authentication system" → "authentication-system-analysis"
- "react performance issues" → "react-performance-investigation"
- "api design patterns" → "api-design-patterns-research"
## Error Handling
- If research directory creation fails, check permissions and path
- If fast-repo-context claude skill is unavailable, fall back to direct code search
- If external resources are unreachable, continue with internal research
- Always document any limitations or issues encountered
# Example
<example>
<user>
please load local research on "authentication system analysis" and update the document with any new findings.
</user>
<assistant>
```bash
python3 ~/.claude/skills/local-research/scripts/research_ops.py locate authentication system analysis
```
Good, found the research file at `<file-path>`. Now loading the content and summarizing the key points for you.
</assistant>
</example>

View File

@@ -0,0 +1,236 @@
#!/usr/bin/env python3
"""
Research Helper Script for Local Research Skill
This script provides utility functions for managing research files,
generating timestamps, and handling research naming conventions.
"""
import re
import sys
from datetime import datetime
from pathlib import Path
def generate_research_name(user_input: str) -> str:
"""
Generate a descriptive research name based on user input.
Args:
user_input: The original user query/description
Returns:
A kebab-case research name
"""
# Remove common prefixes and normalize
input_clean = user_input.lower()
prefixes_to_remove = [
"analyze ",
"investigate ",
"research ",
"look at ",
"examine ",
"study ",
"explore ",
"understand ",
]
for prefix in prefixes_to_remove:
if input_clean.startswith(prefix):
input_clean = input_clean[len(prefix) :]
# Map common patterns to descriptive names
pattern_map = {
"auth": "authentication",
"api": "api",
"db": "database",
"ui": "user-interface",
"ux": "user-experience",
"perf": "performance",
"sec": "security",
"test": "testing",
"config": "configuration",
}
# Split into words and process each
words = input_clean.split()
processed_terms = []
for word in words:
# Remove punctuation and apply pattern mapping
word_clean = re.sub(r"[^a-z0-9-]", "", word)
if word_clean:
# Apply pattern mapping
if word_clean in pattern_map:
word_clean = pattern_map[word_clean]
processed_terms.append(word_clean)
# Remove duplicates while preserving order
seen = set()
unique_terms = []
for term in processed_terms:
if term not in seen:
seen.add(term)
unique_terms.append(term)
# Join with hyphens and limit length
research_name = "-".join(unique_terms)
if len(research_name) > 80:
research_name = "-".join(unique_terms[:5])
return research_name or "research"
def create_research_file(research_name: str, user_query: str) -> str:
"""
Create a new research file with timestamp and return the path.
Args:
research_name: The generated research name
user_query: The original user query
Returns:
Path to the created research file
"""
# Create research directory
research_dir = Path.home() / "workspace" / "llm" / "research"
research_dir.mkdir(parents=True, exist_ok=True)
# Generate timestamp
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
# Create file path
filename = f"{research_name}-{timestamp}.md"
filepath = research_dir / filename
# Create file with initial header
with open(filepath, "w") as f:
f.write(f"# {research_name.replace('-', ' ').title()}\n")
f.write(f"- **Created**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"- **Research Query**: {user_query}\n\n")
f.write("## Executive Summary\n\n")
f.write("## Codebase Analysis\n\n")
f.write("## Knowledge Graph Insights\n\n")
f.write("## External Research\n\n")
f.write("## Key Findings\n\n")
f.write("## Recommendations\n\n")
f.write("## Files Referenced\n\n")
f.write("## Next Steps\n\n")
return str(filepath)
def list_research_files() -> list:
"""
List all research files sorted by timestamp (newest first).
Returns:
List of file paths sorted by modification time
"""
research_dir = Path.home() / "workspace" / "llm" / "research"
if not research_dir.exists():
return []
files = []
for file_path in research_dir.glob("*.md"):
files.append((file_path.stat().st_mtime, file_path))
# Sort by modification time (newest first)
files.sort(key=lambda x: x[0], reverse=True)
return [file_path for _, file_path in files]
def locate_research_file(keywords: list) -> str:
"""
Find research file matching keywords.
Args:
keywords: List of keywords to search for
Returns:
Path to the best matching file or None if not found
"""
files = list_research_files()
if not files:
return None
if not keywords:
# Return most recent file
return str(files[0]) if files else None
# Simple keyword matching in filename and content
best_match = None
best_score = 0
for file_path in files:
score = 0
filename = file_path.name.lower()
# Check filename match
for keyword in keywords:
keyword_lower = keyword.lower()
if keyword_lower in filename:
score += 3
# Check content match
try:
with open(file_path, "r") as f:
content = f.read().lower()
for keyword in keywords:
keyword_lower = keyword.lower()
if keyword_lower in content:
score += 1
except Exception:
pass
if score > best_score:
best_score = score
best_match = file_path
return str(best_match) if best_match else None
def main():
"""CLI interface for the research helper."""
if len(sys.argv) < 2:
print("Usage: python research_helper.py <command> [args...]")
print("Commands:")
print(" create <user_query> - Create new research file")
print(" list - List all research files")
print(" locate <keywords...> - Locate research file by keywords")
sys.exit(1)
command = sys.argv[1]
if command == "create":
if len(sys.argv) < 3:
print("Error: create command requires user query")
sys.exit(1)
user_query = " ".join(sys.argv[2:])
research_name = generate_research_name(user_query)
filepath = create_research_file(research_name, user_query)
print(filepath)
elif command == "list":
files = list_research_files()
for file_path in files:
print(f"{file_path}")
elif command == "locate":
keywords = sys.argv[2:] if len(sys.argv) > 2 else []
filepath = locate_research_file(keywords)
if filepath:
print(filepath)
else:
print("No matching research file found")
sys.exit(1)
else:
print(f"Error: Unknown command '{command}'")
sys.exit(1)
if __name__ == "__main__":
main()