darkfoo-code 0.4.2 → 0.4.3

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.
Files changed (2) hide show
  1. package/dist/main.js +255 -234
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2069,7 +2069,7 @@ function App({ model, systemPromptOverride, maxTurns, initialMessages, initialSe
2069
2069
 
2070
2070
  // src/repl.tsx
2071
2071
  import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useMemo } from "react";
2072
- import { Box as Box7, Text as Text7, useApp, useInput as useInput2 } from "ink";
2072
+ import { Box as Box6, Text as Text6, Static, useApp, useInput as useInput2 } from "ink";
2073
2073
  import { nanoid as nanoid6 } from "nanoid";
2074
2074
 
2075
2075
  // src/components/Banner.tsx
@@ -2077,7 +2077,7 @@ init_theme();
2077
2077
  import { memo } from "react";
2078
2078
  import { Box, Text } from "ink";
2079
2079
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
2080
- var version = "0.4.2";
2080
+ var version = "0.4.3";
2081
2081
  var LOGO_LINES = [
2082
2082
  " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
2083
2083
  " \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557",
@@ -2162,115 +2162,13 @@ var Banner = memo(function Banner2({ model, cwd, providerName, providerOnline, m
2162
2162
  ] });
2163
2163
  });
2164
2164
 
2165
- // src/components/Messages.tsx
2165
+ // src/components/StreamingDisplay.tsx
2166
2166
  init_theme();
2167
- init_format();
2168
- import { memo as memo2 } from "react";
2167
+ import { useState, useRef, useEffect, useImperativeHandle, forwardRef, memo as memo2 } from "react";
2169
2168
  import { Box as Box2, Text as Text2 } from "ink";
