chore: import upstream snapshot with attribution
Test Vector Database Adaptors / Test MCP Vector DB Tools (push) Has been cancelled
Tests / Code Quality (Ruff & Mypy) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (macos-latest, 3.11) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (macos-latest, 3.12) (push) Has been cancelled
Tests / Tests (push) Has been cancelled
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers CLI - Convert documentation to AI skills dockerfile:Dockerfile name:skill-seekers]) (push) Has been cancelled
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers MCP Server - 25 tools for AI assistants dockerfile:Dockerfile.mcp name:skill-seekers-mcp]) (push) Has been cancelled
Docker Publish / Test Docker Images (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.10) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.11) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.12) (push) Has been cancelled
Tests / Serial / Integration / E2E Tests (push) Has been cancelled
Tests / MCP Server Tests (push) Has been cancelled
Test Vector Database Adaptors / Test chroma Adaptor (push) Has been cancelled
Test Vector Database Adaptors / Test faiss Adaptor (push) Has been cancelled
Test Vector Database Adaptors / Test qdrant Adaptor (push) Has been cancelled
Test Vector Database Adaptors / Test weaviate Adaptor (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:46:28 +08:00
commit 2cab53bc94
2985 changed files with 1288070 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env bash
#
# Bootstrap Skill Seekers into an Operational Skill for Claude Code
#
# Usage: ./scripts/bootstrap_skill.sh
# Output: output/skill-seekers/ (skill directory)
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SKILL_NAME="skill-seekers"
OUTPUT_DIR="$PROJECT_ROOT/output/$SKILL_NAME"
HEADER_FILE="$SCRIPT_DIR/skill_header.md"
echo "============================================"
echo " Skill Seekers Bootstrap"
echo "============================================"
# Step 1: Sync dependencies
echo "Step 1: uv sync..."
if ! command -v uv &> /dev/null; then
echo "❌ Error: 'uv' is not installed"
echo ""
echo "Install uv:"
echo " curl -LsSf https://astral.sh/uv/install.sh | sh"
echo " # or"
echo " pip install uv"
echo ""
exit 1
fi
cd "$PROJECT_ROOT"
uv sync --quiet
echo "✓ Done"
# Step 2: Run codebase analysis
echo "Step 2: Analyzing codebase..."
rm -rf "$OUTPUT_DIR" 2>/dev/null || true
uv run skill-seekers create "$PROJECT_ROOT" \
--name "$SKILL_NAME" \
--output "$OUTPUT_DIR" 2>&1 | grep -E "^(INFO|✅)" || true
echo "✓ Done"
# Step 3: Prepend header to SKILL.md
echo "Step 3: Adding operational header..."
if [[ -f "$HEADER_FILE" ]]; then
# Detect end of frontmatter dynamically
# Look for second occurrence of '---'
FRONTMATTER_END=$(grep -n '^---$' "$OUTPUT_DIR/SKILL.md" | sed -n '2p' | cut -d: -f1)
if [[ -n "$FRONTMATTER_END" ]]; then
# Skip frontmatter + blank line
AUTO_CONTENT=$(tail -n +$((FRONTMATTER_END + 2)) "$OUTPUT_DIR/SKILL.md")
else
# Fallback to line 6 if no frontmatter found
AUTO_CONTENT=$(tail -n +6 "$OUTPUT_DIR/SKILL.md")
fi
# Combine: header + auto-generated
cat "$HEADER_FILE" > "$OUTPUT_DIR/SKILL.md"
echo "$AUTO_CONTENT" >> "$OUTPUT_DIR/SKILL.md"
echo "✓ Done ($(wc -l < "$OUTPUT_DIR/SKILL.md") lines)"
else
echo "Warning: $HEADER_FILE not found, using auto-generated only"
fi
# Step 4: Validate merged SKILL.md
echo "Step 4: Validating SKILL.md..."
if [[ -f "$OUTPUT_DIR/SKILL.md" ]]; then
# Check file not empty
if [[ ! -s "$OUTPUT_DIR/SKILL.md" ]]; then
echo "❌ Error: SKILL.md is empty"
exit 1
fi
# Check frontmatter exists
if ! head -1 "$OUTPUT_DIR/SKILL.md" | grep -q '^---$'; then
echo "⚠️ Warning: SKILL.md missing frontmatter delimiter"
fi
# Check required fields
if ! grep -q '^name:' "$OUTPUT_DIR/SKILL.md"; then
echo "❌ Error: SKILL.md missing 'name:' field"
exit 1
fi
if ! grep -q '^description:' "$OUTPUT_DIR/SKILL.md"; then
echo "❌ Error: SKILL.md missing 'description:' field"
exit 1
fi
echo "✓ Validation passed"
else
echo "❌ Error: SKILL.md not found"
exit 1
fi
echo ""
echo "============================================"
echo " Bootstrap Complete!"
echo "============================================"
echo ""
echo "Output: $OUTPUT_DIR/"
echo " - SKILL.md ($(wc -l < "$OUTPUT_DIR/SKILL.md") lines)"
echo " - references/ (API docs, patterns, examples)"
echo ""
echo "Install to Claude Code:"
echo " cp -r output/$SKILL_NAME ~/.claude/skills/"
echo ""
echo "Verify:"
echo " ls ~/.claude/skills/$SKILL_NAME/SKILL.md"
echo ""
+63
View File
@@ -0,0 +1,63 @@
#!/bin/bash
# Check if Chinese translations are in sync with English originals
# Usage: ./scripts/check_translation_sync.sh
set -e
echo "🔍 Checking translation sync..."
echo ""
MISSING=0
OUT_OF_SYNC=0
# Find all English docs (excluding zh-CN and archive)
find docs -name "*.md" -not -path "docs/zh-CN/*" -not -path "docs/archive/*" | while read -r en_file; do
# Calculate corresponding Chinese file path
rel_path="${en_file#docs/}"
zh_file="docs/zh-CN/$rel_path"
# Check if Chinese version exists
if [ ! -f "$zh_file" ]; then
echo "❌ Missing: $zh_file (source: $en_file)"
MISSING=$((MISSING + 1))
continue
fi
# Get last modification times
en_mtime=$(git log -1 --format=%ct "$en_file" 2>/dev/null || stat -c %Y "$en_file" 2>/dev/null || echo 0)
zh_mtime=$(git log -1 --format=%ct "$zh_file" 2>/dev/null || stat -c %Y "$zh_file" 2>/dev/null || echo 0)
# Check if English is newer
if [ "$en_mtime" -gt "$zh_mtime" ]; then
echo "⚠️ Out of sync: $zh_file (English updated more recently)"
OUT_OF_SYNC=$((OUT_OF_SYNC + 1))
fi
done
echo ""
# Summary
TOTAL_EN=$(find docs -name "*.md" -not -path "docs/zh-CN/*" -not -path "docs/archive/*" | wc -l)
TOTAL_ZH=$(find docs/zh-CN -name "*.md" 2>/dev/null | wc -l)
echo "📊 Summary:"
echo " English docs: $TOTAL_EN"
echo " Chinese docs: $TOTAL_ZH"
if [ "$MISSING" -gt 0 ]; then
echo " ❌ Missing translations: $MISSING"
fi
if [ "$OUT_OF_SYNC" -gt 0 ]; then
echo " ⚠️ Out of sync: $OUT_OF_SYNC"
fi
if [ "$MISSING" -eq 0 ] && [ "$OUT_OF_SYNC" -eq 0 ]; then
echo ""
echo "✅ All translations in sync!"
exit 0
else
echo ""
echo "❌ Translation sync issues found"
exit 1
fi
+72
View File
@@ -0,0 +1,72 @@
#!/bin/bash
# Performance Benchmark Runner for Skill Seekers
# Runs comprehensive benchmarks for all platform adaptors
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Skill Seekers Performance Benchmarks ║${NC}"
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo ""
# Ensure we're in the project root
if [ ! -f "pyproject.toml" ]; then
echo -e "${RED}Error: Must run from project root${NC}"
exit 1
fi
# Check if package is installed
if ! python -c "import skill_seekers" 2>/dev/null; then
echo -e "${YELLOW}Package not installed. Installing...${NC}"
pip install -e . > /dev/null 2>&1
echo -e "${GREEN}✓ Package installed${NC}"
fi
echo -e "${BLUE}Running benchmark suite...${NC}"
echo ""
# Run benchmarks with pytest
if pytest tests/test_adaptor_benchmarks.py -v -m benchmark --tb=short -s; then
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ All Benchmarks Passed ✓ ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
# Summary
echo -e "${CYAN}Benchmark Summary:${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo "✓ format_skill_md() benchmarked across 11 adaptors"
echo "✓ Package operations benchmarked (time + size)"
echo "✓ Scaling behavior analyzed (1-50 references)"
echo "✓ JSON vs ZIP compression ratios measured"
echo "✓ Metadata processing overhead quantified"
echo "✓ Empty vs full skill performance compared"
echo ""
echo -e "${YELLOW}📊 Key Insights:${NC}"
echo "• All adaptors complete formatting in < 500ms"
echo "• Package operations complete in < 1 second"
echo "• Linear scaling confirmed (not exponential)"
echo "• Metadata overhead < 10%"
echo "• ZIP compression ratio: ~80-90x"
echo ""
exit 0
else
echo ""
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║ Some Benchmarks Failed ✗ ║${NC}"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}Check the output above for details${NC}"
exit 1
fi
+248
View File
@@ -0,0 +1,248 @@
#!/bin/bash
# Integration Test Runner with Docker Infrastructure
# Manages vector database services and runs integration tests
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
COMPOSE_FILE="tests/docker-compose.test.yml"
function print_header() {
echo -e "${CYAN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Skill Seekers Integration Test Runner ║${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
function check_docker() {
if ! command -v docker &> /dev/null; then
echo -e "${RED}Error: Docker not found${NC}"
echo "Please install Docker: https://docs.docker.com/get-docker/"
exit 1
fi
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
echo -e "${RED}Error: docker-compose not found${NC}"
echo "Please install docker-compose: https://docs.docker.com/compose/install/"
exit 1
fi
}
function start_services() {
echo -e "${BLUE}Starting test infrastructure...${NC}"
echo ""
# Use either docker-compose or docker compose
if command -v docker-compose &> /dev/null; then
docker-compose -f "$COMPOSE_FILE" up -d
else
docker compose -f "$COMPOSE_FILE" up -d
fi
echo ""
echo -e "${YELLOW}Waiting for services to be ready...${NC}"
sleep 5
# Check service health
local all_healthy=true
echo -n "Weaviate... "
if curl -s http://localhost:8080/v1/.well-known/ready > /dev/null 2>&1; then
echo -e "${GREEN}${NC}"
else
echo -e "${RED}${NC}"
all_healthy=false
fi
echo -n "Qdrant... "
if curl -s http://localhost:6333/ > /dev/null 2>&1; then
echo -e "${GREEN}${NC}"
else
echo -e "${RED}${NC}"
all_healthy=false
fi
echo -n "ChromaDB... "
if curl -s http://localhost:8000/api/v1/heartbeat > /dev/null 2>&1; then
echo -e "${GREEN}${NC}"
else
echo -e "${RED}${NC}"
all_healthy=false
fi
echo ""
if [ "$all_healthy" = false ]; then
echo -e "${YELLOW}Warning: Some services may not be ready yet${NC}"
echo -e "${YELLOW}Waiting an additional 10 seconds...${NC}"
sleep 10
fi
}
function stop_services() {
echo -e "${BLUE}Stopping test infrastructure...${NC}"
if command -v docker-compose &> /dev/null; then
docker-compose -f "$COMPOSE_FILE" down -v
else
docker compose -f "$COMPOSE_FILE" down -v
fi
echo -e "${GREEN}✓ Services stopped${NC}"
}
function run_tests() {
echo -e "${BLUE}Running integration tests...${NC}"
echo ""
# Install required packages if missing
local missing_packages=()
if ! python -c "import weaviate" 2>/dev/null; then
missing_packages+=("weaviate-client")
fi
if ! python -c "import chromadb" 2>/dev/null; then
missing_packages+=("chromadb")
fi
if ! python -c "import qdrant_client" 2>/dev/null; then
missing_packages+=("qdrant-client")
fi
if [ ${#missing_packages[@]} -gt 0 ]; then
echo -e "${YELLOW}Installing missing packages: ${missing_packages[*]}${NC}"
pip install "${missing_packages[@]}" > /dev/null 2>&1
echo -e "${GREEN}✓ Packages installed${NC}"
echo ""
fi
# Run tests
if pytest tests/test_integration_adaptors.py -v -m integration --tb=short; then
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ All Integration Tests Passed ✓ ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
return 0
else
echo ""
echo -e "${RED}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║ Some Integration Tests Failed ✗ ║${NC}"
echo -e "${RED}╚════════════════════════════════════════════════════════════╝${NC}"
return 1
fi
}
function show_logs() {
echo -e "${BLUE}Showing service logs...${NC}"
echo ""
if command -v docker-compose &> /dev/null; then
docker-compose -f "$COMPOSE_FILE" logs --tail=50
else
docker compose -f "$COMPOSE_FILE" logs --tail=50
fi
}
function show_status() {
echo -e "${BLUE}Service status:${NC}"
echo ""
if command -v docker-compose &> /dev/null; then
docker-compose -f "$COMPOSE_FILE" ps
else
docker compose -f "$COMPOSE_FILE" ps
fi
}
function show_help() {
echo "Integration Test Runner"
echo ""
echo "Usage: $0 [command]"
echo ""
echo "Commands:"
echo " start Start vector database services"
echo " stop Stop and clean up services"
echo " test Run integration tests"
echo " run Start services + run tests + stop services (default)"
echo " logs Show service logs"
echo " status Show service status"
echo " help Show this help message"
echo ""
echo "Examples:"
echo " $0 # Run complete workflow"
echo " $0 start # Just start services"
echo " $0 test # Run tests (services must be running)"
echo " $0 stop # Stop all services"
}
# Main script
print_header
check_docker
# Parse command
COMMAND="${1:-run}"
case "$COMMAND" in
start)
start_services
echo ""
echo -e "${GREEN}Services started successfully!${NC}"
echo "Run tests with: $0 test"
;;
stop)
stop_services
;;
test)
run_tests
;;
run)
echo -e "${CYAN}Running complete workflow:${NC}"
echo "1. Start services"
echo "2. Run tests"
echo "3. Stop services"
echo ""
start_services
echo ""
if run_tests; then
TEST_RESULT=0
else
TEST_RESULT=1
fi
echo ""
stop_services
exit $TEST_RESULT
;;
logs)
show_logs
;;
status)
show_status
;;
help|--help|-h)
show_help
;;
*)
echo -e "${RED}Unknown command: $COMMAND${NC}"
echo ""
show_help
exit 1
;;
esac
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# Fast parallel test runner for local development.
# Phase 1: Fast unit tests with xdist (~2-3 min)
# Phase 2: Serial/Integration/E2E tests (~10-15 min)
# Phase 3: MCP tests (if MCP installed)
set -e
MCP_SKIP="--ignore=tests/test_mcp_server.py --ignore=tests/test_mcp_fastmcp.py --ignore=tests/test_install_skill_e2e.py --ignore=tests/test_unified_mcp_integration.py --ignore=tests/test_mcp_git_sources.py --ignore=tests/test_mcp_vector_dbs.py --ignore=tests/test_mcp_workflow_tools.py --ignore=tests/test_server_fastmcp_http.py"
INTEGRATION_SKIP="--ignore=tests/test_real_world_fastmcp.py --ignore=tests/test_issue_277_discord_e2e.py --ignore=tests/test_browser_renderer.py --ignore=tests/test_integration_adaptors.py --ignore=tests/test_bootstrap_skill_e2e.py --ignore=tests/test_git_sources_e2e.py --ignore=tests/test_marketplace_publisher.py --ignore=tests/test_sync_config_e2e.py --ignore=tests/test_estimate_pages.py"
echo "=== Phase 1: Fast Unit Tests (parallel) ==="
pytest tests/ -n auto --dist=loadfile \
${MCP_SKIP} ${INTEGRATION_SKIP} \
-m "not slow and not integration and not e2e and not network and not serial" \
-q --timeout=120 "$@"
echo ""
echo "=== Phase 2: Serial/Integration/E2E Tests ==="
pytest tests/ \
-m "integration or e2e or slow or network or serial" \
-v --timeout=300 "$@"
echo ""
echo "=== Phase 3: MCP Tests ==="
python -c "import mcp" 2>/dev/null && {
pytest tests/test_mcp_server.py tests/test_mcp_fastmcp.py \
tests/test_mcp_git_sources.py tests/test_mcp_vector_dbs.py \
tests/test_mcp_workflow_tools.py tests/test_unified_mcp_integration.py \
tests/test_server_fastmcp_http.py tests/test_install_skill.py \
tests/test_install_skill_e2e.py \
-v --timeout=180 "$@"
} || echo "MCP not installed — skipping Phase 3"
echo ""
echo "All phases complete."
+43
View File
@@ -0,0 +1,43 @@
---
name: skill-seekers
description: Generate LLM skills from documentation, codebases, and GitHub repositories
---
# Skill Seekers
## Prerequisites
```bash
pip install skill-seekers
# Or: uv pip install skill-seekers
```
## Commands
| Source | Command |
|--------|---------|
| Local code | `skill-seekers create ./path` |
| Docs URL | `skill-seekers create https://docs.example.com` |
| GitHub | `skill-seekers create owner/repo` |
| PDF | `skill-seekers create document.pdf` |
## Quick Start
```bash
# Analyze local codebase
skill-seekers create /path/to/project --name my-skill
# Package for Claude
yes | skill-seekers package output/my-skill/ --no-open
```
## Options
| Flag | Description |
|------|-------------|
| `--preset quick/standard/comprehensive` | Analysis preset |
| `--skip-patterns` | Skip pattern detection |
| `--skip-test-examples` | Skip test extraction |
---
+246
View File
@@ -0,0 +1,246 @@
#!/usr/bin/env python3
"""
Translate Skill Seekers documentation to Chinese.
Usage:
python scripts/translate_doc.py <file> --target-lang zh-CN
python scripts/translate_doc.py docs/getting-started/02-quick-start.md
"""
import argparse
import os
import re
from pathlib import Path
from datetime import datetime
def get_version() -> str:
"""Get current version from package."""
try:
from skill_seekers import __version__
return __version__
except ImportError:
return "3.1.0"
def translate_with_anthropic(content: str, api_key: str) -> str:
"""Translate content using Anthropic Claude API."""
try:
import anthropic
client = anthropic.Anthropic(api_key=api_key)
system_prompt = """You are a professional technical translator translating Skill Seekers documentation from English to Simplified Chinese.
Translation rules:
1. Keep technical terms in English: CLI, API, JSON, YAML, MCP, URL, HTTP, etc.
2. Keep code examples, commands, and file paths in English
3. Keep proper nouns (product names, company names) in English
4. Use Simplified Chinese (简体中文)
5. Maintain all Markdown formatting
6. Translate link text but keep link targets (will be handled separately)
7. Use professional, technical Chinese appropriate for developers
8. Preserve all code blocks, they should remain exactly the same
Output ONLY the translated content, no explanations."""
message = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=8000,
temperature=0.1,
system=system_prompt,
messages=[
{
"role": "user",
"content": f"Translate this technical documentation to Simplified Chinese:\n\n{content}"
}
]
)
return message.content[0].text
except Exception as e:
print(f"Translation API error: {e}")
return None
def add_translation_header(content: str, original_file: Path, target_lang: str) -> str:
"""Add translation header to document."""
version = get_version()
date = datetime.now().strftime("%Y-%m-%d")
original_name = original_file.name
# Calculate relative path from docs/
try:
relative_path = original_file.relative_to("docs")
original_link = f"../{relative_path}"
except ValueError:
original_link = f"../{original_file.name}"
header = f"""> **注意:** 本文档是 [{original_name}]({original_link}) 的中文翻译。
>
> - **最后翻译日期:** {date}
> - **英文原文版本:** {version}
> - **翻译状态:** ⚠️ 待审阅
>
> 如果本文档与英文版本有冲突,请以英文版本为准。
>
> ---
>
> **Note:** This document is a Chinese translation of [{original_name}]({original_link}).
>
> - **Last translated:** {date}
> - **Original version:** {version}
> - **Translation status:** ⚠️ Pending review
>
> If there are conflicts, the English version takes precedence.
---
"""
return header + content
def fix_links(content: str, original_file: Path) -> str:
"""Fix internal links to point to Chinese versions."""
# Pattern for markdown links: [text](path)
# We need to convert links to other docs to point to zh-CN versions
def replace_link(match):
text = match.group(1)
path = match.group(2)
# Skip external links
if path.startswith(('http://', 'https://', '#', 'mailto:')):
return match.group(0)
# Skip anchor-only links
if path.startswith('#'):
return match.group(0)
# For relative links to other md files, adjust path
if path.endswith('.md'):
# If it's a relative link, it should point to zh-CN version
if not path.startswith('/'):
# Count directory levels
depth = len(original_file.parent.parts) - 1 # -1 for 'docs'
if depth > 0:
# Going up to docs/, then into zh-CN/
prefix = '../' * depth
new_path = prefix + 'zh-CN/' + path.lstrip('./')
else:
new_path = 'zh-CN/' + path
return f'[{text}]({new_path})'
return match.group(0)
# Replace markdown links
content = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', replace_link, content)
return content
def translate_file(input_path: str, target_lang: str = "zh-CN"):
"""Translate a documentation file."""
input_file = Path(input_path).resolve()
if not input_file.exists():
print(f"❌ File not found: {input_file}")
return False
# Read English content
with open(input_file, 'r', encoding='utf-8') as f:
content = f.read()
# Remove existing translation header if present (for re-translation)
if '> **注意:**' in content[:500]:
# Find the separator and remove everything before it
separator_pos = content.find('---\n\n')
if separator_pos != -1:
content = content[separator_pos + 5:]
# Translate content
api_key = os.environ.get('ANTHROPIC_API_KEY')
if api_key:
print(f"🤖 Translating with Claude API: {input_file.name}")
translated = translate_with_anthropic(content, api_key)
if translated:
content = translated
else:
print(f"⚠️ Translation failed, keeping original content for: {input_file.name}")
else:
print(f"⚠️ No ANTHROPIC_API_KEY, skipping translation for: {input_file.name}")
return False
# Fix internal links
content = fix_links(content, input_file)
# Add translation header
content = add_translation_header(content, input_file, target_lang)
# Determine output path
try:
relative_path = input_file.relative_to(Path("docs").resolve())
except ValueError:
# If file is not in docs/, use just the filename
relative_path = Path(input_file.name)
output_file = Path("docs") / target_lang / relative_path
output_file.parent.mkdir(parents=True, exist_ok=True)
# Write translated content
with open(output_file, 'w', encoding='utf-8') as f:
f.write(content)
print(f"✅ Created: {output_file}")
return True
def main():
parser = argparse.ArgumentParser(
description="Translate Skill Seekers documentation to Chinese"
)
parser.add_argument(
"file",
nargs='?',
help="Path to the documentation file to translate (not needed with --batch)"
)
parser.add_argument(
"--target-lang",
default="zh-CN",
help="Target language code (default: zh-CN)"
)
parser.add_argument(
"--batch",
action="store_true",
help="Translate all documentation files"
)
args = parser.parse_args()
if args.batch:
# Translate all docs
docs_dir = Path("docs")
files_to_translate = []
for pattern in ["**/*.md"]:
files = list(docs_dir.glob(pattern))
for f in files:
# Skip already translated files and archive
if "zh-CN" not in str(f) and "archive" not in str(f):
files_to_translate.append(f)
print(f"🔄 Batch translating {len(files_to_translate)} files...")
success_count = 0
for f in files_to_translate:
if translate_file(str(f), args.target_lang):
success_count += 1
print(f"\n✅ Successfully translated {success_count}/{len(files_to_translate)} files")
else:
# Translate single file
translate_file(args.file, args.target_lang)
if __name__ == "__main__":
main()