Files
dss/tools/analysis/project_analyzer.py
Digital Production Factory d53b61008c feat(analysis): Implement project analysis engine and CI/CD workflow
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.
2025-12-10 11:05:27 -03:00

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)