@codebakers/cli 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp/server.js +92 -6
- package/package.json +1 -1
- package/src/mcp/server.ts +114 -6
package/dist/mcp/server.js
CHANGED
|
@@ -1536,6 +1536,7 @@ Just describe what you want to build! I'll automatically:
|
|
|
1536
1536
|
async handleUpgrade(args) {
|
|
1537
1537
|
const { areas = ['all'], severity = 'all', dryRun = false } = args;
|
|
1538
1538
|
const context = this.gatherProjectContext();
|
|
1539
|
+
const cwd = process.cwd();
|
|
1539
1540
|
let response = `# ⬆️ Project Upgrade Analysis\n\n`;
|
|
1540
1541
|
// Stack detection
|
|
1541
1542
|
response += `## Your Stack (Preserving As-Is)\n\n`;
|
|
@@ -1569,6 +1570,83 @@ Just describe what you want to build! I'll automatically:
|
|
|
1569
1570
|
const hasNext = context.dependencies.includes('next');
|
|
1570
1571
|
response += `| Framework | ${hasNext ? 'Next.js' : 'Unknown'} | ✓ Keeping |\n`;
|
|
1571
1572
|
response += `\n---\n\n`;
|
|
1573
|
+
// Git Analysis Section
|
|
1574
|
+
response += `## Deep Analysis\n\n`;
|
|
1575
|
+
// Check if git repo
|
|
1576
|
+
const isGitRepo = fs.existsSync(path.join(cwd, '.git'));
|
|
1577
|
+
if (isGitRepo) {
|
|
1578
|
+
response += `### Git Hot Spots (Most Changed Files)\n\n`;
|
|
1579
|
+
try {
|
|
1580
|
+
// Get files with most commits
|
|
1581
|
+
const gitLog = (0, child_process_1.execSync)('git log --pretty=format: --name-only --since="6 months ago" 2>/dev/null | sort | uniq -c | sort -rg | head -10', { cwd, encoding: 'utf-8', timeout: 10000 }).trim();
|
|
1582
|
+
if (gitLog) {
|
|
1583
|
+
const hotSpots = gitLog.split('\n')
|
|
1584
|
+
.map(line => line.trim())
|
|
1585
|
+
.filter(line => line && !line.includes('node_modules'))
|
|
1586
|
+
.slice(0, 5);
|
|
1587
|
+
if (hotSpots.length > 0) {
|
|
1588
|
+
hotSpots.forEach((line, i) => {
|
|
1589
|
+
const match = line.match(/^\s*(\d+)\s+(.+)$/);
|
|
1590
|
+
if (match) {
|
|
1591
|
+
const [, count, file] = match;
|
|
1592
|
+
response += `${i + 1}. \`${file}\` - ${count} changes\n`;
|
|
1593
|
+
}
|
|
1594
|
+
});
|
|
1595
|
+
response += `\n`;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
// Count fix commits
|
|
1599
|
+
const fixCount = (0, child_process_1.execSync)('git log --oneline --since="6 months ago" 2>/dev/null | grep -i "fix" | wc -l', { cwd, encoding: 'utf-8', timeout: 5000 }).trim();
|
|
1600
|
+
if (parseInt(fixCount) > 0) {
|
|
1601
|
+
response += `**Bug Fix Commits:** ${fixCount} (in last 6 months)\n\n`;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
catch {
|
|
1605
|
+
response += `*(Git analysis unavailable)*\n\n`;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
else {
|
|
1609
|
+
response += `*(Not a git repository - skipping git analysis)*\n\n`;
|
|
1610
|
+
}
|
|
1611
|
+
// TODO/FIXME Scan
|
|
1612
|
+
response += `### Developer Notes (TODO/FIXME)\n\n`;
|
|
1613
|
+
try {
|
|
1614
|
+
const todoScan = (0, child_process_1.execSync)('grep -r "TODO\\|FIXME\\|HACK\\|XXX\\|BUG" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" -l 2>/dev/null | head -20', { cwd, encoding: 'utf-8', timeout: 10000 }).trim();
|
|
1615
|
+
if (todoScan) {
|
|
1616
|
+
const todoFiles = todoScan.split('\n').filter(f => !f.includes('node_modules'));
|
|
1617
|
+
const todoCount = todoFiles.length;
|
|
1618
|
+
if (todoCount > 0) {
|
|
1619
|
+
response += `Found developer notes in **${todoCount} files**:\n\n`;
|
|
1620
|
+
// Count by type
|
|
1621
|
+
try {
|
|
1622
|
+
const todoTypes = (0, child_process_1.execSync)('grep -roh "TODO\\|FIXME\\|HACK\\|XXX\\|BUG" --include="*.ts" --include="*.tsx" 2>/dev/null | sort | uniq -c | sort -rg', { cwd, encoding: 'utf-8', timeout: 10000 }).trim();
|
|
1623
|
+
if (todoTypes) {
|
|
1624
|
+
todoTypes.split('\n').forEach(line => {
|
|
1625
|
+
const match = line.trim().match(/^\s*(\d+)\s+(.+)$/);
|
|
1626
|
+
if (match) {
|
|
1627
|
+
const [, count, type] = match;
|
|
1628
|
+
const icon = type === 'FIXME' || type === 'BUG' ? '🔴' :
|
|
1629
|
+
type === 'HACK' ? '🟡' : '📝';
|
|
1630
|
+
response += `- ${icon} ${count} ${type}s\n`;
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
response += `\n`;
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
catch {
|
|
1637
|
+
// Ignore count errors
|
|
1638
|
+
}
|
|
1639
|
+
response += `*I can implement these TODOs and fix FIXMEs during upgrade.*\n\n`;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
else {
|
|
1643
|
+
response += `✅ No TODO/FIXME comments found - clean codebase!\n\n`;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
catch {
|
|
1647
|
+
response += `*(TODO scan unavailable)*\n\n`;
|
|
1648
|
+
}
|
|
1649
|
+
response += `---\n\n`;
|
|
1572
1650
|
// Scan for upgrade opportunities
|
|
1573
1651
|
response += `## Upgrade Opportunities\n\n`;
|
|
1574
1652
|
const upgrades = [];
|
|
@@ -1626,18 +1704,26 @@ Just describe what you want to build! I'll automatically:
|
|
|
1626
1704
|
if (upgrades.length === 0) {
|
|
1627
1705
|
response += `✅ No major upgrade opportunities detected!\n\n`;
|
|
1628
1706
|
}
|
|
1707
|
+
// Review mode options
|
|
1708
|
+
response += `---\n\n`;
|
|
1709
|
+
response += `## Review Modes\n\n`;
|
|
1710
|
+
response += `Pick a focus for the upgrade:\n\n`;
|
|
1711
|
+
response += `- **Security Audit** - Auth, secrets, injections, OWASP top 10\n`;
|
|
1712
|
+
response += `- **Performance Review** - Bundle size, queries, caching\n`;
|
|
1713
|
+
response += `- **Code Quality** - Patterns, DRY, complexity\n`;
|
|
1714
|
+
response += `- **Pre-Launch** - Everything for production\n`;
|
|
1715
|
+
response += `- **Quick Scan** - Top 5 issues only\n`;
|
|
1716
|
+
response += `- **Comprehensive** - All of the above\n\n`;
|
|
1629
1717
|
// Recommendations
|
|
1630
1718
|
response += `---\n\n`;
|
|
1631
1719
|
response += `## Recommended Actions\n\n`;
|
|
1632
1720
|
if (dryRun) {
|
|
1633
1721
|
response += `**(Dry Run Mode - No changes will be made)**\n\n`;
|
|
1634
1722
|
}
|
|
1635
|
-
response += `1.
|
|
1636
|
-
response += `2.
|
|
1637
|
-
response += `3.
|
|
1638
|
-
response += `
|
|
1639
|
-
response += ` - "Add error boundaries to components"\n`;
|
|
1640
|
-
response += ` - "Set up Playwright testing"\n\n`;
|
|
1723
|
+
response += `1. Tell me your main concerns (security, performance, etc.)\n`;
|
|
1724
|
+
response += `2. I'll prioritize fixes based on your needs\n`;
|
|
1725
|
+
response += `3. Hot spot files get fixed first (where bugs live)\n`;
|
|
1726
|
+
response += `4. I'll implement your TODOs and fix FIXMEs along the way\n\n`;
|
|
1641
1727
|
response += `---\n\n`;
|
|
1642
1728
|
response += `**Key Principle:** Your stack stays the same. Only code quality patterns are upgraded.\n`;
|
|
1643
1729
|
return {
|
package/package.json
CHANGED
package/src/mcp/server.ts
CHANGED
|
@@ -1729,6 +1729,7 @@ Just describe what you want to build! I'll automatically:
|
|
|
1729
1729
|
private async handleUpgrade(args: { areas?: string[]; severity?: string; dryRun?: boolean }) {
|
|
1730
1730
|
const { areas = ['all'], severity = 'all', dryRun = false } = args;
|
|
1731
1731
|
const context = this.gatherProjectContext();
|
|
1732
|
+
const cwd = process.cwd();
|
|
1732
1733
|
|
|
1733
1734
|
let response = `# ⬆️ Project Upgrade Analysis\n\n`;
|
|
1734
1735
|
|
|
@@ -1762,6 +1763,104 @@ Just describe what you want to build! I'll automatically:
|
|
|
1762
1763
|
|
|
1763
1764
|
response += `\n---\n\n`;
|
|
1764
1765
|
|
|
1766
|
+
// Git Analysis Section
|
|
1767
|
+
response += `## Deep Analysis\n\n`;
|
|
1768
|
+
|
|
1769
|
+
// Check if git repo
|
|
1770
|
+
const isGitRepo = fs.existsSync(path.join(cwd, '.git'));
|
|
1771
|
+
|
|
1772
|
+
if (isGitRepo) {
|
|
1773
|
+
response += `### Git Hot Spots (Most Changed Files)\n\n`;
|
|
1774
|
+
try {
|
|
1775
|
+
// Get files with most commits
|
|
1776
|
+
const gitLog = execSync(
|
|
1777
|
+
'git log --pretty=format: --name-only --since="6 months ago" 2>/dev/null | sort | uniq -c | sort -rg | head -10',
|
|
1778
|
+
{ cwd, encoding: 'utf-8', timeout: 10000 }
|
|
1779
|
+
).trim();
|
|
1780
|
+
|
|
1781
|
+
if (gitLog) {
|
|
1782
|
+
const hotSpots = gitLog.split('\n')
|
|
1783
|
+
.map(line => line.trim())
|
|
1784
|
+
.filter(line => line && !line.includes('node_modules'))
|
|
1785
|
+
.slice(0, 5);
|
|
1786
|
+
|
|
1787
|
+
if (hotSpots.length > 0) {
|
|
1788
|
+
hotSpots.forEach((line, i) => {
|
|
1789
|
+
const match = line.match(/^\s*(\d+)\s+(.+)$/);
|
|
1790
|
+
if (match) {
|
|
1791
|
+
const [, count, file] = match;
|
|
1792
|
+
response += `${i + 1}. \`${file}\` - ${count} changes\n`;
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
response += `\n`;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
// Count fix commits
|
|
1800
|
+
const fixCount = execSync(
|
|
1801
|
+
'git log --oneline --since="6 months ago" 2>/dev/null | grep -i "fix" | wc -l',
|
|
1802
|
+
{ cwd, encoding: 'utf-8', timeout: 5000 }
|
|
1803
|
+
).trim();
|
|
1804
|
+
|
|
1805
|
+
if (parseInt(fixCount) > 0) {
|
|
1806
|
+
response += `**Bug Fix Commits:** ${fixCount} (in last 6 months)\n\n`;
|
|
1807
|
+
}
|
|
1808
|
+
} catch {
|
|
1809
|
+
response += `*(Git analysis unavailable)*\n\n`;
|
|
1810
|
+
}
|
|
1811
|
+
} else {
|
|
1812
|
+
response += `*(Not a git repository - skipping git analysis)*\n\n`;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
// TODO/FIXME Scan
|
|
1816
|
+
response += `### Developer Notes (TODO/FIXME)\n\n`;
|
|
1817
|
+
try {
|
|
1818
|
+
const todoScan = execSync(
|
|
1819
|
+
'grep -r "TODO\\|FIXME\\|HACK\\|XXX\\|BUG" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" -l 2>/dev/null | head -20',
|
|
1820
|
+
{ cwd, encoding: 'utf-8', timeout: 10000 }
|
|
1821
|
+
).trim();
|
|
1822
|
+
|
|
1823
|
+
if (todoScan) {
|
|
1824
|
+
const todoFiles = todoScan.split('\n').filter(f => !f.includes('node_modules'));
|
|
1825
|
+
const todoCount = todoFiles.length;
|
|
1826
|
+
|
|
1827
|
+
if (todoCount > 0) {
|
|
1828
|
+
response += `Found developer notes in **${todoCount} files**:\n\n`;
|
|
1829
|
+
|
|
1830
|
+
// Count by type
|
|
1831
|
+
try {
|
|
1832
|
+
const todoTypes = execSync(
|
|
1833
|
+
'grep -roh "TODO\\|FIXME\\|HACK\\|XXX\\|BUG" --include="*.ts" --include="*.tsx" 2>/dev/null | sort | uniq -c | sort -rg',
|
|
1834
|
+
{ cwd, encoding: 'utf-8', timeout: 10000 }
|
|
1835
|
+
).trim();
|
|
1836
|
+
|
|
1837
|
+
if (todoTypes) {
|
|
1838
|
+
todoTypes.split('\n').forEach(line => {
|
|
1839
|
+
const match = line.trim().match(/^\s*(\d+)\s+(.+)$/);
|
|
1840
|
+
if (match) {
|
|
1841
|
+
const [, count, type] = match;
|
|
1842
|
+
const icon = type === 'FIXME' || type === 'BUG' ? '🔴' :
|
|
1843
|
+
type === 'HACK' ? '🟡' : '📝';
|
|
1844
|
+
response += `- ${icon} ${count} ${type}s\n`;
|
|
1845
|
+
}
|
|
1846
|
+
});
|
|
1847
|
+
response += `\n`;
|
|
1848
|
+
}
|
|
1849
|
+
} catch {
|
|
1850
|
+
// Ignore count errors
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
response += `*I can implement these TODOs and fix FIXMEs during upgrade.*\n\n`;
|
|
1854
|
+
}
|
|
1855
|
+
} else {
|
|
1856
|
+
response += `✅ No TODO/FIXME comments found - clean codebase!\n\n`;
|
|
1857
|
+
}
|
|
1858
|
+
} catch {
|
|
1859
|
+
response += `*(TODO scan unavailable)*\n\n`;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
response += `---\n\n`;
|
|
1863
|
+
|
|
1765
1864
|
// Scan for upgrade opportunities
|
|
1766
1865
|
response += `## Upgrade Opportunities\n\n`;
|
|
1767
1866
|
|
|
@@ -1827,6 +1926,17 @@ Just describe what you want to build! I'll automatically:
|
|
|
1827
1926
|
response += `✅ No major upgrade opportunities detected!\n\n`;
|
|
1828
1927
|
}
|
|
1829
1928
|
|
|
1929
|
+
// Review mode options
|
|
1930
|
+
response += `---\n\n`;
|
|
1931
|
+
response += `## Review Modes\n\n`;
|
|
1932
|
+
response += `Pick a focus for the upgrade:\n\n`;
|
|
1933
|
+
response += `- **Security Audit** - Auth, secrets, injections, OWASP top 10\n`;
|
|
1934
|
+
response += `- **Performance Review** - Bundle size, queries, caching\n`;
|
|
1935
|
+
response += `- **Code Quality** - Patterns, DRY, complexity\n`;
|
|
1936
|
+
response += `- **Pre-Launch** - Everything for production\n`;
|
|
1937
|
+
response += `- **Quick Scan** - Top 5 issues only\n`;
|
|
1938
|
+
response += `- **Comprehensive** - All of the above\n\n`;
|
|
1939
|
+
|
|
1830
1940
|
// Recommendations
|
|
1831
1941
|
response += `---\n\n`;
|
|
1832
1942
|
response += `## Recommended Actions\n\n`;
|
|
@@ -1835,12 +1945,10 @@ Just describe what you want to build! I'll automatically:
|
|
|
1835
1945
|
response += `**(Dry Run Mode - No changes will be made)**\n\n`;
|
|
1836
1946
|
}
|
|
1837
1947
|
|
|
1838
|
-
response += `1.
|
|
1839
|
-
response += `2.
|
|
1840
|
-
response += `3.
|
|
1841
|
-
response += `
|
|
1842
|
-
response += ` - "Add error boundaries to components"\n`;
|
|
1843
|
-
response += ` - "Set up Playwright testing"\n\n`;
|
|
1948
|
+
response += `1. Tell me your main concerns (security, performance, etc.)\n`;
|
|
1949
|
+
response += `2. I'll prioritize fixes based on your needs\n`;
|
|
1950
|
+
response += `3. Hot spot files get fixed first (where bugs live)\n`;
|
|
1951
|
+
response += `4. I'll implement your TODOs and fix FIXMEs along the way\n\n`;
|
|
1844
1952
|
|
|
1845
1953
|
response += `---\n\n`;
|
|
1846
1954
|
response += `**Key Principle:** Your stack stays the same. Only code quality patterns are upgraded.\n`;
|