Files
wehub-resource-sync 2cab53bc94
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers CLI - Convert documentation to AI skills dockerfile:Dockerfile name:skill-seekers]) (push) Waiting to run
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) Waiting to run
Docker Publish / Test Docker Images (push) Blocked by required conditions
Test Vector Database Adaptors / Test chroma Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test faiss Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test qdrant Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test weaviate Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test MCP Vector DB Tools (push) Waiting to run
Tests / Code Quality (Ruff & Mypy) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (macos-latest, 3.11) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (macos-latest, 3.12) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.10) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.11) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.12) (push) Waiting to run
Tests / Tests (push) Blocked by required conditions
Tests / Serial / Integration / E2E Tests (push) Blocked by required conditions
Tests / MCP Server Tests (push) Blocked by required conditions
chore: import upstream snapshot with attribution
2026-07-13 12:46:28 +08:00

285 lines
7.4 KiB
Python

#!/usr/bin/env python3
"""
HTTP Context Provider Server for Continue.dev
Serves framework documentation as Continue.dev context items.
Supports multiple frameworks from Skill Seekers output.
Usage:
python context_server.py
python context_server.py --host 0.0.0.0 --port 8765
"""
import argparse
from pathlib import Path
from functools import lru_cache
from typing import Dict, List
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
app = FastAPI(
title="Skill Seekers Context Server",
description="HTTP context provider for Continue.dev",
version="1.0.0"
)
# Add CORS middleware for browser access
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@lru_cache(maxsize=100)
def load_framework_docs(framework: str) -> str:
"""
Load framework documentation from Skill Seekers output.
Args:
framework: Framework name (vue, react, django, etc.)
Returns:
Documentation content as string
Raises:
FileNotFoundError: If documentation not found
"""
# Try multiple possible locations
possible_paths = [
Path(f"output/{framework}-markdown/SKILL.md"),
Path(f"../../output/{framework}-markdown/SKILL.md"),
Path(f"../../../output/{framework}-markdown/SKILL.md"),
]
for doc_path in possible_paths:
if doc_path.exists():
with open(doc_path, 'r', encoding='utf-8') as f:
return f.read()
raise FileNotFoundError(
f"Documentation not found for framework: {framework}\n"
f"Tried paths: {[str(p) for p in possible_paths]}\n"
f"Run: skill-seekers create --config configs/{framework}.json"
)
@app.get("/")
async def root():
"""Root endpoint with server information."""
return {
"name": "Skill Seekers Context Server",
"description": "HTTP context provider for Continue.dev",
"version": "1.0.0",
"endpoints": {
"/docs/{framework}": "Get framework documentation",
"/frameworks": "List available frameworks",
"/health": "Health check"
}
}
@app.get("/health")
async def health():
"""Health check endpoint."""
return {"status": "healthy"}
@app.get("/frameworks")
async def list_frameworks() -> Dict[str, List[str]]:
"""
List available frameworks.
Returns:
Dictionary with available and missing frameworks
"""
# Check common framework locations
output_dir = Path("output")
if not output_dir.exists():
output_dir = Path("../../output")
if not output_dir.exists():
output_dir = Path("../../../output")
if not output_dir.exists():
return {
"available": [],
"message": "No output directory found. Run skill-seekers to generate documentation."
}
# Find all *-markdown directories
available = []
for item in output_dir.glob("*-markdown"):
framework = item.name.replace("-markdown", "")
skill_file = item / "SKILL.md"
if skill_file.exists():
available.append(framework)
return {
"available": available,
"count": len(available),
"usage": "GET /docs/{framework} to access documentation"
}
@app.get("/docs/{framework}")
async def get_framework_docs(framework: str, query: str = None) -> JSONResponse:
"""
Get framework documentation as Continue.dev context items.
Args:
framework: Framework name (vue, react, django, etc.)
query: Optional search query for filtering (future feature)
Returns:
JSON response with contextItems array for Continue.dev
"""
try:
# Load documentation (cached)
docs = load_framework_docs(framework)
# TODO: Implement query filtering if provided
if query:
# Filter docs based on query (simplified)
# In production, use better search (regex, fuzzy matching, etc.)
pass
# Return in Continue.dev format
return JSONResponse({
"contextItems": [
{
"name": f"{framework.title()} Documentation",
"description": f"Complete {framework} framework expert knowledge",
"content": docs
}
]
})
except FileNotFoundError as e:
raise HTTPException(
status_code=404,
detail=str(e)
)
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Error loading documentation: {str(e)}"
)
@app.get("/project/conventions")
async def get_project_conventions() -> JSONResponse:
"""
Get project-specific conventions.
Returns:
JSON response with project conventions
"""
# Load project conventions if they exist
conventions_path = Path(".project-conventions.md")
if conventions_path.exists():
with open(conventions_path, 'r') as f:
content = f.read()
else:
# Default conventions
content = """
# Project Conventions
## General
- Use TypeScript for all new code
- Follow framework-specific best practices
- Write tests for all features
## Git Workflow
- Feature branch workflow
- Squash commits before merge
- Descriptive commit messages
## Code Style
- Use prettier for formatting
- ESLint for linting
- Follow team conventions
"""
return JSONResponse({
"contextItems": [
{
"name": "Project Conventions",
"description": "Team coding standards and conventions",
"content": content
}
]
})
def main():
parser = argparse.ArgumentParser(
description="HTTP Context Provider Server for Continue.dev"
)
parser.add_argument(
"--host",
type=str,
default="127.0.0.1",
help="Host to bind to (default: 127.0.0.1, use 0.0.0.0 for all interfaces)"
)
parser.add_argument(
"--port",
type=int,
default=8765,
help="Port to bind to (default: 8765)"
)
parser.add_argument(
"--reload",
action="store_true",
help="Enable auto-reload on code changes (development)"
)
args = parser.parse_args()
print("=" * 60)
print("Skill Seekers Context Server for Continue.dev")
print("=" * 60)
print(f"Server: http://{args.host}:{args.port}")
print(f"Endpoints:")
print(f" - GET / # Server info")
print(f" - GET /health # Health check")
print(f" - GET /frameworks # List available frameworks")
print(f" - GET /docs/{{framework}} # Get framework docs")
print(f" - GET /project/conventions # Get project conventions")
print("=" * 60)
print(f"\nConfigure Continue.dev:")
print(f"""
{{
"contextProviders": [
{{
"name": "http",
"params": {{
"url": "http://{args.host}:{args.port}/docs/vue",
"title": "vue-docs",
"displayTitle": "Vue.js Documentation"
}}
}}
]
}}
""")
print("=" * 60)
print("\nPress Ctrl+C to stop\n")
# Run server
uvicorn.run(
app,
host=args.host,
port=args.port,
reload=args.reload,
log_level="info"
)
if __name__ == "__main__":
main()