Skip to content
Merged

Dev #24

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ocs-stats",
"version": "1.3.1",
"version": "1.3.2",
"description": "OpenCode Skills - One-click installer with gamified XP stats",
"type": "module",
"bin": {
Expand Down
58 changes: 28 additions & 30 deletions src/display.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,50 @@ const CATEGORY_CONFIG = {
security: {
title: 'SECURITY AGENT',
getStats: (data) => {
const totalFixed = (data.issuesFixed?.critical || 0) +
(data.issuesFixed?.high || 0) +
(data.issuesFixed?.medium || 0) +
const totalFixed = (data.issuesFixed?.critical || 0) +
(data.issuesFixed?.high || 0) +
(data.issuesFixed?.medium || 0) +
(data.issuesFixed?.low || 0);
return [
{ label: 'Issues Fixed', value: totalFixed },
{ label: 'Critical', value: data.issuesFixed?.critical || 0 },
{ label: 'High', value: data.issuesFixed?.high || 0 },
{ label: 'Medium', value: data.issuesFixed?.medium || 0 },
{ label: 'Low', value: data.issuesFixed?.low || 0 },
{ label: 'Audits Done', value: data.totalAudits || 0 },
{ label: 'Patterns Added', value: data.patternsAdded || 0 }
{ label: 'Critical', value: data.issuesFixed?.critical || 0 },
{ label: 'High', value: data.issuesFixed?.high || 0 },
{ label: 'Medium', value: data.issuesFixed?.medium || 0 },
{ label: 'Low', value: data.issuesFixed?.low || 0 },
];
}
},
testing: {
title: 'TESTING AGENT',
getStats: (data) => [
{ label: 'Tests Written', value: data.totalTests || 0 },
{ label: 'Unit Tests', value: data.testsWritten?.unit || 0 },
{ label: 'Integration', value: data.testsWritten?.integration || 0 },
{ label: 'E2E Tests', value: data.testsWritten?.e2e || 0 },
{ label: 'Tests Fixed', value: data.testsFixed || 0 },
{ label: 'Patterns Added', value: data.patternsAdded || 0 }
{ label: 'Unit Tests', value: data.testsWritten?.unit || 0 },
{ label: 'Integration', value: data.testsWritten?.integration || 0 },
{ label: 'E2E Tests', value: data.testsWritten?.e2e || 0 },
{ label: 'Tests Fixed', value: data.testsFixed || 0 },
]
},
'code-review': {
title: 'CODE REVIEW AGENT',
getStats: (data) => [
{ label: 'Total Reviews', value: data.totalReviews || 0 },
{ label: 'Critical Found', value: data.issuesFound?.critical || 0 },
{ label: 'High Found', value: data.issuesFound?.high || 0 },
{ label: 'Medium Found', value: data.issuesFound?.medium || 0 },
{ label: 'Low Found', value: data.issuesFound?.low || 0 },
{ label: 'Patterns Added', value: data.patternsAdded || 0 }
]
getStats: (data) => {
const totalFixed = (data.issuesFixed?.critical || 0) +
(data.issuesFixed?.high || 0) +
(data.issuesFixed?.medium || 0) +
(data.issuesFixed?.low || 0);
return [
{ label: 'Issues Fixed', value: totalFixed },
{ label: 'Critical', value: data.issuesFixed?.critical || 0 },
{ label: 'High', value: data.issuesFixed?.high || 0 },
{ label: 'Medium', value: data.issuesFixed?.medium || 0 },
{ label: 'Low', value: data.issuesFixed?.low || 0 },
];
}
},
docs: {
title: 'DOCUMENTATION AGENT',
getStats: (data) => [
{ label: 'Total Docs', value: data.totalDocsWritten || 0 },
{ label: 'New Sections', value: data.docsStats?.newSections || 0 },
{ label: 'Improvements', value: data.docsStats?.improvements || 0 },
{ label: 'Code Examples', value: data.docsStats?.codeExamples || 0 },
{ label: 'Tutorials', value: data.docsStats?.tutorials || 0 },
{ label: 'API Docs', value: data.docsStats?.apiDocs || 0 }
{ label: 'Sections', value: data.docsWritten?.sections || 0 },
{ label: 'Tutorials', value: data.docsWritten?.tutorials || 0 },
{ label: 'API Docs', value: data.docsWritten?.apiDocs || 0 },
]
}
};
Expand All @@ -65,7 +63,7 @@ export function progressBar(current, max, width = 16) {

export function getNextLevelXp(currentLevel, levelThresholds) {
const nextLevel = levelThresholds?.find(t => t.level === currentLevel + 1);
return nextLevel ? nextLevel.xpRequired : null;
return nextLevel ? nextLevel.xpToNextLevel : null;
}

function line(content) {
Expand Down
29 changes: 16 additions & 13 deletions src/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,12 @@ function compareVersion(v1, v2) {

function smartMergeXp(userXp, templateXp) {
const preserveFields = [
'xp', 'totalTests', 'totalAudits',
'testsWritten', 'issuesFixed', 'testsFixed', 'patternsAdded',
'completedSuites', 'completedAudits', 'seenPatterns', 'seenIssues',
'mistakes', 'mistakeHistory', 'levelHistory'
'xp', 'level', 'title',
'testsWritten', 'testsFixed',
'issuesFixed',
'docsWritten',
'seenIssues', 'seenPatterns',
'mistakes', 'mistakeHistory'
];

let merged = { ...templateXp };
Expand All @@ -180,7 +182,6 @@ function smartMergeXp(userXp, templateXp) {
}
}

merged.xpTable = templateXp.xpTable;
merged.levelThresholds = templateXp.levelThresholds;

const userXpValue = userXp.xp || 0;
Expand All @@ -190,7 +191,7 @@ function smartMergeXp(userXp, templateXp) {
let newLevel = 1;
let newTitle = 'Novice';
for (let i = thresholds.length - 1; i >= 0; i--) {
if (userXpValue >= thresholds[i].xpRequired) {
if (userXpValue >= thresholds[i].xpToNextLevel) {
newLevel = thresholds[i].level;
newTitle = thresholds[i].title;
break;
Expand All @@ -204,8 +205,9 @@ function smartMergeXp(userXp, templateXp) {

function getSmartMergePreserveInfo(userXp, templateXp) {
const preserveFields = [
'xp', 'level', 'title', 'totalTests', 'totalAudits',
'testsWritten', 'issuesFixed', 'testsFixed', 'patternsAdded'
'xp', 'level', 'title',
'testsWritten', 'testsFixed',
'issuesFixed', 'docsWritten',
];

const preserved = [];
Expand All @@ -217,16 +219,17 @@ function getSmartMergePreserveInfo(userXp, templateXp) {
preserved.push(`level ${userXp[field]}`);
} else if (field === 'title') {
preserved.push(`title: ${userXp[field]}`);
} else if (field === 'totalTests') {
preserved.push(`tests: ${userXp[field]}`);
} else if (field === 'testsWritten' && userXp.testsWritten) {
} else if (field === 'testsWritten' && userXp.testsWritten) {
const total = (userXp.testsWritten.unit || 0) + (userXp.testsWritten.integration || 0) + (userXp.testsWritten.e2e || 0);
if (total > 0) preserved.push(`tests: ${total}`);
} else if (field === 'testsFixed' && userXp.testsFixed > 0) {
preserved.push(`fixed: ${userXp.testsFixed}`);
} else if (field === 'issuesFixed' && userXp.issuesFixed) {
const total = (userXp.issuesFixed.critical || 0) + (userXp.issuesFixed.high || 0) + (userXp.issuesFixed.medium || 0) + (userXp.issuesFixed.low || 0);
if (total > 0) preserved.push(`fixed: ${total}`);
} else if (field === 'patternsAdded' && userXp.patternsAdded > 0) {
preserved.push(`patterns: ${userXp[field]}`);
} else if (field === 'docsWritten' && userXp.docsWritten) {
const total = (userXp.docsWritten.sections || 0) + (userXp.docsWritten.tutorials || 0) + (userXp.docsWritten.apiDocs || 0);
if (total > 0) preserved.push(`docs: ${total}`);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions templates/.ocs-version
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
1.3.2: Fix stats display and smart merge to use correct xp.json field names
1.3.1: Fix version display showing undefined after update check
1.3.0: Smarter agents — Phase 1/2 system, cumulative levels, no-commit rule, dynamic knowledge base
1.2.6: Smart merge for agent files - preserve user mode/tools
Expand Down
Loading