feat: Complete Phase 1 - AI Coding Assistant Integrations (v2.10.0)
Add comprehensive integration guides for 4 AI coding assistants: ## New Integration Guides (98KB total) - docs/integrations/WINDSURF.md (20KB) - Windsurf IDE with .windsurfrules - docs/integrations/CLINE.md (25KB) - Cline VS Code extension with MCP - docs/integrations/CONTINUE_DEV.md (28KB) - Continue.dev for any IDE - docs/integrations/INTEGRATIONS.md (25KB) - Comprehensive hub with decision tree ## Working Examples (3 directories, 11 files) - examples/windsurf-fastapi-context/ - FastAPI + Windsurf automation - examples/cline-django-assistant/ - Django + Cline with MCP server - examples/continue-dev-universal/ - HTTP context server for all IDEs ## README.md Updates - Updated tagline: Universal preprocessor for 10+ AI systems - Expanded Supported Integrations table (7 → 10 platforms) - Added 'AI Coding Assistant Integrations' section (60+ lines) - Cross-links to all new guides and examples ## Impact - Week 2 of ACTION_PLAN.md: 4/4 tasks complete (100%) ✅ - Total new documentation: ~3,000 lines - Total new code: ~1,000 lines (automation scripts, servers) - Integration coverage: LangChain, LlamaIndex, Pinecone, Cursor, Windsurf, Cline, Continue.dev, Claude, Gemini, ChatGPT ## Key Features - All guides follow proven 11-section pattern from CURSOR.md - Real-world examples with automation scripts - Multi-IDE consistency (Continue.dev works in VS Code, JetBrains, Vim) - MCP integration for dynamic documentation access - Complete troubleshooting sections with solutions Positions Skill Seekers as universal preprocessor for ANY AI system. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
597
examples/continue-dev-universal/README.md
Normal file
597
examples/continue-dev-universal/README.md
Normal file
@@ -0,0 +1,597 @@
|
||||
# Continue.dev + Universal Context Example
|
||||
|
||||
Complete example showing how to use Skill Seekers to create IDE-agnostic context providers for Continue.dev across VS Code, JetBrains, and other IDEs.
|
||||
|
||||
## What This Example Does
|
||||
|
||||
- ✅ Generates framework documentation (Vue.js example)
|
||||
- ✅ Creates HTTP context provider server
|
||||
- ✅ Works across all IDEs (VS Code, IntelliJ, PyCharm, WebStorm, etc.)
|
||||
- ✅ Single configuration, consistent results
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Generate Documentation
|
||||
|
||||
```bash
|
||||
# Install Skill Seekers
|
||||
pip install skill-seekers[mcp]
|
||||
|
||||
# Generate Vue.js documentation
|
||||
skill-seekers scrape --config configs/vue.json
|
||||
skill-seekers package output/vue --target markdown
|
||||
```
|
||||
|
||||
### 2. Start Context Server
|
||||
|
||||
```bash
|
||||
# Use the provided HTTP context server
|
||||
python context_server.py
|
||||
|
||||
# Server runs on http://localhost:8765
|
||||
# Serves documentation at /docs/{framework}
|
||||
```
|
||||
|
||||
### 3. Configure Continue.dev
|
||||
|
||||
Edit `~/.continue/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/vue",
|
||||
"title": "vue-docs",
|
||||
"displayTitle": "Vue.js Documentation",
|
||||
"description": "Vue.js framework expert knowledge"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Test in Any IDE
|
||||
|
||||
**VS Code:**
|
||||
```bash
|
||||
code my-vue-project/
|
||||
# Open Continue panel (Cmd+L)
|
||||
# Type: @vue-docs Create a Vue 3 component with Composition API
|
||||
```
|
||||
|
||||
**IntelliJ IDEA:**
|
||||
```bash
|
||||
idea my-vue-project/
|
||||
# Open Continue panel (Cmd+L)
|
||||
# Type: @vue-docs Create a Vue 3 component with Composition API
|
||||
```
|
||||
|
||||
**Result:** IDENTICAL suggestions in both IDEs!
|
||||
|
||||
## Expected Results
|
||||
|
||||
### Before (Without Context Provider)
|
||||
|
||||
**Prompt:** "Create a Vue component"
|
||||
|
||||
**Continue Output:**
|
||||
```javascript
|
||||
export default {
|
||||
name: 'MyComponent',
|
||||
data() {
|
||||
return {
|
||||
message: 'Hello'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
❌ Uses Options API (outdated)
|
||||
❌ No TypeScript
|
||||
❌ No Composition API
|
||||
❌ Generic patterns
|
||||
|
||||
### After (With Context Provider)
|
||||
|
||||
**Prompt:** "@vue-docs Create a Vue component"
|
||||
|
||||
**Continue Output:**
|
||||
```typescript
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
interface Props {
|
||||
title: string
|
||||
count?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
count: 0
|
||||
})
|
||||
|
||||
const message = ref('Hello')
|
||||
const displayCount = computed(() => props.count * 2)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>{{ props.title }}</h2>
|
||||
<p>{{ message }} - Count: {{ displayCount }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Component styles */
|
||||
</style>
|
||||
```
|
||||
|
||||
✅ Composition API with `<script setup>`
|
||||
✅ TypeScript interfaces
|
||||
✅ Proper props definition
|
||||
✅ Vue 3 best practices
|
||||
|
||||
## Files in This Example
|
||||
|
||||
- `context_server.py` - HTTP context provider server (FastAPI)
|
||||
- `quickstart.py` - Automation script for setup
|
||||
- `requirements.txt` - Python dependencies
|
||||
- `config.example.json` - Sample Continue.dev configuration
|
||||
|
||||
## Multi-IDE Testing
|
||||
|
||||
This example demonstrates IDE consistency:
|
||||
|
||||
### Test 1: VS Code
|
||||
```bash
|
||||
cd examples/continue-dev-universal
|
||||
python context_server.py &
|
||||
|
||||
code test-project/
|
||||
# In Continue: @vue-docs Create a component
|
||||
# Note the exact code generated
|
||||
```
|
||||
|
||||
### Test 2: IntelliJ IDEA
|
||||
```bash
|
||||
# Same server still running
|
||||
idea test-project/
|
||||
# In Continue: @vue-docs Create a component
|
||||
# Code should be IDENTICAL to VS Code
|
||||
```
|
||||
|
||||
### Test 3: PyCharm
|
||||
```bash
|
||||
# Same server still running
|
||||
pycharm test-project/
|
||||
# In Continue: @vue-docs Create a component
|
||||
# Code should be IDENTICAL to both above
|
||||
```
|
||||
|
||||
**Why it works:** Continue.dev uses the SAME `~/.continue/config.json` across all IDEs!
|
||||
|
||||
## Context Server Architecture
|
||||
|
||||
The `context_server.py` implements a simple HTTP server:
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from skill_seekers.cli.doc_scraper import load_skill
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@app.get("/docs/{framework}")
|
||||
async def get_framework_docs(framework: str):
|
||||
"""
|
||||
Serve framework documentation as Continue context.
|
||||
|
||||
Args:
|
||||
framework: Framework name (vue, react, django, etc.)
|
||||
|
||||
Returns:
|
||||
JSON with contextItems array
|
||||
"""
|
||||
# Load documentation
|
||||
docs = load_skill(f"output/{framework}-markdown/SKILL.md")
|
||||
|
||||
return {
|
||||
"contextItems": [
|
||||
{
|
||||
"name": f"{framework.title()} Documentation",
|
||||
"description": f"Complete {framework} framework knowledge",
|
||||
"content": docs
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Multi-Framework Support
|
||||
|
||||
Add more frameworks easily:
|
||||
|
||||
```bash
|
||||
# Generate React docs
|
||||
skill-seekers scrape --config configs/react.json
|
||||
skill-seekers package output/react --target markdown
|
||||
|
||||
# Generate Django docs
|
||||
skill-seekers scrape --config configs/django.json
|
||||
skill-seekers package output/django --target markdown
|
||||
|
||||
# Server automatically serves both at:
|
||||
# http://localhost:8765/docs/react
|
||||
# http://localhost:8765/docs/django
|
||||
```
|
||||
|
||||
Update `~/.continue/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/vue",
|
||||
"title": "vue-docs",
|
||||
"displayTitle": "Vue.js"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/react",
|
||||
"title": "react-docs",
|
||||
"displayTitle": "React"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/django",
|
||||
"title": "django-docs",
|
||||
"displayTitle": "Django"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Now you can use:
|
||||
```
|
||||
@vue-docs @react-docs @django-docs Create a full-stack app
|
||||
```
|
||||
|
||||
## Team Deployment
|
||||
|
||||
### Option 1: Shared Server
|
||||
|
||||
```bash
|
||||
# Run on team server
|
||||
ssh team-server
|
||||
python context_server.py --host 0.0.0.0 --port 8765
|
||||
|
||||
# Team members update config:
|
||||
{
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://team-server.company.com:8765/docs/vue",
|
||||
"title": "vue-docs"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Option 2: Docker Deployment
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
COPY context_server.py .
|
||||
COPY output/ output/
|
||||
|
||||
EXPOSE 8765
|
||||
CMD ["python", "context_server.py", "--host", "0.0.0.0"]
|
||||
```
|
||||
|
||||
```bash
|
||||
# Build and run
|
||||
docker build -t skill-seekers-context .
|
||||
docker run -d -p 8765:8765 skill-seekers-context
|
||||
|
||||
# Team uses: http://your-server:8765/docs/vue
|
||||
```
|
||||
|
||||
### Option 3: Kubernetes Deployment
|
||||
|
||||
```yaml
|
||||
# deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: skill-seekers-context
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: skill-seekers-context
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: skill-seekers-context
|
||||
spec:
|
||||
containers:
|
||||
- name: context-server
|
||||
image: skill-seekers-context:latest
|
||||
ports:
|
||||
- containerPort: 8765
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: skill-seekers-context
|
||||
spec:
|
||||
selector:
|
||||
app: skill-seekers-context
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8765
|
||||
type: LoadBalancer
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Add Project-Specific Context
|
||||
|
||||
```python
|
||||
# In context_server.py
|
||||
|
||||
@app.get("/project/conventions")
|
||||
async def get_project_conventions():
|
||||
"""Serve company-specific patterns."""
|
||||
return {
|
||||
"contextItems": [{
|
||||
"name": "Project Conventions",
|
||||
"description": "Company coding standards",
|
||||
"content": """
|
||||
# Company Coding Standards
|
||||
|
||||
## Vue Components
|
||||
- Always use Composition API
|
||||
- TypeScript is required
|
||||
- Props must have interfaces
|
||||
- Use Pinia for state management
|
||||
|
||||
## API Calls
|
||||
- Use axios with interceptors
|
||||
- All endpoints must be typed
|
||||
- Error handling with try/catch
|
||||
- Loading states required
|
||||
"""
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
Add to Continue config:
|
||||
|
||||
```json
|
||||
{
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/vue",
|
||||
"title": "vue-docs"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/project/conventions",
|
||||
"title": "conventions",
|
||||
"displayTitle": "Company Standards"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Now use both:
|
||||
```
|
||||
@vue-docs @conventions Create a component following our standards
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: Context provider not showing
|
||||
|
||||
**Solution:** Check server is running
|
||||
```bash
|
||||
curl http://localhost:8765/docs/vue
|
||||
# Should return JSON
|
||||
|
||||
# If not running:
|
||||
python context_server.py
|
||||
```
|
||||
|
||||
### Issue: Different results in different IDEs
|
||||
|
||||
**Solution:** Verify same config file
|
||||
```bash
|
||||
# All IDEs use same config
|
||||
cat ~/.continue/config.json
|
||||
|
||||
# NOT project-specific configs
|
||||
# (those would cause inconsistency)
|
||||
```
|
||||
|
||||
### Issue: Documentation outdated
|
||||
|
||||
**Solution:** Re-generate and restart
|
||||
```bash
|
||||
skill-seekers scrape --config configs/vue.json
|
||||
skill-seekers package output/vue --target markdown
|
||||
|
||||
# Restart server (will load new docs)
|
||||
pkill -f context_server.py
|
||||
python context_server.py
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### RAG Integration
|
||||
|
||||
```python
|
||||
# rag_context_server.py
|
||||
from langchain_community.vectorstores import Chroma
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
|
||||
# Load vector store
|
||||
embeddings = OpenAIEmbeddings()
|
||||
vectorstore = Chroma(
|
||||
persist_directory="./chroma_db",
|
||||
embedding_function=embeddings
|
||||
)
|
||||
|
||||
@app.get("/docs/search")
|
||||
async def search_docs(query: str, k: int = 5):
|
||||
"""RAG-powered search."""
|
||||
results = vectorstore.similarity_search(query, k=k)
|
||||
|
||||
return {
|
||||
"contextItems": [
|
||||
{
|
||||
"name": f"Result {i+1}",
|
||||
"description": doc.metadata.get("source", "Docs"),
|
||||
"content": doc.page_content
|
||||
}
|
||||
for i, doc in enumerate(results)
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Continue config:
|
||||
|
||||
```json
|
||||
{
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/search?query={query}",
|
||||
"title": "rag-search",
|
||||
"displayTitle": "RAG Search"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### MCP Integration
|
||||
|
||||
```bash
|
||||
# Install MCP support
|
||||
pip install skill-seekers[mcp]
|
||||
|
||||
# Continue config with MCP
|
||||
{
|
||||
"mcpServers": {
|
||||
"skill-seekers": {
|
||||
"command": "python",
|
||||
"args": ["-m", "skill_seekers.mcp.server_fastmcp", "--transport", "stdio"]
|
||||
}
|
||||
},
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "mcp",
|
||||
"params": {
|
||||
"serverName": "skill-seekers"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Tips
|
||||
|
||||
### 1. Cache Documentation
|
||||
|
||||
```python
|
||||
from functools import lru_cache
|
||||
|
||||
@lru_cache(maxsize=100)
|
||||
def load_cached_docs(framework: str) -> str:
|
||||
"""Cache docs in memory."""
|
||||
return load_skill(f"output/{framework}-markdown/SKILL.md")
|
||||
```
|
||||
|
||||
### 2. Compress Responses
|
||||
|
||||
```python
|
||||
from fastapi.responses import JSONResponse
|
||||
import gzip
|
||||
|
||||
@app.get("/docs/{framework}")
|
||||
async def get_docs(framework: str):
|
||||
docs = load_cached_docs(framework)
|
||||
|
||||
# Compress if large
|
||||
if len(docs) > 10000:
|
||||
docs = gzip.compress(docs.encode()).decode('latin1')
|
||||
|
||||
return JSONResponse(...)
|
||||
```
|
||||
|
||||
### 3. Load Balancing
|
||||
|
||||
```bash
|
||||
# Run multiple instances
|
||||
python context_server.py --port 8765 &
|
||||
python context_server.py --port 8766 &
|
||||
python context_server.py --port 8767 &
|
||||
|
||||
# Configure Continue with failover
|
||||
{
|
||||
"contextProviders": [
|
||||
{
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": "http://localhost:8765/docs/vue",
|
||||
"fallbackUrls": [
|
||||
"http://localhost:8766/docs/vue",
|
||||
"http://localhost:8767/docs/vue"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Related Examples
|
||||
|
||||
- [Cursor Example](../cursor-react-skill/) - IDE-specific approach
|
||||
- [Windsurf Example](../windsurf-fastapi-context/) - Windsurf IDE
|
||||
- [Cline Example](../cline-django-assistant/) - VS Code extension
|
||||
- [LangChain RAG Example](../langchain-rag-pipeline/) - RAG integration
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Add more frameworks for full-stack development
|
||||
2. Deploy to team server for shared access
|
||||
3. Integrate with RAG for deep search
|
||||
4. Create project-specific context providers
|
||||
5. Set up CI/CD for automatic documentation updates
|
||||
|
||||
## Support
|
||||
|
||||
- **Skill Seekers Issues:** [GitHub](https://github.com/yusufkaraaslan/Skill_Seekers/issues)
|
||||
- **Continue.dev Docs:** [docs.continue.dev](https://docs.continue.dev/)
|
||||
- **Integration Guide:** [CONTINUE_DEV.md](../../docs/integrations/CONTINUE_DEV.md)
|
||||
284
examples/continue-dev-universal/context_server.py
Normal file
284
examples/continue-dev-universal/context_server.py
Normal file
@@ -0,0 +1,284 @@
|
||||
#!/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 scrape --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()
|
||||
190
examples/continue-dev-universal/quickstart.py
Normal file
190
examples/continue-dev-universal/quickstart.py
Normal file
@@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Quickstart script for Continue.dev + Skill Seekers integration.
|
||||
|
||||
Usage:
|
||||
python quickstart.py --framework vue
|
||||
python quickstart.py --framework django --skip-scrape
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_command(cmd: list[str], description: str) -> bool:
|
||||
"""Run a shell command and return success status."""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"STEP: {description}")
|
||||
print(f"{'='*60}")
|
||||
print(f"Running: {' '.join(cmd)}\n")
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
if result.stdout:
|
||||
print(result.stdout)
|
||||
if result.stderr:
|
||||
print(result.stderr, file=sys.stderr)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f"❌ ERROR: {description} failed with code {result.returncode}")
|
||||
return False
|
||||
|
||||
print(f"✅ SUCCESS: {description}")
|
||||
return True
|
||||
|
||||
|
||||
def create_continue_config(framework: str, port: int = 8765) -> Path:
|
||||
"""
|
||||
Create Continue.dev configuration.
|
||||
|
||||
Args:
|
||||
framework: Framework name
|
||||
port: Context server port
|
||||
|
||||
Returns:
|
||||
Path to created config file
|
||||
"""
|
||||
config_dir = Path.home() / ".continue"
|
||||
config_dir.mkdir(exist_ok=True)
|
||||
|
||||
config_path = config_dir / "config.json"
|
||||
|
||||
# Load existing config or create new
|
||||
if config_path.exists():
|
||||
with open(config_path, 'r') as f:
|
||||
config = json.load(f)
|
||||
else:
|
||||
config = {
|
||||
"models": [],
|
||||
"contextProviders": []
|
||||
}
|
||||
|
||||
# Add context provider for this framework
|
||||
provider = {
|
||||
"name": "http",
|
||||
"params": {
|
||||
"url": f"http://localhost:{port}/docs/{framework}",
|
||||
"title": f"{framework}-docs",
|
||||
"displayTitle": f"{framework.title()} Documentation",
|
||||
"description": f"{framework} framework expert knowledge"
|
||||
}
|
||||
}
|
||||
|
||||
# Check if already exists
|
||||
existing = [
|
||||
p for p in config.get("contextProviders", [])
|
||||
if p.get("params", {}).get("title") == provider["params"]["title"]
|
||||
]
|
||||
|
||||
if not existing:
|
||||
config.setdefault("contextProviders", []).append(provider)
|
||||
print(f"✅ Added {framework} context provider to Continue config")
|
||||
else:
|
||||
print(f"⏭️ {framework} context provider already exists in Continue config")
|
||||
|
||||
# Save config
|
||||
with open(config_path, 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
|
||||
return config_path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Quickstart script for Continue.dev + Skill Seekers"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--framework",
|
||||
type=str,
|
||||
required=True,
|
||||
help="Framework to generate documentation for (vue, react, django, etc.)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-scrape",
|
||||
action="store_true",
|
||||
help="Skip scraping step (use existing output)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--port",
|
||||
type=int,
|
||||
default=8765,
|
||||
help="Context server port (default: 8765)"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
framework = args.framework.lower()
|
||||
output_dir = Path(f"output/{framework}")
|
||||
|
||||
print("=" * 60)
|
||||
print("Continue.dev + Skill Seekers Quickstart")
|
||||
print("=" * 60)
|
||||
print(f"Framework: {framework}")
|
||||
print(f"Context server port: {args.port}")
|
||||
print("=" * 60)
|
||||
|
||||
# Step 1: Scrape documentation (unless skipped)
|
||||
if not args.skip_scrape:
|
||||
if not run_command(
|
||||
[
|
||||
"skill-seekers",
|
||||
"scrape",
|
||||
"--config",
|
||||
f"configs/{framework}.json"
|
||||
],
|
||||
f"Scraping {framework} documentation"
|
||||
):
|
||||
return 1
|
||||
else:
|
||||
print(f"\n⏭️ SKIPPED: Using existing {output_dir}")
|
||||
|
||||
if not output_dir.exists():
|
||||
print(f"❌ ERROR: {output_dir} does not exist!")
|
||||
print(f"Run without --skip-scrape to generate documentation first.")
|
||||
return 1
|
||||
|
||||
# Step 2: Package documentation
|
||||
if not run_command(
|
||||
[
|
||||
"skill-seekers",
|
||||
"package",
|
||||
str(output_dir),
|
||||
"--target",
|
||||
"markdown"
|
||||
],
|
||||
f"Packaging {framework} documentation"
|
||||
):
|
||||
return 1
|
||||
|
||||
# Step 3: Create Continue config
|
||||
print(f"\n{'='*60}")
|
||||
print(f"STEP: Configuring Continue.dev")
|
||||
print(f"{'='*60}")
|
||||
|
||||
config_path = create_continue_config(framework, args.port)
|
||||
print(f"✅ Continue config updated: {config_path}")
|
||||
|
||||
# Step 4: Instructions for starting server
|
||||
print(f"\n{'='*60}")
|
||||
print(f"✅ SUCCESS: Setup complete!")
|
||||
print(f"{'='*60}")
|
||||
print(f"\nNext steps:")
|
||||
print(f"\n1. Start context server:")
|
||||
print(f" python context_server.py --port {args.port}")
|
||||
print(f"\n2. Open any IDE with Continue.dev:")
|
||||
print(f" - VS Code: code my-project/")
|
||||
print(f" - IntelliJ: idea my-project/")
|
||||
print(f" - PyCharm: pycharm my-project/")
|
||||
print(f"\n3. Test in Continue panel (Cmd+L or Ctrl+L):")
|
||||
print(f" @{framework}-docs Create a {framework} component")
|
||||
print(f"\n4. Verify Continue references documentation")
|
||||
print(f"\nContinue config location: {config_path}")
|
||||
print(f"Context provider: @{framework}-docs")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
3
examples/continue-dev-universal/requirements.txt
Normal file
3
examples/continue-dev-universal/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
skill-seekers[mcp]>=2.9.0
|
||||
fastapi>=0.115.0
|
||||
uvicorn>=0.32.0
|
||||
Reference in New Issue
Block a user