Initial Release: OpenQode Public Alpha v1.3

This commit is contained in:
Gemini AI
2025-12-14 00:40:14 +04:00
Unverified
commit 8e8d80c110
119 changed files with 31174 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
import React, { useState, useEffect } from 'react';
import { Box, Text, useInput } from 'ink';
import * as Diff from 'diff';
const h = React.createElement;
const DiffView = ({
original = '',
modified = '',
file = 'unknown.js',
onApply,
onSkip,
width = 80,
height = 20
}) => {
// Generate diff objects
// [{ value: 'line', added: boolean, removed: boolean }]
const diff = Diff.diffLines(original, modified);
// Scroll state
const [scrollTop, setScrollTop] = useState(0);
// Calculate total lines for scrolling
const totalLines = diff.reduce((acc, part) => acc + part.value.split('\n').length - 1, 0);
const visibleLines = height - 4; // Header + Footer space
useInput((input, key) => {
if (key.upArrow) {
setScrollTop(prev => Math.max(0, prev - 1));
}
if (key.downArrow) {
setScrollTop(prev => Math.min(totalLines - visibleLines, prev + 1));
}
if (key.pageUp) {
setScrollTop(prev => Math.max(0, prev - visibleLines));
}
if (key.pageDown) {
setScrollTop(prev => Math.min(totalLines - visibleLines, prev + visibleLines));
}
if (input === 'y' || input === 'Y' || key.return) {
onApply();
}
if (input === 'n' || input === 'N' || key.escape) {
onSkip();
}
});
// Render Logic
let currentLine = 0;
const renderedLines = [];
diff.forEach((part) => {
const lines = part.value.split('\n');
// last element of split is often empty if value ends with newline
if (lines[lines.length - 1] === '') lines.pop();
lines.forEach((line) => {
currentLine++;
// Check visibility
if (currentLine <= scrollTop || currentLine > scrollTop + visibleLines) {
return;
}
let color = 'gray'; // Unchanged
let prefix = ' ';
let bg = undefined;
if (part.added) {
color = 'green';
prefix = '+ ';
} else if (part.removed) {
color = 'red';
prefix = '- ';
}
renderedLines.push(
h(Box, { key: currentLine, width: '100%' },
h(Text, { color: 'gray', dimColor: true }, `${currentLine.toString().padEnd(4)} `),
h(Text, { color: color, backgroundColor: bg, wrap: 'truncate-end' }, prefix + line)
)
);
});
});
return h(Box, {
flexDirection: 'column',
width: width,
height: height,
borderStyle: 'double',
borderColor: 'yellow'
},
// Header
h(Box, { flexDirection: 'column', paddingX: 1, borderStyle: 'single', borderBottom: true, borderTop: false, borderLeft: false, borderRight: false },
h(Text, { bold: true, color: 'yellow' }, `Reviewing: ${file}`),
h(Box, { justifyContent: 'space-between' },
h(Text, { dimColor: true }, `Lines: ${totalLines} | Changes: ${diff.filter(p => p.added || p.removed).length} blocks`),
h(Text, { color: 'blue' }, 'UP/DOWN to scroll')
)
),
// Diff Content
h(Box, { flexDirection: 'column', flexGrow: 1, paddingX: 1 },
renderedLines.length > 0
? renderedLines
: h(Text, { color: 'gray' }, 'No changes detected (Files are identical)')
),
// Footer Actions
h(Box, {
borderStyle: 'single',
borderTop: true,
borderBottom: false,
borderLeft: false,
borderRight: false,
paddingX: 1,
justifyContent: 'center',
gap: 4
},
h(Text, { color: 'green', bold: true }, '[Y] Apply Changes'),
h(Text, { color: 'red', bold: true }, '[N] Discard/Skip')
)
);
};
export default DiffView;