This commit introduces a new project analysis engine to the DSS. Key features include: - A new analysis module in `dss-mvp1/dss/analyze` that can parse React projects and generate a dependency graph. - A command-line interface (`dss-mvp1/dss-cli.py`) to run the analysis, designed for use in CI/CD pipelines. - A new `dss_project_export_context` tool in the Claude MCP server to allow AI agents to access the analysis results. - A `.gitlab-ci.yml` file to automate the analysis on every push, ensuring the project context is always up-to-date. - Tests for the new analysis functionality. This new architecture enables DSS to have a deep, version-controlled understanding of a project's structure, which can be used to power more intelligent agents and provide better developer guidance. The analysis is no longer automatically triggered on `init`, but is designed to be run manually or by a CI/CD pipeline.
86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
import os
|
|
import json
|
|
import networkx as nx
|
|
from pyast_ts import parse
|
|
import cssutils
|
|
import logging
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
log = logging.getLogger(__name__)
|
|
|
|
# Configure cssutils to ignore noisy error messages
|
|
cssutils.log.setLevel(logging.CRITICAL)
|
|
|
|
def analyze_react_project(project_path: str) -> dict:
|
|
"""
|
|
Analyzes a React project, building a graph of its components and styles.
|
|
|
|
Args:
|
|
project_path: The root path of the React project.
|
|
|
|
Returns:
|
|
A dictionary containing the component graph and analysis report.
|
|
"""
|
|
log.info(f"Starting analysis of project at: {project_path}")
|
|
graph = nx.DiGraph()
|
|
|
|
# Supported extensions for react/js/ts files
|
|
supported_exts = ('.js', '.jsx', '.ts', '.tsx')
|
|
|
|
for root, _, files in os.walk(project_path):
|
|
for file in files:
|
|
file_path = os.path.join(root, file)
|
|
relative_path = os.path.relpath(file_path, project_path)
|
|
|
|
if file.endswith(supported_exts):
|
|
graph.add_node(relative_path, type='file', language='typescript')
|
|
try:
|
|
with open(file_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Placeholder for AST parsing and analysis
|
|
# ast = parse(content)
|
|
# For now, we'll just add the node
|
|
|
|
except Exception as e:
|
|
log.error(f"Could not process file {file_path}: {e}")
|
|
|
|
elif file.endswith('.css'):
|
|
graph.add_node(relative_path, type='file', language='css')
|
|
try:
|
|
# Placeholder for CSS parsing
|
|
# sheet = cssutils.parseFile(file_path)
|
|
pass
|
|
except Exception as e:
|
|
log.error(f"Could not parse css file {file_path}: {e}")
|
|
|
|
log.info(f"Analysis complete. Found {graph.number_of_nodes()} files.")
|
|
|
|
# Convert graph to a serializable format
|
|
serializable_graph = nx.node_link_data(graph)
|
|
|
|
return serializable_graph
|
|
|
|
def save_analysis(project_path: str, analysis_data: dict):
|
|
"""
|
|
Saves the analysis data to a file in the project's .dss directory.
|
|
"""
|
|
dss_dir = os.path.join(project_path, '.dss')
|
|
os.makedirs(dss_dir, exist_ok=True)
|
|
|
|
output_path = os.path.join(dss_dir, 'analysis_graph.json')
|
|
|
|
with open(output_path, 'w', encoding='utf-8') as f:
|
|
json.dump(analysis_data, f, indent=2)
|
|
|
|
log.info(f"Analysis data saved to {output_path}")
|
|
|
|
if __name__ == '__main__':
|
|
# Example usage:
|
|
# Replace '.' with the actual path to a React project for testing.
|
|
# In a real scenario, this would be called by the MCP.
|
|
target_project_path = '.'
|
|
analysis_result = analyze_react_project(target_project_path)
|
|
save_analysis(target_project_path, analysis_result)
|