@iaforged/context-code 1.0.82 → 1.0.84

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.
@@ -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 pasteId = nextPasteIdRef.current++;
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, useState } from 'react';
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, PASTE_THRESHOLD, tryReadImageFromPath, } from '../utils/imagePaste.js';
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 shouldHandleAsPaste = onPaste &&
160
- (input.length > PASTE_THRESHOLD ||
161
- pastePendingRef.current ||
162
- hasImageFilePath ||
163
- isFromPaste);
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.82",
3
+ "version": "1.0.84",
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",