ideacode 1.3.3 → 1.3.4
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 +32 -29
- package/dist/ui/theme.js +3 -2
- package/package.json +1 -1
package/dist/repl.js
CHANGED
|
@@ -52,6 +52,7 @@ const LOADING_TICK_MS = 80;
|
|
|
52
52
|
const MAX_EMPTY_ASSISTANT_RETRIES = 3;
|
|
53
53
|
const TYPING_LAYOUT_FREEZE_MS = 120;
|
|
54
54
|
const INPUT_COMMIT_INTERVAL_MS = 45;
|
|
55
|
+
const SLASH_SUGGESTION_ROWS = Math.max(1, COMMANDS.length);
|
|
55
56
|
const TRUNCATE_NOTE = "\n\n(Output truncated to save context. Use read with offset/limit, grep with a specific pattern, or tail with fewer lines to get more.)";
|
|
56
57
|
function truncateToolResult(content) {
|
|
57
58
|
if (content.length <= MAX_TOOL_RESULT_CHARS)
|
|
@@ -996,11 +997,11 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
996
997
|
}
|
|
997
998
|
if (showSlashSuggestions && filteredSlashCommands.length > 0) {
|
|
998
999
|
if (key.upArrow) {
|
|
999
|
-
setSlashSuggestionIndex((i) => Math.
|
|
1000
|
+
setSlashSuggestionIndex((i) => Math.min(filteredSlashCommands.length - 1, i + 1));
|
|
1000
1001
|
return;
|
|
1001
1002
|
}
|
|
1002
1003
|
if (key.downArrow) {
|
|
1003
|
-
setSlashSuggestionIndex((i) => Math.
|
|
1004
|
+
setSlashSuggestionIndex((i) => Math.max(0, i - 1));
|
|
1004
1005
|
return;
|
|
1005
1006
|
}
|
|
1006
1007
|
if (key.tab) {
|
|
@@ -1239,22 +1240,8 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
1239
1240
|
handleQuit();
|
|
1240
1241
|
}
|
|
1241
1242
|
});
|
|
1242
|
-
if (showModelSelector) {
|
|
1243
|
-
const modelModalMaxHeight = 18;
|
|
1244
|
-
const modelModalWidth = 108;
|
|
1245
|
-
const modelModalHeight = Math.min(filteredModelList.length + 4, modelModalMaxHeight);
|
|
1246
|
-
const topPad = Math.max(0, Math.floor((termRows - modelModalHeight) / 2));
|
|
1247
|
-
const leftPad = Math.max(0, Math.floor((termColumns - modelModalWidth) / 2));
|
|
1248
|
-
const visibleModelCount = Math.min(filteredModelList.length, modelModalHeight - 4);
|
|
1249
|
-
const modelScrollOffset = Math.max(0, Math.min(modelIndex - Math.floor(visibleModelCount / 2), filteredModelList.length - visibleModelCount));
|
|
1250
|
-
const visibleModels = filteredModelList.slice(modelScrollOffset, modelScrollOffset + visibleModelCount);
|
|
1251
|
-
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: modelModalWidth, minHeight: modelModalHeight, children: [_jsx(Text, { bold: true, children: " Select model " }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: inkColors.textSecondary, children: " Filter: " }), _jsx(Text, { children: modelSearchFilter || " " }), modelSearchFilter.length > 0 && (_jsxs(Text, { color: inkColors.textDisabled, children: [" ", "(", filteredModelList.length, " match", filteredModelList.length !== 1 ? "es" : "", ")"] }))] }), visibleModels.length === 0 ? (_jsx(Text, { color: inkColors.textSecondary, children: " No match \u2014 type to search by id or name " })) : (visibleModels.map((m, i) => {
|
|
1252
|
-
const actualIndex = modelScrollOffset + i;
|
|
1253
|
-
return (_jsxs(Text, { color: actualIndex === modelIndex ? inkColors.primary : undefined, children: [actualIndex === modelIndex ? "› " : " ", m.name ? `${m.id} — ${m.name}` : m.id] }, m.id));
|
|
1254
|
-
})), _jsx(Text, { color: inkColors.textSecondary, children: " \u2191/\u2193 select Enter confirm Esc cancel Type to filter " })] })] }), _jsx(Box, { flexGrow: 1 })] }));
|
|
1255
|
-
}
|
|
1256
1243
|
const slashSuggestionBoxLines = showSlashSuggestions
|
|
1257
|
-
? 3 +
|
|
1244
|
+
? 3 + SLASH_SUGGESTION_ROWS
|
|
1258
1245
|
: 0;
|
|
1259
1246
|
const atSuggestionBoxLines = cursorInAtSegment
|
|
1260
1247
|
? 4 + Math.max(1, filteredFilePaths.length)
|
|
@@ -1273,6 +1260,28 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
1273
1260
|
const sliceEnd = logStartIndex + logViewportHeight;
|
|
1274
1261
|
const visibleLogLines = useMemo(() => effectiveLogLines.slice(logStartIndex, sliceEnd), [effectiveLogLines, logStartIndex, sliceEnd]);
|
|
1275
1262
|
const useSimpleInputRenderer = inputLineCount > 1;
|
|
1263
|
+
const calculatedFooterLines = suggestionBoxLines + 1 + layoutInputLineCount;
|
|
1264
|
+
useEffect(() => {
|
|
1265
|
+
if (!isInputLayoutFrozen) {
|
|
1266
|
+
setFrozenFooterLines(calculatedFooterLines);
|
|
1267
|
+
}
|
|
1268
|
+
}, [isInputLayoutFrozen, calculatedFooterLines]);
|
|
1269
|
+
const footerLines = isInputLayoutFrozen ? frozenFooterLines : calculatedFooterLines;
|
|
1270
|
+
loadingFooterLinesRef.current = footerLines;
|
|
1271
|
+
if (showModelSelector) {
|
|
1272
|
+
const modelModalMaxHeight = 18;
|
|
1273
|
+
const modelModalWidth = 108;
|
|
1274
|
+
const modelModalHeight = Math.min(filteredModelList.length + 4, modelModalMaxHeight);
|
|
1275
|
+
const topPad = Math.max(0, Math.floor((termRows - modelModalHeight) / 2));
|
|
1276
|
+
const leftPad = Math.max(0, Math.floor((termColumns - modelModalWidth) / 2));
|
|
1277
|
+
const visibleModelCount = Math.min(filteredModelList.length, modelModalHeight - 4);
|
|
1278
|
+
const modelScrollOffset = Math.max(0, Math.min(modelIndex - Math.floor(visibleModelCount / 2), filteredModelList.length - visibleModelCount));
|
|
1279
|
+
const visibleModels = filteredModelList.slice(modelScrollOffset, modelScrollOffset + visibleModelCount);
|
|
1280
|
+
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: modelModalWidth, minHeight: modelModalHeight, children: [_jsx(Text, { bold: true, children: " Select model " }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: inkColors.textSecondary, children: " Filter: " }), _jsx(Text, { children: modelSearchFilter || " " }), modelSearchFilter.length > 0 && (_jsxs(Text, { color: inkColors.textDisabled, children: [" ", "(", filteredModelList.length, " match", filteredModelList.length !== 1 ? "es" : "", ")"] }))] }), visibleModels.length === 0 ? (_jsx(Text, { color: inkColors.textSecondary, children: " No match \u2014 type to search by id or name " })) : (visibleModels.map((m, i) => {
|
|
1281
|
+
const actualIndex = modelScrollOffset + i;
|
|
1282
|
+
return (_jsxs(Text, { color: actualIndex === modelIndex ? inkColors.primary : undefined, children: [actualIndex === modelIndex ? "› " : " ", m.name ? `${m.id} — ${m.name}` : m.id] }, m.id));
|
|
1283
|
+
})), _jsx(Text, { color: inkColors.textSecondary, children: " \u2191/\u2193 select Enter confirm Esc cancel Type to filter " })] })] }), _jsx(Box, { flexGrow: 1 })] }));
|
|
1284
|
+
}
|
|
1276
1285
|
if (showHelpModal) {
|
|
1277
1286
|
const helpModalWidth = Math.min(88, Math.max(80, termColumns - 4));
|
|
1278
1287
|
const helpContentRows = 20;
|
|
@@ -1295,21 +1304,15 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
1295
1304
|
const leftPad = Math.max(0, Math.floor((termColumns - paletteModalWidth) / 2));
|
|
1296
1305
|
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 })] }));
|
|
1297
1306
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
if (!isInputLayoutFrozen) {
|
|
1301
|
-
setFrozenFooterLines(calculatedFooterLines);
|
|
1302
|
-
}
|
|
1303
|
-
}, [isInputLayoutFrozen, calculatedFooterLines]);
|
|
1304
|
-
const footerLines = isInputLayoutFrozen ? frozenFooterLines : calculatedFooterLines;
|
|
1305
|
-
loadingFooterLinesRef.current = footerLines;
|
|
1306
|
-
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) => {
|
|
1307
|
-
const i = filteredSlashCommands.length - 1 - rev;
|
|
1307
|
+
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, height: slashSuggestionBoxLines, children: [filteredSlashCommands.length === 0 ? (_jsx(Text, { color: inkColors.textSecondary, children: " No match " })) : ([...filteredSlashCommands.slice(0, SLASH_SUGGESTION_ROWS)].reverse().map((c, rev) => {
|
|
1308
|
+
const i = Math.min(filteredSlashCommands.length, SLASH_SUGGESTION_ROWS) - 1 - rev;
|
|
1308
1309
|
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));
|
|
1309
|
-
})),
|
|
1310
|
+
})), Array.from({
|
|
1311
|
+
length: Math.max(0, SLASH_SUGGESTION_ROWS - Math.min(filteredSlashCommands.length, SLASH_SUGGESTION_ROWS)),
|
|
1312
|
+
}).map((_, idx) => (_jsx(Text, { children: "\u00A0" }, `slash-pad-${idx}`))), _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) => {
|
|
1310
1313
|
const i = filteredFilePaths.length - 1 - rev;
|
|
1311
1314
|
return (_jsxs(Text, { color: i === clampedAtFileIndex ? inkColors.primary : undefined, children: [i === clampedAtFileIndex ? "› " : " ", p] }, p));
|
|
1312
|
-
})), _jsx(Box, { flexDirection: "row", marginTop: 1, children: _jsx(Text, { color: inkColors.textSecondary, children: " Files (\u2191/\u2193 select, Enter/Tab complete, Esc clear) " }) })] })), _jsxs(Box, { flexDirection: "row", marginTop: 0, children: [_jsxs(Text, { color: inkColors.
|
|
1315
|
+
})), _jsx(Box, { flexDirection: "row", marginTop: 1, children: _jsx(Text, { color: inkColors.textSecondary, children: " Files (\u2191/\u2193 select, Enter/Tab complete, Esc clear) " }) })] })), _jsxs(Box, { flexDirection: "row", marginTop: 0, children: [_jsxs(Text, { color: inkColors.footerHint, children: [" ", icons.tool, " ", tokenDisplay] }), _jsx(Text, { color: inkColors.footerHint, children: ` · / ! @ trackpad/↑/↓ scroll Ctrl+J newline Tab queue Esc Esc edit` })] }), _jsx(Box, { flexDirection: "column", marginTop: 0, children: inputValue.length === 0 ? (_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: inkColors.primary, children: [icons.prompt, " "] }), cursorBlinkOn ? (_jsx(Text, { inverse: true, color: inkColors.primary, children: " " })) : (_jsx(Text, { color: inkColors.primary, children: " " })), _jsx(Text, { color: inkColors.textSecondary, children: "Message or / for commands, @ for files, ! for shell, ? for help..." })] })) : ((() => {
|
|
1313
1316
|
const lines = inputValue.split("\n");
|
|
1314
1317
|
let lineStart = 0;
|
|
1315
1318
|
return (_jsx(_Fragment, { children: lines.flatMap((lineText, lineIdx) => {
|
package/dist/ui/theme.js
CHANGED
|
@@ -22,7 +22,7 @@ const THEME_DARK = {
|
|
|
22
22
|
error: { main: "#f87171", dim: "#dc2626" },
|
|
23
23
|
muted: { main: "#8a9a7a", dim: "#6a7a5a", dark: "#4a5a3a" },
|
|
24
24
|
background: { dark: "#1a1a1a", darker: "#0f0f0f" },
|
|
25
|
-
text: { primary: "#e2e8f0", secondary: "#98a08f", disabled: "#6f7867" },
|
|
25
|
+
text: { primary: "#e2e8f0", secondary: "#98a08f", disabled: "#6f7867", footerHint: "#635e4b" },
|
|
26
26
|
},
|
|
27
27
|
ui: {
|
|
28
28
|
borderColor: "#7F9A65",
|
|
@@ -51,7 +51,7 @@ const THEME_LIGHT = {
|
|
|
51
51
|
error: { main: "#dc2626", dim: "#b91c1c" },
|
|
52
52
|
muted: { main: "#6b7a5a", dim: "#5a6a4a", dark: "#4a5a3a" },
|
|
53
53
|
background: { dark: "#f1f5f9", darker: "#e2e8f0" },
|
|
54
|
-
text: { primary: "#1e293b", secondary: "#5f6758", disabled: "#778070" },
|
|
54
|
+
text: { primary: "#1e293b", secondary: "#5f6758", disabled: "#778070", footerHint: "#635e4b" },
|
|
55
55
|
},
|
|
56
56
|
ui: {
|
|
57
57
|
borderColor: "#5a7247",
|
|
@@ -125,5 +125,6 @@ export const inkColors = {
|
|
|
125
125
|
textPrimary: theme.colors.text.primary,
|
|
126
126
|
textSecondary: theme.colors.text.secondary,
|
|
127
127
|
textDisabled: theme.colors.text.disabled,
|
|
128
|
+
footerHint: theme.colors.text.footerHint,
|
|
128
129
|
};
|
|
129
130
|
export const icons = theme.icons;
|