codeep 1.0.37 → 1.0.39

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.
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useMemo, useEffect } from 'react';
3
- import { Text, Box, useInput, useStdin } from 'ink';
2
+ import { useState, useMemo, useEffect, useRef } from 'react';
3
+ import { Text, Box, useInput } from 'ink';
4
+ import clipboardy from 'clipboardy';
4
5
  const COMMANDS = [
5
6
  { cmd: '/help', desc: 'Show help' },
6
7
  { cmd: '/status', desc: 'Show status' },
@@ -32,7 +33,10 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
32
33
  const [selectedIndex, setSelectedIndex] = useState(0);
33
34
  const [pasteInfo, setPasteInfo] = useState(null);
34
35
  const [historyIndex, setHistoryIndex] = useState(-1);
35
- const { stdin } = useStdin();
36
+ // Paste detection using timing - chars arriving < 5ms apart = paste
37
+ const inputBuffer = useRef('');
38
+ const lastInputTime = useRef(0);
39
+ const pasteTimeout = useRef(null);
36
40
  // Clear input when clearTrigger changes
37
41
  useEffect(() => {
38
42
  if (clearTrigger > 0) {
@@ -55,24 +59,22 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
55
59
  setSelectedIndex(0);
56
60
  }
57
61
  }, [suggestions.length]);
58
- // Listen for raw stdin data to detect paste (multiple chars at once)
59
- useEffect(() => {
60
- if (disabled || !stdin)
61
- return;
62
- const handleData = (data) => {
63
- const str = data.toString();
64
- // Detect paste: multiple printable characters arriving at once
65
- // Exclude control sequences (start with ESC)
66
- if (str.length > 1 && !str.startsWith('\x1b') && !str.startsWith('\x16')) {
67
- // This is likely a paste - multiple chars at once
68
- handlePastedText(str, true);
69
- }
70
- };
71
- stdin.on('data', handleData);
72
- return () => {
73
- stdin.off('data', handleData);
74
- };
75
- }, [disabled, stdin]);
62
+ // Process buffered input - called after paste timeout
63
+ const processBuffer = () => {
64
+ const buffer = inputBuffer.current;
65
+ inputBuffer.current = '';
66
+ if (!buffer)
67
+ return;
68
+ // If buffer has multiple chars (> 20), treat as paste and show indicator
69
+ if (buffer.length > 20) {
70
+ handlePastedText(buffer, true);
71
+ }
72
+ else {
73
+ // Short buffer - just add to value normally
74
+ setValue(prev => prev + buffer);
75
+ setCursorPos(prev => prev + buffer.length);
76
+ }
77
+ };
76
78
  const handlePastedText = (text, fromCtrlV = false) => {
77
79
  const trimmed = text.trim();
78
80
  if (!trimmed)
@@ -226,15 +228,45 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
226
228
  setCursorPos(newBefore.length);
227
229
  return;
228
230
  }
231
+ // Handle Ctrl+V - paste from clipboard
232
+ // Terminal sends ASCII 22 (\x16) for Ctrl+V
233
+ if (input === '\x16' || (key.ctrl && input === 'v')) {
234
+ try {
235
+ const clipboardText = clipboardy.readSync();
236
+ if (clipboardText) {
237
+ handlePastedText(clipboardText, true);
238
+ }
239
+ }
240
+ catch {
241
+ // Clipboard read failed, ignore
242
+ }
243
+ return;
244
+ }
229
245
  // Regular character input
230
246
  if (input && !key.ctrl && !key.meta) {
231
- // If we have paste info, clear it when user starts typing
247
+ // If we have paste info and user types new char, clear paste
232
248
  if (pasteInfo) {
233
249
  setPasteInfo(null);
234
250
  setValue('');
235
251
  setCursorPos(0);
236
252
  }
237
- // Normal single character input
253
+ const now = Date.now();
254
+ const timeSinceLastInput = now - lastInputTime.current;
255
+ lastInputTime.current = now;
256
+ // If chars arrive very fast (< 5ms apart), buffer them as paste
257
+ if (timeSinceLastInput < 5 || inputBuffer.current.length > 0) {
258
+ inputBuffer.current += input;
259
+ // Clear existing timeout
260
+ if (pasteTimeout.current) {
261
+ clearTimeout(pasteTimeout.current);
262
+ }
263
+ // Set timeout to process buffer
264
+ pasteTimeout.current = setTimeout(() => {
265
+ processBuffer();
266
+ }, 10);
267
+ return; // Don't add to value yet
268
+ }
269
+ // Normal single character input (slow typing)
238
270
  setValue(prev => prev.slice(0, cursorPos) + input + prev.slice(cursorPos));
239
271
  setCursorPos(prev => prev + input.length);
240
272
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
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",