codeep 1.0.63 → 1.0.64

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, 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();
@@ -1350,7 +1350,7 @@ export const App = () => {
1350
1350
  return (_jsx(LanguageSelect, { onClose: () => setScreen('chat'), notify: notify }));
1351
1351
  }
1352
1352
  // Main chat screen
1353
- 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) => {
1353
+ 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) => {
1354
1354
  const actionColor = change.action === 'delete' ? 'red' : change.action === 'edit' ? 'yellow' : 'green';
1355
1355
  const actionLabel = change.action === 'delete' ? 'DELETE' : change.action === 'edit' ? 'EDIT' : 'CREATE';
1356
1356
  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,7 +14,7 @@ interface AgentProgressProps {
14
14
  export declare const AgentProgress: React.FC<AgentProgressProps>;
15
15
  /**
16
16
  * Live Code Stream component - shows code being written/edited by agent
17
- * FIXED HEIGHT to prevent layout shift and empty lines
17
+ * Displays code progressively 10 lines at a time ABOVE agent progress
18
18
  */
19
19
  interface LiveCodeStreamProps {
20
20
  actions: ActionLog[];
@@ -2,7 +2,7 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
2
2
  /**
3
3
  * Agent progress display component
4
4
  */
5
- import { useState, useEffect } from 'react';
5
+ import { useState, useEffect, useRef } from 'react';
6
6
  import { Box, Text } from 'ink';
7
7
  // Spinner frames for animation (no emojis)
8
8
  const SPINNER_FRAMES = ['/', '-', '\\', '|'];
@@ -40,7 +40,7 @@ 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', paddingX: 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, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { 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) }), (currentAction.type === 'write' || currentAction.type === 'edit') && currentAction.details && (_jsxs(Text, { color: "gray", children: [" (", currentAction.details.split('\n').length, " lines)"] }))] }), (currentAction.type === 'write' || currentAction.type === 'edit') && currentAction.details && (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: currentAction.details.split('\n').slice(-5).map((line, i) => (_jsxs(Text, { color: "gray", dimColor: true, children: [line.slice(0, 60), line.length > 60 ? '…' : ''] }, i))) }))] })), _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"] }))] }))] }));
43
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: dryRun ? 'yellow' : '#f02a30', paddingX: 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
45
  // Get file extension for language detection
46
46
  const getFileExtension = (filename) => {
@@ -139,10 +139,41 @@ const isSectionBreak = (line, prevLine) => {
139
139
  }
140
140
  return false;
141
141
  };
142
- const LIVE_CODE_LINES = 8; // Fixed number of visible lines
142
+ const LINES_PER_CHUNK = 10; // Show 10 lines at a time
143
143
  export const LiveCodeStream = ({ actions, isRunning }) => {
144
+ // Track how many lines we've shown so far
145
+ const [visibleLineCount, setVisibleLineCount] = useState(LINES_PER_CHUNK);
146
+ const lastActionIdRef = useRef('');
144
147
  // Find the current write/edit action with code content
145
148
  const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
149
+ // Create a unique ID for current action
150
+ const currentActionId = currentAction
151
+ ? `${currentAction.type}-${currentAction.target}-${currentAction.details?.length || 0}`
152
+ : '';
153
+ // Reset visible lines when action changes
154
+ useEffect(() => {
155
+ if (currentActionId !== lastActionIdRef.current) {
156
+ lastActionIdRef.current = currentActionId;
157
+ setVisibleLineCount(LINES_PER_CHUNK);
158
+ }
159
+ }, [currentActionId]);
160
+ // Progressively show more lines
161
+ useEffect(() => {
162
+ if (!isRunning || !currentAction)
163
+ return;
164
+ if (currentAction.type !== 'write' && currentAction.type !== 'edit')
165
+ return;
166
+ if (!currentAction.details)
167
+ return;
168
+ const totalLines = currentAction.details.split('\n').length;
169
+ // If we haven't shown all lines yet, schedule showing more
170
+ if (visibleLineCount < totalLines) {
171
+ const timer = setTimeout(() => {
172
+ setVisibleLineCount(prev => Math.min(prev + LINES_PER_CHUNK, totalLines));
173
+ }, 200); // Show next 10 lines every 200ms
174
+ return () => clearTimeout(timer);
175
+ }
176
+ }, [isRunning, currentAction, visibleLineCount]);
146
177
  // Only show for write/edit actions with content while running
147
178
  if (!isRunning || !currentAction)
148
179
  return null;
@@ -159,19 +190,13 @@ export const LiveCodeStream = ({ actions, isRunning }) => {
159
190
  const totalLines = allLines.length;
160
191
  const actionLabel = currentAction.type === 'write' ? '✨ Creating' : '✏️ Editing';
161
192
  const actionColor = currentAction.type === 'write' ? 'green' : 'yellow';
162
- // Show last N lines (sliding window)
163
- const startLine = Math.max(0, totalLines - LIVE_CODE_LINES);
164
- const visibleLines = allLines.slice(startLine, totalLines);
165
- // Pad to fixed height to prevent layout shift
166
- const paddedLines = [...visibleLines];
167
- while (paddedLines.length < LIVE_CODE_LINES) {
168
- paddedLines.push('');
169
- }
170
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsxs(Text, { color: actionColor, bold: true, children: [actionLabel, " "] }), _jsx(Text, { color: "white", bold: true, children: filename }), _jsxs(Text, { color: "gray", children: [" \u2022 ", langLabel, " \u2022 "] }), _jsx(Text, { color: "cyan", children: totalLines }), _jsx(Text, { color: "gray", children: " lines" }), startLine > 0 && _jsxs(Text, { color: "gray", dimColor: true, children: [" (showing ", startLine + 1, "-", totalLines, ")"] })] }), paddedLines.map((line, i) => {
171
- const lineNum = startLine + i + 1;
172
- const isRealLine = i < visibleLines.length;
173
- return (_jsxs(Text, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: [isRealLine ? String(lineNum).padStart(4, ' ') : ' ', " \u2502", ' '] }), isRealLine ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: getCodeColor(line, ext), children: line.slice(0, 70) }), line.length > 70 && _jsx(Text, { color: "gray", children: "\u2026" })] })) : (_jsx(Text, { children: " " }))] }, `fixed-line-${i}`));
174
- })] }));
193
+ // Show lines up to visibleLineCount
194
+ const linesToShow = allLines.slice(0, visibleLineCount);
195
+ const hasMoreLines = visibleLineCount < totalLines;
196
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: actionColor, children: '─'.repeat(60) }), _jsxs(Text, { children: [_jsxs(Text, { color: actionColor, bold: true, children: [actionLabel, " "] }), _jsx(Text, { color: "white", bold: true, children: filename }), _jsxs(Text, { color: "gray", children: [" \u2022 ", langLabel, " \u2022 "] }), _jsx(Text, { color: "cyan", children: visibleLineCount }), _jsxs(Text, { color: "gray", children: ["/", totalLines, " lines"] }), hasMoreLines && _jsx(Text, { color: "yellow", children: " \u25BC streaming..." })] }), linesToShow.map((line, i) => {
197
+ const lineNum = i + 1;
198
+ return (_jsxs(Text, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: [String(lineNum).padStart(4, ' '), " \u2502", ' '] }), _jsx(Text, { color: getCodeColor(line, ext), children: line.slice(0, 80) }), line.length > 80 && _jsx(Text, { color: "gray", children: "\u2026" })] }, `line-${i}`));
199
+ }), hasMoreLines && (_jsxs(Text, { color: "gray", dimColor: true, children: [' ', "\u2502 ... ", totalLines - visibleLineCount, " more lines loading..."] })), _jsx(Text, { color: actionColor, children: '─'.repeat(60) })] }));
175
200
  };
176
201
  // Helper functions for action display
177
202
  const getActionColor = (type) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.63",
3
+ "version": "1.0.64",
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",