feat: auto-update developmentIndex on session archive (closes #58)

- Add updateDevelopmentIndex() function to session-manager.ts
- Auto-append entry to developmentIndex when archiving sessions
- Add timeline view toggle for Development History section
- Support both 'archivedAt' and 'date' field names for compatibility
- Add dynamic calculation for statistics (Total Features, Last Updated)
- Add CSS styles for timeline view
This commit is contained in:
catlog22
2026-01-11 11:05:41 +08:00
parent 30ff742310
commit 2c11392848
3 changed files with 362 additions and 37 deletions

View File

@@ -737,6 +737,11 @@ function executeArchive(params: Params): any {
}
}
// Update development index with archived session info
if (sessionMetadata) {
updateDevelopmentIndex(sessionMetadata);
}
return {
operation: 'archive',
session_id,
@@ -903,6 +908,72 @@ function executeStats(params: Params): any {
};
}
/**
* Updates the project's development index when a session is archived.
* Simplified: only appends entries, does NOT manage statistics.
* Dashboard aggregator handles dynamic calculation.
*/
function updateDevelopmentIndex(sessionMetadata: any): void {
if (!sessionMetadata || !sessionMetadata.session_id) {
console.warn('Skipping development index update due to missing session metadata.');
return;
}
const root = findWorkflowRoot();
const projectTechFile = join(root, WORKFLOW_BASE, 'project-tech.json');
if (!existsSync(projectTechFile)) {
console.warn(`Skipping development index update: ${projectTechFile} not found.`);
return;
}
try {
const projectData = readJsonFile(projectTechFile);
// Ensure development_index exists
if (!projectData.development_index) {
projectData.development_index = { feature: [], enhancement: [], bugfix: [], refactor: [], docs: [] };
}
// Type inference from description
const description = (sessionMetadata.description || '').toLowerCase();
let devType: 'feature' | 'enhancement' | 'bugfix' | 'refactor' | 'docs' = 'enhancement';
if (sessionMetadata.type === 'docs') {
devType = 'docs';
} else if (/\b(fix|bug|resolve)\b/.test(description)) {
devType = 'bugfix';
} else if (/\b(feature|implement|add|create)\b/.test(description)) {
devType = 'feature';
} else if (/\b(refactor|restructure|cleanup)\b/.test(description)) {
devType = 'refactor';
}
const entry = {
title: sessionMetadata.description || sessionMetadata.project || sessionMetadata.session_id,
sessionId: sessionMetadata.session_id,
type: devType,
tags: sessionMetadata.tags || [],
archivedAt: sessionMetadata.archived_at || new Date().toISOString(),
};
// Append to correct category
if (!projectData.development_index[devType]) {
projectData.development_index[devType] = [];
}
projectData.development_index[devType].push(entry);
// CRITICAL: Do NOT touch projectData.statistics
// Dashboard aggregator handles dynamic calculation
writeJsonFile(projectTechFile, projectData);
console.log(`Development index updated for session: ${sessionMetadata.session_id}`);
} catch (error) {
console.error(`Failed to update development index: ${(error as Error).message}`);
}
}
// ============================================================
// Main Execute Function
// ============================================================