codeep 1.0.57 → 1.0.59

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.
@@ -140,49 +140,57 @@ const isSectionBreak = (line, prevLine) => {
140
140
  return false;
141
141
  };
142
142
  export const LiveCodeStream = ({ actions, isRunning }) => {
143
- // Use ref for tracking to avoid re-render loops
143
+ // Use refs for mutable state to minimize re-renders
144
144
  const lastActionIdRef = useRef(null);
145
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
+ const visibleEndLineRef = useRef(0);
147
+ // Single state for forcing re-render - increment only when needed
148
+ const [, forceRender] = useState(0);
151
149
  // Find the current write/edit action with code content
152
150
  const currentAction = actions.length > 0 ? actions[actions.length - 1] : null;
151
+ // Only show for write/edit actions
152
+ const isWriteOrEdit = currentAction && (currentAction.type === 'write' || currentAction.type === 'edit');
153
153
  // Create a unique ID for the current action
154
154
  const actionId = currentAction ? `${currentAction.target}-${currentAction.timestamp}` : null;
155
155
  // Get total lines for current action
156
156
  const totalLines = currentAction?.details ? currentAction.details.split('\n').length : 0;
157
- // Stream lines progressively using interval instead of recursive setTimeout
157
+ // Stream lines progressively - minimize state updates
158
158
  useEffect(() => {
159
159
  // Clear any existing timer
160
160
  if (timerRef.current) {
161
161
  clearInterval(timerRef.current);
162
162
  timerRef.current = null;
163
163
  }
164
- if (!currentAction || !currentAction.details || !isRunning) {
165
- if (displayState.endLine !== 0 || displayState.actionId !== null) {
166
- setDisplayState({ endLine: 0, actionId: null });
164
+ // Only stream for write/edit actions with content
165
+ if (!currentAction || !currentAction.details || !isRunning || !isWriteOrEdit) {
166
+ if (visibleEndLineRef.current !== 0) {
167
+ visibleEndLineRef.current = 0;
168
+ lastActionIdRef.current = null;
167
169
  }
168
170
  return;
169
171
  }
170
172
  // If this is a new action, reset and start streaming
171
173
  if (actionId !== lastActionIdRef.current) {
172
174
  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);
175
+ const lines = currentAction.details.split('\n').length;
176
+ visibleEndLineRef.current = Math.min(10, lines);
177
+ forceRender(n => n + 1);
178
+ // Only start interval if there are more lines to show
179
+ if (lines > 10) {
180
+ timerRef.current = setInterval(() => {
181
+ const currentLines = currentAction.details?.split('\n').length || 0;
182
+ const newEndLine = Math.min(visibleEndLineRef.current + 10, currentLines);
183
+ if (newEndLine !== visibleEndLineRef.current) {
184
+ visibleEndLineRef.current = newEndLine;
185
+ forceRender(n => n + 1);
186
+ }
178
187
  // Stop interval when we've shown all lines
179
- if (newEndLine >= totalLines && timerRef.current) {
188
+ if (newEndLine >= currentLines && timerRef.current) {
180
189
  clearInterval(timerRef.current);
181
190
  timerRef.current = null;
182
191
  }
183
- return { ...prev, endLine: newEndLine };
184
- });
185
- }, 150); // Slightly slower for smoother experience
192
+ }, 200); // Slower interval to reduce flickering
193
+ }
186
194
  }
187
195
  return () => {
188
196
  if (timerRef.current) {
@@ -190,7 +198,7 @@ export const LiveCodeStream = ({ actions, isRunning }) => {
190
198
  timerRef.current = null;
191
199
  }
192
200
  };
193
- }, [actionId, isRunning, totalLines]);
201
+ }, [actionId, isRunning, isWriteOrEdit, currentAction]);
194
202
  // Only show for write/edit actions with content while running
195
203
  if (!isRunning || !currentAction)
196
204
  return null;
@@ -206,19 +214,20 @@ export const LiveCodeStream = ({ actions, isRunning }) => {
206
214
  const allLines = code.split('\n');
207
215
  const actionLabel = currentAction.type === 'write' ? '✨ Creating' : '✏️ Editing';
208
216
  const actionColor = currentAction.type === 'write' ? 'green' : 'yellow';
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
217
+ // Use ref value for rendering
218
+ const visibleEndLine = visibleEndLineRef.current || Math.min(10, totalLines);
219
+ // Sliding window: show only last 10 lines
212
220
  const WINDOW_SIZE = 10;
213
221
  const startLine = Math.max(0, visibleEndLine - WINDOW_SIZE);
214
222
  const linesToShow = allLines.slice(startLine, visibleEndLine);
215
223
  const remainingLines = totalLines - visibleEndLine;
216
224
  const linesAbove = startLine;
217
- return (_jsxs(Box, { flexDirection: "column", 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;
219
- const lineColor = getCodeColor(line, ext);
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) })] }));
225
+ // Pad lines to fixed height to prevent layout shifts
226
+ const paddedLines = [...linesToShow];
227
+ while (paddedLines.length < WINDOW_SIZE) {
228
+ paddedLines.push('');
229
+ }
230
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { 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: visibleEndLine }), _jsxs(Text, { color: "gray", children: ["/", totalLines] }), remainingLines > 0 && _jsx(Text, { color: "yellow", children: " \u25BC" })] }), _jsx(Text, { color: actionColor, children: '─'.repeat(76) }), _jsx(Text, { color: "gray", dimColor: true, children: linesAbove > 0 ? ` ⋮ ${linesAbove} lines above` : ' ' }), paddedLines.map((line, i) => (_jsxs(Text, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: [line ? String(startLine + i + 1).padStart(4, ' ') : ' ', " \u2502", ' '] }), _jsx(Text, { color: line ? getCodeColor(line, ext) : 'gray', children: line.slice(0, 68) }), line.length > 68 && _jsx(Text, { color: "gray", children: "\u2026" })] }, `line-${startLine + i}`))), _jsx(Text, { color: "yellow", children: remainingLines > 0 ? ` ⋮ ${remainingLines} more lines...` : ' ' }), _jsx(Text, { color: actionColor, children: '─'.repeat(76) })] }));
222
231
  };
223
232
  // Helper functions for action display
224
233
  const getActionColor = (type) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.57",
3
+ "version": "1.0.59",
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",