2170
-
2171
- // src/utils/markdown.ts
2172
- function renderMarkdown(text) {
2173
- const lines = text.split("\n");
2174
- const result = [];
2175
- let inCodeBlock = false;
2176
- let codeBlockLang = "";
2177
- for (const line of lines) {
2178
- if (line.trimStart().startsWith("```")) {
2179
- if (!inCodeBlock) {
2180
- codeBlockLang = line.trimStart().slice(3).trim();
2181
- const label = codeBlockLang ? ` ${codeBlockLang}` : "";
2182
- result.push(`\x1B[2m\x1B[38;2;94;234;212m\u2500\u2500\u2500 code${label} \u2500\u2500\u2500\x1B[0m`);
2183
- inCodeBlock = true;
2184
- } else {
2185
- result.push(`\x1B[2m\x1B[38;2;94;234;212m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m`);
2186
- inCodeBlock = false;
2187
- codeBlockLang = "";
2188
- }
2189
- continue;
2190
- }
2191
- if (inCodeBlock) {
2192
- result.push(`\x1B[38;2;251;191;36m ${line}\x1B[0m`);
2193
- continue;
2194
- }
2195
- const headerMatch = line.match(/^(#{1,6})\s+(.+)/);
2196
- if (headerMatch) {
2197
- const level = headerMatch[1].length;
2198
- const text2 = headerMatch[2];
2199
- if (level <= 2) {
2200
- result.push(`\x1B[1m\x1B[38;2;94;234;212m${text2}\x1B[0m`);
2201
- } else {
2202
- result.push(`\x1B[1m${text2}\x1B[0m`);
2203
- }
2204
- continue;
2205
- }
2206
- const listMatch = line.match(/^(\s*)[*-]\s+(.+)/);
2207
- if (listMatch) {
2208
- const indent = listMatch[1] || "";
2209
- const content = renderInline(listMatch[2]);
2210
- result.push(`${indent}\x1B[38;2;94;234;212m\u2022\x1B[0m ${content}`);
2211
- continue;
2212
- }
2213
- const orderedMatch = line.match(/^(\s*)\d+\.\s+(.+)/);
2214
- if (orderedMatch) {
2215
- const indent = orderedMatch[1] || "";
2216
- const content = renderInline(orderedMatch[2]);
2217
- result.push(`${indent}${content}`);
2218
- continue;
2219
- }
2220
- if (/^---+$|^\*\*\*+$|^___+$/.test(line.trim())) {
2221
- result.push(`\x1B[2m${"\u2500".repeat(40)}\x1B[0m`);
2222
- continue;
2223
- }
2224
- result.push(renderInline(line));
2225
- }
2226
- return result.join("\n");
2227
- }
2228
- function renderInline(text) {
2229
- return text.replace(/`([^`]+)`/g, "\x1B[38;2;251;191;36m$1\x1B[0m").replace(/\*\*\*(.+?)\*\*\*/g, "\x1B[1m\x1B[3m$1\x1B[0m").replace(/\*\*(.+?)\*\*/g, "\x1B[1m$1\x1B[0m").replace(/\*(.+?)\*/g, "\x1B[3m$1\x1B[0m").replace(/\[([^\]]+)\]\(([^)]+)\)/g, "\x1B[4m\x1B[38;2;94;234;212m$1\x1B[0m");
2230
- }
2231
-
2232
- // src/components/Messages.tsx
2233
2169
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
2234
- var Messages = memo2(function Messages2({ messages }) {
2235
- return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", children: messages.map((msg) => /* @__PURE__ */ jsx3(MessageRow, { message: msg }, msg.id)) });
2236
- });
2237
- var MessageRow = memo2(function MessageRow2({ message }) {
2238
- switch (message.role) {
2239
- case "user":
2240
- return /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, marginBottom: 1, children: [
2241
- /* @__PURE__ */ jsx3(Text2, { color: theme.cyan, bold: true, children: "\u276F " }),
2242
- /* @__PURE__ */ jsx3(Text2, { bold: true, color: theme.text, children: message.content })
2243
- ] });
2244
- case "assistant": {
2245
- if (!message.content && message.toolCalls) return null;
2246
- if (!message.content) return null;
2247
- const rendered = renderMarkdown(message.content);
2248
- return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs2(Box2, { children: [
2249
- /* @__PURE__ */ jsx3(Text2, { color: theme.cyan, children: "\u23BF " }),
2250
- /* @__PURE__ */ jsx3(Text2, { wrap: "wrap", children: rendered })
2251
- ] }) });
2252
- }
2253
- case "tool": {
2254
- const lines = message.content.split("\n");
2255
- const preview = lines.length > 8 ? lines.slice(0, 8).join("\n") + `
2256
- ... (${lines.length - 8} more lines)` : message.content;
2257
- return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsxs2(Text2, { color: theme.dim, children: [
2258
- "\u23BF ",
2259
- truncate(preview, 1200)
2260
- ] }) });
2261
- }
2262
- default:
2263
- return null;
2264
- }
2265
- });
2266
-
2267
- // src/components/StreamingDisplay.tsx
2268
- init_theme();
2269
- import { useState, useRef, useEffect, useImperativeHandle, forwardRef, memo as memo3 } from "react";
2270
- import { Box as Box3, Text as Text3 } from "ink";
2271
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2272
2170
  var FLUSH_INTERVAL_MS = 150;
2273
- var StreamingDisplay = memo3(forwardRef(function StreamingDisplay2(_, ref) {
2171
+ var StreamingDisplay = memo2(forwardRef(function StreamingDisplay2(_, ref) {
2274
2172
  const bufferRef = useRef("");
2275
2173
  const [displayText, setDisplayText] = useState("");
2276
2174
  const timerRef = useRef(null);
@@ -2309,46 +2207,46 @@ var StreamingDisplay = memo3(forwardRef(function StreamingDisplay2(_, ref) {
2309
2207
  return () => stopTimer();
2310
2208
  }, []);
2311
2209
  if (!displayText) return null;
2312
- return /* @__PURE__ */ jsxs3(Box3, { marginBottom: 1, children: [
2313
- /* @__PURE__ */ jsx4(Text3, { color: theme.cyan, children: "\u23BF " }),
2314
- /* @__PURE__ */ jsx4(Text3, { color: theme.text, wrap: "wrap", children: displayText })
2210
+ return /* @__PURE__ */ jsxs2(Box2, { marginBottom: 1, children: [
2211
+ /* @__PURE__ */ jsx3(Text2, { color: theme.cyan, children: "\u23BF " }),
2212
+ /* @__PURE__ */ jsx3(Text2, { color: theme.text, wrap: "wrap", children: displayText })
2315
2213
  ] });
2316
2214
  }));
2317
2215
 
2318
2216
  // src/components/ToolCall.tsx
2319
2217
  init_theme();
2320
2218
  init_format();
2321
- import { memo as memo4 } from "react";
2322
- import { Box as Box4, Text as Text4 } from "ink";
2323
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2324
- var ActiveToolCall = memo4(function ActiveToolCall2({ toolName, args }) {
2325
- return /* @__PURE__ */ jsxs4(Box4, { marginLeft: 2, children: [
2326
- /* @__PURE__ */ jsx5(Text4, { color: theme.cyan, children: "..." }),
2327
- /* @__PURE__ */ jsxs4(Text4, { bold: true, color: theme.yellow, children: [
2219
+ import { memo as memo3 } from "react";
2220
+ import { Box as Box3, Text as Text3 } from "ink";
2221
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2222
+ var ActiveToolCall = memo3(function ActiveToolCall2({ toolName, args }) {
2223
+ return /* @__PURE__ */ jsxs3(Box3, { marginLeft: 2, children: [
2224
+ /* @__PURE__ */ jsx4(Text3, { color: theme.cyan, children: "..." }),
2225
+ /* @__PURE__ */ jsxs3(Text3, { bold: true, color: theme.yellow, children: [
2328
2226
  " ",
2329
2227
  toolName
2330
2228
  ] }),
2331
- args ? /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
2229
+ args ? /* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
2332
2230
  " ",
2333
2231
  formatToolArgs(args)
2334
2232
  ] }) : null
2335
2233
  ] });
2336
2234
  });
2337
- var ToolResultDisplay = memo4(function ToolResultDisplay2({ toolName, output, isError }) {
2235
+ var ToolResultDisplay = memo3(function ToolResultDisplay2({ toolName, output, isError }) {
2338
2236
  const icon = isError ? "\u2718" : "\u2714";
2339
2237
  const iconColor = isError ? theme.pink : theme.green;
2340
2238
  const lines = output.split("\n");
2341
2239
  const preview = lines.length > 6 ? lines.slice(0, 6).join("\n") + `
2342
2240
  ... (${lines.length - 6} more lines)` : output;
2343
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [
2344
- /* @__PURE__ */ jsxs4(Box4, { children: [
2345
- /* @__PURE__ */ jsxs4(Text4, { color: iconColor, children: [
2241
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [
2242
+ /* @__PURE__ */ jsxs3(Box3, { children: [
2243
+ /* @__PURE__ */ jsxs3(Text3, { color: iconColor, children: [
2346
2244
  icon,
2347
2245
  " "
2348
2246
  ] }),
2349
- /* @__PURE__ */ jsx5(Text4, { bold: true, color: theme.yellow, children: toolName })
2247
+ /* @__PURE__ */ jsx4(Text3, { bold: true, color: theme.yellow, children: toolName })
2350
2248
  ] }),
2351
- /* @__PURE__ */ jsx5(Box4, { marginLeft: 2, children: /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
2249
+ /* @__PURE__ */ jsx4(Box3, { marginLeft: 2, children: /* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
2352
2250
  "\u23BF ",
2353
2251
  truncate(preview, 1200)
2354
2252
  ] }) })
@@ -2369,9 +2267,9 @@ function formatToolArgs(args) {
2369
2267
  // src/components/StatusLine.tsx
2370
2268
  init_theme();
2371
2269
  init_state();
2372
- import { memo as memo5 } from "react";
2373
- import { Box as Box5, Text as Text5 } from "ink";
2374
- import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2270
+ import { memo as memo4 } from "react";
2271
+ import { Box as Box4, Text as Text4 } from "ink";
2272
+ import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2375
2273
  function getContextLimit(model) {
2376
2274
  const lower = model.toLowerCase();
2377
2275
  if (lower.includes("llama3.1")) return 131072;
@@ -2382,47 +2280,47 @@ function getContextLimit(model) {
2382
2280
  if (lower.includes("deepseek")) return 32768;
2383
2281
  return 8192;
2384
2282
  }
2385
- var StatusLine = memo5(function StatusLine2({ model, messageCount, tokenEstimate, isStreaming }) {
2283
+ var StatusLine = memo4(function StatusLine2({ model, messageCount, tokenEstimate, isStreaming }) {
2386
2284
  const state2 = getAppState();
2387
2285
  const contextLimit = getContextLimit(model);
2388
2286
  const usage = Math.min(tokenEstimate / contextLimit, 1);
2389
2287
  const pct = (usage * 100).toFixed(0);
2390
2288
  const usageColor = usage > 0.8 ? theme.pink : usage > 0.5 ? theme.yellow : theme.cyan;
2391
2289
  const activeTasks = state2.tasks.filter((t) => t.status === "in_progress").length;
2392
- return /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, children: [
2393
- /* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
2290
+ return /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, children: [
2291
+ /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
2394
2292
  "\u2500".repeat(2),
2395
2293
  " "
2396
2294
  ] }),
2397
- /* @__PURE__ */ jsx6(Text5, { color: theme.cyan, bold: true, children: model ? model.split(":")[0] : "--" }),
2398
- /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
2399
- /* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
2295
+ /* @__PURE__ */ jsx5(Text4, { color: theme.cyan, bold: true, children: model ? model.split(":")[0] : "--" }),
2296
+ /* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
2297
+ /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
2400
2298
  messageCount,
2401
2299
  " msgs"
2402
2300
  ] }),
2403
- /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
2404
- /* @__PURE__ */ jsxs5(Text5, { color: usageColor, children: [
2301
+ /* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
2302
+ /* @__PURE__ */ jsxs4(Text4, { color: usageColor, children: [
2405
2303
  "ctx ",
2406
2304
  pct,
2407
2305
  "%"
2408
2306
  ] }),
2409
- state2.planMode ? /* @__PURE__ */ jsxs5(Fragment, { children: [
2410
- /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
2411
- /* @__PURE__ */ jsx6(Text5, { color: theme.yellow, bold: true, children: "PLAN" })
2307
+ state2.planMode ? /* @__PURE__ */ jsxs4(Fragment, { children: [
2308
+ /* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
2309
+ /* @__PURE__ */ jsx5(Text4, { color: theme.yellow, bold: true, children: "PLAN" })
2412
2310
  ] }) : null,
2413
- activeTasks > 0 ? /* @__PURE__ */ jsxs5(Fragment, { children: [
2414
- /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
2415
- /* @__PURE__ */ jsxs5(Text5, { color: theme.green, children: [
2311
+ activeTasks > 0 ? /* @__PURE__ */ jsxs4(Fragment, { children: [
2312
+ /* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
2313
+ /* @__PURE__ */ jsxs4(Text4, { color: theme.green, children: [
2416
2314
  activeTasks,
2417
2315
  " task",
2418
2316
  activeTasks > 1 ? "s" : ""
2419
2317
  ] })
2420
2318
  ] }) : null,
2421
- isStreaming ? /* @__PURE__ */ jsxs5(Fragment, { children: [
2422
- /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
2423
- /* @__PURE__ */ jsx6(Text5, { color: theme.cyan, children: "streaming" })
2319
+ isStreaming ? /* @__PURE__ */ jsxs4(Fragment, { children: [
2320
+ /* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
2321
+ /* @__PURE__ */ jsx5(Text4, { color: theme.cyan, children: "streaming" })
2424
2322
  ] }) : null,
2425
- /* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
2323
+ /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
2426
2324
  " ",
2427
2325
  "\u2500".repeat(2)
2428
2326
  ] })
@@ -2431,8 +2329,8 @@ var StatusLine = memo5(function StatusLine2({ model, messageCount, tokenEstimate
2431
2329
 
2432
2330
  // src/components/UserInput.tsx
2433
2331
  init_theme();
2434
- import { useState as useState2, useCallback, memo as memo6 } from "react";
2435
- import { Box as Box6, Text as Text6, useInput } from "ink";
2332
+ import { useState as useState2, useCallback, memo as memo5 } from "react";
2333
+ import { Box as Box5, Text as Text5, useInput } from "ink";
2436
2334
  import TextInput from "ink-text-input";
2437
2335
 
2438
2336
  // src/commands/help.ts
@@ -3468,8 +3366,8 @@ function getCommandNames() {
3468
3366
  }
3469
3367
 
3470
3368
  // src/components/UserInput.tsx
3471
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
3472
- var UserInput = memo6(function UserInput2({ value, onChange, onSubmit, disabled, history }) {
3369
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
3370
+ var UserInput = memo5(function UserInput2({ value, onChange, onSubmit, disabled, history }) {
3473
3371
  const [historyIdx, setHistoryIdx] = useState2(-1);
3474
3372
  const [suggestion, setSuggestion] = useState2("");
3475
3373
  useInput((_input, key) => {
@@ -3517,20 +3415,20 @@ var UserInput = memo6(function UserInput2({ value, onChange, onSubmit, disabled,
3517
3415
  const borderColor = disabled ? theme.dim : isBash ? theme.yellow : isCommand ? theme.purple : theme.cyan;
3518
3416
  const promptChar = isBash ? "!" : "\u276F";
3519
3417
  const promptColor = isBash ? theme.yellow : theme.cyan;
3520
- return /* @__PURE__ */ jsxs6(
3521
- Box6,
3418
+ return /* @__PURE__ */ jsxs5(
3419
+ Box5,
3522
3420
  {
3523
3421
  borderStyle: "round",
3524
3422
  borderColor,
3525
3423
  paddingLeft: 1,
3526
3424
  paddingRight: 1,
3527
3425
  children: [
3528
- /* @__PURE__ */ jsxs6(Text6, { color: disabled ? theme.dim : promptColor, bold: true, children: [
3426
+ /* @__PURE__ */ jsxs5(Text5, { color: disabled ? theme.dim : promptColor, bold: true, children: [
3529
3427
  promptChar,
3530
3428
  " "
3531
3429
  ] }),
3532
- disabled ? /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: "..." }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
3533
- /* @__PURE__ */ jsx7(
3430
+ disabled ? /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: "..." }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
3431
+ /* @__PURE__ */ jsx6(
3534
3432
  TextInput,
3535
3433
  {
3536
3434
  value,
@@ -3544,7 +3442,7 @@ var UserInput = memo6(function UserInput2({ value, onChange, onSubmit, disabled,
3544
3442
  }
3545
3443
  }
3546
3444
  ),
3547
- suggestion ? /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: suggestion }) : null
3445
+ suggestion ? /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: suggestion }) : null
3548
3446
  ] })
3549
3447
  ]
3550
3448
  }
@@ -3560,7 +3458,71 @@ init_tools();
3560
3458
  init_bash();
3561
3459
  init_hooks();
3562
3460
  init_theme();
3563
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3461
+
3462
+ // src/utils/markdown.ts
3463
+ function renderMarkdown(text) {
3464
+ const lines = text.split("\n");
3465
+ const result = [];
3466
+ let inCodeBlock = false;
3467
+ let codeBlockLang = "";
3468
+ for (const line of lines) {
3469
+ if (line.trimStart().startsWith("```")) {
3470
+ if (!inCodeBlock) {
3471
+ codeBlockLang = line.trimStart().slice(3).trim();
3472
+ const label = codeBlockLang ? ` ${codeBlockLang}` : "";
3473
+ result.push(`\x1B[2m\x1B[38;2;94;234;212m\u2500\u2500\u2500 code${label} \u2500\u2500\u2500\x1B[0m`);
3474
+ inCodeBlock = true;
3475
+ } else {
3476
+ result.push(`\x1B[2m\x1B[38;2;94;234;212m\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\x1B[0m`);
3477
+ inCodeBlock = false;
3478
+ codeBlockLang = "";
3479
+ }
3480
+ continue;
3481
+ }
3482
+ if (inCodeBlock) {
3483
+ result.push(`\x1B[38;2;251;191;36m ${line}\x1B[0m`);
3484
+ continue;
3485
+ }
3486
+ const headerMatch = line.match(/^(#{1,6})\s+(.+)/);
3487
+ if (headerMatch) {
3488
+ const level = headerMatch[1].length;
3489
+ const text2 = headerMatch[2];
3490
+ if (level <= 2) {
3491
+ result.push(`\x1B[1m\x1B[38;2;94;234;212m${text2}\x1B[0m`);
3492
+ } else {
3493
+ result.push(`\x1B[1m${text2}\x1B[0m`);
3494
+ }
3495
+ continue;
3496
+ }
3497
+ const listMatch = line.match(/^(\s*)[*-]\s+(.+)/);
3498
+ if (listMatch) {
3499
+ const indent = listMatch[1] || "";
3500
+ const content = renderInline(listMatch[2]);
3501
+ result.push(`${indent}\x1B[38;2;94;234;212m\u2022\x1B[0m ${content}`);
3502
+ continue;
3503
+ }
3504
+ const orderedMatch = line.match(/^(\s*)\d+\.\s+(.+)/);
3505
+ if (orderedMatch) {
3506
+ const indent = orderedMatch[1] || "";
3507
+ const content = renderInline(orderedMatch[2]);
3508
+ result.push(`${indent}${content}`);
3509
+ continue;
3510
+ }
3511
+ if (/^---+$|^\*\*\*+$|^___+$/.test(line.trim())) {
3512
+ result.push(`\x1B[2m${"\u2500".repeat(40)}\x1B[0m`);
3513
+ continue;
3514
+ }
3515
+ result.push(renderInline(line));
3516
+ }
3517
+ return result.join("\n");
3518
+ }
3519
+ function renderInline(text) {
3520
+ return text.replace(/`([^`]+)`/g, "\x1B[38;2;251;191;36m$1\x1B[0m").replace(/\*\*\*(.+?)\*\*\*/g, "\x1B[1m\x1B[3m$1\x1B[0m").replace(/\*\*(.+?)\*\*/g, "\x1B[1m$1\x1B[0m").replace(/\*(.+?)\*/g, "\x1B[3m$1\x1B[0m").replace(/\[([^\]]+)\]\(([^)]+)\)/g, "\x1B[4m\x1B[38;2;94;234;212m$1\x1B[0m");
3521
+ }
3522
+
3523
+ // src/repl.tsx
3524
+ init_format();
3525
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
3564
3526
  function getContextLimit3(model) {
3565
3527
  const lower = model.toLowerCase();
3566
3528
  if (lower.includes("llama3.1")) return 131072;
@@ -3571,6 +3533,57 @@ function getContextLimit3(model) {
3571
3533
  if (lower.includes("deepseek")) return 32768;
3572
3534
  return 8192;
3573
3535
  }
3536
+ function FrozenItemView({ item }) {
3537
+ switch (item.kind) {
3538
+ case "banner":
3539
+ return /* @__PURE__ */ jsx7(Banner, { model: item.model, cwd: item.cwd, providerName: item.providerName, providerOnline: item.providerOnline });
3540
+ case "user":
3541
+ return /* @__PURE__ */ jsxs6(Box6, { marginTop: 1, marginBottom: 1, children: [
3542
+ /* @__PURE__ */ jsx7(Text6, { color: theme.cyan, bold: true, children: "\u276F " }),
3543
+ /* @__PURE__ */ jsx7(Text6, { bold: true, color: theme.text, children: item.content })
3544
+ ] });
3545
+ case "assistant": {
3546
+ if (!item.content) return null;
3547
+ return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs6(Box6, { children: [
3548
+ /* @__PURE__ */ jsx7(Text6, { color: theme.cyan, children: "\u23BF " }),
3549
+ /* @__PURE__ */ jsx7(Text6, { wrap: "wrap", children: renderMarkdown(item.content) })
3550
+ ] }) });
3551
+ }
3552
+ case "tool": {
3553
+ const lines = item.content.split("\n");
3554
+ const preview = lines.length > 8 ? lines.slice(0, 8).join("\n") + `
3555
+ ... (${lines.length - 8} more lines)` : item.content;
3556
+ return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsxs6(Text6, { color: theme.dim, children: [
3557
+ "\u23BF ",
3558
+ truncate(preview, 1200)
3559
+ ] }) });
3560
+ }
3561
+ case "tool-result": {
3562
+ const icon = item.isError ? "\u2718" : "\u2714";
3563
+ const iconColor = item.isError ? theme.pink : theme.green;
3564
+ const lines = item.output.split("\n");
3565
+ const preview = lines.length > 6 ? lines.slice(0, 6).join("\n") + `
3566
+ ... (${lines.length - 6} more lines)` : item.output;
3567
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [
3568
+ /* @__PURE__ */ jsxs6(Box6, { children: [
3569
+ /* @__PURE__ */ jsxs6(Text6, { color: iconColor, children: [
3570
+ icon,
3571
+ " "
3572
+ ] }),
3573
+ /* @__PURE__ */ jsx7(Text6, { bold: true, color: theme.yellow, children: item.toolName })
3574
+ ] }),
3575
+ /* @__PURE__ */ jsx7(Box6, { marginLeft: 2, children: /* @__PURE__ */ jsxs6(Text6, { color: theme.dim, children: [
3576
+ "\u23BF ",
3577
+ truncate(preview, 1200)
3578
+ ] }) })
3579
+ ] });
3580
+ }
3581
+ case "info":
3582
+ return /* @__PURE__ */ jsx7(Box6, { marginBottom: 1, marginLeft: 2, children: /* @__PURE__ */ jsx7(Text6, { children: item.text }) });
3583
+ default:
3584
+ return null;
3585
+ }
3586
+ }
3574
3587
  function REPL({ initialPrompt }) {
3575
3588
  const { model: initialModel, systemPromptOverride, maxTurns, initialMessages, initialSessionId } = useDarkfooContext();
3576
3589
  const { exit } = useApp();
@@ -3580,16 +3593,16 @@ function REPL({ initialPrompt }) {
3580
3593
  const [isStreaming, setIsStreaming] = useState3(false);
3581
3594
  const [receivedText, setReceivedText] = useState3(false);
3582
3595
  const [activeTool, setActiveTool] = useState3(null);
3583
- const [toolResults, setToolResults] = useState3([]);
3584
3596
  const [commandOutput, setCommandOutput] = useState3(null);
3585
3597
  const [inputHistory, setInputHistory] = useState3([]);
3586
3598
  const [tokenCounts, setTokenCounts] = useState3({ input: 0, output: 0 });
3587
3599
  const [systemPrompt, setSystemPrompt] = useState3("");
3588
- const [mascotMood, setMascotMood] = useState3("idle");
3589
3600
  const [providerOnline, setProviderOnline] = useState3(true);
3590
3601
  const abortRef = useRef2(null);
3591
3602
  const hasRun = useRef2(false);
3592
3603
  const sessionId = useRef2(initialSessionId ?? createSessionId());
3604
+ const [frozen, setFrozen] = useState3([]);
3605
+ const frozenBanner = useRef2(false);
3593
3606
  const streamingRef = useRef2(null);
3594
3607
  const messagesRef = useRef2(messages);
3595
3608
  messagesRef.current = messages;
@@ -3600,6 +3613,9 @@ function REPL({ initialPrompt }) {
3600
3613
  const tools = getTools();
3601
3614
  const cwd = process.cwd();
3602
3615
  const providerName = useMemo(() => getActiveProviderName(), [model, providerOnline]);
3616
+ const freeze = useCallback2((item) => {
3617
+ setFrozen((prev) => [...prev, item]);
3618
+ }, []);
3603
3619
  useEffect2(() => {
3604
3620
  if (systemPromptOverride) {
3605
3621
  setSystemPrompt(systemPromptOverride);
@@ -3617,30 +3633,46 @@ function REPL({ initialPrompt }) {
3617
3633
  setProviderOnline(ok);
3618
3634
  if (!ok) {
3619
3635
  setModel("");
3636
+ if (!frozenBanner.current) {
3637
+ frozenBanner.current = true;
3638
+ freeze({ id: "banner", kind: "banner", model: "", cwd, providerName: getActiveProviderName(), providerOnline: false });
3639
+ }
3620
3640
  return;
3621
3641
  }
3622
- provider.listModels().then((models) => {
3623
- if (models.length === 0) {
3624
- setModel("");
3625
- return;
3642
+ provider.listModels().then((resolvedModels) => {
3643
+ let resolved = "";
3644
+ if (resolvedModels.length > 0) {
3645
+ const requested = model.toLowerCase();
3646
+ const match = resolvedModels.find((m) => m.name.toLowerCase() === requested);
3647
+ if (match) {
3648
+ resolved = match.name;
3649
+ } else {
3650
+ const preferred = resolvedModels.find((m) => m.name.includes("llama3.1")) ?? resolvedModels.find((m) => m.name.includes("qwen")) ?? resolvedModels.find((m) => m.name.includes("instruct")) ?? resolvedModels[0];
3651
+ if (preferred) {
3652
+ resolved = preferred.name;
3653
+ freeze({ id: nanoid6(), kind: "info", text: `Model "${model}" not found. Using ${preferred.name} instead.` });
3654
+ }
3655
+ }
3626
3656
  }
3627
- const requested = model.toLowerCase();
3628
- const match = models.find((m) => m.name.toLowerCase() === requested);
3629
- if (match) {
3630
- setModel(match.name);
3631
- return;
3657
+ setModel(resolved);
3658
+ if (!frozenBanner.current) {
3659
+ frozenBanner.current = true;
3660
+ freeze({ id: "banner", kind: "banner", model: resolved, cwd, providerName: getActiveProviderName(), providerOnline: true });
3632
3661
  }
3633
- const preferred = models.find((m) => m.name.includes("llama3.1")) ?? models.find((m) => m.name.includes("qwen")) ?? models.find((m) => m.name.includes("instruct")) ?? models[0];
3634
- if (preferred) {
3635
- setModel(preferred.name);
3636
- setCommandOutput(`Model "${model}" not found. Using ${preferred.name} instead.`);
3637
- } else {
3638
- setModel("");
3662
+ }).catch(() => {
3663
+ setModel("");
3664
+ if (!frozenBanner.current) {
3665
+ frozenBanner.current = true;
3666
+ freeze({ id: "banner", kind: "banner", model: "", cwd, providerName: getActiveProviderName(), providerOnline: false });
3639
3667
  }
3640
- }).catch(() => setModel(""));
3668
+ });
3641
3669
  }).catch(() => {
3642
3670
  setProviderOnline(false);
3643
3671
  setModel("");
3672
+ if (!frozenBanner.current) {
3673
+ frozenBanner.current = true;
3674
+ freeze({ id: "banner", kind: "banner", model: "", cwd, providerName: getActiveProviderName(), providerOnline: false });
3675
+ }
3644
3676
  });
3645
3677
  }, []);
3646
3678
  const clearMessages = useCallback2(() => setMessages([]), []);
@@ -3670,12 +3702,12 @@ function REPL({ initialPrompt }) {
3670
3702
  content: userMessage,
3671
3703
  timestamp: Date.now()
3672
3704
  };
3705
+ freeze({ id: userMsg.id, kind: "user", content: userMessage });
3673
3706
  setMessages((prev) => [...prev, userMsg]);
3674
3707
  setIsStreaming(true);
3675
3708
  setReceivedText(false);
3676
- setToolResults([]);
3709
+ setActiveTool(null);
3677
3710
  setCommandOutput(null);
3678
- setMascotMood("thinking");
3679
3711
  streamingRef.current?.clear();
3680
3712
  const controller = new AbortController();
3681
3713
  abortRef.current = controller;
@@ -3699,20 +3731,14 @@ function REPL({ initialPrompt }) {
3699
3731
  if (!gotFirstText) {
3700
3732
  gotFirstText = true;
3701
3733
  setReceivedText(true);
3702
- setMascotMood("idle");
3703
3734
  }
3704
3735
  break;
3705
3736
  case "tool_call":
3706
3737
  setActiveTool({ name: event.toolCall.function.name, args: event.toolCall.function.arguments });
3707
- setMascotMood("working");
3708
3738
  break;
3709
3739
  case "tool_result":
3710
3740
  setActiveTool(null);
3711
- setMascotMood(event.isError ? "error" : "working");
3712
- setToolResults((prev) => [
3713
- ...prev,
3714
- { id: nanoid6(), toolName: event.toolName, output: event.output, isError: event.isError }
3715
- ]);
3741
+ freeze({ id: nanoid6(), kind: "tool-result", toolName: event.toolName, output: event.output, isError: event.isError });
3716
3742
  break;
3717
3743
  case "usage":
3718
3744
  setTokenCounts((prev) => ({
@@ -3724,6 +3750,9 @@ function REPL({ initialPrompt }) {
3724
3750
  streamingRef.current?.clear();
3725
3751
  setReceivedText(false);
3726
3752
  gotFirstText = false;
3753
+ if (event.message.content) {
3754
+ freeze({ id: event.message.id, kind: "assistant", content: event.message.content });
3755
+ }
3727
3756
  setMessages((prev) => {
3728
3757
  const updated = [...prev, event.message];
3729
3758
  saveSession(sessionId.current, updated, currentModel, cwd).catch(() => {
@@ -3733,7 +3762,7 @@ function REPL({ initialPrompt }) {
3733
3762
  break;
3734
3763
  case "error":
3735
3764
  streamingRef.current?.clear();
3736
- setMascotMood("error");
3765
+ freeze({ id: nanoid6(), kind: "assistant", content: `Error: ${event.error}` });
3737
3766
  setMessages((prev) => [
3738
3767
  ...prev,
3739
3768
  { id: nanoid6(), role: "assistant", content: `Error: ${event.error}`, timestamp: Date.now() }
@@ -3744,6 +3773,7 @@ function REPL({ initialPrompt }) {
3744
3773
  } catch (err) {
3745
3774
  if (err.name !== "AbortError") {
3746
3775
  const msg = err instanceof Error ? err.message : String(err);
3776
+ freeze({ id: nanoid6(), kind: "assistant", content: `Error: ${msg}` });
3747
3777
  setMessages((prev) => [
3748
3778
  ...prev,
3749
3779
  { id: nanoid6(), role: "assistant", content: `Error: ${msg}`, timestamp: Date.now() }
@@ -3754,13 +3784,10 @@ function REPL({ initialPrompt }) {
3754
3784
  setIsStreaming(false);
3755
3785
  setReceivedText(false);
3756
3786
  setActiveTool(null);
3757
- setToolResults([]);
3758
- setMascotMood((prev) => prev === "error" ? "error" : "success");
3759
- setTimeout(() => setMascotMood("idle"), 2e3);
3760
3787
  abortRef.current = null;
3761
3788
  }
3762
3789
  },
3763
- [tools, cwd]
3790
+ [tools, cwd, freeze]
3764
3791
  );
3765
3792
  const handleSubmit = useCallback2(
3766
3793
  async (value) => {
@@ -3778,17 +3805,13 @@ function REPL({ initialPrompt }) {
3778
3805
  if (result.replaceMessages) {
3779
3806
  setMessages(result.replaceMessages);
3780
3807
  }
3781
- if (result.foxMood) {
3782
- setMascotMood(result.foxMood);
3783
- setTimeout(() => setMascotMood("idle"), 3e3);
3784
- }
3785
3808
  if (result.exit) return;
3786
3809
  if (!result.silent && result.output) {
3787
3810
  runQuery(result.output);
3788
3811
  return;
3789
3812
  }
3790
3813
  if (result.output) {
3791
- setCommandOutput(result.output);
3814
+ freeze({ id: nanoid6(), kind: "info", text: result.output });
3792
3815
  }
3793
3816
  }
3794
3817
  return;
@@ -3797,16 +3820,15 @@ function REPL({ initialPrompt }) {
3797
3820
  const cmd = value.slice(1).trim();
3798
3821
  if (!cmd) return;
3799
3822
  setIsStreaming(true);
3800
- setCommandOutput(null);
3801
3823
  try {
3802
3824
  const result = await BashTool.call(
3803
3825
  { command: cmd },
3804
3826
  { cwd, abortSignal: new AbortController().signal }
3805
3827
  );
3806
- setCommandOutput(result.output);
3828
+ freeze({ id: nanoid6(), kind: "info", text: result.output });
3807
3829
  } catch (err) {
3808
3830
  const msg = err instanceof Error ? err.message : String(err);
3809
- setCommandOutput(`Error: ${msg}`);
3831
+ freeze({ id: nanoid6(), kind: "info", text: `Error: ${msg}` });
3810
3832
  } finally {
3811
3833
  setIsStreaming(false);
3812
3834
  }
@@ -3814,7 +3836,7 @@ function REPL({ initialPrompt }) {
3814
3836
  }
3815
3837
  runQuery(value);
3816
3838
  },
3817
- [addToHistory, exit, cwd, runQuery]
3839
+ [addToHistory, exit, cwd, runQuery, freeze]
3818
3840
  );
3819
3841
  useEffect2(() => {
3820
3842
  if (initialPrompt && !hasRun.current) {
@@ -3831,7 +3853,7 @@ function REPL({ initialPrompt }) {
3831
3853
  const usage = estTokens / limit;
3832
3854
  if (usage > 0.85) {
3833
3855
  autoCompactRef.current = true;
3834
- setCommandOutput("\x1B[33m[!] Context 85%+ full \u2014 auto-compacting...\x1B[0m");
3856
+ freeze({ id: nanoid6(), kind: "info", text: "\x1B[33m[!] Context 85%+ full \u2014 auto-compacting...\x1B[0m" });
3835
3857
  const transcript = messages.filter((m) => m.role === "user" || m.role === "assistant" && m.content).map((m) => `${m.role}: ${m.content}`).join("\n\n");
3836
3858
  getProvider().chat({
3837
3859
  model,
@@ -3849,10 +3871,10 @@ ${result.content}
3849
3871
  };
3850
3872
  setMessages([summaryMsg]);
3851
3873
  setTokenCounts({ input: Math.ceil(result.content.length / 4), output: 0 });
3852
- setCommandOutput("\x1B[32m[ok] Auto-compacted conversation.\x1B[0m");
3874
+ freeze({ id: nanoid6(), kind: "info", text: "\x1B[32m[ok] Auto-compacted conversation.\x1B[0m" });
3853
3875
  autoCompactRef.current = false;
3854
3876
  }).catch(() => {
3855
- setCommandOutput("\x1B[31m[err] Auto-compact failed.\x1B[0m");
3877
+ freeze({ id: nanoid6(), kind: "info", text: "\x1B[31m[err] Auto-compact failed.\x1B[0m" });
3856
3878
  autoCompactRef.current = false;
3857
3879
  });
3858
3880
  }
@@ -3866,44 +3888,43 @@ ${result.content}
3866
3888
  }
3867
3889
  }
3868
3890
  });
3869
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", padding: 1, children: [
3870
- /* @__PURE__ */ jsx8(Banner, { model, cwd, providerName, providerOnline, mood: mascotMood }),
3871
- /* @__PURE__ */ jsx8(Messages, { messages }),
3872
- commandOutput ? /* @__PURE__ */ jsx8(Box7, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx8(Text7, { children: commandOutput }) }) : null,
3873
- toolResults.map((tr) => /* @__PURE__ */ jsx8(ToolResultDisplay, { toolName: tr.toolName, output: tr.output, isError: tr.isError }, tr.id)),
3874
- activeTool ? /* @__PURE__ */ jsx8(ActiveToolCall, { toolName: activeTool.name, args: activeTool.args }) : null,
3875
- /* @__PURE__ */ jsx8(StreamingDisplay, { ref: streamingRef }),
3876
- isStreaming && !receivedText && !activeTool ? /* @__PURE__ */ jsxs7(Box7, { marginLeft: 2, children: [
3877
- /* @__PURE__ */ jsx8(Text7, { color: theme.cyan, children: "..." }),
3878
- /* @__PURE__ */ jsx8(Text7, { color: theme.dim, children: " Thinking" })
3879
- ] }) : null,
3880
- /* @__PURE__ */ jsx8(
3881
- UserInput,
3882
- {
3883
- value: inputValue,
3884
- onChange: setInputValue,
3885
- onSubmit: handleSubmit,
3886
- disabled: isStreaming,
3887
- history: inputHistory
3888
- }
3889
- ),
3890
- /* @__PURE__ */ jsx8(
3891
- StatusLine,
3892
- {
3893
- model,
3894
- messageCount: messages.length,
3895
- tokenEstimate: tokenCounts.input + tokenCounts.output,
3896
- isStreaming
3897
- }
3898
- )
3891
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
3892
+ /* @__PURE__ */ jsx7(Static, { items: frozen, children: (item) => /* @__PURE__ */ jsx7(FrozenItemView, { item }, item.id) }),
3893
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [
3894
+ activeTool ? /* @__PURE__ */ jsx7(ActiveToolCall, { toolName: activeTool.name, args: activeTool.args }) : null,
3895
+ /* @__PURE__ */ jsx7(StreamingDisplay, { ref: streamingRef }),
3896
+ isStreaming && !receivedText && !activeTool ? /* @__PURE__ */ jsxs6(Box6, { marginLeft: 2, children: [
3897
+ /* @__PURE__ */ jsx7(Text6, { color: theme.cyan, children: "..." }),
3898
+ /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: " Thinking" })
3899
+ ] }) : null,
3900
+ /* @__PURE__ */ jsx7(
3901
+ UserInput,
3902
+ {
3903
+ value: inputValue,
3904
+ onChange: setInputValue,
3905
+ onSubmit: handleSubmit,
3906
+ disabled: isStreaming,
3907
+ history: inputHistory
3908
+ }
3909
+ ),
3910
+ /* @__PURE__ */ jsx7(
3911
+ StatusLine,
3912
+ {
3913
+ model,
3914
+ messageCount: messages.length,
3915
+ tokenEstimate: tokenCounts.input + tokenCounts.output,
3916
+ isStreaming
3917
+ }
3918
+ )
3919
+ ] })
3899
3920
  ] });
3900
3921
  }
3901
3922
 
3902
3923
  // src/main.tsx
3903
3924
  init_providers();
3904
- import { jsx as jsx9 } from "react/jsx-runtime";
3925
+ import { jsx as jsx8 } from "react/jsx-runtime";
3905
3926
  var program = new Command();
3906
- program.name("darkfoo").description("Darkfoo Code \u2014 local AI coding assistant powered by local LLM providers").version("0.4.2").option("-m, --model <model>", "Model to use", "llama3.1:8b").option("-p, --prompt <prompt>", "Run a single prompt (non-interactive)").option("-c, --continue", "Resume the most recent session").option("--resume <id>", "Resume a specific session by ID").option("--max-turns <n>", "Maximum tool-use turns per query", "30").option("--debug", "Enable debug logging to stderr").option("--output-format <format>", "Output format for non-interactive mode (text, json)").option("--provider <name>", "LLM provider backend (ollama, llama-cpp, vllm, tgi, etc.)").option("--system-prompt <prompt>", "Override the system prompt").action(async (options) => {
3927
+ program.name("darkfoo").description("Darkfoo Code \u2014 local AI coding assistant powered by local LLM providers").version("0.4.3").option("-m, --model <model>", "Model to use", "llama3.1:8b").option("-p, --prompt <prompt>", "Run a single prompt (non-interactive)").option("-c, --continue", "Resume the most recent session").option("--resume <id>", "Resume a specific session by ID").option("--max-turns <n>", "Maximum tool-use turns per query", "30").option("--debug", "Enable debug logging to stderr").option("--output-format <format>", "Output format for non-interactive mode (text, json)").option("--provider <name>", "LLM provider backend (ollama, llama-cpp, vllm, tgi, etc.)").option("--system-prompt <prompt>", "Override the system prompt").action(async (options) => {
3907
3928
  const { model, prompt, provider, systemPrompt } = options;
3908
3929
  if (options.debug) {
3909
3930
  const { setDebugMode: setDebugMode2 } = await Promise.resolve().then(() => (init_debug(), debug_exports));
@@ -4038,7 +4059,7 @@ Error: ${event.error}
4038
4059
  }
4039
4060
  }
4040
4061
  const { waitUntilExit } = render(
4041
- /* @__PURE__ */ jsx9(
4062
+ /* @__PURE__ */ jsx8(
4042
4063
  App,
4043
4064
  {
4044
4065
  model: resolvedModel,
@@ -4046,7 +4067,7 @@ Error: ${event.error}
4046
4067
  maxTurns,
4047
4068
  initialMessages,
4048
4069
  initialSessionId,
4049
- children: /* @__PURE__ */ jsx9(REPL, {})
4070
+ children: /* @__PURE__ */ jsx8(REPL, {})
4050
4071
  }
4051
4072
  )
4052
4073
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "darkfoo-code",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Darkfoo Code — local AI coding assistant powered by Ollama, vLLM, llama.cpp, and other LLM providers",
5
5
  "type": "module",
6
6
  "license": "MIT",