codeep 1.0.54 → 1.0.56

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.
@@ -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 = ['/', '-', '\\', '|'];
@@ -140,36 +140,58 @@ const isSectionBreak = (line, prevLine) => {
140
140
  return false;
141
141
  };
142
142
  export const LiveCodeStream = ({ actions, isRunning }) => {
143
- // State for streaming effect - show lines progressively
144
- const [visibleLines, setVisibleLines] = useState(0);
145
- const [lastActionId, setLastActionId] = useState(null);
143
+ // Use ref for tracking to avoid re-render loops
144
+ const lastActionIdRef = useRef(null);
145
+ const timerRef = useRef(null);
146
+ // State for visible lines - only update when batch is ready
147
+ const [displayState, setDisplayState] = useState({
148
+ endLine: 0,
149
+ actionId: null,
150
+ });
146
151
  // Find the current write/edit action with code content
147
152
  const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
148
153
  // Create a unique ID for the current action
149
154
  const actionId = currentAction ? `${currentAction.target}-${currentAction.timestamp}` : null;
150
- // Reset visible lines when action changes, then stream progressively
155
+ // Get total lines for current action
156
+ const totalLines = currentAction?.details ? currentAction.details.split('\n').length : 0;
157
+ // Stream lines progressively using interval instead of recursive setTimeout
151
158
  useEffect(() => {
152
- if (!currentAction || !currentAction.details) {
153
- setVisibleLines(0);
154
- return;
159
+ // Clear any existing timer
160
+ if (timerRef.current) {
161
+ clearInterval(timerRef.current);
162
+ timerRef.current = null;
155
163
  }
156
- // If this is a new action, reset and start streaming
157
- if (actionId !== lastActionId) {
158
- setLastActionId(actionId);
159
- setVisibleLines(10); // Start with first 10 lines
164
+ if (!currentAction || !currentAction.details || !isRunning) {
165
+ if (displayState.endLine !== 0 || displayState.actionId !== null) {
166
+ setDisplayState({ endLine: 0, actionId: null });
167
+ }
160
168
  return;
161
169
  }
162
- // Stream more lines progressively
163
- const totalLines = currentAction.details.split('\n').length;
164
- if (visibleLines < totalLines) {
165
- const timer = setTimeout(() => {
166
- // Add 10 more lines every 100ms
167
- setVisibleLines(prev => Math.min(prev + 10, totalLines));
168
- }, 100);
169
- return () => clearTimeout(timer);
170
+ // If this is a new action, reset and start streaming
171
+ if (actionId !== lastActionIdRef.current) {
172
+ lastActionIdRef.current = actionId;
173
+ setDisplayState({ endLine: 10, actionId });
174
+ // Start interval to stream more lines
175
+ timerRef.current = setInterval(() => {
176
+ setDisplayState(prev => {
177
+ const newEndLine = Math.min(prev.endLine + 10, totalLines);
178
+ // Stop interval when we've shown all lines
179
+ if (newEndLine >= totalLines && timerRef.current) {
180
+ clearInterval(timerRef.current);
181
+ timerRef.current = null;
182
+ }
183
+ return { ...prev, endLine: newEndLine };
184
+ });
185
+ }, 150); // Slightly slower for smoother experience
170
186
  }
171
- }, [currentAction, actionId, lastActionId, visibleLines]);
172
- // Only show for write/edit actions with content
187
+ return () => {
188
+ if (timerRef.current) {
189
+ clearInterval(timerRef.current);
190
+ timerRef.current = null;
191
+ }
192
+ };
193
+ }, [actionId, isRunning, totalLines]);
194
+ // Only show for write/edit actions with content while running
173
195
  if (!isRunning || !currentAction)
174
196
  return null;
175
197
  if (currentAction.type !== 'write' && currentAction.type !== 'edit')
@@ -182,26 +204,21 @@ export const LiveCodeStream = ({ actions, isRunning }) => {
182
204
  const ext = getFileExtension(filename);
183
205
  const langLabel = getLanguageLabel(ext);
184
206
  const allLines = code.split('\n');
185
- const totalLines = allLines.length;
186
207
  const actionLabel = currentAction.type === 'write' ? '✨ Creating' : '✏️ Editing';
187
208
  const actionColor = currentAction.type === 'write' ? 'green' : 'yellow';
188
- // Only show lines up to visibleLines (streaming effect)
189
- const linesToShow = allLines.slice(0, visibleLines);
190
- const remainingLines = totalLines - visibleLines;
191
- // Calculate code stats
192
- const commentLines = allLines.filter(l => {
193
- const t = l.trim();
194
- return t.startsWith('//') || t.startsWith('#') || t.startsWith('/*') || t.startsWith('*');
195
- }).length;
196
- 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: visibleLines }), _jsxs(Text, { color: "gray", children: ["/", totalLines, " lines"] }), remainingLines > 0 && (_jsx(Text, { color: "yellow", children: " \u25BC streaming..." }))] })] }), fullPath !== filename && (_jsxs(Text, { color: "gray", dimColor: true, children: [" \uD83D\uDCC1 ", fullPath] })), _jsx(Text, { color: actionColor, children: '┌' + '─'.repeat(78) + '┐' }), _jsx(Box, { flexDirection: "column", children: linesToShow.map((line, i) => {
197
- const lineNum = i + 1;
198
- const prevLine = i > 0 ? allLines[i - 1] : null;
199
- const showSeparator = isSectionBreak(line, prevLine);
209
+ // Use displayState for rendering
210
+ const visibleEndLine = displayState.endLine;
211
+ // Sliding window: show only last 10 lines of what's been "written" so far
212
+ const WINDOW_SIZE = 10;
213
+ const startLine = Math.max(0, visibleEndLine - WINDOW_SIZE);
214
+ const linesToShow = allLines.slice(startLine, visibleEndLine);
215
+ const remainingLines = totalLines - visibleEndLine;
216
+ const linesAbove = startLine;
217
+ 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: visibleEndLine }), _jsxs(Text, { color: "gray", children: ["/", totalLines, " lines"] }), remainingLines > 0 && (_jsx(Text, { color: "yellow", children: " \u25BC streaming..." }))] })] }), fullPath !== filename && (_jsxs(Text, { color: "gray", dimColor: true, children: [" \uD83D\uDCC1 ", fullPath] })), _jsx(Text, { color: actionColor, children: '─'.repeat(80) }), linesAbove > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" \u22EE ", linesAbove, " lines above"] })), _jsx(Box, { flexDirection: "column", children: linesToShow.map((line, i) => {
218
+ const lineNum = startLine + i + 1;
200
219
  const lineColor = getCodeColor(line, ext);
201
- // Zebra striping for better readability (subtle)
202
- const isEvenLine = i % 2 === 0;
203
- 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));
204
- }) }), remainingLines > 0 && (_jsxs(Text, { color: "yellow", children: ['│', " ... ", remainingLines, " more lines loading... ", '│'] })), _jsx(Text, { color: actionColor, children: '└' + '─'.repeat(78) + '┘' })] }));
220
+ return (_jsxs(Text, { children: [_jsx(Text, { color: "gray", dimColor: true, children: String(lineNum).padStart(4, ' ') }), _jsx(Text, { color: "gray", dimColor: true, children: " \u2502 " }), _jsx(Text, { color: lineColor, children: line.slice(0, 72) }), line.length > 72 && _jsx(Text, { color: "gray", children: "\u2026" })] }, i));
221
+ }) }), remainingLines > 0 && (_jsxs(Text, { color: "yellow", children: [" \u22EE ", remainingLines, " more lines..."] })), _jsx(Text, { color: actionColor, children: '─'.repeat(80) })] }));
205
222
  };
206
223
  // Helper functions for action display
207
224
  const getActionColor = (type) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.54",
3
+ "version": "1.0.56",
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",