code-ollama 0.9.0 → 0.9.1
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/assets/{tui-VKBxlYAz.js → tui-_1XJg3dh.js} +195 -98
- package/dist/cli.js +22 -5
- package/package.json +1 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { a as tick, c as
|
|
1
|
+
import { _ as VERSION, a as tick, c as setClearHandler, d as loadConfig, f as saveConfig, g as PLAN_GENERATION_INSTRUCTION, h as ROLE, i as executeTool, l as listModels, m as withSystemMessage, n as TOOLS, o as clear, p as resetSystemMessage, r as WRITE_TOOLS, s as reset, t as READ_TOOLS, u as streamChat } from "../cli.js";
|
|
2
2
|
import { readdirSync } from "node:fs";
|
|
3
3
|
import { join, relative } from "node:path";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { exec } from "node:child_process";
|
|
6
|
-
import { Box, Text, render, useApp, useInput } from "ink";
|
|
6
|
+
import { Box, Static, Text, render, useApp, useInput, useStdout } from "ink";
|
|
7
7
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { Select, Spinner } from "@inkjs/ui";
|
|
9
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { marked } from "marked";
|
|
11
|
-
import
|
|
11
|
+
import { markedTerminal } from "marked-terminal";
|
|
12
12
|
//#region src/constants/command.ts
|
|
13
13
|
var LIST = [
|
|
14
14
|
{
|
|
@@ -45,22 +45,46 @@ var LABEL = {
|
|
|
45
45
|
var HEADER_PREFIX = "🦙 ";
|
|
46
46
|
//#endregion
|
|
47
47
|
//#region src/components/CodeBlock/CodeBlock.tsx
|
|
48
|
+
var highlightCache = /* @__PURE__ */ new Map();
|
|
49
|
+
var CODE_BLOCK_REGEX = /^(`{3,})(\w+)?[ \t]*\n([\s\S]*?)^\1[ \t]*$/gm;
|
|
50
|
+
async function prewarmCodeBlocks(content) {
|
|
51
|
+
const promises = [];
|
|
52
|
+
let match;
|
|
53
|
+
CODE_BLOCK_REGEX.lastIndex = 0;
|
|
54
|
+
while ((match = CODE_BLOCK_REGEX.exec(content)) !== null) {
|
|
55
|
+
const language = match[2];
|
|
56
|
+
const code = match[3].trim();
|
|
57
|
+
// v8 ignore next 2
|
|
58
|
+
if (code) promises.push(prewarmHighlight(code, language));
|
|
59
|
+
}
|
|
60
|
+
await Promise.all(promises);
|
|
61
|
+
}
|
|
62
|
+
async function prewarmHighlight(code, language) {
|
|
63
|
+
// v8 ignore start
|
|
64
|
+
const cacheKey = `${language ?? ""}:${code}`;
|
|
65
|
+
if (highlightCache.has(cacheKey)) return;
|
|
66
|
+
// v8 ignore stop
|
|
67
|
+
const result = await highlightCode(code, language);
|
|
68
|
+
highlightCache.set(cacheKey, result);
|
|
69
|
+
}
|
|
48
70
|
async function highlightCode(code, language = "text") {
|
|
49
71
|
const { codeToANSI } = await import("@shikijs/cli");
|
|
50
72
|
try {
|
|
51
73
|
return await codeToANSI(code, language, "github-light");
|
|
52
74
|
} catch {
|
|
53
|
-
// v8 ignore next
|
|
75
|
+
// v8 ignore next
|
|
54
76
|
return code;
|
|
55
77
|
}
|
|
56
78
|
}
|
|
57
79
|
var CodeBlock = memo(function CodeBlock({ code, language, role }) {
|
|
58
|
-
const
|
|
80
|
+
const cacheKey = `${language ?? ""}:${code}`;
|
|
81
|
+
const [highlighted, setHighlighted] = useState(() => highlightCache.get(cacheKey) ?? code);
|
|
59
82
|
useEffect(() => {
|
|
60
83
|
let canceled = false;
|
|
61
84
|
async function loadHighlight() {
|
|
62
85
|
try {
|
|
63
86
|
const result = await highlightCode(code, language);
|
|
87
|
+
highlightCache.set(cacheKey, result);
|
|
64
88
|
if (!canceled) setHighlighted(result);
|
|
65
89
|
} catch {}
|
|
66
90
|
}
|
|
@@ -68,7 +92,11 @@ var CodeBlock = memo(function CodeBlock({ code, language, role }) {
|
|
|
68
92
|
return () => {
|
|
69
93
|
canceled = true;
|
|
70
94
|
};
|
|
71
|
-
}, [
|
|
95
|
+
}, [
|
|
96
|
+
cacheKey,
|
|
97
|
+
code,
|
|
98
|
+
language
|
|
99
|
+
]);
|
|
72
100
|
const isSystem = role === ROLE.SYSTEM;
|
|
73
101
|
return /* @__PURE__ */ jsx(Box, {
|
|
74
102
|
flexDirection: "column",
|
|
@@ -76,41 +104,34 @@ var CodeBlock = memo(function CodeBlock({ code, language, role }) {
|
|
|
76
104
|
borderColor: isSystem ? "gray" : "dim",
|
|
77
105
|
paddingX: 1,
|
|
78
106
|
marginY: 1,
|
|
79
|
-
children: /* @__PURE__ */ jsx(
|
|
107
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
80
108
|
dimColor: isSystem,
|
|
81
109
|
children: highlighted
|
|
82
|
-
})
|
|
110
|
+
})
|
|
83
111
|
});
|
|
84
112
|
});
|
|
85
113
|
//#endregion
|
|
86
114
|
//#region src/components/Markdown/Markdown.tsx
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
var HR_PLACEHOLDER = "__CODE_OLLAMA_HR_PLACEHOLDER__";
|
|
116
|
+
marked.use(markedTerminal({ theme: "gitHub" }));
|
|
117
|
+
marked.use({ renderer: { hr: () => `${HR_PLACEHOLDER}\n` } });
|
|
118
|
+
function renderMarkdown(content, hrWidth) {
|
|
119
|
+
const hr = "─".repeat(Math.max(1, hrWidth));
|
|
120
|
+
try {
|
|
121
|
+
const result = marked.parse(content);
|
|
122
|
+
return (typeof result === "string" ? result.trim() : content).replaceAll(HR_PLACEHOLDER, hr);
|
|
123
|
+
} catch {
|
|
124
|
+
return content;
|
|
125
|
+
}
|
|
126
|
+
// v8 ignore stop
|
|
92
127
|
}
|
|
93
128
|
var Markdown = memo(function Markdown({ content, color, dimColor }) {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
let canceled = false;
|
|
97
|
-
function loadMarkdown() {
|
|
98
|
-
try {
|
|
99
|
-
const result = renderMarkdown(content);
|
|
100
|
-
// v8 ignore start
|
|
101
|
-
if (!canceled) setRendered(result);
|
|
102
|
-
} catch {}
|
|
103
|
-
// v8 ignore stop
|
|
104
|
-
}
|
|
105
|
-
loadMarkdown();
|
|
106
|
-
return () => {
|
|
107
|
-
canceled = true;
|
|
108
|
-
};
|
|
109
|
-
}, [content]);
|
|
129
|
+
const { stdout } = useStdout();
|
|
130
|
+
const availableWidth = stdout.columns - 4;
|
|
110
131
|
return /* @__PURE__ */ jsx(Text, {
|
|
111
132
|
color,
|
|
112
133
|
dimColor,
|
|
113
|
-
children:
|
|
134
|
+
children: useMemo(() => renderMarkdown(content, availableWidth), [content, availableWidth])
|
|
114
135
|
});
|
|
115
136
|
});
|
|
116
137
|
//#endregion
|
|
@@ -132,10 +153,10 @@ function getMessageColor(role) {
|
|
|
132
153
|
}
|
|
133
154
|
function parseContent(content) {
|
|
134
155
|
const segments = [];
|
|
135
|
-
const codeBlockRegex = /```(\w+)?\n?([\s\S]*?)```/g;
|
|
136
156
|
let lastIndex = 0;
|
|
137
157
|
let match;
|
|
138
|
-
|
|
158
|
+
CODE_BLOCK_REGEX.lastIndex = 0;
|
|
159
|
+
while ((match = CODE_BLOCK_REGEX.exec(content)) !== null) {
|
|
139
160
|
if (match.index > lastIndex) {
|
|
140
161
|
const textContent = content.slice(lastIndex, match.index).trim();
|
|
141
162
|
// v8 ignore next 2 - Defensive check for empty trimmed content
|
|
@@ -144,8 +165,8 @@ function parseContent(content) {
|
|
|
144
165
|
content: textContent
|
|
145
166
|
});
|
|
146
167
|
}
|
|
147
|
-
const language = match[
|
|
148
|
-
const codeContent = match[
|
|
168
|
+
const language = match[2];
|
|
169
|
+
const codeContent = match[3].trim();
|
|
149
170
|
// v8 ignore next 2 - Defensive check for empty code block
|
|
150
171
|
if (codeContent) segments.push({
|
|
151
172
|
type: "code",
|
|
@@ -163,7 +184,7 @@ function parseContent(content) {
|
|
|
163
184
|
});
|
|
164
185
|
}
|
|
165
186
|
// v8 ignore next 2 - Defensive fallback for edge case
|
|
166
|
-
if (segments.length
|
|
187
|
+
if (!segments.length && content.trim()) segments.push({
|
|
167
188
|
type: "text",
|
|
168
189
|
content: content.trim()
|
|
169
190
|
});
|
|
@@ -212,11 +233,14 @@ var Message = memo(function Message({ message }) {
|
|
|
212
233
|
})
|
|
213
234
|
});
|
|
214
235
|
});
|
|
215
|
-
function Messages({ messages, isLoading, streamingMessage }) {
|
|
236
|
+
function Messages({ messages, isLoading, sessionId = 0, streamingMessage }) {
|
|
216
237
|
return /* @__PURE__ */ jsxs(Box, {
|
|
217
238
|
flexDirection: "column",
|
|
218
239
|
children: [
|
|
219
|
-
|
|
240
|
+
/* @__PURE__ */ jsx(Static, {
|
|
241
|
+
items: messages.filter(({ content }) => content !== TURN_ABORTED_MESSAGE),
|
|
242
|
+
children: (message, index) => /* @__PURE__ */ jsx(Message, { message }, index)
|
|
243
|
+
}, sessionId),
|
|
220
244
|
streamingMessage && /* @__PURE__ */ jsx(Message, { message: streamingMessage }),
|
|
221
245
|
isLoading && !streamingMessage?.content && /* @__PURE__ */ jsx(Box, {
|
|
222
246
|
marginTop: -1,
|
|
@@ -385,16 +409,27 @@ var INTERRUPT_REASON = /* @__PURE__ */ function(INTERRUPT_REASON) {
|
|
|
385
409
|
}({});
|
|
386
410
|
//#endregion
|
|
387
411
|
//#region src/components/TextInput/TextInput.tsx
|
|
388
|
-
function TextInput({ value, isDisabled = false, placeholder, onChange, onSubmit }) {
|
|
412
|
+
function TextInput({ value, isDisabled = false, placeholder, cursorPosition: externalCursorPosition, onChange, onSubmit }) {
|
|
389
413
|
const [cursorPosition, setCursorPosition] = useState(value.length);
|
|
390
414
|
const prevValueRef = useRef(value);
|
|
415
|
+
const prevExternalCursorRef = useRef(externalCursorPosition);
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
if (externalCursorPosition !== void 0 && externalCursorPosition !== prevExternalCursorRef.current) {
|
|
418
|
+
prevExternalCursorRef.current = externalCursorPosition;
|
|
419
|
+
setCursorPosition(externalCursorPosition);
|
|
420
|
+
}
|
|
421
|
+
}, [externalCursorPosition]);
|
|
391
422
|
useEffect(() => {
|
|
392
423
|
const prevValue = prevValueRef.current;
|
|
393
424
|
prevValueRef.current = value;
|
|
394
425
|
if (value === "") setCursorPosition(0);
|
|
395
|
-
else if (value.length > prevValue.length && cursorPosition <= prevValue.length) setCursorPosition(value.length);
|
|
426
|
+
else if (value.length > prevValue.length + 1 && cursorPosition <= prevValue.length && externalCursorPosition === void 0) setCursorPosition(value.length);
|
|
396
427
|
else if (cursorPosition > value.length) setCursorPosition(value.length);
|
|
397
|
-
}, [
|
|
428
|
+
}, [
|
|
429
|
+
value,
|
|
430
|
+
cursorPosition,
|
|
431
|
+
externalCursorPosition
|
|
432
|
+
]);
|
|
398
433
|
useInput((input, key) => {
|
|
399
434
|
// v8 ignore next
|
|
400
435
|
if (isDisabled) return;
|
|
@@ -441,12 +476,23 @@ function TextInput({ value, isDisabled = false, placeholder, onChange, onSubmit
|
|
|
441
476
|
}, { isActive: !isDisabled });
|
|
442
477
|
const displayValue = value || (placeholder ?? "");
|
|
443
478
|
const isPlaceholder = Boolean(!value && placeholder);
|
|
444
|
-
const
|
|
479
|
+
const cursorChar = displayValue[cursorPosition] || " ";
|
|
445
480
|
const before = displayValue.slice(0, cursorPosition);
|
|
446
481
|
const after = displayValue.slice(cursorPosition + 1);
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
482
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
483
|
+
/* @__PURE__ */ jsx(Text, {
|
|
484
|
+
dimColor: isPlaceholder,
|
|
485
|
+
children: before
|
|
486
|
+
}),
|
|
487
|
+
/* @__PURE__ */ jsx(Text, {
|
|
488
|
+
inverse: true,
|
|
489
|
+
children: cursorChar
|
|
490
|
+
}),
|
|
491
|
+
/* @__PURE__ */ jsx(Text, {
|
|
492
|
+
dimColor: isPlaceholder,
|
|
493
|
+
children: after
|
|
494
|
+
})
|
|
495
|
+
] });
|
|
450
496
|
}
|
|
451
497
|
//#endregion
|
|
452
498
|
//#region src/components/Chat/CommandMenu.tsx
|
|
@@ -470,7 +516,7 @@ function CommandMenu({ input, onSubmit }) {
|
|
|
470
516
|
//#endregion
|
|
471
517
|
//#region src/components/Chat/FileSuggestions.tsx
|
|
472
518
|
var MAX_VISIBLE_OPTIONS = 5;
|
|
473
|
-
var MENTION_PATTERN = /(
|
|
519
|
+
var MENTION_PATTERN = /(^|.)@(\S+)/;
|
|
474
520
|
var RIPGREP_MAX_BUFFER = 10 * 1024 * 1024;
|
|
475
521
|
function normalizePath(filePath) {
|
|
476
522
|
return filePath.replaceAll("\\", "/");
|
|
@@ -486,8 +532,17 @@ function getMentionMatch(input) {
|
|
|
486
532
|
function buildNextInput(input, filePath) {
|
|
487
533
|
const mentionMatch = getMentionMatch(input);
|
|
488
534
|
// v8 ignore next 3
|
|
489
|
-
if (!mentionMatch) return
|
|
490
|
-
|
|
535
|
+
if (!mentionMatch) return {
|
|
536
|
+
value: input,
|
|
537
|
+
cursorPosition: input.length
|
|
538
|
+
};
|
|
539
|
+
const mentionEndIndex = mentionMatch.prefix.length + 1 + mentionMatch.query.length;
|
|
540
|
+
const suffix = input.slice(mentionEndIndex);
|
|
541
|
+
const separator = !suffix.length || !/\s/.test(suffix[0]) ? " " : "";
|
|
542
|
+
return {
|
|
543
|
+
value: `${mentionMatch.prefix}${filePath}${separator}${suffix}`,
|
|
544
|
+
cursorPosition: mentionMatch.prefix.length + filePath.length + separator.length
|
|
545
|
+
};
|
|
491
546
|
}
|
|
492
547
|
function listProjectFilesFallback(rootDir) {
|
|
493
548
|
const filePaths = [];
|
|
@@ -558,7 +613,7 @@ function FileSuggestions({ input, isDisabled = false, onChange, onSelect }) {
|
|
|
558
613
|
onChange(null);
|
|
559
614
|
return;
|
|
560
615
|
}
|
|
561
|
-
onChange(buildNextInput(input, options[focusedIndex]));
|
|
616
|
+
onChange(buildNextInput(input, options[focusedIndex]).value);
|
|
562
617
|
}, [
|
|
563
618
|
focusedIndex,
|
|
564
619
|
input,
|
|
@@ -596,21 +651,38 @@ function FileSuggestions({ input, isDisabled = false, onChange, onSelect }) {
|
|
|
596
651
|
//#endregion
|
|
597
652
|
//#region src/components/Chat/Input.tsx
|
|
598
653
|
function hasFileSuggestionQuery(input) {
|
|
599
|
-
return /(
|
|
654
|
+
return /(^|.)@\S+/.test(input);
|
|
600
655
|
}
|
|
601
656
|
function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
602
657
|
const { exit } = useApp();
|
|
603
658
|
const [input, setInput] = useState("");
|
|
659
|
+
const [cursorPosition, setCursorPosition] = useState(void 0);
|
|
604
660
|
const fileSuggestionRef = useRef(null);
|
|
605
661
|
const resetInput = useCallback(() => {
|
|
606
662
|
setInput("");
|
|
607
663
|
}, []);
|
|
608
664
|
const handleSelectFileSuggestion = useCallback((nextInput) => {
|
|
609
|
-
setInput(nextInput);
|
|
665
|
+
setInput(nextInput.value);
|
|
666
|
+
setCursorPosition(nextInput.cursorPosition);
|
|
610
667
|
}, []);
|
|
611
668
|
const handleFileSuggestionChange = useCallback((nextInput) => {
|
|
612
|
-
|
|
613
|
-
|
|
669
|
+
if (nextInput) {
|
|
670
|
+
const mentionMatch = /(^|.)@(\S+)/.exec(input);
|
|
671
|
+
// v8 ignore start
|
|
672
|
+
if (mentionMatch) {
|
|
673
|
+
const prefixLength = mentionMatch.index + mentionMatch[1].length;
|
|
674
|
+
const queryLength = mentionMatch[2].length;
|
|
675
|
+
const suffix = input.slice(prefixLength + 1 + queryLength);
|
|
676
|
+
fileSuggestionRef.current = {
|
|
677
|
+
value: nextInput,
|
|
678
|
+
cursorPosition: nextInput.length - suffix.length
|
|
679
|
+
};
|
|
680
|
+
} else fileSuggestionRef.current = {
|
|
681
|
+
value: nextInput,
|
|
682
|
+
cursorPosition: nextInput.length
|
|
683
|
+
};
|
|
684
|
+
} else fileSuggestionRef.current = null;
|
|
685
|
+
}, [input]);
|
|
614
686
|
const submitAndReset = useCallback((input) => {
|
|
615
687
|
const trimmedInput = input.trim();
|
|
616
688
|
if (!trimmedInput) return;
|
|
@@ -652,6 +724,7 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
652
724
|
/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, { children: "> " }), /* @__PURE__ */ jsx(TextInput, {
|
|
653
725
|
value: input,
|
|
654
726
|
isDisabled,
|
|
727
|
+
cursorPosition,
|
|
655
728
|
onChange: setInput,
|
|
656
729
|
onSubmit: handleSubmitText,
|
|
657
730
|
placeholder: "Ask anything... (/ commands, @ files)"
|
|
@@ -786,11 +859,13 @@ function Chat({ model, onCommand, mode, onModeChange, sessionId }) {
|
|
|
786
859
|
return;
|
|
787
860
|
}
|
|
788
861
|
}
|
|
862
|
+
await prewarmCodeBlocks(assistantMessage.content);
|
|
789
863
|
commitAssistantMessage();
|
|
790
864
|
} catch (error) {
|
|
791
865
|
// v8 ignore next
|
|
792
866
|
if (!controller.signal.aborted) {
|
|
793
867
|
assistantMessage.content = `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
868
|
+
await prewarmCodeBlocks(assistantMessage.content);
|
|
794
869
|
commitAssistantMessage();
|
|
795
870
|
}
|
|
796
871
|
} finally {
|
|
@@ -856,6 +931,7 @@ function Chat({ model, onCommand, mode, onModeChange, sessionId }) {
|
|
|
856
931
|
return;
|
|
857
932
|
}
|
|
858
933
|
}
|
|
934
|
+
await prewarmCodeBlocks(assistantMessage.content);
|
|
859
935
|
const researchMessages = commitAssistantMessage();
|
|
860
936
|
const planInstruction = {
|
|
861
937
|
role: ROLE.SYSTEM,
|
|
@@ -896,6 +972,7 @@ function Chat({ model, onCommand, mode, onModeChange, sessionId }) {
|
|
|
896
972
|
// v8 ignore next
|
|
897
973
|
if (!controller.signal.aborted) {
|
|
898
974
|
assistantMessage.content = `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
975
|
+
await prewarmCodeBlocks(assistantMessage.content);
|
|
899
976
|
commitAssistantMessage();
|
|
900
977
|
}
|
|
901
978
|
} finally {
|
|
@@ -996,6 +1073,7 @@ function Chat({ model, onCommand, mode, onModeChange, sessionId }) {
|
|
|
996
1073
|
/* @__PURE__ */ jsx(Messages, {
|
|
997
1074
|
messages,
|
|
998
1075
|
isLoading,
|
|
1076
|
+
sessionId,
|
|
999
1077
|
streamingMessage
|
|
1000
1078
|
}),
|
|
1001
1079
|
pendingPlan && /* @__PURE__ */ jsx(PlanApproval, {
|
|
@@ -1013,10 +1091,13 @@ function Chat({ model, onCommand, mode, onModeChange, sessionId }) {
|
|
|
1013
1091
|
children: interruptReason === INTERRUPT_REASON.REJECTED ? "❗ Tool call rejected." : "❗ Execution interrupted."
|
|
1014
1092
|
})
|
|
1015
1093
|
}),
|
|
1016
|
-
!pendingPlan && !pendingToolCall && /* @__PURE__ */ jsx(
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1094
|
+
!pendingPlan && !pendingToolCall && /* @__PURE__ */ jsx(Box, {
|
|
1095
|
+
marginTop: 1,
|
|
1096
|
+
children: /* @__PURE__ */ jsx(Input, {
|
|
1097
|
+
isDisabled: isLoading,
|
|
1098
|
+
onInterrupt: handleInterrupt,
|
|
1099
|
+
onSubmit: handleSubmit
|
|
1100
|
+
})
|
|
1020
1101
|
})
|
|
1021
1102
|
]
|
|
1022
1103
|
});
|
|
@@ -1061,45 +1142,53 @@ function abbreviatePath(dir) {
|
|
|
1061
1142
|
const home = homedir();
|
|
1062
1143
|
return dir.startsWith(home) ? `~${dir.slice(home.length)}` : dir;
|
|
1063
1144
|
}
|
|
1064
|
-
function Header({ model }) {
|
|
1145
|
+
function Header({ model, onLoad }) {
|
|
1065
1146
|
const directory = abbreviatePath(process.cwd());
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
children: [
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
]
|
|
1081
|
-
})] }),
|
|
1082
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1083
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1084
|
-
/* @__PURE__ */ jsx(Text, {
|
|
1147
|
+
useEffect(() => {
|
|
1148
|
+
onLoad();
|
|
1149
|
+
}, []);
|
|
1150
|
+
return /* @__PURE__ */ jsx(Static, {
|
|
1151
|
+
items: [0],
|
|
1152
|
+
children: (key) => /* @__PURE__ */ jsxs(Box, {
|
|
1153
|
+
borderStyle: "round",
|
|
1154
|
+
flexDirection: "column",
|
|
1155
|
+
paddingX: 1,
|
|
1156
|
+
children: [
|
|
1157
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
1158
|
+
bold: true,
|
|
1159
|
+
children: [HEADER_PREFIX, "Code Ollama"]
|
|
1160
|
+
}), /* @__PURE__ */ jsxs(Text, {
|
|
1085
1161
|
dimColor: true,
|
|
1086
|
-
children:
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1162
|
+
children: [
|
|
1163
|
+
" (v",
|
|
1164
|
+
VERSION,
|
|
1165
|
+
")"
|
|
1166
|
+
]
|
|
1167
|
+
})] }),
|
|
1168
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
1169
|
+
marginTop: 1,
|
|
1170
|
+
children: [
|
|
1171
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1172
|
+
dimColor: true,
|
|
1173
|
+
children: "model:".padEnd(11)
|
|
1174
|
+
}),
|
|
1175
|
+
/* @__PURE__ */ jsx(Text, { children: model.padEnd(model.length + 3) }),
|
|
1176
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1177
|
+
color: "cyan",
|
|
1178
|
+
children: "/model"
|
|
1179
|
+
}),
|
|
1180
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1181
|
+
dimColor: true,
|
|
1182
|
+
children: " to switch"
|
|
1183
|
+
})
|
|
1184
|
+
]
|
|
1092
1185
|
}),
|
|
1093
|
-
/* @__PURE__ */ jsx(Text, {
|
|
1186
|
+
/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1094
1187
|
dimColor: true,
|
|
1095
|
-
children: "
|
|
1096
|
-
})
|
|
1097
|
-
]
|
|
1098
|
-
|
|
1099
|
-
dimColor: true,
|
|
1100
|
-
children: "directory:".padEnd(11)
|
|
1101
|
-
}), /* @__PURE__ */ jsx(Text, { children: directory })] })
|
|
1102
|
-
]
|
|
1188
|
+
children: "directory:".padEnd(11)
|
|
1189
|
+
}), /* @__PURE__ */ jsx(Text, { children: directory })] })
|
|
1190
|
+
]
|
|
1191
|
+
}, key)
|
|
1103
1192
|
});
|
|
1104
1193
|
}
|
|
1105
1194
|
//#endregion
|
|
@@ -1149,6 +1238,10 @@ function App() {
|
|
|
1149
1238
|
const [picking, setPicking] = useState(false);
|
|
1150
1239
|
const [mode, setMode] = useState(NAME.SAFE);
|
|
1151
1240
|
const [sessionId, setSessionId] = useState(0);
|
|
1241
|
+
const [isHeaderLoaded, setIsHeaderLoaded] = useState(false);
|
|
1242
|
+
const handleHeaderLoad = useCallback(() => {
|
|
1243
|
+
setIsHeaderLoaded(true);
|
|
1244
|
+
}, []);
|
|
1152
1245
|
const handleCommand = useCallback((command) => {
|
|
1153
1246
|
switch (command) {
|
|
1154
1247
|
case "/model":
|
|
@@ -1156,6 +1249,7 @@ function App() {
|
|
|
1156
1249
|
break;
|
|
1157
1250
|
case "/clear":
|
|
1158
1251
|
resetSystemMessage();
|
|
1252
|
+
clear();
|
|
1159
1253
|
setPicking(false);
|
|
1160
1254
|
setSessionId((sessionId) => sessionId + 1);
|
|
1161
1255
|
break;
|
|
@@ -1204,8 +1298,11 @@ function App() {
|
|
|
1204
1298
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1205
1299
|
flexDirection: "column",
|
|
1206
1300
|
children: [
|
|
1207
|
-
/* @__PURE__ */ jsx(Header, {
|
|
1208
|
-
|
|
1301
|
+
/* @__PURE__ */ jsx(Header, {
|
|
1302
|
+
model,
|
|
1303
|
+
onLoad: handleHeaderLoad
|
|
1304
|
+
}),
|
|
1305
|
+
isHeaderLoaded && body,
|
|
1209
1306
|
/* @__PURE__ */ jsx(Footer, {
|
|
1210
1307
|
mode,
|
|
1211
1308
|
onToggleMode: handleToggleMode
|
|
@@ -1216,14 +1313,14 @@ function App() {
|
|
|
1216
1313
|
//#endregion
|
|
1217
1314
|
//#region src/tui.tsx
|
|
1218
1315
|
function renderApp() {
|
|
1219
|
-
|
|
1220
|
-
const app = render(
|
|
1316
|
+
let resetKey = 0;
|
|
1317
|
+
const app = render(/* @__PURE__ */ jsx(App, {}, resetKey), {
|
|
1221
1318
|
exitOnCtrlC: false,
|
|
1222
1319
|
maxFps: 60
|
|
1223
1320
|
});
|
|
1224
1321
|
setClearHandler(() => {
|
|
1225
|
-
|
|
1226
|
-
app.rerender(
|
|
1322
|
+
reset();
|
|
1323
|
+
app.rerender(/* @__PURE__ */ jsx(App, {}, ++resetKey));
|
|
1227
1324
|
});
|
|
1228
1325
|
}
|
|
1229
1326
|
//#endregion
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { exec } from "node:child_process";
|
|
|
8
8
|
import { promisify } from "node:util";
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/constants/package.ts
|
|
11
|
-
var VERSION = "0.9.
|
|
11
|
+
var VERSION = "0.9.1";
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/constants/prompt.ts
|
|
14
14
|
var BASE_SYSTEM_PROMPT = `You are a coding assistant that helps users write, edit, and understand code. You have access to tools for reading files, writing files, running shell commands, and searching code
|
|
@@ -166,7 +166,24 @@ async function listModels() {
|
|
|
166
166
|
const { models } = await client.list();
|
|
167
167
|
return models.map(({ name }) => name);
|
|
168
168
|
}
|
|
169
|
-
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/utils/screen.ts
|
|
171
|
+
var clearHandler = null;
|
|
172
|
+
function setClearHandler(handler) {
|
|
173
|
+
clearHandler = handler;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Clear the screen with Ink.
|
|
177
|
+
*/
|
|
178
|
+
function clear() {
|
|
179
|
+
clearHandler?.();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Reset the screen with ANSI escape sequence.
|
|
183
|
+
*/
|
|
184
|
+
function reset() {
|
|
185
|
+
process.stdout.write("\x1Bc\x1B[?25l");
|
|
186
|
+
}
|
|
170
187
|
//#endregion
|
|
171
188
|
//#region src/utils/time.ts
|
|
172
189
|
var tick = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -512,8 +529,8 @@ async function processRunStream(messages, model) {
|
|
|
512
529
|
}
|
|
513
530
|
async function main(args = process.argv.slice(2)) {
|
|
514
531
|
if (!args.length) {
|
|
515
|
-
const { renderApp } = await import("./assets/tui-
|
|
516
|
-
|
|
532
|
+
const { renderApp } = await import("./assets/tui-_1XJg3dh.js");
|
|
533
|
+
reset();
|
|
517
534
|
renderApp();
|
|
518
535
|
return;
|
|
519
536
|
}
|
|
@@ -535,4 +552,4 @@ function isEntrypoint(argv1 = process.argv[1]) {
|
|
|
535
552
|
if (isEntrypoint()) main();
|
|
536
553
|
// v8 ignore stop
|
|
537
554
|
//#endregion
|
|
538
|
-
export { tick as a,
|
|
555
|
+
export { VERSION as _, tick as a, setClearHandler as c, loadConfig as d, saveConfig as f, PLAN_GENERATION_INSTRUCTION as g, ROLE as h, executeTool as i, listModels as l, withSystemMessage as m, main, TOOLS as n, clear as o, resetSystemMessage as p, WRITE_TOOLS as r, reset as s, READ_TOOLS as t, streamChat as u };
|