feat(dashboard): simplify lite task UI and add exploration context support

- Remove status indicators from lite task cards (progress bars, percentages)
- Remove status icons and badges from task detail items
- Remove stats bar showing completed/in-progress/pending counts
- Add Plan tab in drawer for plan.json data display
- Add exploration-*.json parsing for context tab
- Add collapsible sections for architecture, dependencies, patterns
- Fix currentPath selector bug causing TypeError

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
catlog22
2025-12-05 15:47:49 +08:00
parent 72fe6195af
commit 60bb11c315
7 changed files with 2314 additions and 186 deletions

View File

@@ -87,7 +87,8 @@ async function processSession(session, isActive) {
tasks: [],
taskCount: 0,
hasReview: false,
reviewSummary: null
reviewSummary: null,
reviewDimensions: []
};
// Load tasks for active sessions (full details)
@@ -121,6 +122,10 @@ async function processSession(session, isActive) {
if (existsSync(reviewDir)) {
result.hasReview = true;
result.reviewSummary = loadReviewSummary(reviewDir);
// Load dimension data for review sessions
if (session.type === 'review') {
result.reviewDimensions = await loadDimensionData(reviewDir);
}
}
} else {
// For archived, also load tasks (same as active)
@@ -150,6 +155,10 @@ async function processSession(session, isActive) {
if (existsSync(reviewDir)) {
result.hasReview = true;
result.reviewSummary = loadReviewSummary(reviewDir);
// Load dimension data for review sessions
if (session.type === 'review') {
result.reviewDimensions = await loadDimensionData(reviewDir);
}
}
}
@@ -266,15 +275,33 @@ async function loadDimensionData(reviewDir) {
for (const file of dimFiles) {
try {
const data = JSON.parse(readFileSync(join(dimensionsDir, file), 'utf8'));
// Handle array structure: [ { findings: [...], summary: {...} } ]
let findings = [];
let summary = null;
let status = 'completed';
if (Array.isArray(data) && data.length > 0) {
const dimData = data[0];
findings = dimData.findings || [];
summary = dimData.summary || null;
status = dimData.status || 'completed';
} else if (data.findings) {
findings = data.findings;
summary = data.summary || null;
status = data.status || 'completed';
}
dimensions.push({
name: basename(file, '.json'),
findings: Array.isArray(data) ? data : (data.findings || []),
status: data.status || 'completed'
findings: findings,
summary: summary,
status: status
});
} catch {
// Skip invalid dimension files
}
}
}
return dimensions;
}

View File

@@ -241,16 +241,59 @@ async function getSessionDetailData(sessionPath, dataType) {
// Load review data from .review/
if (dataType === 'review' || dataType === 'all') {
const reviewDir = join(normalizedPath, '.review');
result.review = { dimensions: {} };
result.review = {
state: null,
dimensions: [],
severityDistribution: null,
totalFindings: 0
};
if (existsSync(reviewDir)) {
// Load review-state.json
const stateFile = join(reviewDir, 'review-state.json');
if (existsSync(stateFile)) {
try {
const state = JSON.parse(readFileSync(stateFile, 'utf8'));
result.review.state = state;
result.review.severityDistribution = state.severity_distribution || {};
result.review.totalFindings = state.total_findings || 0;
result.review.phase = state.phase || 'unknown';
result.review.dimensionSummaries = state.dimension_summaries || {};
result.review.crossCuttingConcerns = state.cross_cutting_concerns || [];
result.review.criticalFiles = state.critical_files || [];
} catch (e) {
// Skip unreadable state
}
}
// Load dimension findings
const dimensionsDir = join(reviewDir, 'dimensions');
if (existsSync(dimensionsDir)) {
const files = readdirSync(dimensionsDir).filter(f => f.endsWith('.json'));
for (const file of files) {
try {
const dimName = file.replace('.json', '');
const content = JSON.parse(readFileSync(join(dimensionsDir, file), 'utf8'));
result.review.dimensions[dimName] = content.findings || content;
const data = JSON.parse(readFileSync(join(dimensionsDir, file), 'utf8'));
// Handle array structure: [ { findings: [...] } ]
let findings = [];
let summary = null;
if (Array.isArray(data) && data.length > 0) {
const dimData = data[0];
findings = dimData.findings || [];
summary = dimData.summary || null;
} else if (data.findings) {
findings = data.findings;
summary = data.summary || null;
}
result.review.dimensions.push({
name: dimName,
findings: findings,
summary: summary,
count: findings.length
});
} catch (e) {
// Skip unreadable files
}