code-ollama 0.15.1 → 0.16.0
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.
|
@@ -734,16 +734,6 @@ function ToolApproval({ toolCall, onDecision }) {
|
|
|
734
734
|
});
|
|
735
735
|
}
|
|
736
736
|
//#endregion
|
|
737
|
-
//#region src/components/Chat/constants.ts
|
|
738
|
-
var ACTION_NOT_PERFORMED = "The requested action was NOT performed";
|
|
739
|
-
var PLAN_CHECKLIST_REMINDER = "Then display the execution plan as an unchecked Markdown checklist only";
|
|
740
|
-
var PLAN_EXECUTION_REMINDER = `Do not claim success and do not call ${Array.from(WRITE_TOOLS).join(", ")} until the user approves execution`;
|
|
741
|
-
var INTERRUPT_REASON = /* @__PURE__ */ function(INTERRUPT_REASON) {
|
|
742
|
-
INTERRUPT_REASON["INTERRUPTED"] = "interrupted";
|
|
743
|
-
INTERRUPT_REASON["REJECTED"] = "rejected";
|
|
744
|
-
return INTERRUPT_REASON;
|
|
745
|
-
}({});
|
|
746
|
-
//#endregion
|
|
747
737
|
//#region src/components/TextInput/TextInput.tsx
|
|
748
738
|
function buildLineSegments(displayValue, cursorPosition, width) {
|
|
749
739
|
const safeWidth = Math.max(1, width);
|
|
@@ -1043,17 +1033,28 @@ function FileSuggestions({ input, isDisabled = false, onChange, onSelect }) {
|
|
|
1043
1033
|
});
|
|
1044
1034
|
}
|
|
1045
1035
|
//#endregion
|
|
1046
|
-
//#region src/components/Chat/
|
|
1036
|
+
//#region src/components/Chat/ChatInput.tsx
|
|
1047
1037
|
function hasFileSuggestionQuery(input) {
|
|
1048
1038
|
return /(^|.)@\S+/.test(input);
|
|
1049
1039
|
}
|
|
1050
|
-
function
|
|
1040
|
+
function ChatInput({ history: sessionHistory, isDisabled = false, onInterrupt, onSubmit }) {
|
|
1051
1041
|
const { exit } = useApp();
|
|
1042
|
+
const [history, setHistory] = useState(sessionHistory);
|
|
1043
|
+
const [historyIndex, setHistoryIndex] = useState(null);
|
|
1052
1044
|
const [input, setInput] = useState("");
|
|
1053
1045
|
const [cursorPosition, setCursorPosition] = useState(void 0);
|
|
1054
1046
|
const fileSuggestionRef = useRef(null);
|
|
1047
|
+
useEffect(() => {
|
|
1048
|
+
setHistory(sessionHistory);
|
|
1049
|
+
setHistoryIndex(null);
|
|
1050
|
+
setInput("");
|
|
1051
|
+
setCursorPosition(void 0);
|
|
1052
|
+
fileSuggestionRef.current = null;
|
|
1053
|
+
}, [sessionHistory]);
|
|
1055
1054
|
const resetInput = useCallback(() => {
|
|
1056
1055
|
setInput("");
|
|
1056
|
+
setCursorPosition(void 0);
|
|
1057
|
+
setHistoryIndex(null);
|
|
1057
1058
|
}, []);
|
|
1058
1059
|
const handleSelectFileSuggestion = useCallback((nextInput) => {
|
|
1059
1060
|
setInput(nextInput.value);
|
|
@@ -1077,15 +1078,58 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
1077
1078
|
};
|
|
1078
1079
|
} else fileSuggestionRef.current = null;
|
|
1079
1080
|
}, [input]);
|
|
1081
|
+
const handleInputChange = useCallback((nextInput) => {
|
|
1082
|
+
setInput(nextInput);
|
|
1083
|
+
setHistoryIndex(null);
|
|
1084
|
+
}, []);
|
|
1080
1085
|
const submitAndReset = useCallback((input) => {
|
|
1081
1086
|
const trimmedInput = input.trim();
|
|
1082
1087
|
if (!trimmedInput) return;
|
|
1083
1088
|
onSubmit(trimmedInput);
|
|
1089
|
+
if (!trimmedInput.startsWith("/")) setHistory((previousHistory) => [...previousHistory, trimmedInput]);
|
|
1084
1090
|
resetInput();
|
|
1085
1091
|
fileSuggestionRef.current = null;
|
|
1086
1092
|
}, [onSubmit, resetInput]);
|
|
1087
1093
|
const showCommandMenu = input.startsWith("/");
|
|
1088
1094
|
const showFileSuggestions = !showCommandMenu && hasFileSuggestionQuery(input);
|
|
1095
|
+
const handleHistoryNavigation = useCallback((direction) => {
|
|
1096
|
+
if (!history.length || showFileSuggestions) return;
|
|
1097
|
+
if (direction === "up") {
|
|
1098
|
+
if (historyIndex === null) {
|
|
1099
|
+
if (input) return;
|
|
1100
|
+
const nextIndex = history.length - 1;
|
|
1101
|
+
const nextInput = history[nextIndex];
|
|
1102
|
+
setHistoryIndex(nextIndex);
|
|
1103
|
+
setInput(nextInput);
|
|
1104
|
+
setCursorPosition(nextInput.length);
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
if (historyIndex === 0) return;
|
|
1108
|
+
const nextIndex = historyIndex - 1;
|
|
1109
|
+
const nextInput = history[nextIndex];
|
|
1110
|
+
setHistoryIndex(nextIndex);
|
|
1111
|
+
setInput(nextInput);
|
|
1112
|
+
setCursorPosition(nextInput.length);
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
if (historyIndex === null) return;
|
|
1116
|
+
if (historyIndex === history.length - 1) {
|
|
1117
|
+
setHistoryIndex(null);
|
|
1118
|
+
setInput("");
|
|
1119
|
+
setCursorPosition(0);
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
const nextIndex = historyIndex + 1;
|
|
1123
|
+
const nextInput = history[nextIndex];
|
|
1124
|
+
setHistoryIndex(nextIndex);
|
|
1125
|
+
setInput(nextInput);
|
|
1126
|
+
setCursorPosition(nextInput.length);
|
|
1127
|
+
}, [
|
|
1128
|
+
history,
|
|
1129
|
+
historyIndex,
|
|
1130
|
+
input,
|
|
1131
|
+
showFileSuggestions
|
|
1132
|
+
]);
|
|
1089
1133
|
const handleSubmitText = useCallback((input) => {
|
|
1090
1134
|
if (input.startsWith("/")) return;
|
|
1091
1135
|
if (hasFileSuggestionQuery(input)) {
|
|
@@ -1097,8 +1141,8 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
1097
1141
|
const handleSubmitCommand = useCallback((input) => {
|
|
1098
1142
|
if (LIST.find(({ name }) => name === input)) submitAndReset(input);
|
|
1099
1143
|
}, [submitAndReset]);
|
|
1100
|
-
useInput((
|
|
1101
|
-
const isCtrlC = key.ctrl &&
|
|
1144
|
+
useInput((inputKey, key) => {
|
|
1145
|
+
const isCtrlC = key.ctrl && inputKey === "c";
|
|
1102
1146
|
if (isDisabled) {
|
|
1103
1147
|
if (key.escape || isCtrlC) onInterrupt?.();
|
|
1104
1148
|
return;
|
|
@@ -1110,6 +1154,11 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
1110
1154
|
}
|
|
1111
1155
|
exit();
|
|
1112
1156
|
}
|
|
1157
|
+
if (key.upArrow) {
|
|
1158
|
+
handleHistoryNavigation("up");
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
if (key.downArrow) handleHistoryNavigation("down");
|
|
1113
1162
|
});
|
|
1114
1163
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1115
1164
|
flexDirection: "column",
|
|
@@ -1119,7 +1168,7 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
1119
1168
|
isDisabled,
|
|
1120
1169
|
cursorPosition,
|
|
1121
1170
|
wrapIndent: 2,
|
|
1122
|
-
onChange:
|
|
1171
|
+
onChange: handleInputChange,
|
|
1123
1172
|
onSubmit: handleSubmitText,
|
|
1124
1173
|
placeholder: "Ask anything... (/ commands, @ files)"
|
|
1125
1174
|
})] }),
|
|
@@ -1137,6 +1186,16 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
1137
1186
|
});
|
|
1138
1187
|
}
|
|
1139
1188
|
//#endregion
|
|
1189
|
+
//#region src/components/Chat/constants.ts
|
|
1190
|
+
var ACTION_NOT_PERFORMED = "The requested action was NOT performed";
|
|
1191
|
+
var PLAN_CHECKLIST_REMINDER = "Then display the execution plan as an unchecked Markdown checklist only";
|
|
1192
|
+
var PLAN_EXECUTION_REMINDER = `Do not claim success and do not call ${Array.from(WRITE_TOOLS).join(", ")} until the user approves execution`;
|
|
1193
|
+
var INTERRUPT_REASON = /* @__PURE__ */ function(INTERRUPT_REASON) {
|
|
1194
|
+
INTERRUPT_REASON["INTERRUPTED"] = "interrupted";
|
|
1195
|
+
INTERRUPT_REASON["REJECTED"] = "rejected";
|
|
1196
|
+
return INTERRUPT_REASON;
|
|
1197
|
+
}({});
|
|
1198
|
+
//#endregion
|
|
1140
1199
|
//#region src/components/Chat/plan.ts
|
|
1141
1200
|
function hasExecutablePlan(content) {
|
|
1142
1201
|
return content.split("\n").some((line) => {
|
|
@@ -1148,6 +1207,7 @@ function hasExecutablePlan(content) {
|
|
|
1148
1207
|
//#region src/components/Chat/Chat.tsx
|
|
1149
1208
|
function Chat({ initialMessages, model, onCommand, onMessagesChange, mode, onModeChange, sessionId }) {
|
|
1150
1209
|
const sessionMessages = initialMessages ?? [];
|
|
1210
|
+
const history = useMemo(() => sessionMessages.flatMap(({ role, content }) => role === "user" && !content.startsWith("/") ? [content] : []), [sessionMessages]);
|
|
1151
1211
|
const [messages, setMessages] = useState(sessionMessages);
|
|
1152
1212
|
const [streamingMessage, setStreamingMessage] = useState(null);
|
|
1153
1213
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -1496,7 +1556,8 @@ function Chat({ initialMessages, model, onCommand, onMessagesChange, mode, onMod
|
|
|
1496
1556
|
}),
|
|
1497
1557
|
!pendingPlan && !pendingToolCall && /* @__PURE__ */ jsx(Box, {
|
|
1498
1558
|
marginTop: 1,
|
|
1499
|
-
children: /* @__PURE__ */ jsx(
|
|
1559
|
+
children: /* @__PURE__ */ jsx(ChatInput, {
|
|
1560
|
+
history,
|
|
1500
1561
|
isDisabled: isLoading,
|
|
1501
1562
|
onInterrupt: handleInterrupt,
|
|
1502
1563
|
onSubmit: handleSubmit
|
package/dist/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ var LIST = [
|
|
|
33
33
|
//#endregion
|
|
34
34
|
//#region package.json
|
|
35
35
|
var name = "code-ollama";
|
|
36
|
-
var version = "0.
|
|
36
|
+
var version = "0.16.0";
|
|
37
37
|
//#endregion
|
|
38
38
|
//#region src/constants/package.ts
|
|
39
39
|
var NAME = name;
|
|
@@ -931,7 +931,7 @@ async function main(args = process.argv.slice(2)) {
|
|
|
931
931
|
else await launchTui();
|
|
932
932
|
}
|
|
933
933
|
async function launchTui(sessionId) {
|
|
934
|
-
const { renderApp } = await import("./assets/tui-
|
|
934
|
+
const { renderApp } = await import("./assets/tui-85A3pZD2.js");
|
|
935
935
|
reset();
|
|
936
936
|
renderApp(sessionId);
|
|
937
937
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-ollama",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Ollama coding agent that runs in your terminal",
|
|
5
5
|
"author": "Mark <mark@remarkablemark.org> (https://remarkablemark.org)",
|
|
6
6
|
"type": "module",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@types/node": "25.8.0",
|
|
58
58
|
"@types/react": "19.2.14",
|
|
59
59
|
"@vitest/coverage-v8": "4.1.6",
|
|
60
|
-
"eslint": "10.
|
|
60
|
+
"eslint": "10.4.0",
|
|
61
61
|
"eslint-plugin-prettier": "5.5.5",
|
|
62
62
|
"eslint-plugin-simple-import-sort": "13.0.0",
|
|
63
63
|
"globals": "17.6.0",
|