codeep 1.0.38 → 1.0.40

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
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState, useMemo, useEffect, useRef } from 'react';
3
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' },
@@ -81,21 +82,22 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
81
82
  const lines = trimmed.split(/\r?\n/);
82
83
  const lineCount = lines.length;
83
84
  const charCount = trimmed.length;
84
- // For multi-line, long pastes, or explicit Ctrl+V - show indicator
85
- if (lineCount > 1 || charCount > 100 || (fromCtrlV && charCount > 20)) {
86
- const firstLine = lines[0].substring(0, 60);
87
- const preview = firstLine + (lines[0].length > 60 ? '...' : '');
85
+ // For multi-line or long pastes - show info box with preview
86
+ if (lineCount > 1 || charCount > 80 || (fromCtrlV && charCount > 30)) {
87
+ // Create preview - first line truncated
88
+ const firstLine = lines[0].substring(0, 50);
89
+ const preview = firstLine + (lines[0].length > 50 || lineCount > 1 ? '...' : '');
88
90
  setPasteInfo({
89
91
  lines: lineCount,
90
92
  chars: charCount,
91
93
  preview,
92
94
  fullText: trimmed,
93
95
  });
94
- // Show only indicator in input field, NOT the actual pasted text
95
- const indicator = `📋 Paste: ${charCount} chars`;
96
- // Replace entire value with just the indicator (don't append pasted text)
97
- setValue(indicator);
98
- setCursorPos(indicator.length);
96
+ // Show truncated text in input (not ugly indicator)
97
+ const displayText = trimmed.replace(/\r?\n/g, ' ').substring(0, 60);
98
+ const inputText = displayText + (trimmed.length > 60 ? '...' : '');
99
+ setValue(inputText);
100
+ setCursorPos(inputText.length);
99
101
  }
100
102
  else {
101
103
  // Short paste - insert directly
@@ -111,11 +113,8 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
111
113
  // Handle Enter - submit
112
114
  if (key.return) {
113
115
  if (value.trim()) {
114
- let submitValue = value.trim();
115
- // Replace paste indicator with actual content
116
- if (pasteInfo && submitValue.includes('📋 Paste:')) {
117
- submitValue = submitValue.replace(/📋 Paste: \d+ chars/, pasteInfo.fullText);
118
- }
116
+ // If we have paste info, submit the full pasted text
117
+ const submitValue = pasteInfo ? pasteInfo.fullText : value.trim();
119
118
  onSubmit(submitValue);
120
119
  setValue('');
121
120
  setCursorPos(0);
@@ -127,8 +126,9 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
127
126
  // Handle Escape - clear paste info or input
128
127
  if (key.escape) {
129
128
  if (pasteInfo) {
130
- // Remove paste indicator from value
131
- setValue(prev => prev.replace(/📋 Paste: \d+ chars/, ''));
129
+ // Clear pasted content
130
+ setValue('');
131
+ setCursorPos(0);
132
132
  setPasteInfo(null);
133
133
  }
134
134
  else if (value) {
@@ -140,12 +140,15 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
140
140
  // Handle Backspace
141
141
  if (key.backspace || key.delete) {
142
142
  if (cursorPos > 0) {
143
- setValue(prev => prev.slice(0, cursorPos - 1) + prev.slice(cursorPos));
144
- setCursorPos(prev => prev - 1);
145
- // Clear paste info if we deleted the indicator
146
- if (pasteInfo && !value.includes('📋 Paste:')) {
143
+ // If paste info exists, clear everything on backspace
144
+ if (pasteInfo) {
145
+ setValue('');
146
+ setCursorPos(0);
147
147
  setPasteInfo(null);
148
+ return;
148
149
  }
150
+ setValue(prev => prev.slice(0, cursorPos - 1) + prev.slice(cursorPos));
151
+ setCursorPos(prev => prev - 1);
149
152
  }
150
153
  return;
151
154
  }
@@ -227,6 +230,20 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
227
230
  setCursorPos(newBefore.length);
228
231
  return;
229
232
  }
233
+ // Handle Ctrl+V - paste from clipboard
234
+ // Terminal sends ASCII 22 (\x16) for Ctrl+V
235
+ if (input === '\x16' || (key.ctrl && input === 'v')) {
236
+ try {
237
+ const clipboardText = clipboardy.readSync();
238
+ if (clipboardText) {
239
+ handlePastedText(clipboardText, true);
240
+ }
241
+ }
242
+ catch {
243
+ // Clipboard read failed, ignore
244
+ }
245
+ return;
246
+ }
230
247
  // Regular character input
231
248
  if (input && !key.ctrl && !key.meta) {
232
249
  // If we have paste info and user types new char, clear paste
@@ -266,5 +283,5 @@ export const ChatInput = ({ onSubmit, disabled, history = [], clearTrigger = 0 }
266
283
  const after = value.slice(cursorPos + 1);
267
284
  return (_jsxs(Text, { children: [before, _jsx(Text, { backgroundColor: "white", color: "black", children: cursor }), after] }));
268
285
  };
269
- return (_jsxs(Box, { flexDirection: "column", children: [suggestions.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [suggestions.slice(0, 8).map((s, i) => (_jsxs(Text, { children: [i === selectedIndex ? _jsx(Text, { color: "#f02a30", children: "\u25B8 " }) : ' ', _jsx(Text, { color: i === selectedIndex ? '#f02a30' : undefined, bold: i === selectedIndex, children: s.cmd }), _jsxs(Text, { color: i === selectedIndex ? undefined : 'gray', children: [" - ", s.desc] })] }, s.cmd))), _jsx(Text, { color: "gray", dimColor: true, children: "\u2191\u2193 navigate \u2022 Tab complete \u2022 Esc cancel" })] })), pasteInfo && (_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCCB Pasted Content" }), _jsxs(Text, { children: [_jsx(Text, { color: "white", bold: true, children: pasteInfo.lines }), _jsxs(Text, { color: "gray", children: [" ", pasteInfo.lines === 1 ? 'line' : 'lines', " \u2022 "] }), _jsx(Text, { color: "white", bold: true, children: pasteInfo.chars }), _jsx(Text, { color: "gray", children: " characters" })] }), _jsx(Text, { color: "gray", dimColor: true, wrap: "truncate", children: pasteInfo.preview }), _jsx(Text, { color: "gray", dimColor: true, children: "Press Enter to send \u2022 Esc to remove" })] })), _jsxs(Box, { children: [_jsx(Text, { color: "#f02a30", bold: true, children: '> ' }), disabled ? (_jsx(Text, { color: "yellow", children: "Agent working... (Esc to stop)" })) : (renderInput())] })] }));
286
+ return (_jsxs(Box, { flexDirection: "column", children: [suggestions.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [suggestions.slice(0, 8).map((s, i) => (_jsxs(Text, { children: [i === selectedIndex ? _jsx(Text, { color: "#f02a30", children: "\u25B8 " }) : ' ', _jsx(Text, { color: i === selectedIndex ? '#f02a30' : undefined, bold: i === selectedIndex, children: s.cmd }), _jsxs(Text, { color: i === selectedIndex ? undefined : 'gray', children: [" - ", s.desc] })] }, s.cmd))), _jsx(Text, { color: "gray", dimColor: true, children: "\u2191\u2193 navigate \u2022 Tab complete \u2022 Esc cancel" })] })), pasteInfo && (_jsx(Box, { borderStyle: "round", borderColor: "green", paddingX: 1, marginBottom: 1, flexDirection: "column", children: _jsxs(Text, { children: [_jsx(Text, { color: "green", bold: true, children: "\uD83D\uDCCB " }), _jsx(Text, { color: "white", bold: true, children: pasteInfo.chars }), _jsx(Text, { color: "gray", children: " chars" }), pasteInfo.lines > 1 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " \u2022 " }), _jsx(Text, { color: "white", bold: true, children: pasteInfo.lines }), _jsx(Text, { color: "gray", children: " lines" })] })), _jsx(Text, { color: "gray", dimColor: true, children: " (Enter send \u2022 Esc cancel)" })] }) })), _jsxs(Box, { children: [_jsx(Text, { color: "#f02a30", bold: true, children: '> ' }), disabled ? (_jsx(Text, { color: "yellow", children: "Agent working... (Esc to stop)" })) : (renderInput())] })] }));
270
287
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
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",