ideacode 1.2.4 → 1.2.5
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/repl.js +55 -25
- package/package.json +1 -1
package/dist/repl.js
CHANGED
|
@@ -281,30 +281,6 @@ function orbitDots(frame) {
|
|
|
281
281
|
.map((ch, i) => (i === activeIndex ? colors.gray(ch) : colors.mutedDark(ch)))
|
|
282
282
|
.join("");
|
|
283
283
|
}
|
|
284
|
-
const LoadingStatus = React.memo(function LoadingStatus({ active, label, }) {
|
|
285
|
-
const [frame, setFrame] = useState(0);
|
|
286
|
-
const startedAtRef = useRef(null);
|
|
287
|
-
useEffect(() => {
|
|
288
|
-
if (!active) {
|
|
289
|
-
startedAtRef.current = null;
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
if (startedAtRef.current == null) {
|
|
293
|
-
startedAtRef.current = Date.now();
|
|
294
|
-
setFrame(0);
|
|
295
|
-
}
|
|
296
|
-
const anim = setInterval(() => setFrame((n) => n + 1), LOADING_TICK_MS);
|
|
297
|
-
return () => {
|
|
298
|
-
clearInterval(anim);
|
|
299
|
-
};
|
|
300
|
-
}, [active]);
|
|
301
|
-
if (!active)
|
|
302
|
-
return _jsx(Text, { color: inkColors.textSecondary, children: "\u00A0" });
|
|
303
|
-
const startedAt = startedAtRef.current ?? Date.now();
|
|
304
|
-
const elapsedSeconds = Math.max(0, (Date.now() - startedAt) / 1000);
|
|
305
|
-
const elapsedText = elapsedSeconds < 10 ? `${elapsedSeconds.toFixed(1)}s` : `${Math.floor(elapsedSeconds)}s`;
|
|
306
|
-
return (_jsxs(Text, { color: inkColors.textSecondary, children: [" ", orbitDots(frame), " ", colors.gray(label), " ", colors.gray(elapsedText)] }));
|
|
307
|
-
});
|
|
308
284
|
export function Repl({ apiKey, cwd, onQuit }) {
|
|
309
285
|
const { rows: termRows, columns: termColumns } = useTerminalSize();
|
|
310
286
|
// Big ASCII art logo for ideacode
|
|
@@ -403,6 +379,10 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
403
379
|
}, [cwd, onQuit]);
|
|
404
380
|
const [loading, setLoading] = useState(false);
|
|
405
381
|
const [loadingLabel, setLoadingLabel] = useState("Thinking…");
|
|
382
|
+
const loadingActiveRef = useRef(false);
|
|
383
|
+
const loadingLabelRef = useRef(loadingLabel);
|
|
384
|
+
const loadingFooterLinesRef = useRef(2);
|
|
385
|
+
const loadingRenderRef = useRef(null);
|
|
406
386
|
const cursorBlinkOn = true;
|
|
407
387
|
const [showPalette, setShowPalette] = useState(false);
|
|
408
388
|
const [paletteIndex, setPaletteIndex] = useState(0);
|
|
@@ -428,6 +408,55 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
428
408
|
process.stdout.write("\x1b[?1006l\x1b[?1000l");
|
|
429
409
|
};
|
|
430
410
|
}, []);
|
|
411
|
+
useEffect(() => {
|
|
412
|
+
loadingActiveRef.current = loading;
|
|
413
|
+
loadingLabelRef.current = loadingLabel;
|
|
414
|
+
if (!process.stdout.isTTY)
|
|
415
|
+
return;
|
|
416
|
+
const clearLoadingLine = () => {
|
|
417
|
+
const up = Math.max(1, loadingFooterLinesRef.current);
|
|
418
|
+
try {
|
|
419
|
+
writeSync(process.stdout.fd, `\x1b7\x1b[${up}A\r\x1b[2K\x1b8`);
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
// Best effort only.
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
if (!loading) {
|
|
426
|
+
if (loadingRenderRef.current) {
|
|
427
|
+
clearInterval(loadingRenderRef.current);
|
|
428
|
+
loadingRenderRef.current = null;
|
|
429
|
+
}
|
|
430
|
+
clearLoadingLine();
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const startedAt = Date.now();
|
|
434
|
+
let frame = 0;
|
|
435
|
+
const renderTick = () => {
|
|
436
|
+
if (!loadingActiveRef.current || !process.stdout.isTTY)
|
|
437
|
+
return;
|
|
438
|
+
const elapsedSeconds = Math.max(0, (Date.now() - startedAt) / 1000);
|
|
439
|
+
const elapsedText = elapsedSeconds < 10 ? `${elapsedSeconds.toFixed(1)}s` : `${Math.floor(elapsedSeconds)}s`;
|
|
440
|
+
const line = ` ${orbitDots(frame)} ${colors.gray(loadingLabelRef.current)} ${colors.gray(elapsedText)}`;
|
|
441
|
+
const up = Math.max(1, loadingFooterLinesRef.current);
|
|
442
|
+
try {
|
|
443
|
+
writeSync(process.stdout.fd, `\x1b7\x1b[${up}A\r\x1b[2K${line}\x1b8`);
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
// Best effort only.
|
|
447
|
+
}
|
|
448
|
+
frame = (frame + 1) % 6;
|
|
449
|
+
};
|
|
450
|
+
renderTick();
|
|
451
|
+
loadingRenderRef.current = setInterval(renderTick, LOADING_TICK_MS);
|
|
452
|
+
return () => {
|
|
453
|
+
if (loadingRenderRef.current) {
|
|
454
|
+
clearInterval(loadingRenderRef.current);
|
|
455
|
+
loadingRenderRef.current = null;
|
|
456
|
+
}
|
|
457
|
+
clearLoadingLine();
|
|
458
|
+
};
|
|
459
|
+
}, [loading, loadingLabel]);
|
|
431
460
|
const estimatedTokens = useMemo(() => estimateTokens(messages, undefined), [messages]);
|
|
432
461
|
const contextWindowK = useMemo(() => {
|
|
433
462
|
const ctx = modelList.find((m) => m.id === currentModel)?.context_length;
|
|
@@ -1173,7 +1202,8 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
1173
1202
|
return (_jsxs(Box, { flexDirection: "column", height: termRows, overflow: "hidden", children: [_jsx(Box, { height: topPad }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: leftPad }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: inkColors.primary, paddingX: 2, paddingY: 1, width: paletteModalWidth, minHeight: paletteModalHeight, children: [_jsx(Text, { bold: true, children: " Command palette " }), COMMANDS.map((c, i) => (_jsxs(Text, { color: i === paletteIndex ? inkColors.primary : undefined, children: [i === paletteIndex ? "› " : " ", c.cmd, _jsxs(Text, { color: inkColors.textSecondary, children: [" \u2014 ", c.desc] })] }, c.cmd))), _jsxs(Text, { color: paletteIndex === COMMANDS.length ? inkColors.primary : undefined, children: [paletteIndex === COMMANDS.length ? "› " : " ", "Cancel (Esc)"] }), _jsx(Text, { color: inkColors.textSecondary, children: " \u2191/\u2193 select, Enter confirm, Esc close " })] })] }), _jsx(Box, { flexGrow: 1 })] }));
|
|
1174
1203
|
}
|
|
1175
1204
|
const footerLines = suggestionBoxLines + 1 + stableInputLineCount;
|
|
1176
|
-
|
|
1205
|
+
loadingFooterLinesRef.current = footerLines;
|
|
1206
|
+
return (_jsxs(Box, { flexDirection: "column", height: termRows, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, minHeight: 0, overflow: "hidden", children: [_jsx(LogViewport, { lines: visibleLogLines, startIndex: logStartIndex, height: logViewportHeight }), _jsx(Box, { flexDirection: "row", marginTop: 1, marginBottom: 0, children: _jsx(Text, { color: inkColors.textSecondary, children: "\u00A0" }) })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, height: footerLines, children: [showSlashSuggestions && (_jsxs(Box, { flexDirection: "column", marginBottom: 0, paddingLeft: 2, borderStyle: "single", borderColor: inkColors.textDisabled, children: [filteredSlashCommands.length === 0 ? (_jsx(Text, { color: inkColors.textSecondary, children: " No match " })) : ([...filteredSlashCommands].reverse().map((c, rev) => {
|
|
1177
1207
|
const i = filteredSlashCommands.length - 1 - rev;
|
|
1178
1208
|
return (_jsxs(Text, { color: i === clampedSlashIndex ? inkColors.primary : undefined, children: [i === clampedSlashIndex ? "› " : " ", c.cmd, _jsxs(Text, { color: inkColors.textSecondary, children: [" \u2014 ", c.desc] })] }, c.cmd));
|
|
1179
1209
|
})), _jsx(Text, { color: inkColors.textSecondary, children: " Commands (\u2191/\u2193 select, Enter run, Esc clear) " })] })), cursorInAtSegment && !showSlashSuggestions && (_jsxs(Box, { flexDirection: "column", marginBottom: 0, paddingLeft: 2, borderStyle: "single", borderColor: inkColors.textDisabled, children: [filteredFilePaths.length === 0 ? (_jsxs(Text, { color: inkColors.textSecondary, children: [" ", hasCharsAfterAt ? "No match" : "Type to search files", " "] })) : ([...filteredFilePaths].reverse().map((p, rev) => {
|