Revert "feat: Enterprise DSS architecture implementation"
Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled

This reverts commit 9dbd56271e.
This commit is contained in:
DSS
2025-12-11 09:59:45 -03:00
parent 9dbd56271e
commit 44cea9443b
27 changed files with 397 additions and 3887 deletions

View File

@@ -3,14 +3,8 @@ DSS Configuration Module
========================
Handles configuration management for the Design System Server (DSS) Claude Plugin.
Supports local/remote/CI mode detection, persistent configuration storage, and
Supports local/remote mode detection, persistent configuration storage, and
environment variable overrides.
Enterprise Architecture:
- LOCAL: Developer workstation, reads from .dss/ cache, advisory validation
- REMOTE: Headless/server mode, full analysis, metrics upload
- CI: CI/CD pipeline, authoritative enforcement, blocking validation
- AUTO: Detect environment automatically (CI env vars -> CI, else LOCAL with cache)
"""
import json
@@ -19,7 +13,6 @@ import os
import uuid
from enum import Enum
from pathlib import Path
from typing import Optional
import aiohttp
from pydantic import BaseModel, Field, ValidationError
@@ -31,28 +24,14 @@ CONFIG_DIR = Path.home() / ".dss"
CONFIG_FILE = CONFIG_DIR / "config.json"
DEFAULT_REMOTE_URL = "https://dss.overbits.luz.uy"
DEFAULT_LOCAL_URL = "http://localhost:6006"
DEFAULT_DASHBOARD_URL = "https://dss.overbits.luz.uy/api/metrics"
# CI environment variables that indicate we're running in a pipeline
CI_ENV_VARS = [
"CI",
"GITEA_ACTIONS",
"GITHUB_ACTIONS",
"GITLAB_CI",
"JENKINS_URL",
"CIRCLECI",
"TRAVIS",
"BUILDKITE",
]
class DSSMode(str, Enum):
"""Operation modes for the DSS plugin."""
LOCAL = "local" # Developer workstation - advisory, uses cache
REMOTE = "remote" # Headless server - full analysis
CI = "ci" # CI/CD pipeline - authoritative enforcement
AUTO = "auto" # Auto-detect based on environment
LOCAL = "local"
REMOTE = "remote"
AUTO = "auto"
class DSSConfig(BaseModel):
@@ -63,21 +42,15 @@ class DSSConfig(BaseModel):
mode (DSSMode): The configured operation mode (default: AUTO).
remote_url (str): URL for the remote DSS API.
local_url (str): URL for the local DSS API (usually localhost).
dashboard_url (str): URL for metrics dashboard API.
session_id (str): Unique identifier for this client instance.
project_path (str): Current project path (for local analysis).
rules_version (str): Pinned @dss/rules version for this project.
"""
mode: DSSMode = Field(default=DSSMode.AUTO, description="Operation mode preference")
remote_url: str = Field(default=DEFAULT_REMOTE_URL, description="Remote API endpoint")
local_url: str = Field(default=DEFAULT_LOCAL_URL, description="Local API endpoint")
dashboard_url: str = Field(default=DEFAULT_DASHBOARD_URL, description="Metrics dashboard API")
session_id: str = Field(
default_factory=lambda: str(uuid.uuid4()), description="Persistent session ID"
)
project_path: Optional[str] = Field(default=None, description="Current project path")
rules_version: Optional[str] = Field(default=None, description="Pinned @dss/rules version")
class Config:
validate_assignment = True
@@ -128,75 +101,38 @@ class DSSConfig(BaseModel):
Determine the actual runtime mode based on priority rules.
Priority:
1. DSS_MODE environment variable (explicit override)
2. CI environment detection (GITEA_ACTIONS, CI, GITHUB_ACTIONS, etc.)
3. Configured 'mode' (if not AUTO)
4. Auto-detection (check for .dss/ folder, ping local health)
5. Fallback to LOCAL (developer-first)
1. DSS_MODE environment variable
2. Configured 'mode' (if not AUTO)
3. Auto-detection (ping local health endpoint)
4. Fallback to REMOTE
Returns:
DSSMode: The resolved active mode (LOCAL, REMOTE, or CI).
DSSMode: The resolved active mode (LOCAL or REMOTE).
"""
# 1. Check Environment Variable (explicit override)
# 1. Check Environment Variable
env_mode = os.getenv("DSS_MODE")
if env_mode:
try:
resolved = DSSMode(env_mode.lower())
logger.info(f"Mode set via DSS_MODE env var: {resolved.value}")
return resolved
# Normalize string to enum
return DSSMode(env_mode.lower())
except ValueError:
logger.warning(f"Invalid DSS_MODE env var '{env_mode}', ignoring.")
# 2. Check CI environment variables
if self._is_ci_environment():
logger.info("CI environment detected. Using CI mode (authoritative enforcement).")
return DSSMode.CI
# 3. Check Configuration (if explicit, not AUTO)
# 2. Check Configuration (if explicit)
if self.mode != DSSMode.AUTO:
logger.info(f"Using configured mode: {self.mode.value}")
return self.mode
# 4. Auto-detect based on environment
# 3. Auto-detect
logger.info("Auto-detecting DSS mode...")
# Check for local .dss/ folder (indicates project setup)
if self._has_local_dss_folder():
logger.info("Found .dss/ folder. Using LOCAL mode with cache.")
return DSSMode.LOCAL
# Check if local server is running
is_local_healthy = await self._check_local_health()
if is_local_healthy:
logger.info(f"Local server detected at {self.local_url}. Using LOCAL mode.")
logger.info(f"Local server detected at {self.local_url}. Switching to LOCAL mode.")
return DSSMode.LOCAL
# 5. Fallback to LOCAL (developer-first, will use stale cache if available)
logger.info("Fallback to LOCAL mode (offline-capable with cache).")
return DSSMode.LOCAL
def _is_ci_environment(self) -> bool:
"""Check if running in a CI/CD environment."""
for env_var in CI_ENV_VARS:
if os.getenv(env_var):
logger.debug(f"CI detected via {env_var} env var")
return True
return False
def _has_local_dss_folder(self) -> bool:
"""Check if current directory or project has .dss/ folder."""
# Check current working directory
cwd_dss = Path.cwd() / ".dss"
if cwd_dss.exists() and cwd_dss.is_dir():
return True
# Check configured project path
if self.project_path:
project_dss = Path(self.project_path) / ".dss"
if project_dss.exists() and project_dss.is_dir():
return True
return False
else:
logger.info("Local server unreachable. Fallback to REMOTE mode.")
# 4. Fallback
return DSSMode.REMOTE
async def _check_local_health(self) -> bool:
"""
@@ -225,46 +161,3 @@ class DSSConfig(BaseModel):
if active_mode == DSSMode.LOCAL:
return self.local_url
return self.remote_url
def get_mode_behavior(self, active_mode: DSSMode) -> dict:
"""
Get behavior configuration for the active mode.
Returns dict with:
- blocking: Whether validation errors block operations
- upload_metrics: Whether to upload metrics to dashboard
- use_cache: Whether to use local .dss/ cache
- cache_ttl: Cache time-to-live in seconds
"""
behaviors = {
DSSMode.LOCAL: {
"blocking": False, # Advisory only
"upload_metrics": False,
"use_cache": True,
"cache_ttl": 3600, # 1 hour
"show_stale_warning": True,
},
DSSMode.REMOTE: {
"blocking": True,
"upload_metrics": True,
"use_cache": False,
"cache_ttl": 0,
"show_stale_warning": False,
},
DSSMode.CI: {
"blocking": True, # Authoritative enforcement
"upload_metrics": True,
"use_cache": False,
"cache_ttl": 0,
"show_stale_warning": False,
},
DSSMode.AUTO: {
# AUTO resolves to another mode, shouldn't reach here
"blocking": False,
"upload_metrics": False,
"use_cache": True,
"cache_ttl": 3600,
"show_stale_warning": True,
},
}
return behaviors.get(active_mode, behaviors[DSSMode.LOCAL])