feat: add project overview section and enhance task item styles

- Introduced a new project overview section in the dashboard, displaying project details, technology stack, architecture, key components, and development history.
- Updated the server logic to include project overview data.
- Enhanced task item styles with status-based background colors for better visual distinction.
- Improved markdown modal functionality for viewing context and implementation plan with normalized line endings.
- Refactored task rendering logic to simplify task item display and improve performance.
This commit is contained in:
catlog22
2025-12-06 20:50:23 +08:00
parent e2c5a514cb
commit 5b14c8a832
5 changed files with 855 additions and 122 deletions

View File

@@ -19,6 +19,7 @@ export async function aggregateData(sessions, workflowDir) {
liteFix: []
},
reviewData: null,
projectOverview: null,
statistics: {
totalSessions: 0,
activeSessions: 0,
@@ -65,6 +66,13 @@ export async function aggregateData(sessions, workflowDir) {
console.error('Error scanning lite tasks:', err.message);
}
// Load project overview from project.json
try {
data.projectOverview = loadProjectOverview(workflowDir);
} catch (err) {
console.error('Error loading project overview:', err.message);
}
return data;
}
@@ -338,3 +346,64 @@ function sortTaskIds(a, b) {
const [b1, b2] = parseId(b);
return a1 - b1 || a2 - b2;
}
/**
* Load project overview from project.json
* @param {string} workflowDir - Path to .workflow directory
* @returns {Object|null} - Project overview data or null if not found
*/
function loadProjectOverview(workflowDir) {
const projectFile = join(workflowDir, 'project.json');
if (!existsSync(projectFile)) {
console.log(`Project file not found at: ${projectFile}`);
return null;
}
try {
const fileContent = readFileSync(projectFile, 'utf8');
const projectData = JSON.parse(fileContent);
console.log(`Successfully loaded project overview: ${projectData.project_name || 'Unknown'}`);
return {
projectName: projectData.project_name || 'Unknown',
description: projectData.overview?.description || '',
initializedAt: projectData.initialized_at || null,
technologyStack: projectData.overview?.technology_stack || {
languages: [],
frameworks: [],
build_tools: [],
test_frameworks: []
},
architecture: projectData.overview?.architecture || {
style: 'Unknown',
layers: [],
patterns: []
},
keyComponents: projectData.overview?.key_components || [],
features: projectData.features || [],
developmentIndex: projectData.development_index || {
feature: [],
enhancement: [],
bugfix: [],
refactor: [],
docs: []
},
statistics: projectData.statistics || {
total_features: 0,
total_sessions: 0,
last_updated: null
},
metadata: projectData._metadata || {
initialized_by: 'unknown',
analysis_timestamp: null,
analysis_mode: 'unknown'
}
};
} catch (err) {
console.error(`Failed to parse project.json at ${projectFile}:`, err.message);
console.error('Error stack:', err.stack);
return null;
}
}

View File

@@ -120,6 +120,7 @@ async function getWorkflowData(projectPath) {
archivedSessions: [],
liteTasks: { litePlan: [], liteFix: [] },
reviewData: { dimensions: {} },
projectOverview: null,
statistics: {
totalSessions: 0,
activeSessions: 0,
@@ -332,6 +333,7 @@ function generateServerDashboard(initialPath) {
archivedSessions: [],
liteTasks: { litePlan: [], liteFix: [] },
reviewData: { dimensions: {} },
projectOverview: null,
statistics: { totalSessions: 0, activeSessions: 0, totalTasks: 0, completedTasks: 0, reviewFindings: 0, litePlanCount: 0, liteFixCount: 0 }
};