Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
This commit is contained in:
113
dss-claude-plugin/core/mcp_extensions.py
Normal file
113
dss-claude-plugin/core/mcp_extensions.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""
|
||||
MCP Extensions for Context Awareness
|
||||
Implements the Factory Pattern to wrap existing tools with context
|
||||
and defines 5 new tools for the Context Compiler.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Callable
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
from .compiler import ContextCompiler
|
||||
|
||||
# Singleton compiler instance
|
||||
COMPILER = ContextCompiler(skins_dir=os.path.join(os.path.dirname(__file__), "skins"))
|
||||
|
||||
# --- FACTORY PATTERN: Context Wrapper ---
|
||||
|
||||
def with_context(default_manifest_path: str = None):
|
||||
"""
|
||||
Decorator that injects the compiled context into the tool's arguments.
|
||||
Use this to upgrade existing 'token extractor' tools to be 'context aware'.
|
||||
|
||||
The manifest path is extracted from kwargs['manifest_path'] if present,
|
||||
otherwise falls back to the default_manifest_path provided at decoration time.
|
||||
"""
|
||||
def decorator(func: Callable):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
# 1. Get manifest path (runtime kwarg or decorator default)
|
||||
manifest_path = kwargs.get('manifest_path', default_manifest_path)
|
||||
if not manifest_path:
|
||||
raise ValueError("No manifest_path provided to context-aware tool")
|
||||
|
||||
# 2. Compile Context
|
||||
context = COMPILER.compile(manifest_path)
|
||||
|
||||
# 3. Inject into kwargs
|
||||
kwargs['dss_context'] = context
|
||||
|
||||
# 4. Execute Tool
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# --- 5 NEW MCP TOOLS ---
|
||||
|
||||
def get_active_context(manifest_path: str, debug: bool = False, force_refresh: bool = False) -> str:
|
||||
"""
|
||||
[Tool 1] Returns the fully resolved JSON context for the project.
|
||||
Set debug=True to see provenance (which layer defined which token).
|
||||
Set force_refresh=True to bypass cache (for long-running servers).
|
||||
"""
|
||||
context = COMPILER.compile(manifest_path, debug=debug, force_refresh=force_refresh)
|
||||
return json.dumps(context, indent=2)
|
||||
|
||||
def resolve_token(manifest_path: str, token_path: str, force_refresh: bool = False) -> str:
|
||||
"""
|
||||
[Tool 2] Resolves a specific token value (e.g. 'colors.primary')
|
||||
through the cascade.
|
||||
Set force_refresh=True to bypass cache (for long-running servers).
|
||||
"""
|
||||
context = COMPILER.compile(manifest_path, force_refresh=force_refresh)
|
||||
keys = token_path.split('.')
|
||||
current = context.get("tokens", {})
|
||||
|
||||
for k in keys:
|
||||
if isinstance(current, dict) and k in current:
|
||||
current = current[k]
|
||||
else:
|
||||
return f"Token not found: {token_path}"
|
||||
|
||||
return str(current)
|
||||
|
||||
def validate_manifest(manifest_path: str) -> str:
|
||||
"""
|
||||
[Tool 3] Validates the ds.config.json against the schema.
|
||||
"""
|
||||
# In a full implementation, we would use 'jsonschema' library here.
|
||||
# For now, we perform a basic structural check via the Compiler's loader.
|
||||
try:
|
||||
COMPILER.compile(manifest_path)
|
||||
return "Valid: Project manifest builds successfully."
|
||||
except Exception as e:
|
||||
return f"Invalid: {str(e)}"
|
||||
|
||||
def list_skins() -> str:
|
||||
"""
|
||||
[Tool 4] Lists all available skins in the registry.
|
||||
"""
|
||||
skins_path = COMPILER.skins_dir
|
||||
if not skins_path.exists():
|
||||
return "No skins directory found."
|
||||
|
||||
skins = [f.stem for f in skins_path.glob("*.json")]
|
||||
return json.dumps(skins)
|
||||
|
||||
def get_compiler_status() -> str:
|
||||
"""
|
||||
[Tool 5] Returns the health and configuration of the Context Compiler.
|
||||
"""
|
||||
status = {
|
||||
"status": "active",
|
||||
"skins_directory": str(COMPILER.skins_dir),
|
||||
"cached_skins": list(COMPILER.cache.keys()),
|
||||
"safe_boot_ready": True
|
||||
}
|
||||
return json.dumps(status, indent=2)
|
||||
|
||||
# Instructions for Main Server File:
|
||||
# 1. Import these tools
|
||||
# 2. Register them with the MCP server instance
|
||||
# 3. Apply @with_context wrapper to legacy tools if dynamic context is needed
|
||||
Reference in New Issue
Block a user