codeep 1.0.51 → 1.0.53
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 +2 -2
- package/dist/components/AgentProgress.d.ts +10 -0
- package/dist/components/AgentProgress.js +122 -11
- package/package.json +1 -1
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, AgentSummary } from './components/AgentProgress.js';
|
|
38
|
+
import { AgentProgress, AgentSummary, LiveCodeStream } from './components/AgentProgress.js';
|
|
39
39
|
import { createActionLog } from './utils/tools.js';
|
|
40
40
|
export const App = () => {
|
|
41
41
|
const { exit } = useApp();
|
|
@@ -1330,7 +1330,7 @@ export const App = () => {
|
|
|
1330
1330
|
return (_jsx(LanguageSelect, { onClose: () => setScreen('chat'), notify: notify }));
|
|
1331
1331
|
}
|
|
1332
1332
|
// Main chat screen
|
|
1333
|
-
return (_jsxs(Box, { flexDirection: "column", children: [messages.length === 0 && !isLoading && _jsx(Logo, {}), messages.length === 0 && !isLoading && (_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(MessageList, { messages: messages, streamingContent: streamingContent, scrollOffset: 0, terminalHeight: stdout.rows || 24 }, sessionId), isLoading && !isAgentRunning && _jsx(Loading, { isStreaming: !!streamingContent }), isAgentRunning && (_jsx(AgentProgress, { isRunning: true, iteration: agentIteration, maxIterations: 50, actions: agentActions, currentThinking: agentThinking, dryRun: agentDryRun })), !isAgentRunning && agentResult && (_jsx(AgentSummary, { success: agentResult.success, iterations: agentResult.iterations, actions: agentActions, error: agentResult.error, aborted: agentResult.aborted })), 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) => {
|
|
1333
|
+
return (_jsxs(Box, { flexDirection: "column", children: [messages.length === 0 && !isLoading && _jsx(Logo, {}), messages.length === 0 && !isLoading && (_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(MessageList, { messages: messages, streamingContent: streamingContent, scrollOffset: 0, terminalHeight: stdout.rows || 24 }, sessionId), isLoading && !isAgentRunning && _jsx(Loading, { isStreaming: !!streamingContent }), isAgentRunning && (_jsx(LiveCodeStream, { actions: agentActions, isRunning: true })), isAgentRunning && (_jsx(AgentProgress, { isRunning: true, iteration: agentIteration, maxIterations: 50, actions: agentActions, currentThinking: agentThinking, dryRun: agentDryRun })), !isAgentRunning && agentResult && (_jsx(AgentSummary, { success: agentResult.success, iterations: agentResult.iterations, actions: agentActions, error: agentResult.error, aborted: agentResult.aborted })), 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) => {
|
|
1334
1334
|
const actionColor = change.action === 'delete' ? 'red' : change.action === 'edit' ? 'yellow' : 'green';
|
|
1335
1335
|
const actionLabel = change.action === 'delete' ? 'DELETE' : change.action === 'edit' ? 'EDIT' : 'CREATE';
|
|
1336
1336
|
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));
|
|
@@ -12,6 +12,16 @@ interface AgentProgressProps {
|
|
|
12
12
|
dryRun?: boolean;
|
|
13
13
|
}
|
|
14
14
|
export declare const AgentProgress: React.FC<AgentProgressProps>;
|
|
15
|
+
/**
|
|
16
|
+
* Live Code Stream component - shows ALL code being written/edited by agent
|
|
17
|
+
* Displayed ABOVE the AgentProgress component
|
|
18
|
+
* Enhanced with better syntax highlighting and visual organization
|
|
19
|
+
*/
|
|
20
|
+
interface LiveCodeStreamProps {
|
|
21
|
+
actions: ActionLog[];
|
|
22
|
+
isRunning: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare const LiveCodeStream: React.FC<LiveCodeStreamProps>;
|
|
15
25
|
/**
|
|
16
26
|
* Agent summary component - shown when agent completes
|
|
17
27
|
*/
|
|
@@ -40,29 +40,140 @@ export const AgentProgress = ({ isRunning, iteration, maxIterations, actions, cu
|
|
|
40
40
|
deleted: actions.filter(a => a.type === 'delete' && a.result === 'success').length,
|
|
41
41
|
};
|
|
42
42
|
const totalFileChanges = fileChanges.created + fileChanges.modified + fileChanges.deleted;
|
|
43
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: dryRun ? 'yellow' : '#f02a30', padding: 1, marginY: 1, children: [_jsx(Box, { children: isRunning ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: dryRun ? 'yellow' : '#f02a30', children: ["[", SPINNER_FRAMES[spinnerFrame], "]"] }), _jsxs(Text, { color: dryRun ? 'yellow' : '#f02a30', bold: true, children: [' ', dryRun ? 'DRY RUN' : 'AGENT', ' '] }), _jsx(Text, { color: "gray", children: "|" }), _jsxs(Text, { color: "cyan", children: [" step ", iteration] }), _jsx(Text, { color: "gray", children: " | " }), actionCounts.reads > 0 && _jsxs(Text, { color: "blue", children: [actionCounts.reads, "R "] }), actionCounts.writes > 0 && _jsxs(Text, { color: "green", children: [actionCounts.writes, "W "] }), actionCounts.edits > 0 && _jsxs(Text, { color: "yellow", children: [actionCounts.edits, "E "] }), actionCounts.commands > 0 && _jsxs(Text, { color: "magenta", children: [actionCounts.commands, "C "] }), actionCounts.searches > 0 && _jsxs(Text, { color: "cyan", children: [actionCounts.searches, "S "] }), actions.length === 0 && _jsx(Text, { color: "gray", children: "0 actions" })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: "green", bold: true, children: "[DONE] " }), _jsx(Text, { children: "Agent completed" }), _jsx(Text, { color: "gray", children: " | " }), _jsxs(Text, { color: "white", children: [actions.length, " actions"] })] })) }), isRunning && currentAction && (_jsxs(Box, {
|
|
43
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: dryRun ? 'yellow' : '#f02a30', padding: 1, marginY: 1, children: [_jsx(Box, { children: isRunning ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: dryRun ? 'yellow' : '#f02a30', children: ["[", SPINNER_FRAMES[spinnerFrame], "]"] }), _jsxs(Text, { color: dryRun ? 'yellow' : '#f02a30', bold: true, children: [' ', dryRun ? 'DRY RUN' : 'AGENT', ' '] }), _jsx(Text, { color: "gray", children: "|" }), _jsxs(Text, { color: "cyan", children: [" step ", iteration] }), _jsx(Text, { color: "gray", children: " | " }), actionCounts.reads > 0 && _jsxs(Text, { color: "blue", children: [actionCounts.reads, "R "] }), actionCounts.writes > 0 && _jsxs(Text, { color: "green", children: [actionCounts.writes, "W "] }), actionCounts.edits > 0 && _jsxs(Text, { color: "yellow", children: [actionCounts.edits, "E "] }), actionCounts.commands > 0 && _jsxs(Text, { color: "magenta", children: [actionCounts.commands, "C "] }), actionCounts.searches > 0 && _jsxs(Text, { color: "cyan", children: [actionCounts.searches, "S "] }), actions.length === 0 && _jsx(Text, { color: "gray", children: "0 actions" })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: "green", bold: true, children: "[DONE] " }), _jsx(Text, { children: "Agent completed" }), _jsx(Text, { color: "gray", children: " | " }), _jsxs(Text, { color: "white", children: [actions.length, " actions"] })] })) }), isRunning && currentAction && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "white", bold: true, children: "Now: " }), _jsxs(Text, { color: getActionColor(currentAction.type), children: [getActionLabel(currentAction.type), " "] }), _jsx(Text, { color: "white", children: formatTarget(currentAction.target) })] })), _jsx(Text, { color: "gray", children: '─'.repeat(50) }), recentActions.length > 1 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "gray", dimColor: true, children: "Recent:" }), recentActions.slice(0, -1).map((action, i) => (_jsx(ActionItem, { action: action }, i)))] })), isRunning && totalFileChanges > 0 && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "gray", children: "Changes: " }), fileChanges.created > 0 && _jsxs(Text, { color: "green", children: ["+", fileChanges.created, " "] }), fileChanges.modified > 0 && _jsxs(Text, { color: "yellow", children: ["~", fileChanges.modified, " "] }), fileChanges.deleted > 0 && _jsxs(Text, { color: "red", children: ["-", fileChanges.deleted] })] })), isRunning && currentThinking && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", wrap: "truncate-end", children: ["> ", currentThinking.slice(0, 80), currentThinking.length > 80 ? '...' : ''] }) })), isRunning && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "gray", children: "Press " }), _jsx(Text, { color: "#f02a30", children: "Esc" }), _jsx(Text, { color: "gray", children: " to stop" })] })), !isRunning && totalFileChanges > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: "File Changes:" }), fileChanges.created > 0 && (_jsxs(Text, { color: "green", children: [" + ", fileChanges.created, " file(s) created"] })), fileChanges.modified > 0 && (_jsxs(Text, { color: "yellow", children: [" ~ ", fileChanges.modified, " file(s) modified"] })), fileChanges.deleted > 0 && (_jsxs(Text, { color: "red", children: [" - ", fileChanges.deleted, " file(s) deleted"] }))] }))] }));
|
|
44
44
|
};
|
|
45
|
-
//
|
|
46
|
-
const
|
|
45
|
+
// Get file extension for language detection
|
|
46
|
+
const getFileExtension = (filename) => {
|
|
47
|
+
const parts = filename.split('.');
|
|
48
|
+
return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : '';
|
|
49
|
+
};
|
|
50
|
+
// Get language label from extension
|
|
51
|
+
const getLanguageLabel = (ext) => {
|
|
52
|
+
const langMap = {
|
|
53
|
+
'js': 'JavaScript',
|
|
54
|
+
'jsx': 'React JSX',
|
|
55
|
+
'ts': 'TypeScript',
|
|
56
|
+
'tsx': 'React TSX',
|
|
57
|
+
'html': 'HTML',
|
|
58
|
+
'css': 'CSS',
|
|
59
|
+
'scss': 'SCSS',
|
|
60
|
+
'json': 'JSON',
|
|
61
|
+
'md': 'Markdown',
|
|
62
|
+
'py': 'Python',
|
|
63
|
+
'rb': 'Ruby',
|
|
64
|
+
'go': 'Go',
|
|
65
|
+
'rs': 'Rust',
|
|
66
|
+
'java': 'Java',
|
|
67
|
+
'kt': 'Kotlin',
|
|
68
|
+
'swift': 'Swift',
|
|
69
|
+
'php': 'PHP',
|
|
70
|
+
'sql': 'SQL',
|
|
71
|
+
'sh': 'Shell',
|
|
72
|
+
'bash': 'Bash',
|
|
73
|
+
'yml': 'YAML',
|
|
74
|
+
'yaml': 'YAML',
|
|
75
|
+
'xml': 'XML',
|
|
76
|
+
'vue': 'Vue',
|
|
77
|
+
'svelte': 'Svelte',
|
|
78
|
+
};
|
|
79
|
+
return langMap[ext] || ext.toUpperCase();
|
|
80
|
+
};
|
|
81
|
+
// Enhanced syntax highlighting with more colors
|
|
82
|
+
const getCodeColor = (line, ext) => {
|
|
47
83
|
const trimmed = line.trim();
|
|
48
|
-
//
|
|
49
|
-
if (trimmed
|
|
84
|
+
// Empty lines
|
|
85
|
+
if (!trimmed)
|
|
86
|
+
return 'gray';
|
|
87
|
+
// Comments - multiple styles
|
|
88
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('#') || trimmed.startsWith('/*') ||
|
|
89
|
+
trimmed.startsWith('*') || trimmed.startsWith('<!--') || trimmed.startsWith('"""') ||
|
|
90
|
+
trimmed.startsWith("'''")) {
|
|
50
91
|
return 'gray';
|
|
51
92
|
}
|
|
52
|
-
//
|
|
53
|
-
if (/^(import|export|
|
|
93
|
+
// Import/export statements
|
|
94
|
+
if (/^(import|export|from|require)\b/.test(trimmed)) {
|
|
54
95
|
return 'magenta';
|
|
55
96
|
}
|
|
56
|
-
//
|
|
57
|
-
if (
|
|
97
|
+
// Function/class definitions
|
|
98
|
+
if (/^(function|class|interface|type|enum|const\s+\w+\s*=\s*(\(|async)|def |class |fn |func |pub fn)\b/.test(trimmed)) {
|
|
99
|
+
return 'yellow';
|
|
100
|
+
}
|
|
101
|
+
// Control flow keywords
|
|
102
|
+
if (/^(if|else|for|while|switch|case|try|catch|finally|return|throw|break|continue|async|await)\b/.test(trimmed)) {
|
|
103
|
+
return 'blue';
|
|
104
|
+
}
|
|
105
|
+
// Variable declarations
|
|
106
|
+
if (/^(const|let|var|val|mut)\b/.test(trimmed)) {
|
|
107
|
+
return 'cyan';
|
|
108
|
+
}
|
|
109
|
+
// HTML/JSX tags
|
|
110
|
+
if ((ext === 'html' || ext === 'jsx' || ext === 'tsx' || ext === 'vue' || ext === 'svelte') &&
|
|
111
|
+
(trimmed.startsWith('<') || trimmed.startsWith('</'))) {
|
|
112
|
+
return 'cyan';
|
|
113
|
+
}
|
|
114
|
+
// CSS selectors and properties
|
|
115
|
+
if ((ext === 'css' || ext === 'scss') && (trimmed.includes('{') || trimmed.includes(':'))) {
|
|
116
|
+
return 'green';
|
|
117
|
+
}
|
|
118
|
+
// JSON keys
|
|
119
|
+
if (ext === 'json' && trimmed.includes(':')) {
|
|
58
120
|
return 'cyan';
|
|
59
121
|
}
|
|
60
|
-
// Strings
|
|
61
|
-
if (
|
|
122
|
+
// Strings (but not the whole line)
|
|
123
|
+
if (/["'`]/.test(trimmed)) {
|
|
62
124
|
return 'green';
|
|
63
125
|
}
|
|
64
126
|
return 'white';
|
|
65
127
|
};
|
|
128
|
+
// Check if line is a section separator (empty or comment-only)
|
|
129
|
+
const isSectionBreak = (line, prevLine) => {
|
|
130
|
+
const trimmed = line.trim();
|
|
131
|
+
const prevTrimmed = prevLine?.trim() || '';
|
|
132
|
+
// Empty line after non-empty line
|
|
133
|
+
if (!trimmed && prevTrimmed)
|
|
134
|
+
return true;
|
|
135
|
+
// Comment after code
|
|
136
|
+
if ((trimmed.startsWith('//') || trimmed.startsWith('#') || trimmed.startsWith('/*')) &&
|
|
137
|
+
prevTrimmed && !prevTrimmed.startsWith('//') && !prevTrimmed.startsWith('#')) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
};
|
|
142
|
+
export const LiveCodeStream = ({ actions, isRunning }) => {
|
|
143
|
+
// Find the current write/edit action with code content
|
|
144
|
+
const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
|
|
145
|
+
// Only show for write/edit actions with content
|
|
146
|
+
if (!isRunning || !currentAction)
|
|
147
|
+
return null;
|
|
148
|
+
if (currentAction.type !== 'write' && currentAction.type !== 'edit')
|
|
149
|
+
return null;
|
|
150
|
+
if (!currentAction.details)
|
|
151
|
+
return null;
|
|
152
|
+
const code = currentAction.details;
|
|
153
|
+
const fullPath = currentAction.target;
|
|
154
|
+
const filename = fullPath.split('/').pop() || fullPath;
|
|
155
|
+
const ext = getFileExtension(filename);
|
|
156
|
+
const langLabel = getLanguageLabel(ext);
|
|
157
|
+
const allLines = code.split('\n');
|
|
158
|
+
const totalLines = allLines.length;
|
|
159
|
+
const actionLabel = currentAction.type === 'write' ? '✨ Creating' : '✏️ Editing';
|
|
160
|
+
const actionColor = currentAction.type === 'write' ? 'green' : 'yellow';
|
|
161
|
+
// Calculate code stats
|
|
162
|
+
const nonEmptyLines = allLines.filter(l => l.trim()).length;
|
|
163
|
+
const commentLines = allLines.filter(l => {
|
|
164
|
+
const t = l.trim();
|
|
165
|
+
return t.startsWith('//') || t.startsWith('#') || t.startsWith('/*') || t.startsWith('*');
|
|
166
|
+
}).length;
|
|
167
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsxs(Text, { color: actionColor, bold: true, children: [actionLabel, " "] }), _jsx(Text, { color: "white", bold: true, children: filename })] }), _jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: [langLabel, " \u2022 "] }), _jsx(Text, { color: "cyan", children: totalLines }), _jsx(Text, { color: "gray", children: " lines" }), commentLines > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " \u2022 " }), _jsxs(Text, { color: "gray", dimColor: true, children: [commentLines, " comments"] })] }))] })] }), fullPath !== filename && (_jsxs(Text, { color: "gray", dimColor: true, children: [" \uD83D\uDCC1 ", fullPath] })), _jsx(Text, { color: actionColor, children: '┌' + '─'.repeat(78) + '┐' }), _jsx(Box, { flexDirection: "column", children: allLines.map((line, i) => {
|
|
168
|
+
const lineNum = i + 1;
|
|
169
|
+
const prevLine = i > 0 ? allLines[i - 1] : null;
|
|
170
|
+
const showSeparator = isSectionBreak(line, prevLine);
|
|
171
|
+
const lineColor = getCodeColor(line, ext);
|
|
172
|
+
// Zebra striping for better readability (subtle)
|
|
173
|
+
const isEvenLine = i % 2 === 0;
|
|
174
|
+
return (_jsxs(Box, { flexDirection: "column", children: [showSeparator && i > 0 && (_jsx(Text, { color: "gray", dimColor: true, children: '│' + ' '.repeat(78) + '│' })), _jsxs(Text, { children: [_jsx(Text, { color: actionColor, children: "\u2502" }), _jsx(Text, { color: isEvenLine ? 'gray' : 'white', dimColor: !isEvenLine, children: String(lineNum).padStart(4, ' ') }), _jsx(Text, { color: "gray", dimColor: true, children: " \u2502 " }), _jsx(Text, { color: lineColor, children: line.slice(0, 70) }), line.length > 70 && _jsx(Text, { color: "gray", children: "\u2026" }), line.length <= 70 && _jsx(Text, { children: ' '.repeat(Math.max(0, 70 - line.length)) }), _jsx(Text, { color: actionColor, children: "\u2502" })] })] }, i));
|
|
175
|
+
}) }), _jsx(Text, { color: actionColor, children: '└' + '─'.repeat(78) + '┘' })] }));
|
|
176
|
+
};
|
|
66
177
|
// Helper functions for action display
|
|
67
178
|
const getActionColor = (type) => {
|
|
68
179
|
switch (type) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.53",
|
|
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",
|