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.
- package/dist/components/Input.js +39 -22
- package/package.json +1 -1
package/dist/components/Input.js
CHANGED
|
@@ -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
|
|
85
|
-
if (lineCount > 1 || charCount >
|
|
86
|
-
|
|
87
|
-
const
|
|
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
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
setValue(
|
|
98
|
-
setCursorPos(
|
|
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
|
-
|
|
115
|
-
|
|
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
|
-
//
|
|
131
|
-
setValue(
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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 && (
|
|
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.
|
|
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",
|