codeep 1.0.113 → 1.0.114
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/app.js
CHANGED
|
@@ -35,7 +35,7 @@ import { saveContext, loadContext, clearContext, mergeContext } from './utils/co
|
|
|
35
35
|
import { performCodeReview, formatReviewResult } from './utils/codeReview.js';
|
|
36
36
|
import { learnFromProject, addCustomRule, getLearningStatus } from './utils/learning.js';
|
|
37
37
|
import { getAllSkills, findSkill, formatSkillsList, formatSkillHelp, generateSkillPrompt, saveCustomSkill, deleteCustomSkill, parseSkillChain, parseSkillArgs, searchSkills, trackSkillUsage, getSkillStats } from './utils/skills.js';
|
|
38
|
-
import { AgentProgress,
|
|
38
|
+
import { AgentProgress, LiveCodeStream } from './components/AgentProgress.js';
|
|
39
39
|
import { createActionLog } from './utils/tools.js';
|
|
40
40
|
export const App = () => {
|
|
41
41
|
const { exit } = useApp();
|
|
@@ -1390,7 +1390,7 @@ export const App = () => {
|
|
|
1390
1390
|
// If we got here, we're in an unknown state - default to chat
|
|
1391
1391
|
return null;
|
|
1392
1392
|
}
|
|
1393
|
-
return (_jsxs(Box, { flexDirection: "column", children: [messages.length === 0 && !isLoading && _jsx(Logo, {}), messages.length === 0 && !isLoading && (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { children: ["Connected to ", _jsx(Text, { color: "#f02a30", children: config.get('model') }), ". Type ", _jsx(Text, { color: "#f02a30", children: "/help" }), " for commands."] }) }), _jsx(Text, { children: " " }), _jsx(Box, { justifyContent: "center", children: _jsx(Text, { color: "cyan", bold: true, children: "Welcome to Codeep - Your AI Coding Assistant" }) }), _jsx(Text, { children: " " }), _jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Ask questions about your code or request implementations"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Use ", _jsxs(Text, { color: "cyan", children: ["/agent ", '<task>'] }), " for autonomous task execution"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Type ", _jsx(Text, { color: "cyan", children: "/diff" }), " to review changes, ", _jsx(Text, { color: "cyan", children: "/commit" }), " to generate commit messages"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Configure settings with ", _jsx(Text, { color: "cyan", children: "/settings" }), " - enable Agent Mode for auto-execution"] })] }), _jsx(Text, { children: " " }), _jsx(Box, { justifyContent: "center", children: _jsx(Text, { color: "gray", children: "Start typing your message or use a command to begin..." }) }), _jsx(Text, { children: " " })] })), _jsx(MessageList, { messages: messages, streamingContent: streamingContent }, sessionId), isLoading && !isAgentRunning && _jsx(Loading, { isStreaming: !!streamingContent }), isAgentRunning
|
|
1393
|
+
return (_jsxs(Box, { flexDirection: "column", children: [messages.length === 0 && !isLoading && _jsx(Logo, {}), messages.length === 0 && !isLoading && (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { children: ["Connected to ", _jsx(Text, { color: "#f02a30", children: config.get('model') }), ". Type ", _jsx(Text, { color: "#f02a30", children: "/help" }), " for commands."] }) }), _jsx(Text, { children: " " }), _jsx(Box, { justifyContent: "center", children: _jsx(Text, { color: "cyan", bold: true, children: "Welcome to Codeep - Your AI Coding Assistant" }) }), _jsx(Text, { children: " " }), _jsxs(Box, { flexDirection: "column", paddingX: 2, children: [_jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Ask questions about your code or request implementations"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Use ", _jsxs(Text, { color: "cyan", children: ["/agent ", '<task>'] }), " for autonomous task execution"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Type ", _jsx(Text, { color: "cyan", children: "/diff" }), " to review changes, ", _jsx(Text, { color: "cyan", children: "/commit" }), " to generate commit messages"] }), _jsxs(Text, { children: [_jsx(Text, { color: "#f02a30", children: "\u2022" }), " Configure settings with ", _jsx(Text, { color: "cyan", children: "/settings" }), " - enable Agent Mode for auto-execution"] })] }), _jsx(Text, { children: " " }), _jsx(Box, { justifyContent: "center", children: _jsx(Text, { color: "gray", children: "Start typing your message or use a command to begin..." }) }), _jsx(Text, { children: " " })] })), _jsx(MessageList, { messages: messages, streamingContent: streamingContent }, sessionId), isLoading && !isAgentRunning && _jsx(Loading, { isStreaming: !!streamingContent }), (isAgentRunning || agentResult) && (_jsxs(Box, { flexDirection: "column", children: [_jsx(LiveCodeStream, { actions: agentActions, isRunning: isAgentRunning, terminalWidth: stdout?.columns || 80 }), isAgentRunning && (_jsx(AgentProgress, { isRunning: true, iteration: agentIteration, maxIterations: 50, actions: agentActions, currentThinking: agentThinking, dryRun: agentDryRun }))] }, "agent-ui")), pendingFileChanges.length > 0 && !isLoading && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#f02a30", padding: 1, marginY: 1, children: [_jsxs(Text, { color: "#f02a30", bold: true, children: ["\u2713 Detected ", pendingFileChanges.length, " file change(s):"] }), pendingFileChanges.map((change, i) => {
|
|
1394
1394
|
const actionColor = change.action === 'delete' ? 'red' : change.action === 'edit' ? 'yellow' : 'green';
|
|
1395
1395
|
const actionLabel = change.action === 'delete' ? 'DELETE' : change.action === 'edit' ? 'EDIT' : 'CREATE';
|
|
1396
1396
|
return (_jsxs(Text, { children: ["\u2022 ", _jsxs(Text, { color: actionColor, children: ["[", actionLabel, "]"] }), " ", change.path, change.action !== 'delete' && change.content.includes('\n') && ` (${change.content.split('\n').length} lines)`] }, i));
|
|
@@ -14,8 +14,12 @@ interface AgentProgressProps {
|
|
|
14
14
|
}
|
|
15
15
|
export declare const AgentProgress: React.FC<AgentProgressProps>;
|
|
16
16
|
/**
|
|
17
|
-
* Live Code Stream component - shows current file operation
|
|
18
|
-
*
|
|
17
|
+
* Live Code Stream component - shows current file operation with live preview
|
|
18
|
+
*
|
|
19
|
+
* KEY DESIGN: This component always renders exactly MAX_LINES lines
|
|
20
|
+
* - While running: shows live code preview
|
|
21
|
+
* - When finished: shows summary statistics
|
|
22
|
+
* - This prevents ghost content and terminal jumping because height is constant
|
|
19
23
|
*/
|
|
20
24
|
interface LiveCodeStreamProps {
|
|
21
25
|
actions: ActionLog[];
|
|
@@ -3,7 +3,7 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
* Agent progress display component
|
|
4
4
|
* Optimized with isolated spinner animation and memoization
|
|
5
5
|
*/
|
|
6
|
-
import { useState, useEffect, memo } from 'react';
|
|
6
|
+
import { useState, useEffect, memo, useMemo } from 'react';
|
|
7
7
|
import { Box, Text } from 'ink';
|
|
8
8
|
// Spinner frames for animation (no emojis)
|
|
9
9
|
const SPINNER_FRAMES = ['/', '-', '\\', '|'];
|
|
@@ -145,31 +145,76 @@ const isSectionBreak = (line, prevLine) => {
|
|
|
145
145
|
}
|
|
146
146
|
return false;
|
|
147
147
|
};
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
const MAX_PREVIEW_LINES = 8; // Code preview lines (total box will be ~10 with header/footer)
|
|
149
|
+
export const LiveCodeStream = memo(({ actions, isRunning, terminalWidth = 80 }) => {
|
|
150
|
+
// Calculate statistics from all actions
|
|
151
|
+
const stats = useMemo(() => {
|
|
152
|
+
const filesCreated = actions.filter(a => a.type === 'write' && a.result === 'success');
|
|
153
|
+
const filesEdited = actions.filter(a => a.type === 'edit' && a.result === 'success');
|
|
154
|
+
const filesDeleted = actions.filter(a => a.type === 'delete' && a.result === 'success');
|
|
155
|
+
const filesRead = actions.filter(a => a.type === 'read' && a.result === 'success');
|
|
156
|
+
const commands = actions.filter(a => a.type === 'command' && a.result === 'success');
|
|
157
|
+
const errors = actions.filter(a => a.result === 'error');
|
|
158
|
+
// Calculate total lines written
|
|
159
|
+
let totalLinesWritten = 0;
|
|
160
|
+
for (const action of [...filesCreated, ...filesEdited]) {
|
|
161
|
+
if (action.details) {
|
|
162
|
+
totalLinesWritten += action.details.split('\n').length;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
filesCreated: filesCreated.length,
|
|
167
|
+
filesEdited: filesEdited.length,
|
|
168
|
+
filesDeleted: filesDeleted.length,
|
|
169
|
+
filesRead: filesRead.length,
|
|
170
|
+
commands: commands.length,
|
|
171
|
+
errors: errors.length,
|
|
172
|
+
totalLinesWritten,
|
|
173
|
+
createdFiles: filesCreated.map(a => a.target.split('/').pop() || a.target),
|
|
174
|
+
editedFiles: filesEdited.map(a => a.target.split('/').pop() || a.target),
|
|
175
|
+
};
|
|
176
|
+
}, [actions]);
|
|
177
|
+
// Find the current write/edit action for live preview
|
|
150
178
|
const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
|
|
151
|
-
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
if (currentAction.type !== 'write' && currentAction.type !== 'edit')
|
|
179
|
+
const isCodeAction = currentAction && (currentAction.type === 'write' || currentAction.type === 'edit');
|
|
180
|
+
// Don't render anything if no actions yet (agent just started)
|
|
181
|
+
if (actions.length === 0) {
|
|
155
182
|
return null;
|
|
156
|
-
|
|
157
|
-
|
|
183
|
+
}
|
|
184
|
+
// Get code lines for preview
|
|
185
|
+
const codeLines = useMemo(() => {
|
|
186
|
+
if (!isCodeAction || !currentAction?.details)
|
|
187
|
+
return [];
|
|
188
|
+
return currentAction.details.split('\n');
|
|
189
|
+
}, [isCodeAction, currentAction?.details]);
|
|
190
|
+
const filename = currentAction?.target.split('/').pop() || '';
|
|
158
191
|
const ext = getFileExtension(filename);
|
|
159
192
|
const langLabel = getLanguageLabel(ext);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
193
|
+
// RUNNING STATE: Show live code preview
|
|
194
|
+
if (isRunning && isCodeAction && codeLines.length > 0) {
|
|
195
|
+
// Show last N lines of code being written
|
|
196
|
+
const visibleLines = codeLines.slice(-MAX_PREVIEW_LINES);
|
|
197
|
+
const hiddenCount = Math.max(0, codeLines.length - MAX_PREVIEW_LINES);
|
|
198
|
+
const actionIcon = currentAction.type === 'write' ? '+' : '~';
|
|
199
|
+
const actionColor = currentAction.type === 'write' ? 'green' : 'yellow';
|
|
200
|
+
const boxWidth = Math.min(terminalWidth - 4, 76);
|
|
201
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: actionColor, marginBottom: 1, width: boxWidth, children: [_jsxs(Box, { paddingX: 1, children: [_jsxs(Text, { color: actionColor, bold: true, children: [actionIcon, " "] }), _jsx(Text, { color: "white", bold: true, children: filename }), _jsxs(Text, { color: "gray", children: [" \u2022 ", langLabel, " \u2022 ", codeLines.length, " lines"] })] }), _jsxs(Box, { flexDirection: "column", paddingX: 1, children: [hiddenCount > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ... ", hiddenCount, " more lines above"] })), visibleLines.map((line, i) => {
|
|
202
|
+
const lineNum = hiddenCount + i + 1;
|
|
203
|
+
const displayLine = line.length > boxWidth - 10
|
|
204
|
+
? line.slice(0, boxWidth - 13) + '...'
|
|
205
|
+
: line;
|
|
206
|
+
return (_jsxs(Text, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: [String(lineNum).padStart(3), " "] }), _jsx(Text, { color: getCodeColor(line, ext), children: displayLine || ' ' })] }, i));
|
|
207
|
+
}), Array.from({ length: MAX_PREVIEW_LINES - visibleLines.length }).map((_, i) => (_jsx(Text, { color: "gray", dimColor: true, children: ' ' }, `pad-${i}`)))] })] }));
|
|
208
|
+
}
|
|
209
|
+
// RUNNING STATE but not a code action: show simple status
|
|
210
|
+
if (isRunning && currentAction) {
|
|
211
|
+
const boxWidth = Math.min(terminalWidth - 4, 76);
|
|
212
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", marginBottom: 1, width: boxWidth, children: [_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\u25E6 " }), _jsxs(Text, { color: getActionColor(currentAction.type), children: [getActionLabel(currentAction.type), " "] }), _jsx(Text, { color: "white", children: formatTarget(currentAction.target) })] }), Array.from({ length: MAX_PREVIEW_LINES }).map((_, i) => (_jsx(Text, { color: "gray", dimColor: true, children: " " }, `pad-${i}`)))] }));
|
|
213
|
+
}
|
|
214
|
+
// FINISHED STATE: Show summary statistics (same height as live preview)
|
|
215
|
+
const boxWidth = Math.min(terminalWidth - 4, 76);
|
|
216
|
+
const hasChanges = stats.filesCreated > 0 || stats.filesEdited > 0 || stats.filesDeleted > 0;
|
|
217
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: stats.errors > 0 ? 'red' : 'green', marginBottom: 1, width: boxWidth, children: [_jsxs(Box, { paddingX: 1, children: [_jsxs(Text, { color: stats.errors > 0 ? 'red' : 'green', bold: true, children: [stats.errors > 0 ? '!' : '✓', " Session Complete"] }), _jsxs(Text, { color: "gray", children: [" \u2022 ", actions.length, " actions"] })] }), _jsxs(Box, { flexDirection: "column", paddingX: 1, children: [hasChanges ? (_jsxs(_Fragment, { children: [stats.filesCreated > 0 && (_jsxs(Text, { children: [_jsxs(Text, { color: "green", bold: true, children: [" + ", stats.filesCreated, " "] }), _jsx(Text, { color: "gray", children: "file(s) created" }), stats.createdFiles.length <= 3 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" (", stats.createdFiles.join(', '), ")"] }))] })), stats.filesEdited > 0 && (_jsxs(Text, { children: [_jsxs(Text, { color: "yellow", bold: true, children: [" ~ ", stats.filesEdited, " "] }), _jsx(Text, { color: "gray", children: "file(s) modified" }), stats.editedFiles.length <= 3 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" (", stats.editedFiles.join(', '), ")"] }))] })), stats.filesDeleted > 0 && (_jsxs(Text, { children: [_jsxs(Text, { color: "red", bold: true, children: [" - ", stats.filesDeleted, " "] }), _jsx(Text, { color: "gray", children: "file(s) deleted" })] })), stats.totalLinesWritten > 0 && (_jsxs(Text, { children: [_jsxs(Text, { color: "cyan", bold: true, children: [" \u2261 ", stats.totalLinesWritten, " "] }), _jsx(Text, { color: "gray", children: "total lines written" })] })), stats.filesRead > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", stats.filesRead, " file(s) read"] })), stats.commands > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", stats.commands, " command(s) run"] }))] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " No file changes made" }), stats.filesRead > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", stats.filesRead, " file(s) read"] })), stats.commands > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", stats.commands, " command(s) run"] }))] })), stats.errors > 0 && (_jsxs(Text, { color: "red", children: [" \u2717 ", stats.errors, " error(s) occurred"] })), Array.from({ length: Math.max(0, MAX_PREVIEW_LINES - 6) }).map((_, i) => (_jsx(Text, { color: "gray", dimColor: true, children: " " }, `pad-${i}`)))] })] }));
|
|
173
218
|
});
|
|
174
219
|
LiveCodeStream.displayName = 'LiveCodeStream';
|
|
175
220
|
// Helper functions for action display
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.114",
|
|
4
4
|
"description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|