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,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()