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