@iaforged/context-code 1.0.82 → 1.0.83
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/src/commands.js
CHANGED
|
@@ -132,7 +132,6 @@ import { resetLimits, resetLimitsNonInteractive, } from './commands/reset-limits
|
|
|
132
132
|
import antTrace from './commands/ant-trace/index.js';
|
|
133
133
|
import perfIssue from './commands/perf-issue/index.js';
|
|
134
134
|
import sandboxToggle from './commands/sandbox-toggle/index.js';
|
|
135
|
-
import chrome from './commands/chrome/index.js';
|
|
136
135
|
import stickers from './commands/stickers/index.js';
|
|
137
136
|
import advisor from './commands/advisor.js';
|
|
138
137
|
import { logError } from './utils/log.js';
|
|
@@ -212,7 +211,6 @@ const COMMANDS = memoize(() => [
|
|
|
212
211
|
agents,
|
|
213
212
|
branch,
|
|
214
213
|
btw,
|
|
215
|
-
chrome,
|
|
216
214
|
clear,
|
|
217
215
|
color,
|
|
218
216
|
compact,
|
|
@@ -987,11 +987,16 @@ function PromptInput({ debug, ideSelection, toolPermissionContext, setToolPermis
|
|
|
987
987
|
// the entire terminal.
|
|
988
988
|
// The actual required height is dependent on the content, this
|
|
989
989
|
// is just an estimate.
|
|
990
|
-
const maxLines = Math.min(rows - 10, 2);
|
|
990
|
+
const maxLines = Math.min((process.stdout.rows || 24) - 10, 2);
|
|
991
991
|
// Use special handling for long pasted text (>PASTE_THRESHOLD chars)
|
|
992
992
|
// or if it exceeds the number of lines we want to show
|
|
993
993
|
if (text.length > PASTE_THRESHOLD || numLines > maxLines) {
|
|
994
|
-
const
|
|
994
|
+
const existingIds = Object.keys(pastedContents).map(Number);
|
|
995
|
+
let pasteId = nextPasteIdRef.current;
|
|
996
|
+
if (existingIds.length > 0) {
|
|
997
|
+
pasteId = Math.max(pasteId, Math.max(...existingIds) + 1);
|
|
998
|
+
}
|
|
999
|
+
nextPasteIdRef.current = pasteId + 1;
|
|
995
1000
|
const newContent = {
|
|
996
1001
|
id: pasteId,
|
|
997
1002
|
type: 'text',
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { useEffect
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
import { maybeTruncateInput } from './inputPaste.js';
|
|
3
3
|
export function useMaybeTruncateInput({ input, pastedContents, onInputChange, setCursorOffset, setPastedContents, }) {
|
|
4
|
-
// Track if we've initialized this specific input value
|
|
5
|
-
const [hasAppliedTruncationToInput, setHasAppliedTruncationToInput] = useState(false);
|
|
6
4
|
// Process input for truncation and pasted images from MessageSelector.
|
|
7
5
|
useEffect(() => {
|
|
8
|
-
if (hasAppliedTruncationToInput) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
6
|
if (input.length <= 10_000) {
|
|
12
7
|
return;
|
|
13
8
|
}
|
|
@@ -15,19 +10,11 @@ export function useMaybeTruncateInput({ input, pastedContents, onInputChange, se
|
|
|
15
10
|
onInputChange(newInput);
|
|
16
11
|
setCursorOffset(newInput.length);
|
|
17
12
|
setPastedContents(newPastedContents);
|
|
18
|
-
setHasAppliedTruncationToInput(true);
|
|
19
13
|
}, [
|
|
20
14
|
input,
|
|
21
|
-
hasAppliedTruncationToInput,
|
|
22
15
|
pastedContents,
|
|
23
16
|
onInputChange,
|
|
24
17
|
setPastedContents,
|
|
25
18
|
setCursorOffset,
|
|
26
19
|
]);
|
|
27
|
-
// Reset hasInitializedInput when input is cleared (e.g., after submission)
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
if (input === '') {
|
|
30
|
-
setHasAppliedTruncationToInput(false);
|
|
31
|
-
}
|
|
32
|
-
}, [input]);
|
|
33
20
|
}
|
|
@@ -2,7 +2,7 @@ import { basename } from 'path';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { logError } from '../utils/log.js';
|
|
4
4
|
import { useDebounceCallback } from 'usehooks-ts';
|
|
5
|
-
import { getImageFromClipboard, isImageFilePath,
|
|
5
|
+
import { getImageFromClipboard, isImageFilePath, tryReadImageFromPath, } from '../utils/imagePaste.js';
|
|
6
6
|
import { getPlatform } from '../utils/platform.js';
|
|
7
7
|
const CLIPBOARD_CHECK_DEBOUNCE_MS = 50;
|
|
8
8
|
const PASTE_COMPLETION_TIMEOUT_MS = 100;
|
|
@@ -16,10 +16,27 @@ export function usePasteHandler({ onPaste, onInput, onImagePaste, }) {
|
|
|
16
16
|
// reads stale pasteState.timeoutId (null) and takes the onInput path. If
|
|
17
17
|
// that key is Enter, it submits the old input and the paste is lost.
|
|
18
18
|
const pastePendingRef = React.useRef(false);
|
|
19
|
+
// For detecting fast non-bracketed pastes
|
|
20
|
+
const typingQueueRef = React.useRef([]);
|
|
21
|
+
const typingTimeoutRef = React.useRef(null);
|
|
22
|
+
const flushTypingQueue = React.useCallback((onInputCallback) => {
|
|
23
|
+
if (typingTimeoutRef.current) {
|
|
24
|
+
clearTimeout(typingTimeoutRef.current);
|
|
25
|
+
typingTimeoutRef.current = null;
|
|
26
|
+
}
|
|
27
|
+
const queue = typingQueueRef.current;
|
|
28
|
+
typingQueueRef.current = [];
|
|
29
|
+
for (const q of queue) {
|
|
30
|
+
onInputCallback(q.input, q.key);
|
|
31
|
+
}
|
|
32
|
+
}, []);
|
|
19
33
|
const isMacOS = React.useMemo(() => getPlatform() === 'macos', []);
|
|
20
34
|
React.useEffect(() => {
|
|
21
35
|
return () => {
|
|
22
36
|
isMountedRef.current = false;
|
|
37
|
+
if (typingTimeoutRef.current) {
|
|
38
|
+
clearTimeout(typingTimeoutRef.current);
|
|
39
|
+
}
|
|
23
40
|
};
|
|
24
41
|
}, []);
|
|
25
42
|
const checkClipboardForImageImpl = React.useCallback(() => {
|
|
@@ -156,13 +173,22 @@ export function usePasteHandler({ onPaste, onInput, onImagePaste, }) {
|
|
|
156
173
|
return;
|
|
157
174
|
}
|
|
158
175
|
// Check if we should handle as paste (from bracketed paste, large input, or continuation)
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if (shouldHandleAsPaste) {
|
|
176
|
+
const isAlreadyPaste = pastePendingRef.current ||
|
|
177
|
+
hasImageFilePath ||
|
|
178
|
+
isFromPaste ||
|
|
179
|
+
input.length > 50;
|
|
180
|
+
if (onPaste && isAlreadyPaste) {
|
|
165
181
|
pastePendingRef.current = true;
|
|
182
|
+
// If we had buffered typing that was actually part of this paste, move it!
|
|
183
|
+
if (typingQueueRef.current.length > 0) {
|
|
184
|
+
const queuedText = typingQueueRef.current.map(q => q.input).join('');
|
|
185
|
+
input = queuedText + input;
|
|
186
|
+
if (typingTimeoutRef.current) {
|
|
187
|
+
clearTimeout(typingTimeoutRef.current);
|
|
188
|
+
typingTimeoutRef.current = null;
|
|
189
|
+
}
|
|
190
|
+
typingQueueRef.current = [];
|
|
191
|
+
}
|
|
166
192
|
setPasteState(({ chunks, timeoutId }) => {
|
|
167
193
|
return {
|
|
168
194
|
chunks: [...chunks, input],
|
|
@@ -171,6 +197,41 @@ export function usePasteHandler({ onPaste, onInput, onImagePaste, }) {
|
|
|
171
197
|
});
|
|
172
198
|
return;
|
|
173
199
|
}
|
|
200
|
+
// It might be the start of a paste! (length <= 50)
|
|
201
|
+
// Check if it's pure text (not a control key)
|
|
202
|
+
const isControl = key.ctrl || key.meta || key.option || key.super || key.fn ||
|
|
203
|
+
(key.name !== undefined && key.name.length > 1 && key.name !== 'space' && key.name !== 'number');
|
|
204
|
+
if (onPaste && input.length > 0 && !isControl) {
|
|
205
|
+
typingQueueRef.current.push({ input, key });
|
|
206
|
+
// Calculate total length of queued typing
|
|
207
|
+
const totalLength = typingQueueRef.current.reduce((acc, q) => acc + q.input.length, 0);
|
|
208
|
+
if (totalLength > 50) {
|
|
209
|
+
// Oh! It accumulated to > 50 within the tiny window! It IS a paste!
|
|
210
|
+
pastePendingRef.current = true;
|
|
211
|
+
const queuedText = typingQueueRef.current.map(q => q.input).join('');
|
|
212
|
+
typingQueueRef.current = [];
|
|
213
|
+
if (typingTimeoutRef.current) {
|
|
214
|
+
clearTimeout(typingTimeoutRef.current);
|
|
215
|
+
typingTimeoutRef.current = null;
|
|
216
|
+
}
|
|
217
|
+
setPasteState(({ chunks, timeoutId }) => {
|
|
218
|
+
return {
|
|
219
|
+
chunks: [...chunks, queuedText],
|
|
220
|
+
timeoutId: resetPasteTimeout(timeoutId),
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Schedule flush if not already scheduled
|
|
226
|
+
if (!typingTimeoutRef.current) {
|
|
227
|
+
typingTimeoutRef.current = setTimeout(() => {
|
|
228
|
+
flushTypingQueue(onInput);
|
|
229
|
+
}, 10); // 10ms is completely imperceptible
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// If it's a control key or onPaste is not defined, flush any pending typing immediately
|
|
234
|
+
flushTypingQueue(onInput);
|
|
174
235
|
onInput(input, key);
|
|
175
236
|
if (input.length > 10) {
|
|
176
237
|
// Ensure that setIsPasting is turned off on any other multicharacter
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iaforged/context-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.83",
|
|
4
4
|
"description": "Context Code es un asistente de desarrollo para la terminal. Puede revisar tu proyecto, editar archivos, ejecutar comandos y apoyarte en tareas reales de programacion.",
|
|
5
5
|
"author": "Context AI",
|
|
6
6
|
"license": "MIT",
|