darkfoo-code 0.3.0 → 0.4.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/main.js +191 -138
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -18,18 +18,30 @@ var init_theme = __esm({
|
|
|
18
18
|
"src/utils/theme.ts"() {
|
|
19
19
|
"use strict";
|
|
20
20
|
theme = {
|
|
21
|
-
cyan: "#
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
cyan: "#3b82f6",
|
|
22
|
+
// bright blue (primary)
|
|
23
|
+
cyanDim: "#2563eb",
|
|
24
|
+
// deeper blue
|
|
25
|
+
pink: "#ea580c",
|
|
26
|
+
// burnt orange (accent)
|
|
27
|
+
pinkDim: "#c2410c",
|
|
28
|
+
// deep burnt orange
|
|
29
|
+
purple: "#7c6ddb",
|
|
30
|
+
// blue-violet (midpoint)
|
|
26
31
|
green: "#4ade80",
|
|
27
|
-
|
|
32
|
+
// success green
|
|
33
|
+
yellow: "#f59e0b",
|
|
34
|
+
// warm amber
|
|
28
35
|
red: "#ef4444",
|
|
36
|
+
// errors
|
|
29
37
|
text: "#e2e8f0",
|
|
38
|
+
// body text
|
|
30
39
|
dim: "#7e8ea6",
|
|
40
|
+
// secondary
|
|
31
41
|
surface: "#111827",
|
|
42
|
+
// component backgrounds
|
|
32
43
|
bg: "#0c1021"
|
|
44
|
+
// terminal background
|
|
33
45
|
};
|
|
34
46
|
}
|
|
35
47
|
});
|
|
@@ -2056,37 +2068,16 @@ function App({ model, systemPromptOverride, maxTurns, initialMessages, initialSe
|
|
|
2056
2068
|
}
|
|
2057
2069
|
|
|
2058
2070
|
// src/repl.tsx
|
|
2059
|
-
import { useState as useState2, useCallback as useCallback2, useEffect, useRef } from "react";
|
|
2060
|
-
import { Box as
|
|
2071
|
+
import { useState as useState2, useCallback as useCallback2, useEffect, useRef, useMemo } from "react";
|
|
2072
|
+
import { Box as Box6, Text as Text6, useApp, useInput as useInput2 } from "ink";
|
|
2061
2073
|
import { nanoid as nanoid6 } from "nanoid";
|
|
2062
2074
|
|
|
2063
2075
|
// src/components/Banner.tsx
|
|
2064
2076
|
init_theme();
|
|
2065
|
-
import { memo as memo2 } from "react";
|
|
2066
|
-
import { Box as Box2, Text as Text2 } from "ink";
|
|
2067
|
-
|
|
2068
|
-
// src/components/Mascot.tsx
|
|
2069
2077
|
import { memo } from "react";
|
|
2070
2078
|
import { Box, Text } from "ink";
|
|
2071
2079
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
2072
|
-
var
|
|
2073
|
-
idle: "#5eead4",
|
|
2074
|
-
thinking: "#a78bfa",
|
|
2075
|
-
working: "#fbbf24",
|
|
2076
|
-
success: "#4ade80",
|
|
2077
|
-
error: "#f472b6"
|
|
2078
|
-
};
|
|
2079
|
-
var Mascot = memo(function Mascot2({ mood = "idle" }) {
|
|
2080
|
-
const color = MOOD_COLORS[mood];
|
|
2081
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "center", children: [
|
|
2082
|
-
/* @__PURE__ */ jsx2(Text, { color, children: " \u259F\u2588\u2588\u2599" }),
|
|
2083
|
-
/* @__PURE__ */ jsx2(Text, { color, children: " \u2590\u2588\u2588\u2588\u2588\u258C" }),
|
|
2084
|
-
/* @__PURE__ */ jsx2(Text, { color, children: " \u259C\u2588\u2588\u259B" })
|
|
2085
|
-
] });
|
|
2086
|
-
});
|
|
2087
|
-
|
|
2088
|
-
// src/components/Banner.tsx
|
|
2089
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2080
|
+
var version = "0.4.1";
|
|
2090
2081
|
var LOGO_LINES = [
|
|
2091
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 ",
|
|
2092
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",
|
|
@@ -2097,14 +2088,21 @@ var LOGO_LINES = [
|
|
|
2097
2088
|
];
|
|
2098
2089
|
var SUBTITLE = " -- C O D E --";
|
|
2099
2090
|
var GRADIENT = [
|
|
2100
|
-
"#
|
|
2101
|
-
"#
|
|
2102
|
-
"#
|
|
2103
|
-
"#
|
|
2104
|
-
"#
|
|
2105
|
-
"#
|
|
2106
|
-
"#
|
|
2091
|
+
"#3b82f6",
|
|
2092
|
+
"#5a72e0",
|
|
2093
|
+
"#7c6ddb",
|
|
2094
|
+
"#9a5ec0",
|
|
2095
|
+
"#b8509a",
|
|
2096
|
+
"#d46030",
|
|
2097
|
+
"#ea580c"
|
|
2107
2098
|
];
|
|
2099
|
+
var MOOD_COLORS = {
|
|
2100
|
+
idle: "#3b82f6",
|
|
2101
|
+
thinking: "#7c6ddb",
|
|
2102
|
+
working: "#f59e0b",
|
|
2103
|
+
success: "#4ade80",
|
|
2104
|
+
error: "#ea580c"
|
|
2105
|
+
};
|
|
2108
2106
|
function lineColor(index) {
|
|
2109
2107
|
const t = index / (LOGO_LINES.length - 1);
|
|
2110
2108
|
return GRADIENT[Math.round(t * (GRADIENT.length - 1))];
|
|
@@ -2115,37 +2113,51 @@ function gradientBar(width) {
|
|
|
2115
2113
|
color: GRADIENT[Math.round(i / (width - 1) * (GRADIENT.length - 1))]
|
|
2116
2114
|
}));
|
|
2117
2115
|
}
|
|
2118
|
-
var Banner =
|
|
2116
|
+
var Banner = memo(function Banner2({ model, cwd, providerName, providerOnline, mood = "idle" }) {
|
|
2119
2117
|
const bar = gradientBar(60);
|
|
2120
2118
|
const statusTag = providerOnline ? "[connected]" : "[offline]";
|
|
2121
2119
|
const statusColor = providerOnline ? theme.green ?? "#4ade80" : theme.pink ?? "#f472b6";
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
/* @__PURE__ */
|
|
2120
|
+
const mascotColor = MOOD_COLORS[mood] ?? MOOD_COLORS.idle;
|
|
2121
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
2122
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
2123
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2124
|
+
LOGO_LINES.map((line, i) => /* @__PURE__ */ jsx2(Text, { color: lineColor(i), bold: true, children: line }, i)),
|
|
2125
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.purple ?? "#a78bfa", bold: true, children: SUBTITLE }),
|
|
2126
|
+
/* @__PURE__ */ jsxs(Text, { color: theme.dim ?? "#7e8ea6", children: [
|
|
2127
|
+
" v",
|
|
2128
|
+
version
|
|
2129
|
+
] })
|
|
2130
|
+
] }),
|
|
2131
|
+
/* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", justifyContent: "flex-end", children: [
|
|
2132
|
+
/* @__PURE__ */ jsx2(Text, { color: mascotColor, children: " \u2584\u2588\u2588\u2584" }),
|
|
2133
|
+
/* @__PURE__ */ jsx2(Text, { color: mascotColor, children: " \u2590\u2588\u25E6\u25E6\u2588\u258C" }),
|
|
2134
|
+
/* @__PURE__ */ jsx2(Text, { color: mascotColor, children: " \u2590\u258C\u25C6\u25C6\u2590\u258C" }),
|
|
2135
|
+
/* @__PURE__ */ jsx2(Text, { color: mascotColor, children: " \u2590\u258C\u2584\u2584\u2590\u258C" }),
|
|
2136
|
+
/* @__PURE__ */ jsx2(Text, { color: mascotColor, children: " \u2580\u2580\u2580\u2580" })
|
|
2137
|
+
] })
|
|
2126
2138
|
] }),
|
|
2127
|
-
/* @__PURE__ */
|
|
2128
|
-
/* @__PURE__ */
|
|
2139
|
+
/* @__PURE__ */ jsx2(Text, { children: " " }),
|
|
2140
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2129
2141
|
" ",
|
|
2130
|
-
bar.map((d, i) => /* @__PURE__ */
|
|
2131
|
-
] })
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
model ? /* @__PURE__ */
|
|
2142
|
+
bar.map((d, i) => /* @__PURE__ */ jsx2(Text, { color: d.color, children: d.char }, i))
|
|
2143
|
+
] }),
|
|
2144
|
+
/* @__PURE__ */ jsxs(Box, { marginTop: 1, marginLeft: 2, children: [
|
|
2145
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.dim ?? "#7e8ea6", children: "model " }),
|
|
2146
|
+
model ? /* @__PURE__ */ jsx2(Text, { color: theme.cyan ?? "#5eead4", bold: true, children: model }) : /* @__PURE__ */ jsx2(Text, { color: theme.dim ?? "#7e8ea6", children: "--" })
|
|
2135
2147
|
] }),
|
|
2136
|
-
/* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
/* @__PURE__ */
|
|
2140
|
-
/* @__PURE__ */
|
|
2148
|
+
/* @__PURE__ */ jsxs(Box, { marginLeft: 2, children: [
|
|
2149
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.dim ?? "#7e8ea6", children: "via " }),
|
|
2150
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.text ?? "#e2e8f0", children: providerName }),
|
|
2151
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.dim ?? "#7e8ea6", children: " " }),
|
|
2152
|
+
/* @__PURE__ */ jsx2(Text, { color: statusColor, children: statusTag })
|
|
2141
2153
|
] }),
|
|
2142
|
-
/* @__PURE__ */
|
|
2143
|
-
/* @__PURE__ */
|
|
2144
|
-
/* @__PURE__ */
|
|
2154
|
+
/* @__PURE__ */ jsxs(Box, { marginLeft: 2, children: [
|
|
2155
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.dim ?? "#7e8ea6", children: "cwd " }),
|
|
2156
|
+
/* @__PURE__ */ jsx2(Text, { color: theme.text ?? "#e2e8f0", children: cwd })
|
|
2145
2157
|
] }),
|
|
2146
|
-
/* @__PURE__ */
|
|
2158
|
+
/* @__PURE__ */ jsx2(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
2147
2159
|
" ",
|
|
2148
|
-
bar.map((d, i) => /* @__PURE__ */
|
|
2160
|
+
bar.map((d, i) => /* @__PURE__ */ jsx2(Text, { color: d.color, children: d.char }, i))
|
|
2149
2161
|
] }) })
|
|
2150
2162
|
] });
|
|
2151
2163
|
});
|
|
@@ -2153,8 +2165,8 @@ var Banner = memo2(function Banner2({ model, cwd, providerName, providerOnline,
|
|
|
2153
2165
|
// src/components/Messages.tsx
|
|
2154
2166
|
init_theme();
|
|
2155
2167
|
init_format();
|
|
2156
|
-
import { memo as
|
|
2157
|
-
import { Box as
|
|
2168
|
+
import { memo as memo2 } from "react";
|
|
2169
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
2158
2170
|
|
|
2159
2171
|
// src/utils/markdown.ts
|
|
2160
2172
|
function renderMarkdown(text) {
|
|
@@ -2218,31 +2230,31 @@ function renderInline(text) {
|
|
|
2218
2230
|
}
|
|
2219
2231
|
|
|
2220
2232
|
// src/components/Messages.tsx
|
|
2221
|
-
import { jsx as
|
|
2222
|
-
var Messages =
|
|
2223
|
-
return /* @__PURE__ */
|
|
2233
|
+
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)) });
|
|
2224
2236
|
});
|
|
2225
|
-
|
|
2237
|
+
var MessageRow = memo2(function MessageRow2({ message }) {
|
|
2226
2238
|
switch (message.role) {
|
|
2227
2239
|
case "user":
|
|
2228
|
-
return /* @__PURE__ */
|
|
2229
|
-
/* @__PURE__ */
|
|
2230
|
-
/* @__PURE__ */
|
|
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 })
|
|
2231
2243
|
] });
|
|
2232
2244
|
case "assistant": {
|
|
2233
2245
|
if (!message.content && message.toolCalls) return null;
|
|
2234
2246
|
if (!message.content) return null;
|
|
2235
2247
|
const rendered = renderMarkdown(message.content);
|
|
2236
|
-
return /* @__PURE__ */
|
|
2237
|
-
/* @__PURE__ */
|
|
2238
|
-
/* @__PURE__ */
|
|
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 })
|
|
2239
2251
|
] }) });
|
|
2240
2252
|
}
|
|
2241
2253
|
case "tool": {
|
|
2242
2254
|
const lines = message.content.split("\n");
|
|
2243
2255
|
const preview = lines.length > 8 ? lines.slice(0, 8).join("\n") + `
|
|
2244
2256
|
... (${lines.length - 8} more lines)` : message.content;
|
|
2245
|
-
return /* @__PURE__ */
|
|
2257
|
+
return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: /* @__PURE__ */ jsxs2(Text2, { color: theme.dim, children: [
|
|
2246
2258
|
"\u23BF ",
|
|
2247
2259
|
truncate(preview, 1200)
|
|
2248
2260
|
] }) });
|
|
@@ -2250,46 +2262,47 @@ function MessageRow({ message }) {
|
|
|
2250
2262
|
default:
|
|
2251
2263
|
return null;
|
|
2252
2264
|
}
|
|
2253
|
-
}
|
|
2265
|
+
});
|
|
2254
2266
|
|
|
2255
2267
|
// src/components/ToolCall.tsx
|
|
2256
2268
|
init_theme();
|
|
2257
2269
|
init_format();
|
|
2258
|
-
import {
|
|
2259
|
-
import {
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
/* @__PURE__ */
|
|
2270
|
+
import { memo as memo3 } from "react";
|
|
2271
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
2272
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2273
|
+
var ActiveToolCall = memo3(function ActiveToolCall2({ toolName, args }) {
|
|
2274
|
+
return /* @__PURE__ */ jsxs3(Box3, { marginLeft: 2, children: [
|
|
2275
|
+
/* @__PURE__ */ jsx4(Text3, { color: theme.cyan, children: "..." }),
|
|
2276
|
+
/* @__PURE__ */ jsxs3(Text3, { bold: true, color: theme.yellow, children: [
|
|
2264
2277
|
" ",
|
|
2265
2278
|
toolName
|
|
2266
2279
|
] }),
|
|
2267
|
-
args ? /* @__PURE__ */
|
|
2280
|
+
args ? /* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
|
|
2268
2281
|
" ",
|
|
2269
2282
|
formatToolArgs(args)
|
|
2270
2283
|
] }) : null
|
|
2271
2284
|
] });
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2285
|
+
});
|
|
2286
|
+
var ToolResultDisplay = memo3(function ToolResultDisplay2({ toolName, output, isError }) {
|
|
2274
2287
|
const icon = isError ? "\u2718" : "\u2714";
|
|
2275
2288
|
const iconColor = isError ? theme.pink : theme.green;
|
|
2276
2289
|
const lines = output.split("\n");
|
|
2277
2290
|
const preview = lines.length > 6 ? lines.slice(0, 6).join("\n") + `
|
|
2278
2291
|
... (${lines.length - 6} more lines)` : output;
|
|
2279
|
-
return /* @__PURE__ */
|
|
2280
|
-
/* @__PURE__ */
|
|
2281
|
-
/* @__PURE__ */
|
|
2292
|
+
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [
|
|
2293
|
+
/* @__PURE__ */ jsxs3(Box3, { children: [
|
|
2294
|
+
/* @__PURE__ */ jsxs3(Text3, { color: iconColor, children: [
|
|
2282
2295
|
icon,
|
|
2283
2296
|
" "
|
|
2284
2297
|
] }),
|
|
2285
|
-
/* @__PURE__ */
|
|
2298
|
+
/* @__PURE__ */ jsx4(Text3, { bold: true, color: theme.yellow, children: toolName })
|
|
2286
2299
|
] }),
|
|
2287
|
-
/* @__PURE__ */
|
|
2300
|
+
/* @__PURE__ */ jsx4(Box3, { marginLeft: 2, children: /* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
|
|
2288
2301
|
"\u23BF ",
|
|
2289
2302
|
truncate(preview, 1200)
|
|
2290
2303
|
] }) })
|
|
2291
2304
|
] });
|
|
2292
|
-
}
|
|
2305
|
+
});
|
|
2293
2306
|
function formatToolArgs(args) {
|
|
2294
2307
|
const entries = Object.entries(args);
|
|
2295
2308
|
if (entries.length === 0) return "";
|
|
@@ -2306,8 +2319,8 @@ function formatToolArgs(args) {
|
|
|
2306
2319
|
init_theme();
|
|
2307
2320
|
init_state();
|
|
2308
2321
|
import { memo as memo4 } from "react";
|
|
2309
|
-
import { Box as
|
|
2310
|
-
import { Fragment, jsx as
|
|
2322
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
2323
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2311
2324
|
function getContextLimit(model) {
|
|
2312
2325
|
const lower = model.toLowerCase();
|
|
2313
2326
|
if (lower.includes("llama3.1")) return 131072;
|
|
@@ -2325,40 +2338,40 @@ var StatusLine = memo4(function StatusLine2({ model, messageCount, tokenEstimate
|
|
|
2325
2338
|
const pct = (usage * 100).toFixed(0);
|
|
2326
2339
|
const usageColor = usage > 0.8 ? theme.pink : usage > 0.5 ? theme.yellow : theme.cyan;
|
|
2327
2340
|
const activeTasks = state2.tasks.filter((t) => t.status === "in_progress").length;
|
|
2328
|
-
return /* @__PURE__ */
|
|
2329
|
-
/* @__PURE__ */
|
|
2341
|
+
return /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, children: [
|
|
2342
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2330
2343
|
"\u2500".repeat(2),
|
|
2331
2344
|
" "
|
|
2332
2345
|
] }),
|
|
2333
|
-
/* @__PURE__ */
|
|
2334
|
-
/* @__PURE__ */
|
|
2335
|
-
/* @__PURE__ */
|
|
2346
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.cyan, bold: true, children: model ? model.split(":")[0] : "--" }),
|
|
2347
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
|
|
2348
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2336
2349
|
messageCount,
|
|
2337
2350
|
" msgs"
|
|
2338
2351
|
] }),
|
|
2339
|
-
/* @__PURE__ */
|
|
2340
|
-
/* @__PURE__ */
|
|
2352
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
|
|
2353
|
+
/* @__PURE__ */ jsxs4(Text4, { color: usageColor, children: [
|
|
2341
2354
|
"ctx ",
|
|
2342
2355
|
pct,
|
|
2343
2356
|
"%"
|
|
2344
2357
|
] }),
|
|
2345
|
-
state2.planMode ? /* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2347
|
-
/* @__PURE__ */
|
|
2358
|
+
state2.planMode ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
2359
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
|
|
2360
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.yellow, bold: true, children: "PLAN" })
|
|
2348
2361
|
] }) : null,
|
|
2349
|
-
activeTasks > 0 ? /* @__PURE__ */
|
|
2350
|
-
/* @__PURE__ */
|
|
2351
|
-
/* @__PURE__ */
|
|
2362
|
+
activeTasks > 0 ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
2363
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
|
|
2364
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.green, children: [
|
|
2352
2365
|
activeTasks,
|
|
2353
2366
|
" task",
|
|
2354
2367
|
activeTasks > 1 ? "s" : ""
|
|
2355
2368
|
] })
|
|
2356
2369
|
] }) : null,
|
|
2357
|
-
isStreaming ? /* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2370
|
+
isStreaming ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
2371
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.dim, children: " \u2502 " }),
|
|
2372
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.cyan, children: "streaming" })
|
|
2360
2373
|
] }) : null,
|
|
2361
|
-
/* @__PURE__ */
|
|
2374
|
+
/* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2362
2375
|
" ",
|
|
2363
2376
|
"\u2500".repeat(2)
|
|
2364
2377
|
] })
|
|
@@ -2368,7 +2381,7 @@ var StatusLine = memo4(function StatusLine2({ model, messageCount, tokenEstimate
|
|
|
2368
2381
|
// src/components/UserInput.tsx
|
|
2369
2382
|
init_theme();
|
|
2370
2383
|
import { useState, useCallback, memo as memo5 } from "react";
|
|
2371
|
-
import { Box as
|
|
2384
|
+
import { Box as Box5, Text as Text5, useInput } from "ink";
|
|
2372
2385
|
import TextInput from "ink-text-input";
|
|
2373
2386
|
|
|
2374
2387
|
// src/commands/help.ts
|
|
@@ -3404,7 +3417,7 @@ function getCommandNames() {
|
|
|
3404
3417
|
}
|
|
3405
3418
|
|
|
3406
3419
|
// src/components/UserInput.tsx
|
|
3407
|
-
import { Fragment as Fragment2, jsx as
|
|
3420
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3408
3421
|
var UserInput = memo5(function UserInput2({ value, onChange, onSubmit, disabled, history }) {
|
|
3409
3422
|
const [historyIdx, setHistoryIdx] = useState(-1);
|
|
3410
3423
|
const [suggestion, setSuggestion] = useState("");
|
|
@@ -3453,20 +3466,20 @@ var UserInput = memo5(function UserInput2({ value, onChange, onSubmit, disabled,
|
|
|
3453
3466
|
const borderColor = disabled ? theme.dim : isBash ? theme.yellow : isCommand ? theme.purple : theme.cyan;
|
|
3454
3467
|
const promptChar = isBash ? "!" : "\u276F";
|
|
3455
3468
|
const promptColor = isBash ? theme.yellow : theme.cyan;
|
|
3456
|
-
return /* @__PURE__ */
|
|
3457
|
-
|
|
3469
|
+
return /* @__PURE__ */ jsxs5(
|
|
3470
|
+
Box5,
|
|
3458
3471
|
{
|
|
3459
3472
|
borderStyle: "round",
|
|
3460
3473
|
borderColor,
|
|
3461
3474
|
paddingLeft: 1,
|
|
3462
3475
|
paddingRight: 1,
|
|
3463
3476
|
children: [
|
|
3464
|
-
/* @__PURE__ */
|
|
3477
|
+
/* @__PURE__ */ jsxs5(Text5, { color: disabled ? theme.dim : promptColor, bold: true, children: [
|
|
3465
3478
|
promptChar,
|
|
3466
3479
|
" "
|
|
3467
3480
|
] }),
|
|
3468
|
-
disabled ? /* @__PURE__ */
|
|
3469
|
-
/* @__PURE__ */
|
|
3481
|
+
disabled ? /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: "..." }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
3482
|
+
/* @__PURE__ */ jsx6(
|
|
3470
3483
|
TextInput,
|
|
3471
3484
|
{
|
|
3472
3485
|
value,
|
|
@@ -3480,7 +3493,7 @@ var UserInput = memo5(function UserInput2({ value, onChange, onSubmit, disabled,
|
|
|
3480
3493
|
}
|
|
3481
3494
|
}
|
|
3482
3495
|
),
|
|
3483
|
-
suggestion ? /* @__PURE__ */
|
|
3496
|
+
suggestion ? /* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: suggestion }) : null
|
|
3484
3497
|
] })
|
|
3485
3498
|
]
|
|
3486
3499
|
}
|
|
@@ -3496,7 +3509,7 @@ init_tools();
|
|
|
3496
3509
|
init_bash();
|
|
3497
3510
|
init_hooks();
|
|
3498
3511
|
init_theme();
|
|
3499
|
-
import { jsx as
|
|
3512
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3500
3513
|
function getContextLimit3(model) {
|
|
3501
3514
|
const lower = model.toLowerCase();
|
|
3502
3515
|
if (lower.includes("llama3.1")) return 131072;
|
|
@@ -3507,6 +3520,7 @@ function getContextLimit3(model) {
|
|
|
3507
3520
|
if (lower.includes("deepseek")) return 32768;
|
|
3508
3521
|
return 8192;
|
|
3509
3522
|
}
|
|
3523
|
+
var STREAM_THROTTLE_MS = 80;
|
|
3510
3524
|
function REPL({ initialPrompt }) {
|
|
3511
3525
|
const { model: initialModel, systemPromptOverride, maxTurns, initialMessages, initialSessionId } = useDarkfooContext();
|
|
3512
3526
|
const { exit } = useApp();
|
|
@@ -3526,6 +3540,31 @@ function REPL({ initialPrompt }) {
|
|
|
3526
3540
|
const abortRef = useRef(null);
|
|
3527
3541
|
const hasRun = useRef(false);
|
|
3528
3542
|
const sessionId = useRef(initialSessionId ?? createSessionId());
|
|
3543
|
+
const streamBufferRef = useRef("");
|
|
3544
|
+
const streamFlushTimer = useRef(null);
|
|
3545
|
+
const startStreamFlush = useCallback2(() => {
|
|
3546
|
+
if (streamFlushTimer.current) return;
|
|
3547
|
+
streamFlushTimer.current = setInterval(() => {
|
|
3548
|
+
const buf = streamBufferRef.current;
|
|
3549
|
+
if (buf) {
|
|
3550
|
+
setStreamingText(buf);
|
|
3551
|
+
}
|
|
3552
|
+
}, STREAM_THROTTLE_MS);
|
|
3553
|
+
}, []);
|
|
3554
|
+
const stopStreamFlush = useCallback2(() => {
|
|
3555
|
+
if (streamFlushTimer.current) {
|
|
3556
|
+
clearInterval(streamFlushTimer.current);
|
|
3557
|
+
streamFlushTimer.current = null;
|
|
3558
|
+
}
|
|
3559
|
+
if (streamBufferRef.current) {
|
|
3560
|
+
setStreamingText(streamBufferRef.current);
|
|
3561
|
+
}
|
|
3562
|
+
}, []);
|
|
3563
|
+
useEffect(() => {
|
|
3564
|
+
return () => {
|
|
3565
|
+
if (streamFlushTimer.current) clearInterval(streamFlushTimer.current);
|
|
3566
|
+
};
|
|
3567
|
+
}, []);
|
|
3529
3568
|
const messagesRef = useRef(messages);
|
|
3530
3569
|
messagesRef.current = messages;
|
|
3531
3570
|
const modelRef = useRef(model);
|
|
@@ -3534,6 +3573,7 @@ function REPL({ initialPrompt }) {
|
|
|
3534
3573
|
systemPromptRef.current = systemPrompt;
|
|
3535
3574
|
const tools = getTools();
|
|
3536
3575
|
const cwd = process.cwd();
|
|
3576
|
+
const providerName = useMemo(() => getActiveProviderName(), [model, providerOnline]);
|
|
3537
3577
|
useEffect(() => {
|
|
3538
3578
|
if (systemPromptOverride) {
|
|
3539
3579
|
setSystemPrompt(systemPromptOverride);
|
|
@@ -3606,6 +3646,7 @@ function REPL({ initialPrompt }) {
|
|
|
3606
3646
|
};
|
|
3607
3647
|
setMessages((prev) => [...prev, userMsg]);
|
|
3608
3648
|
setIsStreaming(true);
|
|
3649
|
+
streamBufferRef.current = "";
|
|
3609
3650
|
setStreamingText("");
|
|
3610
3651
|
setToolResults([]);
|
|
3611
3652
|
setCommandOutput(null);
|
|
@@ -3615,6 +3656,8 @@ function REPL({ initialPrompt }) {
|
|
|
3615
3656
|
const allMessages = [...messagesRef.current, userMsg];
|
|
3616
3657
|
const currentModel = modelRef.current;
|
|
3617
3658
|
const currentSystemPrompt = systemPromptRef.current;
|
|
3659
|
+
let receivedFirstText = false;
|
|
3660
|
+
startStreamFlush();
|
|
3618
3661
|
try {
|
|
3619
3662
|
for await (const event of query({
|
|
3620
3663
|
model: currentModel,
|
|
@@ -3627,10 +3670,14 @@ function REPL({ initialPrompt }) {
|
|
|
3627
3670
|
if (controller.signal.aborted) break;
|
|
3628
3671
|
switch (event.type) {
|
|
3629
3672
|
case "text_delta":
|
|
3630
|
-
|
|
3631
|
-
|
|
3673
|
+
streamBufferRef.current += event.text;
|
|
3674
|
+
if (!receivedFirstText) {
|
|
3675
|
+
receivedFirstText = true;
|
|
3676
|
+
setMascotMood("idle");
|
|
3677
|
+
}
|
|
3632
3678
|
break;
|
|
3633
3679
|
case "tool_call":
|
|
3680
|
+
stopStreamFlush();
|
|
3634
3681
|
setActiveTool({ name: event.toolCall.function.name, args: event.toolCall.function.arguments });
|
|
3635
3682
|
setMascotMood("working");
|
|
3636
3683
|
break;
|
|
@@ -3649,15 +3696,20 @@ function REPL({ initialPrompt }) {
|
|
|
3649
3696
|
}));
|
|
3650
3697
|
break;
|
|
3651
3698
|
case "assistant_message":
|
|
3699
|
+
stopStreamFlush();
|
|
3652
3700
|
setMessages((prev) => {
|
|
3653
3701
|
const updated = [...prev, event.message];
|
|
3654
3702
|
saveSession(sessionId.current, updated, currentModel, cwd).catch(() => {
|
|
3655
3703
|
});
|
|
3656
3704
|
return updated;
|
|
3657
3705
|
});
|
|
3706
|
+
streamBufferRef.current = "";
|
|
3658
3707
|
setStreamingText("");
|
|
3708
|
+
receivedFirstText = false;
|
|
3709
|
+
startStreamFlush();
|
|
3659
3710
|
break;
|
|
3660
3711
|
case "error":
|
|
3712
|
+
stopStreamFlush();
|
|
3661
3713
|
setMascotMood("error");
|
|
3662
3714
|
setMessages((prev) => [
|
|
3663
3715
|
...prev,
|
|
@@ -3675,6 +3727,8 @@ function REPL({ initialPrompt }) {
|
|
|
3675
3727
|
]);
|
|
3676
3728
|
}
|
|
3677
3729
|
} finally {
|
|
3730
|
+
stopStreamFlush();
|
|
3731
|
+
streamBufferRef.current = "";
|
|
3678
3732
|
setIsStreaming(false);
|
|
3679
3733
|
setStreamingText("");
|
|
3680
3734
|
setActiveTool(null);
|
|
@@ -3684,7 +3738,7 @@ function REPL({ initialPrompt }) {
|
|
|
3684
3738
|
abortRef.current = null;
|
|
3685
3739
|
}
|
|
3686
3740
|
},
|
|
3687
|
-
[tools, cwd]
|
|
3741
|
+
[tools, cwd, startStreamFlush, stopStreamFlush]
|
|
3688
3742
|
);
|
|
3689
3743
|
const handleSubmit = useCallback2(
|
|
3690
3744
|
async (value) => {
|
|
@@ -3790,22 +3844,21 @@ ${result.content}
|
|
|
3790
3844
|
}
|
|
3791
3845
|
}
|
|
3792
3846
|
});
|
|
3793
|
-
return /* @__PURE__ */
|
|
3794
|
-
/* @__PURE__ */
|
|
3795
|
-
/* @__PURE__ */
|
|
3796
|
-
commandOutput ? /* @__PURE__ */
|
|
3797
|
-
toolResults.map((tr) => /* @__PURE__ */
|
|
3798
|
-
activeTool ? /* @__PURE__ */
|
|
3799
|
-
isStreaming && streamingText ? /* @__PURE__ */
|
|
3800
|
-
/* @__PURE__ */
|
|
3801
|
-
/* @__PURE__ */
|
|
3802
|
-
/* @__PURE__ */ jsx8(Text7, { color: theme.dim, children: " ..." })
|
|
3847
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", padding: 1, children: [
|
|
3848
|
+
/* @__PURE__ */ jsx7(Banner, { model, cwd, providerName, providerOnline, mood: mascotMood }),
|
|
3849
|
+
/* @__PURE__ */ jsx7(Messages, { messages }),
|
|
3850
|
+
commandOutput ? /* @__PURE__ */ jsx7(Box6, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx7(Text6, { children: commandOutput }) }) : null,
|
|
3851
|
+
toolResults.map((tr) => /* @__PURE__ */ jsx7(ToolResultDisplay, { toolName: tr.toolName, output: tr.output, isError: tr.isError }, tr.id)),
|
|
3852
|
+
activeTool ? /* @__PURE__ */ jsx7(ActiveToolCall, { toolName: activeTool.name, args: activeTool.args }) : null,
|
|
3853
|
+
isStreaming && streamingText ? /* @__PURE__ */ jsxs6(Box6, { marginBottom: 1, children: [
|
|
3854
|
+
/* @__PURE__ */ jsx7(Text6, { color: theme.cyan, children: "\u23BF " }),
|
|
3855
|
+
/* @__PURE__ */ jsx7(Text6, { color: theme.text, wrap: "wrap", children: streamingText })
|
|
3803
3856
|
] }) : null,
|
|
3804
|
-
isStreaming && !streamingText && !activeTool ? /* @__PURE__ */
|
|
3805
|
-
/* @__PURE__ */
|
|
3806
|
-
/* @__PURE__ */
|
|
3857
|
+
isStreaming && !streamingText && !activeTool ? /* @__PURE__ */ jsxs6(Box6, { marginLeft: 2, children: [
|
|
3858
|
+
/* @__PURE__ */ jsx7(Text6, { color: theme.cyan, children: "..." }),
|
|
3859
|
+
/* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: " Thinking" })
|
|
3807
3860
|
] }) : null,
|
|
3808
|
-
/* @__PURE__ */
|
|
3861
|
+
/* @__PURE__ */ jsx7(
|
|
3809
3862
|
UserInput,
|
|
3810
3863
|
{
|
|
3811
3864
|
value: inputValue,
|
|
@@ -3815,7 +3868,7 @@ ${result.content}
|
|
|
3815
3868
|
history: inputHistory
|
|
3816
3869
|
}
|
|
3817
3870
|
),
|
|
3818
|
-
/* @__PURE__ */
|
|
3871
|
+
/* @__PURE__ */ jsx7(
|
|
3819
3872
|
StatusLine,
|
|
3820
3873
|
{
|
|
3821
3874
|
model,
|
|
@@ -3829,9 +3882,9 @@ ${result.content}
|
|
|
3829
3882
|
|
|
3830
3883
|
// src/main.tsx
|
|
3831
3884
|
init_providers();
|
|
3832
|
-
import { jsx as
|
|
3885
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
3833
3886
|
var program = new Command();
|
|
3834
|
-
program.name("darkfoo").description("Darkfoo Code \u2014 local AI coding assistant powered by local LLM providers").version("0.
|
|
3887
|
+
program.name("darkfoo").description("Darkfoo Code \u2014 local AI coding assistant powered by local LLM providers").version("0.4.1").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) => {
|
|
3835
3888
|
const { model, prompt, provider, systemPrompt } = options;
|
|
3836
3889
|
if (options.debug) {
|
|
3837
3890
|
const { setDebugMode: setDebugMode2 } = await Promise.resolve().then(() => (init_debug(), debug_exports));
|
|
@@ -3966,7 +4019,7 @@ Error: ${event.error}
|
|
|
3966
4019
|
}
|
|
3967
4020
|
}
|
|
3968
4021
|
const { waitUntilExit } = render(
|
|
3969
|
-
/* @__PURE__ */
|
|
4022
|
+
/* @__PURE__ */ jsx8(
|
|
3970
4023
|
App,
|
|
3971
4024
|
{
|
|
3972
4025
|
model: resolvedModel,
|
|
@@ -3974,7 +4027,7 @@ Error: ${event.error}
|
|
|
3974
4027
|
maxTurns,
|
|
3975
4028
|
initialMessages,
|
|
3976
4029
|
initialSessionId,
|
|
3977
|
-
children: /* @__PURE__ */
|
|
4030
|
+
children: /* @__PURE__ */ jsx8(REPL, {})
|
|
3978
4031
|
}
|
|
3979
4032
|
)
|
|
3980
4033
|
);
|