code-ollama 0.14.0 → 0.14.2
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-TX7C0xYg.js → tui-Dse5XVJ_.js} +397 -180
- package/dist/cli.js +48 -4
- package/package.json +5 -5
- package/dist/assets/shell-CipXM_WI.js +0 -46
|
@@ -7,18 +7,24 @@ import { Box, Static, Text, render, useApp, useInput, useStdout } from "ink";
|
|
|
7
7
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { Select, Spinner } from "@inkjs/ui";
|
|
10
|
-
import {
|
|
10
|
+
import { Marked } from "marked";
|
|
11
11
|
import { markedTerminal } from "marked-terminal";
|
|
12
12
|
//#region src/components/CodeBlock/CodeBlock.tsx
|
|
13
13
|
var highlightCache = /* @__PURE__ */ new Map();
|
|
14
|
-
var CODE_BLOCK_REGEX = /^(`{3,})(\w+)?[ \t]*\n([\s\S]*?)^\
|
|
14
|
+
var CODE_BLOCK_REGEX = /^(?<indent>[ \t]*)(`{3,})(\w+)?[ \t]*\n([\s\S]*?)^\k<indent>\2[ \t]*$/gm;
|
|
15
|
+
function normalizeCodeBlockContent(content, indent = "") {
|
|
16
|
+
if (!indent) return content.trim();
|
|
17
|
+
const indentPattern = new RegExp(`^${indent}`, "gm");
|
|
18
|
+
return content.replace(indentPattern, "").trim();
|
|
19
|
+
}
|
|
15
20
|
async function prewarmCodeBlocks(content) {
|
|
16
21
|
const promises = [];
|
|
17
22
|
let match;
|
|
18
23
|
CODE_BLOCK_REGEX.lastIndex = 0;
|
|
19
24
|
while ((match = CODE_BLOCK_REGEX.exec(content)) !== null) {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
25
|
+
const indent = match[1];
|
|
26
|
+
const language = match[3];
|
|
27
|
+
const code = normalizeCodeBlockContent(match[4], indent);
|
|
22
28
|
// v8 ignore next 2
|
|
23
29
|
if (code) promises.push(prewarmHighlight(code, language));
|
|
24
30
|
}
|
|
@@ -65,7 +71,7 @@ var CodeBlock = memo(function CodeBlock({ code, language, role }) {
|
|
|
65
71
|
const isSystem = role === SYSTEM;
|
|
66
72
|
return /* @__PURE__ */ jsx(Box, {
|
|
67
73
|
flexDirection: "column",
|
|
68
|
-
borderStyle: "
|
|
74
|
+
borderStyle: "bold",
|
|
69
75
|
borderColor: isSystem ? "gray" : "dim",
|
|
70
76
|
paddingX: 1,
|
|
71
77
|
marginY: 1,
|
|
@@ -165,15 +171,29 @@ var inlineMathExtension = {
|
|
|
165
171
|
//#endregion
|
|
166
172
|
//#region src/components/Markdown/Markdown.tsx
|
|
167
173
|
var HR_PLACEHOLDER = "__CODE_OLLAMA_HR_PLACEHOLDER__";
|
|
168
|
-
marked.use(markedTerminal({ theme: "gitHub" }));
|
|
169
|
-
marked.use({
|
|
170
|
-
extensions: [inlineMathExtension],
|
|
171
|
-
renderer: { hr: () => `${HR_PLACEHOLDER}\n` }
|
|
172
|
-
});
|
|
173
174
|
function renderMarkdown(content, hrWidth) {
|
|
174
175
|
const hr = "─".repeat(Math.max(1, hrWidth));
|
|
176
|
+
const markdown = new Marked();
|
|
177
|
+
const rendererExtension = {
|
|
178
|
+
extensions: [inlineMathExtension],
|
|
179
|
+
useNewRenderer: true,
|
|
180
|
+
renderer: {
|
|
181
|
+
hr: () => `${HR_PLACEHOLDER}\n`,
|
|
182
|
+
text(token) {
|
|
183
|
+
const textToken = token;
|
|
184
|
+
if (typeof token === "object" && Array.isArray(textToken.tokens)) return this.parser.parseInline(textToken.tokens);
|
|
185
|
+
return String(textToken.text);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
markdown.use(markedTerminal({
|
|
190
|
+
theme: "gitHub",
|
|
191
|
+
reflowText: true,
|
|
192
|
+
width: Math.max(1, hrWidth)
|
|
193
|
+
}));
|
|
194
|
+
markdown.use(rendererExtension);
|
|
175
195
|
try {
|
|
176
|
-
const result =
|
|
196
|
+
const result = markdown.parse(content);
|
|
177
197
|
return (typeof result === "string" ? result.trim() : content).replaceAll(HR_PLACEHOLDER, hr);
|
|
178
198
|
} catch {
|
|
179
199
|
return content;
|
|
@@ -197,6 +217,101 @@ var TURN_ABORTED_MESSAGE = [
|
|
|
197
217
|
"</turn_aborted>"
|
|
198
218
|
].join("\n");
|
|
199
219
|
//#endregion
|
|
220
|
+
//#region src/components/Messages/utils.ts
|
|
221
|
+
function isWordCharacter(char) {
|
|
222
|
+
return char !== void 0 && /[A-Za-z0-9]/.test(char);
|
|
223
|
+
}
|
|
224
|
+
function isEscaped(content, index) {
|
|
225
|
+
let slashCount = 0;
|
|
226
|
+
for (let cursor = index - 1; cursor >= 0 && content[cursor] === "\\"; cursor--) slashCount += 1;
|
|
227
|
+
return slashCount % 2 === 1;
|
|
228
|
+
}
|
|
229
|
+
function canOpenEmphasis(content, index, length) {
|
|
230
|
+
const previous = content[index - 1];
|
|
231
|
+
const next = content[index + length];
|
|
232
|
+
if (!next || /\s/.test(next)) return false;
|
|
233
|
+
return !isWordCharacter(previous);
|
|
234
|
+
}
|
|
235
|
+
function canCloseEmphasis(content, index, length) {
|
|
236
|
+
const previous = content[index - 1];
|
|
237
|
+
const next = content[index + length];
|
|
238
|
+
if (!previous || /\s/.test(previous)) return false;
|
|
239
|
+
return !isWordCharacter(next);
|
|
240
|
+
}
|
|
241
|
+
function findUnmatchedInlineDelimiter(content) {
|
|
242
|
+
const stack = [];
|
|
243
|
+
for (let index = 0; index < content.length; index += 1) {
|
|
244
|
+
const current = content[index];
|
|
245
|
+
if (isEscaped(content, index)) continue;
|
|
246
|
+
const top = stack.at(-1);
|
|
247
|
+
if (top?.kind === "code") {
|
|
248
|
+
if (current === "`") stack.pop();
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (top?.kind === "latex") {
|
|
252
|
+
if (current === "$") stack.pop();
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (current === "`") {
|
|
256
|
+
stack.push({
|
|
257
|
+
index,
|
|
258
|
+
length: 1,
|
|
259
|
+
kind: "code",
|
|
260
|
+
marker: "`"
|
|
261
|
+
});
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (current === "$") {
|
|
265
|
+
stack.push({
|
|
266
|
+
index,
|
|
267
|
+
length: 1,
|
|
268
|
+
kind: "latex",
|
|
269
|
+
marker: "$"
|
|
270
|
+
});
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (current !== "*") continue;
|
|
274
|
+
const marker = current;
|
|
275
|
+
const length = content[index + 1] === marker ? 2 : 1;
|
|
276
|
+
const token = marker.repeat(length);
|
|
277
|
+
const kind = length === 2 ? "bold" : "italic";
|
|
278
|
+
if (top?.marker === token && top.kind === kind && canCloseEmphasis(content, index, length)) {
|
|
279
|
+
stack.pop();
|
|
280
|
+
if (length === 2) index += 1;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (canOpenEmphasis(content, index, length)) {
|
|
284
|
+
stack.push({
|
|
285
|
+
index,
|
|
286
|
+
length,
|
|
287
|
+
kind,
|
|
288
|
+
marker: token
|
|
289
|
+
});
|
|
290
|
+
if (length === 2) index += 1;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return stack[0] ?? null;
|
|
294
|
+
}
|
|
295
|
+
function splitStreamingInlineContent(content) {
|
|
296
|
+
const unmatched = findUnmatchedInlineDelimiter(content);
|
|
297
|
+
if (!unmatched) return [{
|
|
298
|
+
type: "markdown",
|
|
299
|
+
content
|
|
300
|
+
}];
|
|
301
|
+
const parts = [];
|
|
302
|
+
const prefix = content.slice(0, unmatched.index);
|
|
303
|
+
const plainSuffix = content.slice(unmatched.index + unmatched.length);
|
|
304
|
+
if (prefix) parts.push({
|
|
305
|
+
type: "markdown",
|
|
306
|
+
content: prefix
|
|
307
|
+
});
|
|
308
|
+
if (plainSuffix) parts.push({
|
|
309
|
+
type: "plain",
|
|
310
|
+
content: plainSuffix
|
|
311
|
+
});
|
|
312
|
+
return parts;
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
200
315
|
//#region src/components/Messages/Messages.tsx
|
|
201
316
|
function getMessageColor(role) {
|
|
202
317
|
switch (role) {
|
|
@@ -206,46 +321,92 @@ function getMessageColor(role) {
|
|
|
206
321
|
default: return;
|
|
207
322
|
}
|
|
208
323
|
}
|
|
324
|
+
var FENCE_LINE_REGEX = /^(?<indent>[ \t]*)(?<fence>`{3,})(?<language>\w+)?[ \t]*$/;
|
|
325
|
+
function flushTextSegment(segments, textLines) {
|
|
326
|
+
const textContent = textLines.join("\n").trim();
|
|
327
|
+
if (textContent) segments.push({
|
|
328
|
+
type: "text",
|
|
329
|
+
content: textContent
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function flushCodeSegment(segments, codeLines, fenceState) {
|
|
333
|
+
if (fenceState.ambiguous) {
|
|
334
|
+
segments.push({
|
|
335
|
+
type: "raw",
|
|
336
|
+
content: fenceState.rawLines.join("\n")
|
|
337
|
+
});
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const codeContent = normalizeCodeBlockContent(codeLines.join("\n"), fenceState.indent);
|
|
341
|
+
if (codeContent) segments.push({
|
|
342
|
+
type: "code",
|
|
343
|
+
content: codeContent,
|
|
344
|
+
language: fenceState.language
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function unwrapRawMarkdownFence(content) {
|
|
348
|
+
if (!content.startsWith("```markdown\n") || !content.endsWith("\n```")) return null;
|
|
349
|
+
return content.slice(12, -4);
|
|
350
|
+
}
|
|
209
351
|
function parseContent(content) {
|
|
210
352
|
const segments = [];
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
353
|
+
const lines = content.split("\n");
|
|
354
|
+
const textLines = [];
|
|
355
|
+
const codeLines = [];
|
|
356
|
+
let fenceState = null;
|
|
357
|
+
for (const line of lines) {
|
|
358
|
+
const fenceMatch = FENCE_LINE_REGEX.exec(line);
|
|
359
|
+
if (fenceMatch?.groups) {
|
|
360
|
+
const { indent, fence, language } = fenceMatch.groups;
|
|
361
|
+
if (!fenceState) {
|
|
362
|
+
flushTextSegment(segments, textLines);
|
|
363
|
+
textLines.length = 0;
|
|
364
|
+
fenceState = {
|
|
365
|
+
indent,
|
|
366
|
+
fence,
|
|
367
|
+
language,
|
|
368
|
+
rawLines: [line],
|
|
369
|
+
ambiguous: false,
|
|
370
|
+
rawFenceDepth: 1
|
|
371
|
+
};
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (indent === fenceState.indent && fence === fenceState.fence) {
|
|
375
|
+
fenceState.rawLines.push(line);
|
|
376
|
+
if (fenceState.ambiguous) {
|
|
377
|
+
if (language) {
|
|
378
|
+
fenceState.rawFenceDepth += 1;
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
fenceState.rawFenceDepth -= 1;
|
|
382
|
+
if (fenceState.rawFenceDepth === 0) {
|
|
383
|
+
flushCodeSegment(segments, codeLines, fenceState);
|
|
384
|
+
codeLines.length = 0;
|
|
385
|
+
fenceState = null;
|
|
386
|
+
}
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
if (!language) {
|
|
390
|
+
flushCodeSegment(segments, codeLines, fenceState);
|
|
391
|
+
codeLines.length = 0;
|
|
392
|
+
fenceState = null;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
fenceState.ambiguous = true;
|
|
396
|
+
fenceState.rawFenceDepth += 1;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
222
399
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
type: "code",
|
|
228
|
-
content: codeContent,
|
|
229
|
-
language
|
|
230
|
-
});
|
|
231
|
-
lastIndex = match.index + match[0].length;
|
|
232
|
-
}
|
|
233
|
-
if (lastIndex < content.length) {
|
|
234
|
-
const textContent = content.slice(lastIndex).trim();
|
|
235
|
-
// v8 ignore next 2 - Defensive check for empty trimmed content
|
|
236
|
-
if (textContent) segments.push({
|
|
237
|
-
type: "text",
|
|
238
|
-
content: textContent
|
|
239
|
-
});
|
|
400
|
+
if (fenceState) {
|
|
401
|
+
fenceState.rawLines.push(line);
|
|
402
|
+
codeLines.push(line);
|
|
403
|
+
} else textLines.push(line);
|
|
240
404
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
type: "text",
|
|
244
|
-
content: content.trim()
|
|
245
|
-
});
|
|
405
|
+
if (fenceState) textLines.push(...fenceState.rawLines);
|
|
406
|
+
flushTextSegment(segments, textLines);
|
|
246
407
|
return segments;
|
|
247
408
|
}
|
|
248
|
-
var Message = memo(function Message({ message }) {
|
|
409
|
+
var Message = memo(function Message({ message, isStreaming = false }) {
|
|
249
410
|
const messageColor = getMessageColor(message.role);
|
|
250
411
|
const isSystem = message.role === SYSTEM;
|
|
251
412
|
const isUser = message.role === USER;
|
|
@@ -275,15 +436,34 @@ var Message = memo(function Message({ message }) {
|
|
|
275
436
|
role: message.role
|
|
276
437
|
})
|
|
277
438
|
}, index);
|
|
439
|
+
if (segment.type === "raw") {
|
|
440
|
+
const markdownSource = unwrapRawMarkdownFence(segment.content);
|
|
441
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
442
|
+
marginX: 2,
|
|
443
|
+
children: /* @__PURE__ */ jsx(CodeBlock, {
|
|
444
|
+
code: markdownSource ?? segment.content,
|
|
445
|
+
language: markdownSource ? "markdown" : segment.language,
|
|
446
|
+
role: message.role
|
|
447
|
+
})
|
|
448
|
+
}, index);
|
|
449
|
+
}
|
|
450
|
+
const textParts = isStreaming && !isUser ? splitStreamingInlineContent(segment.content) : [{
|
|
451
|
+
type: "markdown",
|
|
452
|
+
content: segment.content
|
|
453
|
+
}];
|
|
278
454
|
return isUser ? /* @__PURE__ */ jsx(Text, {
|
|
279
455
|
color: messageColor,
|
|
280
456
|
children: prefix + segment.content
|
|
281
457
|
}, index) : /* @__PURE__ */ jsx(Box, {
|
|
458
|
+
flexDirection: "column",
|
|
282
459
|
marginX: 2,
|
|
283
|
-
children: /* @__PURE__ */ jsx(
|
|
284
|
-
|
|
460
|
+
children: textParts.map((part, partIndex) => part.type === "plain" ? /* @__PURE__ */ jsx(Text, {
|
|
461
|
+
color: messageColor,
|
|
462
|
+
children: part.content
|
|
463
|
+
}, partIndex) : /* @__PURE__ */ jsx(Markdown, {
|
|
464
|
+
content: part.content,
|
|
285
465
|
color: messageColor
|
|
286
|
-
})
|
|
466
|
+
}, partIndex))
|
|
287
467
|
}, index);
|
|
288
468
|
})
|
|
289
469
|
});
|
|
@@ -296,7 +476,10 @@ function Messages({ messages, isLoading, sessionId = 0, streamingMessage }) {
|
|
|
296
476
|
items: messages.filter(({ content }) => content !== TURN_ABORTED_MESSAGE),
|
|
297
477
|
children: (message, index) => /* @__PURE__ */ jsx(Message, { message }, index)
|
|
298
478
|
}, sessionId),
|
|
299
|
-
streamingMessage && /* @__PURE__ */ jsx(Message, {
|
|
479
|
+
streamingMessage && /* @__PURE__ */ jsx(Message, {
|
|
480
|
+
isStreaming: true,
|
|
481
|
+
message: streamingMessage
|
|
482
|
+
}),
|
|
300
483
|
isLoading && !streamingMessage?.content && /* @__PURE__ */ jsx(Box, {
|
|
301
484
|
marginTop: -1,
|
|
302
485
|
marginBottom: 1,
|
|
@@ -308,11 +491,12 @@ function Messages({ messages, isLoading, sessionId = 0, streamingMessage }) {
|
|
|
308
491
|
}
|
|
309
492
|
//#endregion
|
|
310
493
|
//#region src/components/SelectPrompt.tsx
|
|
311
|
-
function SelectPrompt({ children, onCancel, ...selectProps }) {
|
|
494
|
+
function SelectPrompt({ borderStyle, children, onCancel, ...selectProps }) {
|
|
312
495
|
useInput((input, key) => {
|
|
313
496
|
if (key.escape || key.ctrl && input === "c") onCancel?.();
|
|
314
497
|
});
|
|
315
498
|
return /* @__PURE__ */ jsxs(Box, {
|
|
499
|
+
borderStyle,
|
|
316
500
|
flexDirection: "column",
|
|
317
501
|
children: [children, /* @__PURE__ */ jsx(Select, { ...selectProps })]
|
|
318
502
|
});
|
|
@@ -373,29 +557,32 @@ var options$1 = [
|
|
|
373
557
|
}
|
|
374
558
|
];
|
|
375
559
|
function PlanApproval({ planContent, onModeChange }) {
|
|
376
|
-
return /* @__PURE__ */ jsx(
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
children:
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
560
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
561
|
+
marginX: 2,
|
|
562
|
+
children: /* @__PURE__ */ jsx(SelectPrompt, {
|
|
563
|
+
borderStyle: "bold",
|
|
564
|
+
options: options$1,
|
|
565
|
+
onChange: useCallback((value) => {
|
|
566
|
+
onModeChange(value);
|
|
567
|
+
}, [onModeChange]),
|
|
568
|
+
onCancel: useCallback(() => {
|
|
569
|
+
onModeChange(PLAN);
|
|
570
|
+
}, [onModeChange]),
|
|
571
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
572
|
+
flexDirection: "column",
|
|
573
|
+
children: [
|
|
574
|
+
/* @__PURE__ */ jsx(Text, {
|
|
575
|
+
bold: true,
|
|
576
|
+
color: "magenta",
|
|
577
|
+
children: "Plan Generated - Choose execution mode:"
|
|
578
|
+
}),
|
|
579
|
+
/* @__PURE__ */ jsx(Box, {
|
|
580
|
+
marginY: 1,
|
|
581
|
+
children: /* @__PURE__ */ jsx(Text, { children: planContent })
|
|
582
|
+
}),
|
|
583
|
+
/* @__PURE__ */ jsx(SelectPromptHint, { message: "Select execution mode" })
|
|
584
|
+
]
|
|
585
|
+
})
|
|
399
586
|
})
|
|
400
587
|
});
|
|
401
588
|
}
|
|
@@ -416,47 +603,51 @@ function ToolApproval({ toolCall, onDecision }) {
|
|
|
416
603
|
onDecision(REJECT);
|
|
417
604
|
}, [onDecision]);
|
|
418
605
|
const args = JSON.stringify(toolCall.function.arguments, null, 2);
|
|
419
|
-
return /* @__PURE__ */
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
606
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
607
|
+
marginX: 2,
|
|
608
|
+
children: /* @__PURE__ */ jsxs(SelectPrompt, {
|
|
609
|
+
borderStyle: "bold",
|
|
610
|
+
options,
|
|
611
|
+
onChange: handleChange,
|
|
612
|
+
onCancel: handleEscape,
|
|
613
|
+
children: [
|
|
614
|
+
/* @__PURE__ */ jsx(Text, {
|
|
615
|
+
color: "yellow",
|
|
616
|
+
children: "Tool requires approval ⚠️ "
|
|
617
|
+
}),
|
|
618
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
619
|
+
flexDirection: "column",
|
|
620
|
+
marginBottom: 1,
|
|
621
|
+
marginX: 2,
|
|
622
|
+
children: [/* @__PURE__ */ jsxs(Text, { children: [
|
|
623
|
+
/* @__PURE__ */ jsx(Text, {
|
|
624
|
+
dimColor: true,
|
|
625
|
+
children: "Tool:"
|
|
626
|
+
}),
|
|
627
|
+
" ",
|
|
628
|
+
toolCall.function.name
|
|
629
|
+
] }), /* @__PURE__ */ jsxs(Text, { children: [
|
|
630
|
+
/* @__PURE__ */ jsx(Text, {
|
|
631
|
+
dimColor: true,
|
|
632
|
+
children: "Arguments:"
|
|
633
|
+
}),
|
|
634
|
+
" ",
|
|
635
|
+
args
|
|
636
|
+
] })]
|
|
637
|
+
}),
|
|
638
|
+
/* @__PURE__ */ jsx(SelectPromptHint, {
|
|
639
|
+
message: "Select approval action",
|
|
640
|
+
escapeLabel: "reject"
|
|
641
|
+
})
|
|
642
|
+
]
|
|
643
|
+
})
|
|
453
644
|
});
|
|
454
645
|
}
|
|
455
646
|
//#endregion
|
|
456
647
|
//#region src/components/Chat/constants.ts
|
|
457
648
|
var ACTION_NOT_PERFORMED = "The requested action was NOT performed";
|
|
458
649
|
var PLAN_CHECKLIST_REMINDER = "Then display the execution plan as an unchecked Markdown checklist only";
|
|
459
|
-
var PLAN_EXECUTION_REMINDER =
|
|
650
|
+
var PLAN_EXECUTION_REMINDER = `Do not claim success and do not call ${Array.from(WRITE_TOOLS).join(", ")} until the user approves execution`;
|
|
460
651
|
var INTERRUPT_REASON = /* @__PURE__ */ function(INTERRUPT_REASON) {
|
|
461
652
|
INTERRUPT_REASON["INTERRUPTED"] = "interrupted";
|
|
462
653
|
INTERRUPT_REASON["REJECTED"] = "rejected";
|
|
@@ -464,7 +655,39 @@ var INTERRUPT_REASON = /* @__PURE__ */ function(INTERRUPT_REASON) {
|
|
|
464
655
|
}({});
|
|
465
656
|
//#endregion
|
|
466
657
|
//#region src/components/TextInput/TextInput.tsx
|
|
467
|
-
function
|
|
658
|
+
function buildLineSegments(displayValue, cursorPosition, width) {
|
|
659
|
+
const safeWidth = Math.max(1, width);
|
|
660
|
+
const cursorChar = displayValue[cursorPosition] || " ";
|
|
661
|
+
const renderValue = displayValue.slice(0, cursorPosition) + cursorChar + displayValue.slice(cursorPosition + 1);
|
|
662
|
+
const totalLength = Math.max(1, renderValue.length);
|
|
663
|
+
const lines = [];
|
|
664
|
+
for (let start = 0; start < totalLength; start += safeWidth) {
|
|
665
|
+
const end = start + safeWidth;
|
|
666
|
+
const text = renderValue.slice(start, end);
|
|
667
|
+
const hasCursor = cursorPosition >= start && cursorPosition < end;
|
|
668
|
+
if (!hasCursor) {
|
|
669
|
+
lines.push({
|
|
670
|
+
text,
|
|
671
|
+
hasCursor,
|
|
672
|
+
beforeCursor: "",
|
|
673
|
+
cursorChar: " ",
|
|
674
|
+
afterCursor: ""
|
|
675
|
+
});
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
const offset = cursorPosition - start;
|
|
679
|
+
lines.push({
|
|
680
|
+
text,
|
|
681
|
+
hasCursor,
|
|
682
|
+
beforeCursor: text.slice(0, offset),
|
|
683
|
+
cursorChar: text[offset] || " ",
|
|
684
|
+
afterCursor: text.slice(offset + 1)
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
return lines;
|
|
688
|
+
}
|
|
689
|
+
function TextInput({ value, isDisabled = false, placeholder, cursorPosition: externalCursorPosition, wrapIndent = 0, onChange, onSubmit }) {
|
|
690
|
+
const { stdout } = useStdout();
|
|
468
691
|
const [cursorPosition, setCursorPosition] = useState(value.length);
|
|
469
692
|
const prevValueRef = useRef(value);
|
|
470
693
|
const prevExternalCursorRef = useRef(externalCursorPosition);
|
|
@@ -522,6 +745,14 @@ function TextInput({ value, isDisabled = false, placeholder, cursorPosition: ext
|
|
|
522
745
|
setCursorPosition(value.length);
|
|
523
746
|
return;
|
|
524
747
|
}
|
|
748
|
+
if (key.ctrl && input === "a") {
|
|
749
|
+
setCursorPosition(0);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
if (key.ctrl && input === "e") {
|
|
753
|
+
setCursorPosition(value.length);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
525
756
|
// v8 ignore start
|
|
526
757
|
if (input) {
|
|
527
758
|
onChange(value.slice(0, cursorPosition) + input + value.slice(cursorPosition));
|
|
@@ -531,23 +762,31 @@ function TextInput({ value, isDisabled = false, placeholder, cursorPosition: ext
|
|
|
531
762
|
}, { isActive: !isDisabled });
|
|
532
763
|
const displayValue = value || (placeholder ?? "");
|
|
533
764
|
const isPlaceholder = Boolean(!value && placeholder);
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
765
|
+
const availableWidth = Math.max(1, stdout.columns - wrapIndent);
|
|
766
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
767
|
+
flexDirection: "column",
|
|
768
|
+
children: useMemo(() => buildLineSegments(displayValue, cursorPosition, availableWidth), [
|
|
769
|
+
availableWidth,
|
|
770
|
+
cursorPosition,
|
|
771
|
+
displayValue
|
|
772
|
+
]).map((line, index) => /* @__PURE__ */ jsx(Text, { children: line.hasCursor ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
773
|
+
/* @__PURE__ */ jsx(Text, {
|
|
774
|
+
dimColor: isPlaceholder,
|
|
775
|
+
children: line.beforeCursor
|
|
776
|
+
}),
|
|
777
|
+
/* @__PURE__ */ jsx(Text, {
|
|
778
|
+
inverse: true,
|
|
779
|
+
children: line.cursorChar
|
|
780
|
+
}),
|
|
781
|
+
/* @__PURE__ */ jsx(Text, {
|
|
782
|
+
dimColor: isPlaceholder,
|
|
783
|
+
children: line.afterCursor
|
|
784
|
+
})
|
|
785
|
+
] }) : /* @__PURE__ */ jsx(Text, {
|
|
547
786
|
dimColor: isPlaceholder,
|
|
548
|
-
children:
|
|
549
|
-
})
|
|
550
|
-
|
|
787
|
+
children: line.text
|
|
788
|
+
}) }, `${String(index)}-${line.text}`))
|
|
789
|
+
});
|
|
551
790
|
}
|
|
552
791
|
//#endregion
|
|
553
792
|
//#region src/components/Chat/CommandMenu.tsx
|
|
@@ -789,6 +1028,7 @@ function Input({ isDisabled = false, onInterrupt, onSubmit }) {
|
|
|
789
1028
|
value: input,
|
|
790
1029
|
isDisabled,
|
|
791
1030
|
cursorPosition,
|
|
1031
|
+
wrapIndent: 2,
|
|
792
1032
|
onChange: setInput,
|
|
793
1033
|
onSubmit: handleSubmitText,
|
|
794
1034
|
placeholder: "Ask anything... (/ commands, @ files)"
|
|
@@ -1228,7 +1468,7 @@ function Header({ model, onLoad }) {
|
|
|
1228
1468
|
return /* @__PURE__ */ jsx(Static, {
|
|
1229
1469
|
items: [0],
|
|
1230
1470
|
children: (key) => /* @__PURE__ */ jsxs(Box, {
|
|
1231
|
-
borderStyle: "
|
|
1471
|
+
borderStyle: "bold",
|
|
1232
1472
|
flexDirection: "column",
|
|
1233
1473
|
paddingX: 1,
|
|
1234
1474
|
children: [
|
|
@@ -1316,47 +1556,35 @@ function ModelPicker({ currentModel, onSelect, onClose }) {
|
|
|
1316
1556
|
}
|
|
1317
1557
|
//#endregion
|
|
1318
1558
|
//#region src/components/SearchSettings.tsx
|
|
1319
|
-
var View = /* @__PURE__ */ function(View) {
|
|
1320
|
-
View["Menu"] = "menu";
|
|
1321
|
-
View["Edit"] = "edit";
|
|
1322
|
-
return View;
|
|
1323
|
-
}(View || {});
|
|
1324
|
-
var Action = /* @__PURE__ */ function(Action) {
|
|
1325
|
-
Action["Set"] = "set";
|
|
1326
|
-
Action["Clear"] = "clear";
|
|
1327
|
-
Action["Cancel"] = "cancel";
|
|
1328
|
-
return Action;
|
|
1329
|
-
}(Action || {});
|
|
1330
1559
|
function SearchSettings({ currentUrl, onClose, onSave }) {
|
|
1331
|
-
const [view, setView] = useState(
|
|
1560
|
+
const [view, setView] = useState("menu");
|
|
1332
1561
|
const [draftUrl, setDraftUrl] = useState(currentUrl ?? "");
|
|
1333
1562
|
const [error, setError] = useState(null);
|
|
1334
1563
|
const options = useMemo(() => {
|
|
1335
1564
|
const nextOptions = [{
|
|
1336
1565
|
label: currentUrl ? "Update SearXNG URL" : "Set SearXNG URL",
|
|
1337
|
-
value:
|
|
1566
|
+
value: "set"
|
|
1338
1567
|
}];
|
|
1339
1568
|
if (currentUrl) nextOptions.push({
|
|
1340
1569
|
label: "Clear SearXNG URL",
|
|
1341
|
-
value:
|
|
1570
|
+
value: "clear"
|
|
1342
1571
|
});
|
|
1343
1572
|
nextOptions.push({
|
|
1344
1573
|
label: "Cancel",
|
|
1345
|
-
value:
|
|
1574
|
+
value: "cancel"
|
|
1346
1575
|
});
|
|
1347
1576
|
return nextOptions;
|
|
1348
1577
|
}, [currentUrl]);
|
|
1349
1578
|
const handleChange = useCallback((value) => {
|
|
1350
1579
|
setError(null);
|
|
1351
1580
|
switch (value) {
|
|
1352
|
-
case
|
|
1581
|
+
case "set":
|
|
1353
1582
|
setDraftUrl(currentUrl ?? "");
|
|
1354
|
-
setView(
|
|
1583
|
+
setView("edit");
|
|
1355
1584
|
break;
|
|
1356
|
-
case
|
|
1585
|
+
case "clear":
|
|
1357
1586
|
onSave({ searxngBaseUrl: void 0 });
|
|
1358
1587
|
break;
|
|
1359
|
-
case Action.Cancel:
|
|
1360
1588
|
default: onClose();
|
|
1361
1589
|
}
|
|
1362
1590
|
}, [
|
|
@@ -1382,18 +1610,19 @@ function SearchSettings({ currentUrl, onClose, onSave }) {
|
|
|
1382
1610
|
}
|
|
1383
1611
|
}, [onSave]);
|
|
1384
1612
|
useInput((input, key) => {
|
|
1385
|
-
if (view ===
|
|
1613
|
+
if (view === "edit" && (key.escape || key.ctrl && input === "c")) {
|
|
1386
1614
|
setDraftUrl(currentUrl ?? "");
|
|
1387
1615
|
setError(null);
|
|
1388
|
-
setView(
|
|
1616
|
+
setView("menu");
|
|
1389
1617
|
}
|
|
1390
1618
|
});
|
|
1391
|
-
if (view ===
|
|
1619
|
+
if (view === "edit") return /* @__PURE__ */ jsxs(Box, {
|
|
1392
1620
|
flexDirection: "column",
|
|
1393
1621
|
children: [
|
|
1394
1622
|
/* @__PURE__ */ jsx(Text, { children: "Set the SearXNG base URL. DuckDuckGo remains the fallback." }),
|
|
1395
1623
|
/* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(Text, { children: "> " }), /* @__PURE__ */ jsx(TextInput, {
|
|
1396
1624
|
value: draftUrl,
|
|
1625
|
+
wrapIndent: 2,
|
|
1397
1626
|
onChange: setDraftUrl,
|
|
1398
1627
|
onSubmit: handleSubmit,
|
|
1399
1628
|
placeholder: "http://localhost:8080"
|
|
@@ -1424,11 +1653,6 @@ function SearchSettings({ currentUrl, onClose, onSave }) {
|
|
|
1424
1653
|
}
|
|
1425
1654
|
//#endregion
|
|
1426
1655
|
//#region src/components/SessionManager.tsx
|
|
1427
|
-
var VIEW = /* @__PURE__ */ function(VIEW) {
|
|
1428
|
-
VIEW["MAIN"] = "main";
|
|
1429
|
-
VIEW["DELETE"] = "delete";
|
|
1430
|
-
return VIEW;
|
|
1431
|
-
}(VIEW || {});
|
|
1432
1656
|
var ACTION = {
|
|
1433
1657
|
BACK: "back",
|
|
1434
1658
|
CLOSE: "close",
|
|
@@ -1442,11 +1666,11 @@ function formatSessionLabel(session) {
|
|
|
1442
1666
|
return `${session.title} (${timestamp})`;
|
|
1443
1667
|
}
|
|
1444
1668
|
function SessionManager({ currentSessionId, onClose, onDelete, onNew, onOpen }) {
|
|
1445
|
-
const [view, setView] = useState(
|
|
1669
|
+
const [view, setView] = useState("main");
|
|
1446
1670
|
const [error, setError] = useState();
|
|
1447
1671
|
const [, refreshSessionList] = useState(0);
|
|
1448
1672
|
const sessions = listSessions();
|
|
1449
|
-
const options = view ===
|
|
1673
|
+
const options = view === "delete" ? [...sessions.filter(({ id }) => id !== currentSessionId).map((session) => ({
|
|
1450
1674
|
label: `Delete ${formatSessionLabel(session)}`,
|
|
1451
1675
|
value: `${ACTION.DELETE_PREFIX}${session.id}`
|
|
1452
1676
|
})), {
|
|
@@ -1479,10 +1703,10 @@ function SessionManager({ currentSessionId, onClose, onDelete, onNew, onOpen })
|
|
|
1479
1703
|
onNew();
|
|
1480
1704
|
break;
|
|
1481
1705
|
case value === ACTION.DELETE_MENU:
|
|
1482
|
-
setView(
|
|
1706
|
+
setView("delete");
|
|
1483
1707
|
break;
|
|
1484
1708
|
case value === ACTION.BACK:
|
|
1485
|
-
setView(
|
|
1709
|
+
setView("main");
|
|
1486
1710
|
break;
|
|
1487
1711
|
case value.startsWith(ACTION.DELETE_PREFIX):
|
|
1488
1712
|
try {
|
|
@@ -1512,7 +1736,7 @@ function SessionManager({ currentSessionId, onClose, onDelete, onNew, onOpen })
|
|
|
1512
1736
|
flexDirection: "column",
|
|
1513
1737
|
children: [
|
|
1514
1738
|
/* @__PURE__ */ jsx(Text, { children: "Sessions" }),
|
|
1515
|
-
/* @__PURE__ */ jsx(SelectPromptHint, { message: view ===
|
|
1739
|
+
/* @__PURE__ */ jsx(SelectPromptHint, { message: view === "delete" ? "Delete session" : "Select session" }),
|
|
1516
1740
|
error && /* @__PURE__ */ jsx(Box, {
|
|
1517
1741
|
marginBottom: 1,
|
|
1518
1742
|
children: /* @__PURE__ */ jsx(Text, {
|
|
@@ -1530,20 +1754,13 @@ function SessionManager({ currentSessionId, onClose, onDelete, onNew, onOpen })
|
|
|
1530
1754
|
}
|
|
1531
1755
|
//#endregion
|
|
1532
1756
|
//#region src/components/App.tsx
|
|
1533
|
-
var SCREEN = /* @__PURE__ */ function(SCREEN) {
|
|
1534
|
-
SCREEN["CHAT"] = "chat";
|
|
1535
|
-
SCREEN["MODEL_PICKER"] = "model-picker";
|
|
1536
|
-
SCREEN["SEARCH_SETTINGS"] = "search-settings";
|
|
1537
|
-
SCREEN["SESSION_MANAGER"] = "session-manager";
|
|
1538
|
-
return SCREEN;
|
|
1539
|
-
}(SCREEN || {});
|
|
1540
1757
|
function createSession(sessionId, model) {
|
|
1541
1758
|
return sessionId ? loadSession(sessionId) : createSession$1(model);
|
|
1542
1759
|
}
|
|
1543
1760
|
function App({ sessionId }) {
|
|
1544
1761
|
const { exit } = useApp();
|
|
1545
1762
|
const [appConfig, setConfig] = useState(() => loadConfig());
|
|
1546
|
-
const [currentScreen, setScreen] = useState(
|
|
1763
|
+
const [currentScreen, setScreen] = useState("chat");
|
|
1547
1764
|
const [mode, setMode] = useState(SAFE);
|
|
1548
1765
|
const [activeSession, setSession] = useState(() => createSession(sessionId, loadConfig().model));
|
|
1549
1766
|
const [isHeaderLoaded, setIsHeaderLoaded] = useState(false);
|
|
@@ -1569,17 +1786,17 @@ function App({ sessionId }) {
|
|
|
1569
1786
|
const handleCreateSession = useCallback(() => {
|
|
1570
1787
|
const nextSession = createSession$1(appConfig.model);
|
|
1571
1788
|
setActiveSession(nextSession);
|
|
1572
|
-
setScreen(
|
|
1789
|
+
setScreen("chat");
|
|
1573
1790
|
clear(nextSession.metadata.id);
|
|
1574
1791
|
return nextSession;
|
|
1575
1792
|
}, [appConfig.model, setActiveSession]);
|
|
1576
1793
|
const handleOpenSession = useCallback((sessionId) => {
|
|
1577
1794
|
if (sessionRef.current.metadata.id === sessionId) {
|
|
1578
|
-
setScreen(
|
|
1795
|
+
setScreen("chat");
|
|
1579
1796
|
return;
|
|
1580
1797
|
}
|
|
1581
1798
|
setActiveSession(loadSession(sessionId));
|
|
1582
|
-
setScreen(
|
|
1799
|
+
setScreen("chat");
|
|
1583
1800
|
clear(sessionId);
|
|
1584
1801
|
}, [setActiveSession]);
|
|
1585
1802
|
const handleDeleteSession = useCallback((sessionId) => {
|
|
@@ -1588,7 +1805,7 @@ function App({ sessionId }) {
|
|
|
1588
1805
|
if (current.metadata.id !== sessionId) return current;
|
|
1589
1806
|
return createSession$1(appConfig.model);
|
|
1590
1807
|
});
|
|
1591
|
-
setScreen(
|
|
1808
|
+
setScreen("session-manager");
|
|
1592
1809
|
}, [appConfig.model]);
|
|
1593
1810
|
const handleMessagesChange = useCallback((messages) => {
|
|
1594
1811
|
setSession((current) => {
|
|
@@ -1605,17 +1822,17 @@ function App({ sessionId }) {
|
|
|
1605
1822
|
const handleCommand = useCallback((command) => {
|
|
1606
1823
|
switch (command) {
|
|
1607
1824
|
case "/session":
|
|
1608
|
-
setScreen(
|
|
1825
|
+
setScreen("session-manager");
|
|
1609
1826
|
break;
|
|
1610
1827
|
case "/model":
|
|
1611
|
-
setScreen(
|
|
1828
|
+
setScreen("model-picker");
|
|
1612
1829
|
break;
|
|
1613
1830
|
case "/search":
|
|
1614
|
-
setScreen(
|
|
1831
|
+
setScreen("search-settings");
|
|
1615
1832
|
break;
|
|
1616
1833
|
case "/clear": {
|
|
1617
1834
|
resetSystemMessage();
|
|
1618
|
-
setScreen(
|
|
1835
|
+
setScreen("chat");
|
|
1619
1836
|
const nextSession = createSession$1(appConfig.model);
|
|
1620
1837
|
setActiveSession(nextSession);
|
|
1621
1838
|
clear(nextSession.metadata.id);
|
|
@@ -1641,10 +1858,10 @@ function App({ sessionId }) {
|
|
|
1641
1858
|
...current,
|
|
1642
1859
|
metadata: updateSessionModel(current.metadata.id, newModel)
|
|
1643
1860
|
}));
|
|
1644
|
-
setScreen(
|
|
1861
|
+
setScreen("chat");
|
|
1645
1862
|
}, []);
|
|
1646
1863
|
const handleClose = useCallback(() => {
|
|
1647
|
-
setScreen(
|
|
1864
|
+
setScreen("chat");
|
|
1648
1865
|
}, []);
|
|
1649
1866
|
const handleToggleMode = useCallback(() => {
|
|
1650
1867
|
setMode((mode) => {
|
|
@@ -1658,21 +1875,21 @@ function App({ sessionId }) {
|
|
|
1658
1875
|
}, []);
|
|
1659
1876
|
let screenContent;
|
|
1660
1877
|
switch (currentScreen) {
|
|
1661
|
-
case
|
|
1878
|
+
case "model-picker":
|
|
1662
1879
|
screenContent = /* @__PURE__ */ jsx(ModelPicker, {
|
|
1663
1880
|
currentModel: appConfig.model,
|
|
1664
1881
|
onSelect: handleUpdateConfig,
|
|
1665
1882
|
onClose: handleClose
|
|
1666
1883
|
});
|
|
1667
1884
|
break;
|
|
1668
|
-
case
|
|
1885
|
+
case "search-settings":
|
|
1669
1886
|
screenContent = /* @__PURE__ */ jsx(SearchSettings, {
|
|
1670
1887
|
currentUrl: appConfig.searxngBaseUrl,
|
|
1671
1888
|
onSave: handleUpdateConfig,
|
|
1672
1889
|
onClose: handleClose
|
|
1673
1890
|
});
|
|
1674
1891
|
break;
|
|
1675
|
-
case
|
|
1892
|
+
case "session-manager":
|
|
1676
1893
|
screenContent = /* @__PURE__ */ jsx(SessionManager, {
|
|
1677
1894
|
currentSessionId: activeSession.metadata.id,
|
|
1678
1895
|
onClose: handleClose,
|
|
@@ -1681,7 +1898,7 @@ function App({ sessionId }) {
|
|
|
1681
1898
|
onOpen: handleOpenSession
|
|
1682
1899
|
});
|
|
1683
1900
|
break;
|
|
1684
|
-
case
|
|
1901
|
+
case "chat":
|
|
1685
1902
|
screenContent = /* @__PURE__ */ jsx(Chat, {
|
|
1686
1903
|
initialMessages: activeSession.messages,
|
|
1687
1904
|
model: appConfig.model,
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as runShell } from "./assets/shell-CipXM_WI.js";
|
|
3
2
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
4
3
|
import cac from "cac";
|
|
5
4
|
import { homedir } from "node:os";
|
|
6
5
|
import { join } from "node:path";
|
|
7
6
|
import { Ollama } from "ollama";
|
|
8
7
|
import { v7 } from "uuid";
|
|
8
|
+
import { exec } from "node:child_process";
|
|
9
|
+
import { promisify } from "node:util";
|
|
10
|
+
//#region \0rolldown/runtime.js
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __exportAll = (all, no_symbols) => {
|
|
13
|
+
let target = {};
|
|
14
|
+
for (var name in all) __defProp(target, name, {
|
|
15
|
+
get: all[name],
|
|
16
|
+
enumerable: true
|
|
17
|
+
});
|
|
18
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
9
22
|
//#region src/constants/command.ts
|
|
10
23
|
var LIST = [
|
|
11
24
|
{
|
|
@@ -32,7 +45,7 @@ var LIST = [
|
|
|
32
45
|
//#endregion
|
|
33
46
|
//#region package.json
|
|
34
47
|
var name = "code-ollama";
|
|
35
|
-
var version = "0.14.
|
|
48
|
+
var version = "0.14.2";
|
|
36
49
|
//#endregion
|
|
37
50
|
//#region src/constants/package.ts
|
|
38
51
|
var NAME = name;
|
|
@@ -603,7 +616,7 @@ function listDir(dirPath) {
|
|
|
603
616
|
* Search for pattern in files using ripgrep if available, fallback to Node.js
|
|
604
617
|
*/
|
|
605
618
|
async function grepSearch(pattern, dirPath) {
|
|
606
|
-
const { execShell } = await
|
|
619
|
+
const { execShell } = await Promise.resolve().then(() => shell_exports);
|
|
607
620
|
try {
|
|
608
621
|
const { stdout } = await execShell(`rg --line-number --no-heading --smart-case "${pattern.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}" "${dirPath.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`);
|
|
609
622
|
// v8 ignore next
|
|
@@ -642,6 +655,37 @@ async function grepSearch(pattern, dirPath) {
|
|
|
642
655
|
}
|
|
643
656
|
}
|
|
644
657
|
//#endregion
|
|
658
|
+
//#region src/utils/tools/shell.ts
|
|
659
|
+
var shell_exports = /* @__PURE__ */ __exportAll({
|
|
660
|
+
execShell: () => execShell,
|
|
661
|
+
runShell: () => runShell
|
|
662
|
+
});
|
|
663
|
+
var execAsync = promisify(exec);
|
|
664
|
+
var SHELL_EXEC_OPTIONS = {
|
|
665
|
+
timeout: 3e4,
|
|
666
|
+
maxBuffer: 1024 * 1024
|
|
667
|
+
};
|
|
668
|
+
/**
|
|
669
|
+
* Execute shell command with shared options (throws on error)
|
|
670
|
+
*/
|
|
671
|
+
function execShell(command) {
|
|
672
|
+
return execAsync(command, SHELL_EXEC_OPTIONS);
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Execute shell command
|
|
676
|
+
*/
|
|
677
|
+
async function runShell(command) {
|
|
678
|
+
try {
|
|
679
|
+
const { stdout, stderr } = await execShell(command);
|
|
680
|
+
return { content: stdout || stderr };
|
|
681
|
+
} catch (error) {
|
|
682
|
+
return {
|
|
683
|
+
content: "",
|
|
684
|
+
error: `Command failed: ${error instanceof Error ? error.message : String(error)}`
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
//#endregion
|
|
645
689
|
//#region src/utils/tools/web/fetch.ts
|
|
646
690
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
647
691
|
var BASE_HEADERS = { "user-agent": `${NAME}/${VERSION}` };
|
|
@@ -904,7 +948,7 @@ async function main(args = process.argv.slice(2)) {
|
|
|
904
948
|
else await launchTui();
|
|
905
949
|
}
|
|
906
950
|
async function launchTui(sessionId) {
|
|
907
|
-
const { renderApp } = await import("./assets/tui-
|
|
951
|
+
const { renderApp } = await import("./assets/tui-Dse5XVJ_.js");
|
|
908
952
|
reset();
|
|
909
953
|
renderApp(sessionId);
|
|
910
954
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-ollama",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
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",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@inkjs/ui": "2.0.0",
|
|
43
43
|
"@shikijs/cli": "4.0.2",
|
|
44
44
|
"cac": "7.0.0",
|
|
45
|
-
"ink": "7.0.
|
|
45
|
+
"ink": "7.0.3",
|
|
46
46
|
"marked": "15.0.12",
|
|
47
47
|
"marked-terminal": "7.3.0",
|
|
48
48
|
"ollama": "0.6.3",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@commitlint/config-conventional": "21.0.1",
|
|
55
55
|
"@eslint/config-helpers": "0.6.0",
|
|
56
56
|
"@eslint/js": "10.0.1",
|
|
57
|
-
"@types/node": "25.
|
|
57
|
+
"@types/node": "25.8.0",
|
|
58
58
|
"@types/react": "19.2.14",
|
|
59
59
|
"@vitest/coverage-v8": "4.1.6",
|
|
60
60
|
"eslint": "10.3.0",
|
|
@@ -66,10 +66,10 @@
|
|
|
66
66
|
"lint-staged": "17.0.4",
|
|
67
67
|
"prettier": "3.8.3",
|
|
68
68
|
"publint": "0.3.21",
|
|
69
|
-
"tsx": "4.
|
|
69
|
+
"tsx": "4.22.0",
|
|
70
70
|
"typescript": "6.0.3",
|
|
71
71
|
"typescript-eslint": "8.59.3",
|
|
72
|
-
"vite": "8.0.
|
|
72
|
+
"vite": "8.0.13",
|
|
73
73
|
"vitest": "4.1.6"
|
|
74
74
|
},
|
|
75
75
|
"files": [
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { exec } from "node:child_process";
|
|
2
|
-
import { promisify } from "node:util";
|
|
3
|
-
//#region \0rolldown/runtime.js
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __exportAll = (all, no_symbols) => {
|
|
6
|
-
let target = {};
|
|
7
|
-
for (var name in all) __defProp(target, name, {
|
|
8
|
-
get: all[name],
|
|
9
|
-
enumerable: true
|
|
10
|
-
});
|
|
11
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
12
|
-
return target;
|
|
13
|
-
};
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region src/utils/tools/shell.ts
|
|
16
|
-
var shell_exports = /* @__PURE__ */ __exportAll({
|
|
17
|
-
execShell: () => execShell,
|
|
18
|
-
runShell: () => runShell
|
|
19
|
-
});
|
|
20
|
-
var execAsync = promisify(exec);
|
|
21
|
-
var SHELL_EXEC_OPTIONS = {
|
|
22
|
-
timeout: 3e4,
|
|
23
|
-
maxBuffer: 1024 * 1024
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Execute shell command with shared options (throws on error)
|
|
27
|
-
*/
|
|
28
|
-
function execShell(command) {
|
|
29
|
-
return execAsync(command, SHELL_EXEC_OPTIONS);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Execute shell command
|
|
33
|
-
*/
|
|
34
|
-
async function runShell(command) {
|
|
35
|
-
try {
|
|
36
|
-
const { stdout, stderr } = await execShell(command);
|
|
37
|
-
return { content: stdout || stderr };
|
|
38
|
-
} catch (error) {
|
|
39
|
-
return {
|
|
40
|
-
content: "",
|
|
41
|
-
error: `Command failed: ${error instanceof Error ? error.message : String(error)}`
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
//#endregion
|
|
46
|
-
export { shell_exports as n, runShell as t };
|