kimiflare 0.8.2 → 0.9.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/LICENSE +21 -0
- package/README.md +16 -4
- package/dist/index.js +61 -38
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sina Meraji
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/logo.png" alt="kimiflare" width="180">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/kimiflare"><img src="https://img.shields.io/npm/v/kimiflare?style=flat-square&color=cb3837" alt="npm version"></a>
|
|
7
|
+
<a href="https://github.com/sinameraji/kimiflare/blob/main/LICENSE"><img src="https://img.shields.io/github/license/sinameraji/kimiflare?style=flat-square&color=2ea44f" alt="license"></a>
|
|
8
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20-339933?style=flat-square&logo=nodedotjs&logoColor=white" alt="Node.js >= 20">
|
|
9
|
+
<img src="https://img.shields.io/badge/typescript-5.7-3178c6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript">
|
|
10
|
+
<a href="https://developers.cloudflare.com/workers-ai/models/kimi-k2.6/"><img src="https://img.shields.io/badge/powered%20by-Kimi--K2.6-f59e0b?style=flat-square" alt="Powered by Kimi-K2.6"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
A terminal coding agent powered by <strong><a href="https://developers.cloudflare.com/workers-ai/models/kimi-k2.6/">Kimi-K2.6</a></strong> on Cloudflare Workers AI. Moonshot's 1T-parameter open-source model runs directly on your Cloudflare account. You bring the token, your traffic goes straight to Cloudflare.
|
|
15
|
+
</p>
|
|
4
16
|
|
|
5
17
|
```
|
|
6
18
|
$ kimiflare
|
|
@@ -198,4 +210,4 @@ Early but functional. Transport + tools + agent loop + print mode are verified e
|
|
|
198
210
|
|
|
199
211
|
## License
|
|
200
212
|
|
|
201
|
-
|
|
213
|
+
[MIT](LICENSE) © Sina Meraji
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ function readCoauthorEnv() {
|
|
|
25
25
|
const enabled = process.env.KIMIFLARE_COAUTHOR;
|
|
26
26
|
if (enabled === "0" || enabled === "false") return void 0;
|
|
27
27
|
const name = process.env.KIMIFLARE_COAUTHOR_NAME || "kimiflare";
|
|
28
|
-
const email = process.env.KIMIFLARE_COAUTHOR_EMAIL || "
|
|
28
|
+
const email = process.env.KIMIFLARE_COAUTHOR_EMAIL || "kimiflare@proton.me";
|
|
29
29
|
return { enabled: true, name, email };
|
|
30
30
|
}
|
|
31
31
|
async function loadConfig() {
|
|
@@ -520,7 +520,7 @@ How to work:
|
|
|
520
520
|
- You have a 262k-token context window. Read as much of a file as needed rather than guessing.
|
|
521
521
|
- If a request is ambiguous, ask one focused question instead of making large assumptions.
|
|
522
522
|
- When you finish a task, stop. Do not add a closing summary.
|
|
523
|
-
- When creating git commits, you may include \`Co-authored-by: kimiflare <
|
|
523
|
+
- When creating git commits, you may include \`Co-authored-by: kimiflare <kimiflare@proton.me>\` in the commit message so kimiflare is credited as a contributor. The bash tool will also auto-append this trailer when it detects \`git commit\` commands.`;
|
|
524
524
|
const ctx = loadContextFile(opts2.cwd);
|
|
525
525
|
const contextBlock = ctx ? `
|
|
526
526
|
|
|
@@ -1474,10 +1474,11 @@ var init_tool_view = __esm({
|
|
|
1474
1474
|
});
|
|
1475
1475
|
|
|
1476
1476
|
// src/ui/markdown.tsx
|
|
1477
|
+
import { useMemo } from "react";
|
|
1477
1478
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
1478
1479
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1479
1480
|
function MD({ text, theme }) {
|
|
1480
|
-
const blocks = parseBlocks(text);
|
|
1481
|
+
const blocks = useMemo(() => parseBlocks(text), [text]);
|
|
1481
1482
|
return /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", children: blocks.map((b, i) => /* @__PURE__ */ jsx3(Block, { block: b, theme }, i)) });
|
|
1482
1483
|
}
|
|
1483
1484
|
function parseBlocks(src) {
|
|
@@ -1633,19 +1634,10 @@ var init_markdown = __esm({
|
|
|
1633
1634
|
});
|
|
1634
1635
|
|
|
1635
1636
|
// src/ui/chat.tsx
|
|
1637
|
+
import React2 from "react";
|
|
1636
1638
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
1637
1639
|
import Spinner2 from "ink-spinner";
|
|
1638
1640
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1639
|
-
function ChatView({ events, showReasoning, theme, verbose }) {
|
|
1640
|
-
return /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: events.map((e, i) => {
|
|
1641
|
-
const prev = events[i - 1];
|
|
1642
|
-
const showSeparator = e.kind === "user" && prev && (prev.kind === "assistant" || prev.kind === "tool");
|
|
1643
|
-
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
1644
|
-
showSeparator && /* @__PURE__ */ jsx4(Box4, { marginY: 1, children: /* @__PURE__ */ jsx4(Text4, { color: theme.info.color, dimColor: theme.info.dim, children: "\u2500".repeat(40) }) }),
|
|
1645
|
-
/* @__PURE__ */ jsx4(EventView, { evt: e, showReasoning, theme, verbose })
|
|
1646
|
-
] }, e.key);
|
|
1647
|
-
}) });
|
|
1648
|
-
}
|
|
1649
1641
|
function EventView({
|
|
1650
1642
|
evt,
|
|
1651
1643
|
showReasoning,
|
|
@@ -1686,11 +1678,22 @@ function EventView({
|
|
|
1686
1678
|
evt.text
|
|
1687
1679
|
] });
|
|
1688
1680
|
}
|
|
1681
|
+
var ChatView;
|
|
1689
1682
|
var init_chat = __esm({
|
|
1690
1683
|
"src/ui/chat.tsx"() {
|
|
1691
1684
|
"use strict";
|
|
1692
1685
|
init_tool_view();
|
|
1693
1686
|
init_markdown();
|
|
1687
|
+
ChatView = React2.memo(function ChatView2({ events, showReasoning, theme, verbose }) {
|
|
1688
|
+
return /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: events.map((e, i) => {
|
|
1689
|
+
const prev = events[i - 1];
|
|
1690
|
+
const showSeparator = e.kind === "user" && prev && (prev.kind === "assistant" || prev.kind === "tool");
|
|
1691
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
1692
|
+
showSeparator && /* @__PURE__ */ jsx4(Box4, { marginY: 1, children: /* @__PURE__ */ jsx4(Text4, { color: theme.info.color, dimColor: theme.info.dim, children: "\u2500".repeat(40) }) }),
|
|
1693
|
+
/* @__PURE__ */ jsx4(EventView, { evt: e, showReasoning, theme, verbose })
|
|
1694
|
+
] }, e.key);
|
|
1695
|
+
}) });
|
|
1696
|
+
});
|
|
1694
1697
|
}
|
|
1695
1698
|
});
|
|
1696
1699
|
|
|
@@ -1943,19 +1946,25 @@ var init_theme_picker = __esm({
|
|
|
1943
1946
|
});
|
|
1944
1947
|
|
|
1945
1948
|
// src/ui/task-list.tsx
|
|
1946
|
-
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
1949
|
+
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
1947
1950
|
import { Box as Box9, Text as Text9 } from "ink";
|
|
1948
1951
|
import Spinner4 from "ink-spinner";
|
|
1949
1952
|
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1950
1953
|
function TaskList({ tasks, theme, startedAt, tokensDelta }) {
|
|
1951
1954
|
const [now, setNow] = useState3(Date.now());
|
|
1955
|
+
const tasksRef = useRef(tasks);
|
|
1956
|
+
tasksRef.current = tasks;
|
|
1952
1957
|
useEffect2(() => {
|
|
1953
1958
|
if (startedAt === null) return;
|
|
1954
|
-
const
|
|
1955
|
-
|
|
1956
|
-
|
|
1959
|
+
const id = setInterval(() => {
|
|
1960
|
+
setNow(Date.now());
|
|
1961
|
+
const current = tasksRef.current;
|
|
1962
|
+
if (current.length > 0 && current.every((t) => t.status === "completed")) {
|
|
1963
|
+
clearInterval(id);
|
|
1964
|
+
}
|
|
1965
|
+
}, 1e3);
|
|
1957
1966
|
return () => clearInterval(id);
|
|
1958
|
-
}, [startedAt
|
|
1967
|
+
}, [startedAt]);
|
|
1959
1968
|
if (tasks.length === 0) return null;
|
|
1960
1969
|
const active = tasks.find((t) => t.status === "in_progress");
|
|
1961
1970
|
const done = tasks.filter((t) => t.status === "completed").length;
|
|
@@ -2547,7 +2556,7 @@ var init_source = __esm({
|
|
|
2547
2556
|
});
|
|
2548
2557
|
|
|
2549
2558
|
// src/ui/text-input.tsx
|
|
2550
|
-
import { useState as useState4, useEffect as useEffect3, useRef } from "react";
|
|
2559
|
+
import { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
2551
2560
|
import { Text as Text10, useInput } from "ink";
|
|
2552
2561
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2553
2562
|
function shouldTreatAsPaste(input) {
|
|
@@ -2583,7 +2592,7 @@ function CustomTextInput({
|
|
|
2583
2592
|
enablePaste = false
|
|
2584
2593
|
}) {
|
|
2585
2594
|
const [cursorOffset, setCursorOffset] = useState4(value.length);
|
|
2586
|
-
const pastesRef =
|
|
2595
|
+
const pastesRef = useRef2(/* @__PURE__ */ new Map());
|
|
2587
2596
|
useEffect3(() => {
|
|
2588
2597
|
if (!focus) return;
|
|
2589
2598
|
setCursorOffset((prev) => prev > value.length ? value.length : prev);
|
|
@@ -3269,16 +3278,29 @@ var app_exports = {};
|
|
|
3269
3278
|
__export(app_exports, {
|
|
3270
3279
|
renderApp: () => renderApp
|
|
3271
3280
|
});
|
|
3272
|
-
import { useState as useState6, useRef as
|
|
3281
|
+
import { useState as useState6, useRef as useRef3, useEffect as useEffect4, useCallback } from "react";
|
|
3273
3282
|
import { Box as Box12, Text as Text13, useApp, useInput as useInput2, render } from "ink";
|
|
3274
3283
|
import { existsSync } from "fs";
|
|
3275
3284
|
import { join as join5 } from "path";
|
|
3276
3285
|
import { unlink } from "fs/promises";
|
|
3277
3286
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3287
|
+
function capEvents(prev) {
|
|
3288
|
+
if (prev.length <= MAX_EVENTS) return prev;
|
|
3289
|
+
return prev.slice(prev.length - MAX_EVENTS);
|
|
3290
|
+
}
|
|
3278
3291
|
function App({ initialCfg, initialUpdateResult }) {
|
|
3279
3292
|
const { exit } = useApp();
|
|
3280
3293
|
const [cfg, setCfg] = useState6(initialCfg);
|
|
3281
|
-
const [events,
|
|
3294
|
+
const [events, setRawEvents] = useState6([]);
|
|
3295
|
+
const setEvents = useCallback(
|
|
3296
|
+
(updater) => {
|
|
3297
|
+
setRawEvents((prev) => {
|
|
3298
|
+
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
3299
|
+
return capEvents(next);
|
|
3300
|
+
});
|
|
3301
|
+
},
|
|
3302
|
+
[]
|
|
3303
|
+
);
|
|
3282
3304
|
const [input, setInput] = useState6("");
|
|
3283
3305
|
const [busy, setBusy] = useState6(false);
|
|
3284
3306
|
const [usage, setUsage] = useState6(null);
|
|
@@ -3303,7 +3325,7 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
3303
3325
|
const [verbose, setVerbose] = useState6(false);
|
|
3304
3326
|
const [hasUpdate, setHasUpdate] = useState6(initialUpdateResult?.hasUpdate ?? false);
|
|
3305
3327
|
const [latestVersion, setLatestVersion] = useState6(initialUpdateResult?.latestVersion ?? null);
|
|
3306
|
-
const messagesRef =
|
|
3328
|
+
const messagesRef = useRef3([
|
|
3307
3329
|
{
|
|
3308
3330
|
role: "system",
|
|
3309
3331
|
content: buildSystemPrompt({
|
|
@@ -3314,17 +3336,17 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
3314
3336
|
})
|
|
3315
3337
|
}
|
|
3316
3338
|
]);
|
|
3317
|
-
const executorRef =
|
|
3318
|
-
const activeAsstIdRef =
|
|
3319
|
-
const activeControllerRef =
|
|
3320
|
-
const sessionIdRef =
|
|
3321
|
-
const modeRef =
|
|
3322
|
-
const effortRef =
|
|
3323
|
-
const tasksRef =
|
|
3324
|
-
const usageRef =
|
|
3325
|
-
const updateCheckedRef =
|
|
3326
|
-
const updateNudgedRef =
|
|
3327
|
-
const compactSuggestedRef =
|
|
3339
|
+
const executorRef = useRef3(new ToolExecutor(ALL_TOOLS));
|
|
3340
|
+
const activeAsstIdRef = useRef3(null);
|
|
3341
|
+
const activeControllerRef = useRef3(null);
|
|
3342
|
+
const sessionIdRef = useRef3(null);
|
|
3343
|
+
const modeRef = useRef3(mode);
|
|
3344
|
+
const effortRef = useRef3(effort);
|
|
3345
|
+
const tasksRef = useRef3([]);
|
|
3346
|
+
const usageRef = useRef3(null);
|
|
3347
|
+
const updateCheckedRef = useRef3(false);
|
|
3348
|
+
const updateNudgedRef = useRef3(false);
|
|
3349
|
+
const compactSuggestedRef = useRef3(false);
|
|
3328
3350
|
useEffect4(() => {
|
|
3329
3351
|
if (!cfg || updateCheckedRef.current) return;
|
|
3330
3352
|
updateCheckedRef.current = true;
|
|
@@ -3603,7 +3625,7 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
3603
3625
|
cwd,
|
|
3604
3626
|
signal: controller.signal,
|
|
3605
3627
|
reasoningEffort: effortRef.current,
|
|
3606
|
-
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "
|
|
3628
|
+
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
3607
3629
|
callbacks: {
|
|
3608
3630
|
onAssistantStart: () => {
|
|
3609
3631
|
const id = nextAssistantId++;
|
|
@@ -3977,7 +3999,7 @@ use: /thinking low | medium | high`
|
|
|
3977
3999
|
cwd: process.cwd(),
|
|
3978
4000
|
signal: controller.signal,
|
|
3979
4001
|
reasoningEffort: effortRef.current,
|
|
3980
|
-
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "
|
|
4002
|
+
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
3981
4003
|
callbacks: {
|
|
3982
4004
|
onAssistantStart: () => {
|
|
3983
4005
|
const id = nextAssistantId++;
|
|
@@ -4242,7 +4264,7 @@ async function renderApp(cfg, updateResult) {
|
|
|
4242
4264
|
const instance = render(/* @__PURE__ */ jsx13(App, { initialCfg: cfg, initialUpdateResult: updateResult }));
|
|
4243
4265
|
await instance.waitUntilExit();
|
|
4244
4266
|
}
|
|
4245
|
-
var CONTEXT_LIMIT, AUTO_COMPACT_SUGGEST_PCT, nextAssistantId, nextKey, mkKey, EFFORT_DESCRIPTIONS;
|
|
4267
|
+
var CONTEXT_LIMIT, AUTO_COMPACT_SUGGEST_PCT, MAX_EVENTS, nextAssistantId, nextKey, mkKey, EFFORT_DESCRIPTIONS;
|
|
4246
4268
|
var init_app = __esm({
|
|
4247
4269
|
"src/app.tsx"() {
|
|
4248
4270
|
"use strict";
|
|
@@ -4267,6 +4289,7 @@ var init_app = __esm({
|
|
|
4267
4289
|
init_sessions();
|
|
4268
4290
|
CONTEXT_LIMIT = 262e3;
|
|
4269
4291
|
AUTO_COMPACT_SUGGEST_PCT = 0.8;
|
|
4292
|
+
MAX_EVENTS = 500;
|
|
4270
4293
|
nextAssistantId = 1;
|
|
4271
4294
|
nextKey = 1;
|
|
4272
4295
|
mkKey = () => `evt_${nextKey++}`;
|
|
@@ -4364,7 +4387,7 @@ async function runPrintMode(opts2) {
|
|
|
4364
4387
|
executor,
|
|
4365
4388
|
cwd,
|
|
4366
4389
|
signal: controller.signal,
|
|
4367
|
-
coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "
|
|
4390
|
+
coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
4368
4391
|
callbacks: {
|
|
4369
4392
|
onReasoningDelta: opts2.showReasoning ? (delta) => {
|
|
4370
4393
|
if (!printedReasoningHeader) {
|