kimiflare 0.7.1 → 0.8.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/index.js +628 -246
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1172,6 +1172,121 @@ var init_executor = __esm({
|
|
|
1172
1172
|
}
|
|
1173
1173
|
});
|
|
1174
1174
|
|
|
1175
|
+
// src/util/update-check.ts
|
|
1176
|
+
import { readFile as readFile6, writeFile as writeFile4, mkdir as mkdir3, access } from "fs/promises";
|
|
1177
|
+
import { homedir as homedir4 } from "os";
|
|
1178
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
1179
|
+
import { fileURLToPath } from "url";
|
|
1180
|
+
function cachePath() {
|
|
1181
|
+
const xdg = process.env.XDG_CONFIG_HOME || join3(homedir4(), ".config");
|
|
1182
|
+
return join3(xdg, "kimiflare", "update-check.json");
|
|
1183
|
+
}
|
|
1184
|
+
async function findPackageJson(startDir) {
|
|
1185
|
+
let dir = startDir;
|
|
1186
|
+
while (true) {
|
|
1187
|
+
const candidate = join3(dir, "package.json");
|
|
1188
|
+
try {
|
|
1189
|
+
const raw = await readFile6(candidate, "utf8");
|
|
1190
|
+
const parsed = JSON.parse(raw);
|
|
1191
|
+
if (parsed.name === "kimiflare" && parsed.version) {
|
|
1192
|
+
return { path: candidate, version: parsed.version };
|
|
1193
|
+
}
|
|
1194
|
+
} catch {
|
|
1195
|
+
}
|
|
1196
|
+
const parent = dirname2(dir);
|
|
1197
|
+
if (parent === dir) break;
|
|
1198
|
+
dir = parent;
|
|
1199
|
+
}
|
|
1200
|
+
return null;
|
|
1201
|
+
}
|
|
1202
|
+
async function readLocalVersion() {
|
|
1203
|
+
const here = dirname2(fileURLToPath(import.meta.url));
|
|
1204
|
+
const found = await findPackageJson(here);
|
|
1205
|
+
return found?.version ?? null;
|
|
1206
|
+
}
|
|
1207
|
+
async function readCache() {
|
|
1208
|
+
try {
|
|
1209
|
+
const raw = await readFile6(cachePath(), "utf8");
|
|
1210
|
+
const parsed = JSON.parse(raw);
|
|
1211
|
+
if (Date.now() - parsed.checkedAt < CACHE_TTL_MS) {
|
|
1212
|
+
return parsed;
|
|
1213
|
+
}
|
|
1214
|
+
} catch {
|
|
1215
|
+
}
|
|
1216
|
+
return null;
|
|
1217
|
+
}
|
|
1218
|
+
async function writeCache(entry) {
|
|
1219
|
+
const p = cachePath();
|
|
1220
|
+
await mkdir3(dirname2(p), { recursive: true });
|
|
1221
|
+
await writeFile4(p, JSON.stringify(entry), "utf8");
|
|
1222
|
+
}
|
|
1223
|
+
async function fetchLatestVersion() {
|
|
1224
|
+
try {
|
|
1225
|
+
const res = await fetch(NPM_REGISTRY, {
|
|
1226
|
+
headers: { "User-Agent": "kimiflare-update-checker", Accept: "application/json" }
|
|
1227
|
+
});
|
|
1228
|
+
if (!res.ok) return null;
|
|
1229
|
+
const data = await res.json();
|
|
1230
|
+
return data.version ?? null;
|
|
1231
|
+
} catch {
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
function stripV(v) {
|
|
1236
|
+
return v.startsWith("v") ? v.slice(1) : v;
|
|
1237
|
+
}
|
|
1238
|
+
function isNewer(local, remote) {
|
|
1239
|
+
const a = stripV(local).split(".").map(Number);
|
|
1240
|
+
const b = stripV(remote).split(".").map(Number);
|
|
1241
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
1242
|
+
const av = a[i] ?? 0;
|
|
1243
|
+
const bv = b[i] ?? 0;
|
|
1244
|
+
if (av < bv) return true;
|
|
1245
|
+
if (av > bv) return false;
|
|
1246
|
+
}
|
|
1247
|
+
return false;
|
|
1248
|
+
}
|
|
1249
|
+
async function checkForUpdate(force = false) {
|
|
1250
|
+
const localVersion = await readLocalVersion();
|
|
1251
|
+
if (!localVersion) return { hasUpdate: false, localVersion: null, latestVersion: null };
|
|
1252
|
+
if (!force) {
|
|
1253
|
+
const cached = await readCache();
|
|
1254
|
+
if (cached) {
|
|
1255
|
+
const hasUpdate2 = isNewer(localVersion, cached.latestVersion);
|
|
1256
|
+
return { hasUpdate: hasUpdate2, localVersion, latestVersion: cached.latestVersion };
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
const latestVersion = await fetchLatestVersion();
|
|
1260
|
+
if (!latestVersion) {
|
|
1261
|
+
return { hasUpdate: false, localVersion, latestVersion: null };
|
|
1262
|
+
}
|
|
1263
|
+
const hasUpdate = isNewer(localVersion, latestVersion);
|
|
1264
|
+
await writeCache({ checkedAt: Date.now(), latestVersion });
|
|
1265
|
+
return { hasUpdate, localVersion, latestVersion };
|
|
1266
|
+
}
|
|
1267
|
+
async function isGitRepo() {
|
|
1268
|
+
let dir = dirname2(fileURLToPath(import.meta.url));
|
|
1269
|
+
while (true) {
|
|
1270
|
+
try {
|
|
1271
|
+
await access(join3(dir, ".git"));
|
|
1272
|
+
return true;
|
|
1273
|
+
} catch {
|
|
1274
|
+
}
|
|
1275
|
+
const parent = dirname2(dir);
|
|
1276
|
+
if (parent === dir) break;
|
|
1277
|
+
dir = parent;
|
|
1278
|
+
}
|
|
1279
|
+
return false;
|
|
1280
|
+
}
|
|
1281
|
+
var CACHE_TTL_MS, NPM_REGISTRY;
|
|
1282
|
+
var init_update_check = __esm({
|
|
1283
|
+
"src/util/update-check.ts"() {
|
|
1284
|
+
"use strict";
|
|
1285
|
+
CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
1286
|
+
NPM_REGISTRY = "https://registry.npmjs.org/kimiflare/latest";
|
|
1287
|
+
}
|
|
1288
|
+
});
|
|
1289
|
+
|
|
1175
1290
|
// src/agent/compact.ts
|
|
1176
1291
|
function indexOfNthUserFromEnd(messages, n) {
|
|
1177
1292
|
let seen = 0;
|
|
@@ -1584,7 +1699,7 @@ import { useEffect, useState } from "react";
|
|
|
1584
1699
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
1585
1700
|
import Spinner3 from "ink-spinner";
|
|
1586
1701
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1587
|
-
function StatusBar({ model, usage, thinking, turnStartedAt, theme, mode, effort, contextLimit }) {
|
|
1702
|
+
function StatusBar({ model, usage, thinking, turnStartedAt, theme, mode, effort, contextLimit, hasUpdate, latestVersion }) {
|
|
1588
1703
|
const [now, setNow] = useState(Date.now());
|
|
1589
1704
|
const modeColor = mode === "plan" ? theme.modeBadge.plan : mode === "auto" ? theme.modeBadge.auto : theme.modeBadge.edit;
|
|
1590
1705
|
const warn = usage && usage.prompt_tokens / contextLimit >= 0.8;
|
|
@@ -1618,6 +1733,12 @@ function StatusBar({ model, usage, thinking, turnStartedAt, theme, mode, effort,
|
|
|
1618
1733
|
warn ? /* @__PURE__ */ jsxs5(Text5, { color: theme.warn, bold: true, children: [
|
|
1619
1734
|
" \xB7 ",
|
|
1620
1735
|
"/compact recommended"
|
|
1736
|
+
] }) : null,
|
|
1737
|
+
hasUpdate ? /* @__PURE__ */ jsxs5(Text5, { color: theme.warn, bold: true, children: [
|
|
1738
|
+
" \xB7 ",
|
|
1739
|
+
"update available",
|
|
1740
|
+
latestVersion ? ` \u2192 ${latestVersion}` : "",
|
|
1741
|
+
" \xB7 run /update"
|
|
1621
1742
|
] }) : null
|
|
1622
1743
|
] })
|
|
1623
1744
|
] });
|
|
@@ -1691,10 +1812,16 @@ var init_permission = __esm({
|
|
|
1691
1812
|
});
|
|
1692
1813
|
|
|
1693
1814
|
// src/ui/resume-picker.tsx
|
|
1694
|
-
import {
|
|
1815
|
+
import { useState as useState2 } from "react";
|
|
1816
|
+
import { Box as Box7, Text as Text7, useWindowSize } from "ink";
|
|
1695
1817
|
import SelectInput2 from "ink-select-input";
|
|
1696
1818
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1697
1819
|
function ResumePicker({ sessions, onPick, theme }) {
|
|
1820
|
+
const { rows } = useWindowSize();
|
|
1821
|
+
const [page, setPage] = useState2(0);
|
|
1822
|
+
const pageSize = Math.max(MIN_PAGE_SIZE, rows - HEADER_ROWS - FOOTER_ROWS);
|
|
1823
|
+
const totalPages = Math.max(1, Math.ceil(sessions.length / pageSize));
|
|
1824
|
+
const safePage = Math.min(page, totalPages - 1);
|
|
1698
1825
|
if (sessions.length === 0) {
|
|
1699
1826
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
1700
1827
|
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
@@ -1708,20 +1835,39 @@ function ResumePicker({ sessions, onPick, theme }) {
|
|
|
1708
1835
|
) })
|
|
1709
1836
|
] });
|
|
1710
1837
|
}
|
|
1711
|
-
const
|
|
1838
|
+
const start = safePage * pageSize;
|
|
1839
|
+
const end = Math.min(start + pageSize, sessions.length);
|
|
1840
|
+
const pageSessions = sessions.slice(start, end);
|
|
1841
|
+
const items = pageSessions.map((s) => ({
|
|
1712
1842
|
label: `${formatDate(s.updatedAt)} \xB7 ${s.messageCount} msgs \xB7 ${s.firstPrompt}`,
|
|
1713
1843
|
value: s.id
|
|
1714
1844
|
}));
|
|
1845
|
+
if (safePage > 0) {
|
|
1846
|
+
items.push({ label: "\u2190 previous page", value: "__prev__" });
|
|
1847
|
+
}
|
|
1848
|
+
if (safePage < totalPages - 1) {
|
|
1849
|
+
items.push({ label: "\u2192 next page", value: "__next__" });
|
|
1850
|
+
}
|
|
1715
1851
|
items.push({ label: "(cancel)", value: "__cancel__" });
|
|
1716
1852
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
1717
1853
|
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
1718
|
-
/* @__PURE__ */
|
|
1854
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
1855
|
+
"Arrow keys to select, Enter to confirm. Page ",
|
|
1856
|
+
safePage + 1,
|
|
1857
|
+
" of ",
|
|
1858
|
+
totalPages,
|
|
1859
|
+
" (",
|
|
1860
|
+
sessions.length,
|
|
1861
|
+
" total)"
|
|
1862
|
+
] }),
|
|
1719
1863
|
/* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(
|
|
1720
1864
|
SelectInput2,
|
|
1721
1865
|
{
|
|
1722
1866
|
items,
|
|
1723
1867
|
onSelect: (item) => {
|
|
1724
1868
|
if (item.value === "__cancel__") return onPick(null);
|
|
1869
|
+
if (item.value === "__prev__") return setPage((p) => Math.max(0, p - 1));
|
|
1870
|
+
if (item.value === "__next__") return setPage((p) => Math.min(totalPages - 1, p + 1));
|
|
1725
1871
|
const picked = sessions.find((s) => s.id === item.value) ?? null;
|
|
1726
1872
|
onPick(picked);
|
|
1727
1873
|
}
|
|
@@ -1742,19 +1888,67 @@ function formatDate(iso) {
|
|
|
1742
1888
|
return iso;
|
|
1743
1889
|
}
|
|
1744
1890
|
}
|
|
1891
|
+
var HEADER_ROWS, FOOTER_ROWS, MIN_PAGE_SIZE;
|
|
1745
1892
|
var init_resume_picker = __esm({
|
|
1746
1893
|
"src/ui/resume-picker.tsx"() {
|
|
1747
1894
|
"use strict";
|
|
1895
|
+
HEADER_ROWS = 5;
|
|
1896
|
+
FOOTER_ROWS = 2;
|
|
1897
|
+
MIN_PAGE_SIZE = 5;
|
|
1748
1898
|
}
|
|
1749
1899
|
});
|
|
1750
1900
|
|
|
1751
|
-
// src/ui/
|
|
1752
|
-
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1901
|
+
// src/ui/theme-picker.tsx
|
|
1753
1902
|
import { Box as Box8, Text as Text8 } from "ink";
|
|
1754
|
-
import
|
|
1903
|
+
import SelectInput3 from "ink-select-input";
|
|
1755
1904
|
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1905
|
+
function ThemePicker({ themes, current, onPick }) {
|
|
1906
|
+
const items = themes.map((t) => ({
|
|
1907
|
+
label: t.label,
|
|
1908
|
+
value: t.name,
|
|
1909
|
+
key: t.name
|
|
1910
|
+
}));
|
|
1911
|
+
items.push({ label: "(cancel)", value: "__cancel__", key: "__cancel__" });
|
|
1912
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
|
|
1913
|
+
/* @__PURE__ */ jsx8(Text8, { color: current.accent, bold: true, children: "Pick a theme" }),
|
|
1914
|
+
/* @__PURE__ */ jsx8(Text8, { color: current.info.color, dimColor: current.info.dim, children: "Arrow keys to preview, Enter to confirm." }),
|
|
1915
|
+
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
1916
|
+
SelectInput3,
|
|
1917
|
+
{
|
|
1918
|
+
items,
|
|
1919
|
+
onHighlight: (item) => {
|
|
1920
|
+
if (item.value !== "__cancel__") {
|
|
1921
|
+
const highlighted = themes.find((t) => t.name === item.value);
|
|
1922
|
+
if (highlighted) onPick(highlighted);
|
|
1923
|
+
}
|
|
1924
|
+
},
|
|
1925
|
+
onSelect: (item) => {
|
|
1926
|
+
if (item.value === "__cancel__") return onPick(null);
|
|
1927
|
+
const picked = themes.find((t) => t.name === item.value) ?? null;
|
|
1928
|
+
onPick(picked);
|
|
1929
|
+
},
|
|
1930
|
+
itemComponent: ({ label, isSelected }) => {
|
|
1931
|
+
const theme = themes.find((t) => t.label === label);
|
|
1932
|
+
const color = theme?.accent ?? current.accent;
|
|
1933
|
+
return /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsx8(Text8, { color, bold: isSelected, dimColor: !isSelected, children: label }) });
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
) })
|
|
1937
|
+
] });
|
|
1938
|
+
}
|
|
1939
|
+
var init_theme_picker = __esm({
|
|
1940
|
+
"src/ui/theme-picker.tsx"() {
|
|
1941
|
+
"use strict";
|
|
1942
|
+
}
|
|
1943
|
+
});
|
|
1944
|
+
|
|
1945
|
+
// src/ui/task-list.tsx
|
|
1946
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
1947
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
1948
|
+
import Spinner4 from "ink-spinner";
|
|
1949
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1756
1950
|
function TaskList({ tasks, theme, startedAt, tokensDelta }) {
|
|
1757
|
-
const [now, setNow] =
|
|
1951
|
+
const [now, setNow] = useState3(Date.now());
|
|
1758
1952
|
useEffect2(() => {
|
|
1759
1953
|
if (startedAt === null) return;
|
|
1760
1954
|
const allDone2 = tasks.length > 0 && tasks.every((t) => t.status === "completed");
|
|
@@ -1772,18 +1966,18 @@ function TaskList({ tasks, theme, startedAt, tokensDelta }) {
|
|
|
1772
1966
|
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
|
|
1773
1967
|
const visibleTasks = tasks.slice(0, MAX_VISIBLE);
|
|
1774
1968
|
const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
|
|
1775
|
-
return /* @__PURE__ */
|
|
1776
|
-
/* @__PURE__ */
|
|
1777
|
-
/* @__PURE__ */
|
|
1778
|
-
headerStats && /* @__PURE__ */
|
|
1969
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginBottom: 1, children: [
|
|
1970
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
1971
|
+
/* @__PURE__ */ jsx9(Text9, { color: allDone ? "green" : theme.accent, bold: true, children: header }),
|
|
1972
|
+
headerStats && /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
1779
1973
|
" ",
|
|
1780
1974
|
"(",
|
|
1781
1975
|
headerStats,
|
|
1782
1976
|
")"
|
|
1783
1977
|
] })
|
|
1784
1978
|
] }),
|
|
1785
|
-
visibleTasks.map((t) => /* @__PURE__ */
|
|
1786
|
-
hiddenPending > 0 && /* @__PURE__ */
|
|
1979
|
+
visibleTasks.map((t) => /* @__PURE__ */ jsx9(TaskRow, { task: t, theme }, t.id)),
|
|
1980
|
+
hiddenPending > 0 && /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
1787
1981
|
" ",
|
|
1788
1982
|
"\u2026 +",
|
|
1789
1983
|
hiddenPending,
|
|
@@ -1793,21 +1987,21 @@ function TaskList({ tasks, theme, startedAt, tokensDelta }) {
|
|
|
1793
1987
|
}
|
|
1794
1988
|
function TaskRow({ task, theme }) {
|
|
1795
1989
|
if (task.status === "completed") {
|
|
1796
|
-
return /* @__PURE__ */
|
|
1990
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
1797
1991
|
" ",
|
|
1798
1992
|
"\u2713 ",
|
|
1799
|
-
/* @__PURE__ */
|
|
1993
|
+
/* @__PURE__ */ jsx9(Text9, { strikethrough: true, children: task.title })
|
|
1800
1994
|
] });
|
|
1801
1995
|
}
|
|
1802
1996
|
if (task.status === "in_progress") {
|
|
1803
|
-
return /* @__PURE__ */
|
|
1997
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.accent, bold: true, children: [
|
|
1804
1998
|
" ",
|
|
1805
|
-
/* @__PURE__ */
|
|
1999
|
+
/* @__PURE__ */ jsx9(Spinner4, { type: "dots" }),
|
|
1806
2000
|
" ",
|
|
1807
2001
|
task.title
|
|
1808
2002
|
] });
|
|
1809
2003
|
}
|
|
1810
|
-
return /* @__PURE__ */
|
|
2004
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
1811
2005
|
" ",
|
|
1812
2006
|
"\u2610 ",
|
|
1813
2007
|
task.title
|
|
@@ -2353,9 +2547,9 @@ var init_source = __esm({
|
|
|
2353
2547
|
});
|
|
2354
2548
|
|
|
2355
2549
|
// src/ui/text-input.tsx
|
|
2356
|
-
import { useState as
|
|
2357
|
-
import { Text as
|
|
2358
|
-
import { jsx as
|
|
2550
|
+
import { useState as useState4, useEffect as useEffect3, useRef } from "react";
|
|
2551
|
+
import { Text as Text10, useInput } from "ink";
|
|
2552
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2359
2553
|
function shouldTreatAsPaste(input) {
|
|
2360
2554
|
if (input.length >= PASTE_CHAR_THRESHOLD) return true;
|
|
2361
2555
|
const newlines = (input.match(/\n/g) ?? []).length;
|
|
@@ -2388,7 +2582,7 @@ function CustomTextInput({
|
|
|
2388
2582
|
mask,
|
|
2389
2583
|
enablePaste = false
|
|
2390
2584
|
}) {
|
|
2391
|
-
const [cursorOffset, setCursorOffset] =
|
|
2585
|
+
const [cursorOffset, setCursorOffset] = useState4(value.length);
|
|
2392
2586
|
const pastesRef = useRef(/* @__PURE__ */ new Map());
|
|
2393
2587
|
useEffect3(() => {
|
|
2394
2588
|
if (!focus) return;
|
|
@@ -2532,7 +2726,7 @@ function CustomTextInput({
|
|
|
2532
2726
|
} else if (cursorOffset === displayValue.length) {
|
|
2533
2727
|
renderedValue += source_default.inverse(" ");
|
|
2534
2728
|
}
|
|
2535
|
-
return /* @__PURE__ */
|
|
2729
|
+
return /* @__PURE__ */ jsx10(Text10, { children: renderedValue });
|
|
2536
2730
|
}
|
|
2537
2731
|
function findPasteTokenEndingAt(value, pos, pastes) {
|
|
2538
2732
|
if (pos <= 0 || value[pos - 1] !== "]") return -1;
|
|
@@ -2553,128 +2747,16 @@ var init_text_input = __esm({
|
|
|
2553
2747
|
}
|
|
2554
2748
|
});
|
|
2555
2749
|
|
|
2556
|
-
// src/util/update-check.ts
|
|
2557
|
-
import { readFile as readFile6, writeFile as writeFile4, mkdir as mkdir3, access } from "fs/promises";
|
|
2558
|
-
import { homedir as homedir4 } from "os";
|
|
2559
|
-
import { join as join3, dirname as dirname2 } from "path";
|
|
2560
|
-
import { fileURLToPath } from "url";
|
|
2561
|
-
function cachePath() {
|
|
2562
|
-
const xdg = process.env.XDG_CONFIG_HOME || join3(homedir4(), ".config");
|
|
2563
|
-
return join3(xdg, "kimiflare", "update-check.json");
|
|
2564
|
-
}
|
|
2565
|
-
async function findPackageJson(startDir) {
|
|
2566
|
-
let dir = startDir;
|
|
2567
|
-
while (true) {
|
|
2568
|
-
const candidate = join3(dir, "package.json");
|
|
2569
|
-
try {
|
|
2570
|
-
const raw = await readFile6(candidate, "utf8");
|
|
2571
|
-
const parsed = JSON.parse(raw);
|
|
2572
|
-
if (parsed.name === "kimiflare" && parsed.version) {
|
|
2573
|
-
return { path: candidate, version: parsed.version };
|
|
2574
|
-
}
|
|
2575
|
-
} catch {
|
|
2576
|
-
}
|
|
2577
|
-
const parent = dirname2(dir);
|
|
2578
|
-
if (parent === dir) break;
|
|
2579
|
-
dir = parent;
|
|
2580
|
-
}
|
|
2581
|
-
return null;
|
|
2582
|
-
}
|
|
2583
|
-
async function readLocalVersion() {
|
|
2584
|
-
const here = dirname2(fileURLToPath(import.meta.url));
|
|
2585
|
-
const found = await findPackageJson(here);
|
|
2586
|
-
return found?.version ?? null;
|
|
2587
|
-
}
|
|
2588
|
-
async function readCache() {
|
|
2589
|
-
try {
|
|
2590
|
-
const raw = await readFile6(cachePath(), "utf8");
|
|
2591
|
-
const parsed = JSON.parse(raw);
|
|
2592
|
-
if (Date.now() - parsed.checkedAt < CACHE_TTL_MS) {
|
|
2593
|
-
return parsed;
|
|
2594
|
-
}
|
|
2595
|
-
} catch {
|
|
2596
|
-
}
|
|
2597
|
-
return null;
|
|
2598
|
-
}
|
|
2599
|
-
async function writeCache(entry) {
|
|
2600
|
-
const p = cachePath();
|
|
2601
|
-
await mkdir3(dirname2(p), { recursive: true });
|
|
2602
|
-
await writeFile4(p, JSON.stringify(entry), "utf8");
|
|
2603
|
-
}
|
|
2604
|
-
async function fetchLatestVersion() {
|
|
2605
|
-
try {
|
|
2606
|
-
const res = await fetch(NPM_REGISTRY, {
|
|
2607
|
-
headers: { "User-Agent": "kimiflare-update-checker", Accept: "application/json" }
|
|
2608
|
-
});
|
|
2609
|
-
if (!res.ok) return null;
|
|
2610
|
-
const data = await res.json();
|
|
2611
|
-
return data.version ?? null;
|
|
2612
|
-
} catch {
|
|
2613
|
-
return null;
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
function stripV(v) {
|
|
2617
|
-
return v.startsWith("v") ? v.slice(1) : v;
|
|
2618
|
-
}
|
|
2619
|
-
function isNewer(local, remote) {
|
|
2620
|
-
const a = stripV(local).split(".").map(Number);
|
|
2621
|
-
const b = stripV(remote).split(".").map(Number);
|
|
2622
|
-
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
2623
|
-
const av = a[i] ?? 0;
|
|
2624
|
-
const bv = b[i] ?? 0;
|
|
2625
|
-
if (av < bv) return true;
|
|
2626
|
-
if (av > bv) return false;
|
|
2627
|
-
}
|
|
2628
|
-
return false;
|
|
2629
|
-
}
|
|
2630
|
-
async function checkForUpdate() {
|
|
2631
|
-
const localVersion = await readLocalVersion();
|
|
2632
|
-
if (!localVersion) return { hasUpdate: false, localVersion: null, latestVersion: null };
|
|
2633
|
-
const cached = await readCache();
|
|
2634
|
-
if (cached) {
|
|
2635
|
-
return { hasUpdate: cached.hasUpdate, localVersion, latestVersion: cached.latestVersion };
|
|
2636
|
-
}
|
|
2637
|
-
const latestVersion = await fetchLatestVersion();
|
|
2638
|
-
if (!latestVersion) {
|
|
2639
|
-
return { hasUpdate: false, localVersion, latestVersion: null };
|
|
2640
|
-
}
|
|
2641
|
-
const hasUpdate = isNewer(localVersion, latestVersion);
|
|
2642
|
-
await writeCache({ checkedAt: Date.now(), latestVersion, hasUpdate });
|
|
2643
|
-
return { hasUpdate, localVersion, latestVersion };
|
|
2644
|
-
}
|
|
2645
|
-
async function isGitRepo() {
|
|
2646
|
-
let dir = dirname2(fileURLToPath(import.meta.url));
|
|
2647
|
-
while (true) {
|
|
2648
|
-
try {
|
|
2649
|
-
await access(join3(dir, ".git"));
|
|
2650
|
-
return true;
|
|
2651
|
-
} catch {
|
|
2652
|
-
}
|
|
2653
|
-
const parent = dirname2(dir);
|
|
2654
|
-
if (parent === dir) break;
|
|
2655
|
-
dir = parent;
|
|
2656
|
-
}
|
|
2657
|
-
return false;
|
|
2658
|
-
}
|
|
2659
|
-
var CACHE_TTL_MS, NPM_REGISTRY;
|
|
2660
|
-
var init_update_check = __esm({
|
|
2661
|
-
"src/util/update-check.ts"() {
|
|
2662
|
-
"use strict";
|
|
2663
|
-
CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
2664
|
-
NPM_REGISTRY = "https://registry.npmjs.org/kimiflare/latest";
|
|
2665
|
-
}
|
|
2666
|
-
});
|
|
2667
|
-
|
|
2668
2750
|
// src/ui/onboarding.tsx
|
|
2669
|
-
import { useState as
|
|
2670
|
-
import { Box as
|
|
2671
|
-
import { Fragment, jsx as
|
|
2751
|
+
import { useState as useState5 } from "react";
|
|
2752
|
+
import { Box as Box10, Text as Text11 } from "ink";
|
|
2753
|
+
import { Fragment, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2672
2754
|
function Onboarding({ onDone }) {
|
|
2673
|
-
const [step, setStep] =
|
|
2674
|
-
const [accountId, setAccountId] =
|
|
2675
|
-
const [apiToken, setApiToken] =
|
|
2676
|
-
const [model, setModel] =
|
|
2677
|
-
const [savedPath, setSavedPath] =
|
|
2755
|
+
const [step, setStep] = useState5("accountId");
|
|
2756
|
+
const [accountId, setAccountId] = useState5("");
|
|
2757
|
+
const [apiToken, setApiToken] = useState5("");
|
|
2758
|
+
const [model, setModel] = useState5(DEFAULT_MODEL);
|
|
2759
|
+
const [savedPath, setSavedPath] = useState5(null);
|
|
2678
2760
|
const stepIndex = STEPS.indexOf(step) + 1;
|
|
2679
2761
|
const handleAccountIdSubmit = (value) => {
|
|
2680
2762
|
const trimmed = value.trim();
|
|
@@ -2703,26 +2785,26 @@ function Onboarding({ onDone }) {
|
|
|
2703
2785
|
setSavedPath(`error: ${e.message}`);
|
|
2704
2786
|
}
|
|
2705
2787
|
};
|
|
2706
|
-
return /* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
2788
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingY: 1, children: [
|
|
2789
|
+
/* @__PURE__ */ jsxs10(Box10, { marginBottom: 1, children: [
|
|
2790
|
+
/* @__PURE__ */ jsx11(Text11, { bold: true, color: "cyan", children: "kimiflare" }),
|
|
2791
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", dimColor: true, children: [
|
|
2710
2792
|
" ",
|
|
2711
2793
|
"Terminal coding agent"
|
|
2712
2794
|
] })
|
|
2713
2795
|
] }),
|
|
2714
|
-
/* @__PURE__ */
|
|
2796
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", dimColor: true, children: [
|
|
2715
2797
|
"Step ",
|
|
2716
2798
|
stepIndex,
|
|
2717
2799
|
" of ",
|
|
2718
2800
|
STEPS.length
|
|
2719
2801
|
] }),
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
step === "accountId" && /* @__PURE__ */
|
|
2722
|
-
/* @__PURE__ */
|
|
2723
|
-
/* @__PURE__ */
|
|
2724
|
-
/* @__PURE__ */
|
|
2725
|
-
/* @__PURE__ */
|
|
2802
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
2803
|
+
step === "accountId" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2804
|
+
/* @__PURE__ */ jsx11(Text11, { children: "Enter your Cloudflare Account ID" }),
|
|
2805
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
2806
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "\u203A " }),
|
|
2807
|
+
/* @__PURE__ */ jsx11(
|
|
2726
2808
|
CustomTextInput,
|
|
2727
2809
|
{
|
|
2728
2810
|
value: accountId,
|
|
@@ -2732,12 +2814,12 @@ function Onboarding({ onDone }) {
|
|
|
2732
2814
|
)
|
|
2733
2815
|
] })
|
|
2734
2816
|
] }),
|
|
2735
|
-
step === "apiToken" && /* @__PURE__ */
|
|
2736
|
-
/* @__PURE__ */
|
|
2737
|
-
/* @__PURE__ */
|
|
2738
|
-
/* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
2740
|
-
/* @__PURE__ */
|
|
2817
|
+
step === "apiToken" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2818
|
+
/* @__PURE__ */ jsx11(Text11, { children: "Enter your Cloudflare API Token" }),
|
|
2819
|
+
/* @__PURE__ */ jsx11(Text11, { color: "gray", dimColor: true, children: "Create one at https://dash.cloudflare.com/profile/api-tokens" }),
|
|
2820
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
2821
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "\u203A " }),
|
|
2822
|
+
/* @__PURE__ */ jsx11(
|
|
2741
2823
|
CustomTextInput,
|
|
2742
2824
|
{
|
|
2743
2825
|
value: apiToken,
|
|
@@ -2748,15 +2830,15 @@ function Onboarding({ onDone }) {
|
|
|
2748
2830
|
)
|
|
2749
2831
|
] })
|
|
2750
2832
|
] }),
|
|
2751
|
-
step === "model" && /* @__PURE__ */
|
|
2752
|
-
/* @__PURE__ */
|
|
2753
|
-
/* @__PURE__ */
|
|
2833
|
+
step === "model" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2834
|
+
/* @__PURE__ */ jsx11(Text11, { children: "Model ID (press Enter for default)" }),
|
|
2835
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", dimColor: true, children: [
|
|
2754
2836
|
"default: ",
|
|
2755
2837
|
DEFAULT_MODEL
|
|
2756
2838
|
] }),
|
|
2757
|
-
/* @__PURE__ */
|
|
2758
|
-
/* @__PURE__ */
|
|
2759
|
-
/* @__PURE__ */
|
|
2839
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
2840
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "\u203A " }),
|
|
2841
|
+
/* @__PURE__ */ jsx11(
|
|
2760
2842
|
CustomTextInput,
|
|
2761
2843
|
{
|
|
2762
2844
|
value: model,
|
|
@@ -2766,10 +2848,10 @@ function Onboarding({ onDone }) {
|
|
|
2766
2848
|
)
|
|
2767
2849
|
] })
|
|
2768
2850
|
] }),
|
|
2769
|
-
step === "confirm" && /* @__PURE__ */
|
|
2770
|
-
/* @__PURE__ */
|
|
2771
|
-
/* @__PURE__ */
|
|
2772
|
-
|
|
2851
|
+
step === "confirm" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2852
|
+
/* @__PURE__ */ jsx11(Text11, { children: "Ready to save configuration" }),
|
|
2853
|
+
/* @__PURE__ */ jsxs10(
|
|
2854
|
+
Box10,
|
|
2773
2855
|
{
|
|
2774
2856
|
flexDirection: "column",
|
|
2775
2857
|
marginTop: 1,
|
|
@@ -2778,25 +2860,25 @@ function Onboarding({ onDone }) {
|
|
|
2778
2860
|
borderColor: "gray",
|
|
2779
2861
|
paddingX: 1,
|
|
2780
2862
|
children: [
|
|
2781
|
-
/* @__PURE__ */
|
|
2863
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2782
2864
|
"Account ID: ",
|
|
2783
2865
|
accountId
|
|
2784
2866
|
] }),
|
|
2785
|
-
/* @__PURE__ */
|
|
2867
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2786
2868
|
"API Token: ",
|
|
2787
2869
|
"\u2022".repeat(apiToken.length)
|
|
2788
2870
|
] }),
|
|
2789
|
-
/* @__PURE__ */
|
|
2871
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2790
2872
|
"Model: ",
|
|
2791
2873
|
model
|
|
2792
2874
|
] })
|
|
2793
2875
|
]
|
|
2794
2876
|
}
|
|
2795
2877
|
),
|
|
2796
|
-
/* @__PURE__ */
|
|
2797
|
-
/* @__PURE__ */
|
|
2798
|
-
/* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
2878
|
+
/* @__PURE__ */ jsx11(Text11, { children: "Press Enter to confirm, or Ctrl+C to cancel" }),
|
|
2879
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
2880
|
+
/* @__PURE__ */ jsx11(Text11, { color: "cyan", children: "\u203A " }),
|
|
2881
|
+
/* @__PURE__ */ jsx11(
|
|
2800
2882
|
CustomTextInput,
|
|
2801
2883
|
{
|
|
2802
2884
|
value: "",
|
|
@@ -2807,7 +2889,7 @@ function Onboarding({ onDone }) {
|
|
|
2807
2889
|
)
|
|
2808
2890
|
] })
|
|
2809
2891
|
] }),
|
|
2810
|
-
savedPath && /* @__PURE__ */
|
|
2892
|
+
savedPath && /* @__PURE__ */ jsxs10(Text11, { color: "green", children: [
|
|
2811
2893
|
"Config saved to ",
|
|
2812
2894
|
savedPath
|
|
2813
2895
|
] })
|
|
@@ -2825,26 +2907,26 @@ var init_onboarding = __esm({
|
|
|
2825
2907
|
});
|
|
2826
2908
|
|
|
2827
2909
|
// src/ui/welcome.tsx
|
|
2828
|
-
import { Box as
|
|
2829
|
-
import { jsx as
|
|
2910
|
+
import { Box as Box11, Text as Text12 } from "ink";
|
|
2911
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2830
2912
|
function Welcome({ theme }) {
|
|
2831
|
-
return /* @__PURE__ */
|
|
2832
|
-
/* @__PURE__ */
|
|
2833
|
-
/* @__PURE__ */
|
|
2834
|
-
/* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
|
|
2914
|
+
/* @__PURE__ */ jsxs11(Box11, { marginBottom: 1, children: [
|
|
2915
|
+
/* @__PURE__ */ jsx12(Text12, { bold: true, color: theme.accent, children: "kimiflare" }),
|
|
2916
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
2835
2917
|
" ",
|
|
2836
2918
|
"Ready when you are."
|
|
2837
2919
|
] })
|
|
2838
2920
|
] }),
|
|
2839
|
-
/* @__PURE__ */
|
|
2840
|
-
/* @__PURE__ */
|
|
2921
|
+
/* @__PURE__ */ jsx12(Box11, { flexDirection: "column", children: SUGGESTIONS.map((s, i) => /* @__PURE__ */ jsxs11(Box11, { children: [
|
|
2922
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
2841
2923
|
" ",
|
|
2842
2924
|
"\u203A",
|
|
2843
2925
|
" "
|
|
2844
2926
|
] }),
|
|
2845
|
-
/* @__PURE__ */
|
|
2927
|
+
/* @__PURE__ */ jsx12(Text12, { color: theme.user, children: s })
|
|
2846
2928
|
] }, i)) }),
|
|
2847
|
-
/* @__PURE__ */
|
|
2929
|
+
/* @__PURE__ */ jsx12(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text12, { color: theme.info.color, dimColor: theme.info.dim, children: "Type a message or /help for commands \xB7 ctrl-c to exit \xB7 shift+tab to cycle modes" }) })
|
|
2848
2930
|
] });
|
|
2849
2931
|
}
|
|
2850
2932
|
var SUGGESTIONS;
|
|
@@ -2867,7 +2949,10 @@ function resolveTheme(name) {
|
|
|
2867
2949
|
function themeNames() {
|
|
2868
2950
|
return Object.keys(THEMES);
|
|
2869
2951
|
}
|
|
2870
|
-
|
|
2952
|
+
function themeList() {
|
|
2953
|
+
return Object.values(THEMES);
|
|
2954
|
+
}
|
|
2955
|
+
var dark, light, highContrast, dracula, nord, oneDark, monokai, solarizedDark, solarizedLight, tokyoNight, gruvboxDark, gruvboxLight, catppuccinMocha, rosePine, THEMES, DEFAULT_THEME_NAME;
|
|
2871
2956
|
var init_theme = __esm({
|
|
2872
2957
|
"src/ui/theme.ts"() {
|
|
2873
2958
|
"use strict";
|
|
@@ -2919,10 +3004,197 @@ var init_theme = __esm({
|
|
|
2919
3004
|
accent: "cyanBright",
|
|
2920
3005
|
modeBadge: { plan: "blueBright", auto: "greenBright", edit: "cyanBright" }
|
|
2921
3006
|
};
|
|
3007
|
+
dracula = {
|
|
3008
|
+
name: "dracula",
|
|
3009
|
+
label: "dracula (purple & cyan, popular dark)",
|
|
3010
|
+
user: "cyanBright",
|
|
3011
|
+
assistant: void 0,
|
|
3012
|
+
reasoning: { color: "magenta", dim: true },
|
|
3013
|
+
info: { color: "gray", dim: true },
|
|
3014
|
+
error: "redBright",
|
|
3015
|
+
warn: "yellowBright",
|
|
3016
|
+
tool: "magentaBright",
|
|
3017
|
+
spinner: "cyanBright",
|
|
3018
|
+
permission: "yellowBright",
|
|
3019
|
+
queue: { color: "gray", dim: true },
|
|
3020
|
+
accent: "magentaBright",
|
|
3021
|
+
modeBadge: { plan: "blueBright", auto: "greenBright", edit: "magentaBright" }
|
|
3022
|
+
};
|
|
3023
|
+
nord = {
|
|
3024
|
+
name: "nord",
|
|
3025
|
+
label: "nord (arctic blue & frost, calm dark)",
|
|
3026
|
+
user: "cyan",
|
|
3027
|
+
assistant: void 0,
|
|
3028
|
+
reasoning: { color: "blue", dim: true },
|
|
3029
|
+
info: { color: "blue", dim: true },
|
|
3030
|
+
error: "red",
|
|
3031
|
+
warn: "yellow",
|
|
3032
|
+
tool: "cyan",
|
|
3033
|
+
spinner: "cyan",
|
|
3034
|
+
permission: "yellow",
|
|
3035
|
+
queue: { color: "blue", dim: true },
|
|
3036
|
+
accent: "cyan",
|
|
3037
|
+
modeBadge: { plan: "blue", auto: "green", edit: "cyan" }
|
|
3038
|
+
};
|
|
3039
|
+
oneDark = {
|
|
3040
|
+
name: "one-dark",
|
|
3041
|
+
label: "one-dark (Atom's classic dark)",
|
|
3042
|
+
user: "cyan",
|
|
3043
|
+
assistant: void 0,
|
|
3044
|
+
reasoning: { color: "gray", dim: true },
|
|
3045
|
+
info: { color: "gray", dim: true },
|
|
3046
|
+
error: "red",
|
|
3047
|
+
warn: "yellow",
|
|
3048
|
+
tool: "blue",
|
|
3049
|
+
spinner: "cyan",
|
|
3050
|
+
permission: "yellow",
|
|
3051
|
+
queue: { color: "gray", dim: true },
|
|
3052
|
+
accent: "blue",
|
|
3053
|
+
modeBadge: { plan: "blue", auto: "green", edit: "cyan" }
|
|
3054
|
+
};
|
|
3055
|
+
monokai = {
|
|
3056
|
+
name: "monokai",
|
|
3057
|
+
label: "monokai (vibrant magenta & yellow)",
|
|
3058
|
+
user: "magentaBright",
|
|
3059
|
+
assistant: void 0,
|
|
3060
|
+
reasoning: { color: "gray", dim: true },
|
|
3061
|
+
info: { color: "gray", dim: true },
|
|
3062
|
+
error: "redBright",
|
|
3063
|
+
warn: "yellowBright",
|
|
3064
|
+
tool: "cyanBright",
|
|
3065
|
+
spinner: "yellowBright",
|
|
3066
|
+
permission: "yellowBright",
|
|
3067
|
+
queue: { color: "gray", dim: true },
|
|
3068
|
+
accent: "magentaBright",
|
|
3069
|
+
modeBadge: { plan: "blueBright", auto: "greenBright", edit: "magentaBright" }
|
|
3070
|
+
};
|
|
3071
|
+
solarizedDark = {
|
|
3072
|
+
name: "solarized-dark",
|
|
3073
|
+
label: "solarized-dark (muted blue & yellow)",
|
|
3074
|
+
user: "cyan",
|
|
3075
|
+
assistant: void 0,
|
|
3076
|
+
reasoning: { color: "blue", dim: true },
|
|
3077
|
+
info: { color: "blue", dim: true },
|
|
3078
|
+
error: "red",
|
|
3079
|
+
warn: "yellow",
|
|
3080
|
+
tool: "cyan",
|
|
3081
|
+
spinner: "yellow",
|
|
3082
|
+
permission: "yellow",
|
|
3083
|
+
queue: { color: "blue", dim: true },
|
|
3084
|
+
accent: "cyan",
|
|
3085
|
+
modeBadge: { plan: "blue", auto: "green", edit: "cyan" }
|
|
3086
|
+
};
|
|
3087
|
+
solarizedLight = {
|
|
3088
|
+
name: "solarized-light",
|
|
3089
|
+
label: "solarized-light (light beige & cyan)",
|
|
3090
|
+
user: "blue",
|
|
3091
|
+
assistant: void 0,
|
|
3092
|
+
reasoning: { color: "cyan", dim: false },
|
|
3093
|
+
info: { color: "cyan", dim: false },
|
|
3094
|
+
error: "red",
|
|
3095
|
+
warn: "yellow",
|
|
3096
|
+
tool: "blue",
|
|
3097
|
+
spinner: "blue",
|
|
3098
|
+
permission: "yellow",
|
|
3099
|
+
queue: { color: "cyan", dim: false },
|
|
3100
|
+
accent: "blue",
|
|
3101
|
+
modeBadge: { plan: "blue", auto: "green", edit: "blue" }
|
|
3102
|
+
};
|
|
3103
|
+
tokyoNight = {
|
|
3104
|
+
name: "tokyo-night",
|
|
3105
|
+
label: "tokyo-night (deep blue & purple)",
|
|
3106
|
+
user: "cyanBright",
|
|
3107
|
+
assistant: void 0,
|
|
3108
|
+
reasoning: { color: "blue", dim: true },
|
|
3109
|
+
info: { color: "blue", dim: true },
|
|
3110
|
+
error: "redBright",
|
|
3111
|
+
warn: "yellow",
|
|
3112
|
+
tool: "magentaBright",
|
|
3113
|
+
spinner: "cyanBright",
|
|
3114
|
+
permission: "yellow",
|
|
3115
|
+
queue: { color: "blue", dim: true },
|
|
3116
|
+
accent: "magentaBright",
|
|
3117
|
+
modeBadge: { plan: "blueBright", auto: "greenBright", edit: "magentaBright" }
|
|
3118
|
+
};
|
|
3119
|
+
gruvboxDark = {
|
|
3120
|
+
name: "gruvbox-dark",
|
|
3121
|
+
label: "gruvbox-dark (warm retro dark)",
|
|
3122
|
+
user: "yellow",
|
|
3123
|
+
assistant: void 0,
|
|
3124
|
+
reasoning: { color: "gray", dim: true },
|
|
3125
|
+
info: { color: "gray", dim: true },
|
|
3126
|
+
error: "red",
|
|
3127
|
+
warn: "yellowBright",
|
|
3128
|
+
tool: "cyan",
|
|
3129
|
+
spinner: "yellow",
|
|
3130
|
+
permission: "yellowBright",
|
|
3131
|
+
queue: { color: "gray", dim: true },
|
|
3132
|
+
accent: "yellow",
|
|
3133
|
+
modeBadge: { plan: "blue", auto: "green", edit: "yellow" }
|
|
3134
|
+
};
|
|
3135
|
+
gruvboxLight = {
|
|
3136
|
+
name: "gruvbox-light",
|
|
3137
|
+
label: "gruvbox-light (warm retro light)",
|
|
3138
|
+
user: "blue",
|
|
3139
|
+
assistant: void 0,
|
|
3140
|
+
reasoning: { color: "blackBright", dim: false },
|
|
3141
|
+
info: { color: "blackBright", dim: false },
|
|
3142
|
+
error: "red",
|
|
3143
|
+
warn: "yellow",
|
|
3144
|
+
tool: "cyan",
|
|
3145
|
+
spinner: "blue",
|
|
3146
|
+
permission: "yellow",
|
|
3147
|
+
queue: { color: "blackBright", dim: false },
|
|
3148
|
+
accent: "blue",
|
|
3149
|
+
modeBadge: { plan: "blue", auto: "green", edit: "blue" }
|
|
3150
|
+
};
|
|
3151
|
+
catppuccinMocha = {
|
|
3152
|
+
name: "catppuccin-mocha",
|
|
3153
|
+
label: "catppuccin-mocha (pastel pink & lavender)",
|
|
3154
|
+
user: "magentaBright",
|
|
3155
|
+
assistant: void 0,
|
|
3156
|
+
reasoning: { color: "gray", dim: true },
|
|
3157
|
+
info: { color: "gray", dim: true },
|
|
3158
|
+
error: "redBright",
|
|
3159
|
+
warn: "yellow",
|
|
3160
|
+
tool: "cyanBright",
|
|
3161
|
+
spinner: "cyanBright",
|
|
3162
|
+
permission: "yellow",
|
|
3163
|
+
queue: { color: "gray", dim: true },
|
|
3164
|
+
accent: "magentaBright",
|
|
3165
|
+
modeBadge: { plan: "blueBright", auto: "greenBright", edit: "magentaBright" }
|
|
3166
|
+
};
|
|
3167
|
+
rosePine = {
|
|
3168
|
+
name: "rose-pine",
|
|
3169
|
+
label: "rose-pine (soft rose & foam)",
|
|
3170
|
+
user: "magenta",
|
|
3171
|
+
assistant: void 0,
|
|
3172
|
+
reasoning: { color: "gray", dim: true },
|
|
3173
|
+
info: { color: "gray", dim: true },
|
|
3174
|
+
error: "red",
|
|
3175
|
+
warn: "yellow",
|
|
3176
|
+
tool: "cyan",
|
|
3177
|
+
spinner: "magenta",
|
|
3178
|
+
permission: "yellow",
|
|
3179
|
+
queue: { color: "gray", dim: true },
|
|
3180
|
+
accent: "magenta",
|
|
3181
|
+
modeBadge: { plan: "blue", auto: "green", edit: "magenta" }
|
|
3182
|
+
};
|
|
2922
3183
|
THEMES = {
|
|
2923
3184
|
dark,
|
|
2924
3185
|
light,
|
|
2925
|
-
"high-contrast": highContrast
|
|
3186
|
+
"high-contrast": highContrast,
|
|
3187
|
+
dracula,
|
|
3188
|
+
nord,
|
|
3189
|
+
"one-dark": oneDark,
|
|
3190
|
+
monokai,
|
|
3191
|
+
"solarized-dark": solarizedDark,
|
|
3192
|
+
"solarized-light": solarizedLight,
|
|
3193
|
+
"tokyo-night": tokyoNight,
|
|
3194
|
+
"gruvbox-dark": gruvboxDark,
|
|
3195
|
+
"gruvbox-light": gruvboxLight,
|
|
3196
|
+
"catppuccin-mocha": catppuccinMocha,
|
|
3197
|
+
"rose-pine": rosePine
|
|
2926
3198
|
};
|
|
2927
3199
|
DEFAULT_THEME_NAME = "dark";
|
|
2928
3200
|
}
|
|
@@ -2997,36 +3269,40 @@ var app_exports = {};
|
|
|
2997
3269
|
__export(app_exports, {
|
|
2998
3270
|
renderApp: () => renderApp
|
|
2999
3271
|
});
|
|
3000
|
-
import { useState as
|
|
3001
|
-
import { Box as
|
|
3272
|
+
import { useState as useState6, useRef as useRef2, useEffect as useEffect4, useCallback } from "react";
|
|
3273
|
+
import { Box as Box12, Text as Text13, useApp, useInput as useInput2, render } from "ink";
|
|
3002
3274
|
import { existsSync } from "fs";
|
|
3003
3275
|
import { join as join5 } from "path";
|
|
3004
3276
|
import { unlink } from "fs/promises";
|
|
3005
|
-
import { jsx as
|
|
3006
|
-
function App({ initialCfg }) {
|
|
3277
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3278
|
+
function App({ initialCfg, initialUpdateResult }) {
|
|
3007
3279
|
const { exit } = useApp();
|
|
3008
|
-
const [cfg, setCfg] =
|
|
3009
|
-
const [events, setEvents] =
|
|
3010
|
-
const [input, setInput] =
|
|
3011
|
-
const [busy, setBusy] =
|
|
3012
|
-
const [usage, setUsage] =
|
|
3013
|
-
const [showReasoning, setShowReasoning] =
|
|
3014
|
-
const [perm, setPerm] =
|
|
3015
|
-
const [queue, setQueue] =
|
|
3016
|
-
const [history, setHistory] =
|
|
3017
|
-
const [historyIndex, setHistoryIndex] =
|
|
3018
|
-
const [draftInput, setDraftInput] =
|
|
3019
|
-
const [mode, setMode] =
|
|
3020
|
-
const [effort, setEffort] =
|
|
3280
|
+
const [cfg, setCfg] = useState6(initialCfg);
|
|
3281
|
+
const [events, setEvents] = useState6([]);
|
|
3282
|
+
const [input, setInput] = useState6("");
|
|
3283
|
+
const [busy, setBusy] = useState6(false);
|
|
3284
|
+
const [usage, setUsage] = useState6(null);
|
|
3285
|
+
const [showReasoning, setShowReasoning] = useState6(false);
|
|
3286
|
+
const [perm, setPerm] = useState6(null);
|
|
3287
|
+
const [queue, setQueue] = useState6([]);
|
|
3288
|
+
const [history, setHistory] = useState6([]);
|
|
3289
|
+
const [historyIndex, setHistoryIndex] = useState6(-1);
|
|
3290
|
+
const [draftInput, setDraftInput] = useState6("");
|
|
3291
|
+
const [mode, setMode] = useState6("edit");
|
|
3292
|
+
const [effort, setEffort] = useState6(
|
|
3021
3293
|
initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
|
|
3022
3294
|
);
|
|
3023
|
-
const [theme, setTheme] =
|
|
3024
|
-
const [resumeSessions, setResumeSessions] =
|
|
3025
|
-
const [
|
|
3026
|
-
const [
|
|
3027
|
-
const [
|
|
3028
|
-
const [
|
|
3029
|
-
const [
|
|
3295
|
+
const [theme, setTheme] = useState6(resolveTheme(initialCfg?.theme));
|
|
3296
|
+
const [resumeSessions, setResumeSessions] = useState6(null);
|
|
3297
|
+
const [showThemePicker, setShowThemePicker] = useState6(false);
|
|
3298
|
+
const [originalTheme, setOriginalTheme] = useState6(null);
|
|
3299
|
+
const [tasks, setTasks] = useState6([]);
|
|
3300
|
+
const [tasksStartedAt, setTasksStartedAt] = useState6(null);
|
|
3301
|
+
const [tasksStartTokens, setTasksStartTokens] = useState6(0);
|
|
3302
|
+
const [turnStartedAt, setTurnStartedAt] = useState6(null);
|
|
3303
|
+
const [verbose, setVerbose] = useState6(false);
|
|
3304
|
+
const [hasUpdate, setHasUpdate] = useState6(initialUpdateResult?.hasUpdate ?? false);
|
|
3305
|
+
const [latestVersion, setLatestVersion] = useState6(initialUpdateResult?.latestVersion ?? null);
|
|
3030
3306
|
const messagesRef = useRef2([
|
|
3031
3307
|
{
|
|
3032
3308
|
role: "system",
|
|
@@ -3047,12 +3323,42 @@ function App({ initialCfg }) {
|
|
|
3047
3323
|
const tasksRef = useRef2([]);
|
|
3048
3324
|
const usageRef = useRef2(null);
|
|
3049
3325
|
const updateCheckedRef = useRef2(false);
|
|
3326
|
+
const updateNudgedRef = useRef2(false);
|
|
3050
3327
|
const compactSuggestedRef = useRef2(false);
|
|
3051
3328
|
useEffect4(() => {
|
|
3052
3329
|
if (!cfg || updateCheckedRef.current) return;
|
|
3053
3330
|
updateCheckedRef.current = true;
|
|
3331
|
+
if (initialUpdateResult) {
|
|
3332
|
+
if (initialUpdateResult.hasUpdate && !updateNudgedRef.current) {
|
|
3333
|
+
updateNudgedRef.current = true;
|
|
3334
|
+
setHasUpdate(true);
|
|
3335
|
+
setLatestVersion(initialUpdateResult.latestVersion);
|
|
3336
|
+
setEvents((e) => [
|
|
3337
|
+
...e,
|
|
3338
|
+
{
|
|
3339
|
+
kind: "info",
|
|
3340
|
+
key: mkKey(),
|
|
3341
|
+
text: `update available: ${initialUpdateResult.localVersion} \u2192 ${initialUpdateResult.latestVersion}`
|
|
3342
|
+
}
|
|
3343
|
+
]);
|
|
3344
|
+
void isGitRepo().then((git) => {
|
|
3345
|
+
setEvents((e) => [
|
|
3346
|
+
...e,
|
|
3347
|
+
{
|
|
3348
|
+
kind: "info",
|
|
3349
|
+
key: mkKey(),
|
|
3350
|
+
text: git ? "run: git pull && npm install && npm run build then restart kimiflare" : "run: npm update -g kimiflare then restart"
|
|
3351
|
+
}
|
|
3352
|
+
]);
|
|
3353
|
+
});
|
|
3354
|
+
}
|
|
3355
|
+
return;
|
|
3356
|
+
}
|
|
3054
3357
|
void checkForUpdate().then((result) => {
|
|
3055
|
-
if (result.hasUpdate) {
|
|
3358
|
+
if (result.hasUpdate && !updateNudgedRef.current) {
|
|
3359
|
+
updateNudgedRef.current = true;
|
|
3360
|
+
setHasUpdate(true);
|
|
3361
|
+
setLatestVersion(result.latestVersion);
|
|
3056
3362
|
setEvents((e) => [
|
|
3057
3363
|
...e,
|
|
3058
3364
|
{
|
|
@@ -3073,7 +3379,7 @@ function App({ initialCfg }) {
|
|
|
3073
3379
|
});
|
|
3074
3380
|
}
|
|
3075
3381
|
});
|
|
3076
|
-
}, [cfg]);
|
|
3382
|
+
}, [cfg, initialUpdateResult]);
|
|
3077
3383
|
useEffect4(() => {
|
|
3078
3384
|
modeRef.current = mode;
|
|
3079
3385
|
messagesRef.current[0] = {
|
|
@@ -3092,6 +3398,39 @@ function App({ initialCfg }) {
|
|
|
3092
3398
|
useEffect4(() => {
|
|
3093
3399
|
effortRef.current = effort;
|
|
3094
3400
|
}, [effort]);
|
|
3401
|
+
useEffect4(() => {
|
|
3402
|
+
if (!cfg) return;
|
|
3403
|
+
const id = setInterval(() => {
|
|
3404
|
+
void checkForUpdate().then((result) => {
|
|
3405
|
+
if (result.hasUpdate) {
|
|
3406
|
+
setHasUpdate(true);
|
|
3407
|
+
setLatestVersion(result.latestVersion);
|
|
3408
|
+
if (!updateNudgedRef.current) {
|
|
3409
|
+
updateNudgedRef.current = true;
|
|
3410
|
+
setEvents((e) => [
|
|
3411
|
+
...e,
|
|
3412
|
+
{
|
|
3413
|
+
kind: "info",
|
|
3414
|
+
key: mkKey(),
|
|
3415
|
+
text: `update available: ${result.localVersion} \u2192 ${result.latestVersion}`
|
|
3416
|
+
}
|
|
3417
|
+
]);
|
|
3418
|
+
void isGitRepo().then((git) => {
|
|
3419
|
+
setEvents((e) => [
|
|
3420
|
+
...e,
|
|
3421
|
+
{
|
|
3422
|
+
kind: "info",
|
|
3423
|
+
key: mkKey(),
|
|
3424
|
+
text: git ? "run: git pull && npm install && npm run build then restart kimiflare" : "run: npm update -g kimiflare then restart"
|
|
3425
|
+
}
|
|
3426
|
+
]);
|
|
3427
|
+
});
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
});
|
|
3431
|
+
}, 30 * 60 * 1e3);
|
|
3432
|
+
return () => clearInterval(id);
|
|
3433
|
+
}, [cfg]);
|
|
3095
3434
|
const saveSessionSafe = useCallback(async () => {
|
|
3096
3435
|
if (!cfg) return;
|
|
3097
3436
|
if (!sessionIdRef.current) {
|
|
@@ -3134,6 +3473,11 @@ function App({ initialCfg }) {
|
|
|
3134
3473
|
setVerbose((v) => !v);
|
|
3135
3474
|
return;
|
|
3136
3475
|
}
|
|
3476
|
+
if (key.ctrl && inputChar === "t") {
|
|
3477
|
+
setOriginalTheme(theme);
|
|
3478
|
+
setShowThemePicker(true);
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3137
3481
|
});
|
|
3138
3482
|
const updateAssistant = useCallback(
|
|
3139
3483
|
(id, patch) => {
|
|
@@ -3204,7 +3548,7 @@ function App({ initialCfg }) {
|
|
|
3204
3548
|
}
|
|
3205
3549
|
}, [cfg, busy, saveSessionSafe]);
|
|
3206
3550
|
const openResumePicker = useCallback(async () => {
|
|
3207
|
-
const sessions = await listSessions(
|
|
3551
|
+
const sessions = await listSessions(200);
|
|
3208
3552
|
setResumeSessions(sessions);
|
|
3209
3553
|
}, []);
|
|
3210
3554
|
const runInit = useCallback(async () => {
|
|
@@ -3372,6 +3716,27 @@ function App({ initialCfg }) {
|
|
|
3372
3716
|
},
|
|
3373
3717
|
[]
|
|
3374
3718
|
);
|
|
3719
|
+
const handleThemePick = useCallback(
|
|
3720
|
+
(picked) => {
|
|
3721
|
+
if (!picked) {
|
|
3722
|
+
if (originalTheme) setTheme(originalTheme);
|
|
3723
|
+
setShowThemePicker(false);
|
|
3724
|
+
setOriginalTheme(null);
|
|
3725
|
+
return;
|
|
3726
|
+
}
|
|
3727
|
+
setTheme(picked);
|
|
3728
|
+
setCfg((c) => c ? { ...c, theme: picked.name } : c);
|
|
3729
|
+
if (cfg) void saveConfig({ ...cfg, theme: picked.name }).catch(() => {
|
|
3730
|
+
});
|
|
3731
|
+
setShowThemePicker(false);
|
|
3732
|
+
setOriginalTheme(null);
|
|
3733
|
+
setEvents((e) => [
|
|
3734
|
+
...e,
|
|
3735
|
+
{ kind: "info", key: mkKey(), text: `theme: ${picked.label}` }
|
|
3736
|
+
]);
|
|
3737
|
+
},
|
|
3738
|
+
[cfg, originalTheme]
|
|
3739
|
+
);
|
|
3375
3740
|
const handleSlash = useCallback(
|
|
3376
3741
|
(cmd) => {
|
|
3377
3742
|
const raw = cmd.trim();
|
|
@@ -3391,6 +3756,7 @@ function App({ initialCfg }) {
|
|
|
3391
3756
|
setTasksStartedAt(null);
|
|
3392
3757
|
setTasksStartTokens(0);
|
|
3393
3758
|
compactSuggestedRef.current = false;
|
|
3759
|
+
updateNudgedRef.current = false;
|
|
3394
3760
|
return true;
|
|
3395
3761
|
}
|
|
3396
3762
|
if (c === "/reasoning") {
|
|
@@ -3457,14 +3823,8 @@ use: /thinking low | medium | high`
|
|
|
3457
3823
|
}
|
|
3458
3824
|
if (c === "/theme") {
|
|
3459
3825
|
if (!arg) {
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
{
|
|
3463
|
-
kind: "info",
|
|
3464
|
-
key: mkKey(),
|
|
3465
|
-
text: `current: ${theme.name} \xB7 available: ${themeNames().join(", ")}`
|
|
3466
|
-
}
|
|
3467
|
-
]);
|
|
3826
|
+
setOriginalTheme(theme);
|
|
3827
|
+
setShowThemePicker(true);
|
|
3468
3828
|
return true;
|
|
3469
3829
|
}
|
|
3470
3830
|
const next = resolveTheme(arg);
|
|
@@ -3535,8 +3895,10 @@ use: /thinking low | medium | high`
|
|
|
3535
3895
|
return true;
|
|
3536
3896
|
}
|
|
3537
3897
|
if (c === "/update") {
|
|
3538
|
-
void checkForUpdate().then((result) => {
|
|
3898
|
+
void checkForUpdate(true).then((result) => {
|
|
3539
3899
|
if (result.hasUpdate) {
|
|
3900
|
+
setHasUpdate(true);
|
|
3901
|
+
setLatestVersion(result.latestVersion);
|
|
3540
3902
|
setEvents((e) => [
|
|
3541
3903
|
...e,
|
|
3542
3904
|
{
|
|
@@ -3556,6 +3918,8 @@ use: /thinking low | medium | high`
|
|
|
3556
3918
|
]);
|
|
3557
3919
|
});
|
|
3558
3920
|
} else {
|
|
3921
|
+
setHasUpdate(false);
|
|
3922
|
+
setLatestVersion(null);
|
|
3559
3923
|
setEvents((e) => [
|
|
3560
3924
|
...e,
|
|
3561
3925
|
{ kind: "info", key: mkKey(), text: "no update available" }
|
|
@@ -3580,7 +3944,7 @@ use: /thinking low | medium | high`
|
|
|
3580
3944
|
{
|
|
3581
3945
|
kind: "info",
|
|
3582
3946
|
key: mkKey(),
|
|
3583
|
-
text: "commands:\n /mode edit|plan|auto switch mode (or shift+tab to cycle)\n /plan /auto /edit shortcuts for /mode\n /thinking low|med|high set reasoning effort (quality vs speed)\n /theme NAME
|
|
3947
|
+
text: "commands:\n /mode edit|plan|auto switch mode (or shift+tab to cycle)\n /plan /auto /edit shortcuts for /mode\n /thinking low|med|high set reasoning effort (quality vs speed)\n /theme interactive theme picker (or ctrl+t)\n /theme NAME set theme by name\n /resume pick a past conversation\n /compact summarize old turns to free context\n /init scan this repo and write a KIMI.md for future agents\n /reasoning toggle show/hide model reasoning\n /clear clear current conversation\n /cost /model /update /logout /help /exit\nkeys: ctrl-c interrupt/exit \xB7 ctrl-r toggle reasoning \xB7 ctrl-o verbose \xB7 ctrl+t theme \xB7 shift+tab cycle mode \xB7 \u2191/\u2193 history"
|
|
3584
3948
|
}
|
|
3585
3949
|
]);
|
|
3586
3950
|
return true;
|
|
@@ -3762,7 +4126,7 @@ use: /thinking low | medium | high`
|
|
|
3762
4126
|
}
|
|
3763
4127
|
}, [usage]);
|
|
3764
4128
|
if (!cfg) {
|
|
3765
|
-
return /* @__PURE__ */
|
|
4129
|
+
return /* @__PURE__ */ jsx13(
|
|
3766
4130
|
Onboarding,
|
|
3767
4131
|
{
|
|
3768
4132
|
onDone: (newCfg) => {
|
|
@@ -3776,12 +4140,15 @@ use: /thinking low | medium | high`
|
|
|
3776
4140
|
);
|
|
3777
4141
|
}
|
|
3778
4142
|
if (resumeSessions !== null) {
|
|
3779
|
-
return /* @__PURE__ */
|
|
4143
|
+
return /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsx13(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick, theme }) });
|
|
4144
|
+
}
|
|
4145
|
+
if (showThemePicker) {
|
|
4146
|
+
return /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsx13(ThemePicker, { themes: themeList(), current: theme, onPick: handleThemePick }) });
|
|
3780
4147
|
}
|
|
3781
4148
|
const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
|
|
3782
|
-
return /* @__PURE__ */
|
|
3783
|
-
!hasConversation && events.length === 0 ? /* @__PURE__ */
|
|
3784
|
-
perm ? /* @__PURE__ */
|
|
4149
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
4150
|
+
!hasConversation && events.length === 0 ? /* @__PURE__ */ jsx13(Welcome, { theme }) : /* @__PURE__ */ jsx13(ChatView, { events, showReasoning, theme, verbose }),
|
|
4151
|
+
perm ? /* @__PURE__ */ jsx13(
|
|
3785
4152
|
PermissionModal,
|
|
3786
4153
|
{
|
|
3787
4154
|
tool: perm.tool,
|
|
@@ -3792,8 +4159,8 @@ use: /thinking low | medium | high`
|
|
|
3792
4159
|
setPerm(null);
|
|
3793
4160
|
}
|
|
3794
4161
|
}
|
|
3795
|
-
) : /* @__PURE__ */
|
|
3796
|
-
tasks.length > 0 && /* @__PURE__ */
|
|
4162
|
+
) : /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
4163
|
+
tasks.length > 0 && /* @__PURE__ */ jsx13(
|
|
3797
4164
|
TaskList,
|
|
3798
4165
|
{
|
|
3799
4166
|
tasks,
|
|
@@ -3802,11 +4169,11 @@ use: /thinking low | medium | high`
|
|
|
3802
4169
|
tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
|
|
3803
4170
|
}
|
|
3804
4171
|
),
|
|
3805
|
-
queue.length > 0 && /* @__PURE__ */
|
|
4172
|
+
queue.length > 0 && /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs12(Text13, { color: theme.queue.color, dimColor: theme.queue.dim, children: [
|
|
3806
4173
|
"\u23F3 ",
|
|
3807
4174
|
q.display
|
|
3808
4175
|
] }, `queue_${i}`)) }),
|
|
3809
|
-
/* @__PURE__ */
|
|
4176
|
+
/* @__PURE__ */ jsx13(
|
|
3810
4177
|
StatusBar,
|
|
3811
4178
|
{
|
|
3812
4179
|
model: cfg.model,
|
|
@@ -3816,12 +4183,14 @@ use: /thinking low | medium | high`
|
|
|
3816
4183
|
theme,
|
|
3817
4184
|
mode,
|
|
3818
4185
|
effort,
|
|
3819
|
-
contextLimit: CONTEXT_LIMIT
|
|
4186
|
+
contextLimit: CONTEXT_LIMIT,
|
|
4187
|
+
hasUpdate,
|
|
4188
|
+
latestVersion
|
|
3820
4189
|
}
|
|
3821
4190
|
),
|
|
3822
|
-
/* @__PURE__ */
|
|
3823
|
-
/* @__PURE__ */
|
|
3824
|
-
/* @__PURE__ */
|
|
4191
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, children: [
|
|
4192
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme.accent, children: "\u203A " }),
|
|
4193
|
+
/* @__PURE__ */ jsx13(
|
|
3825
4194
|
CustomTextInput,
|
|
3826
4195
|
{
|
|
3827
4196
|
value: input,
|
|
@@ -3869,8 +4238,8 @@ use: /thinking low | medium | high`
|
|
|
3869
4238
|
] })
|
|
3870
4239
|
] });
|
|
3871
4240
|
}
|
|
3872
|
-
async function renderApp(cfg) {
|
|
3873
|
-
const instance = render(/* @__PURE__ */
|
|
4241
|
+
async function renderApp(cfg, updateResult) {
|
|
4242
|
+
const instance = render(/* @__PURE__ */ jsx13(App, { initialCfg: cfg, initialUpdateResult: updateResult }));
|
|
3874
4243
|
await instance.waitUntilExit();
|
|
3875
4244
|
}
|
|
3876
4245
|
var CONTEXT_LIMIT, AUTO_COMPACT_SUGGEST_PCT, nextAssistantId, nextKey, mkKey, EFFORT_DESCRIPTIONS;
|
|
@@ -3886,6 +4255,7 @@ var init_app = __esm({
|
|
|
3886
4255
|
init_status();
|
|
3887
4256
|
init_permission();
|
|
3888
4257
|
init_resume_picker();
|
|
4258
|
+
init_theme_picker();
|
|
3889
4259
|
init_task_list();
|
|
3890
4260
|
init_text_input();
|
|
3891
4261
|
init_update_check();
|
|
@@ -3913,6 +4283,7 @@ init_config();
|
|
|
3913
4283
|
init_loop();
|
|
3914
4284
|
init_system_prompt();
|
|
3915
4285
|
init_executor();
|
|
4286
|
+
init_update_check();
|
|
3916
4287
|
import { Command } from "commander";
|
|
3917
4288
|
import { readFileSync as readFileSync2 } from "fs";
|
|
3918
4289
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -3931,6 +4302,7 @@ program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.
|
|
|
3931
4302
|
var opts = program.opts();
|
|
3932
4303
|
async function main() {
|
|
3933
4304
|
const cfg = await loadConfig();
|
|
4305
|
+
const updateResult = await checkForUpdate();
|
|
3934
4306
|
if (opts.print !== void 0) {
|
|
3935
4307
|
if (!cfg) {
|
|
3936
4308
|
console.error(
|
|
@@ -3944,7 +4316,8 @@ async function main() {
|
|
|
3944
4316
|
model,
|
|
3945
4317
|
prompt: opts.print,
|
|
3946
4318
|
allowAll: !!opts.dangerouslyAllowAll,
|
|
3947
|
-
showReasoning: !!opts.reasoning
|
|
4319
|
+
showReasoning: !!opts.reasoning,
|
|
4320
|
+
updateResult
|
|
3948
4321
|
});
|
|
3949
4322
|
return;
|
|
3950
4323
|
}
|
|
@@ -3957,12 +4330,21 @@ async function main() {
|
|
|
3957
4330
|
const { renderApp: renderApp2 } = await Promise.resolve().then(() => (init_app(), app_exports));
|
|
3958
4331
|
if (cfg) {
|
|
3959
4332
|
const model = opts.model ?? cfg.model ?? DEFAULT_MODEL;
|
|
3960
|
-
await renderApp2({ ...cfg, model });
|
|
4333
|
+
await renderApp2({ ...cfg, model }, updateResult);
|
|
3961
4334
|
} else {
|
|
3962
|
-
await renderApp2(null);
|
|
4335
|
+
await renderApp2(null, updateResult);
|
|
3963
4336
|
}
|
|
3964
4337
|
}
|
|
3965
4338
|
async function runPrintMode(opts2) {
|
|
4339
|
+
if (opts2.updateResult.hasUpdate) {
|
|
4340
|
+
const git = await isGitRepo();
|
|
4341
|
+
process.stderr.write(
|
|
4342
|
+
`\x1B[33mkimiflare update available: ${opts2.updateResult.localVersion} \u2192 ${opts2.updateResult.latestVersion}\x1B[0m
|
|
4343
|
+
\x1B[33m ${git ? "git pull && npm install && npm run build" : "npm update -g kimiflare"} then restart\x1B[0m
|
|
4344
|
+
|
|
4345
|
+
`
|
|
4346
|
+
);
|
|
4347
|
+
}
|
|
3966
4348
|
const cwd = process.cwd();
|
|
3967
4349
|
const executor = new ToolExecutor(ALL_TOOLS);
|
|
3968
4350
|
const messages = [
|