kimiflare 0.34.1 → 0.35.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 +491 -152
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -96,6 +96,31 @@ async function loadConfig() {
|
|
|
96
96
|
const envCodeMode = readBooleanEnv("KIMIFLARE_CODE_MODE");
|
|
97
97
|
const envCostAttribution = readBooleanEnv("KIMI_COST_ATTRIBUTION");
|
|
98
98
|
const envFilePicker = readBooleanEnv("KIMIFLARE_FILE_PICKER");
|
|
99
|
+
const envCloudMode = readBooleanEnv("KIMIFLARE_CLOUD");
|
|
100
|
+
if (envCloudMode) {
|
|
101
|
+
return {
|
|
102
|
+
accountId: "",
|
|
103
|
+
apiToken: "",
|
|
104
|
+
model: envModel,
|
|
105
|
+
cloudMode: true,
|
|
106
|
+
reasoningEffort: envEffort,
|
|
107
|
+
coauthor: envCoauthor?.enabled ?? true,
|
|
108
|
+
coauthorName: envCoauthor?.name,
|
|
109
|
+
coauthorEmail: envCoauthor?.email,
|
|
110
|
+
cacheStablePrompts,
|
|
111
|
+
compiledContext,
|
|
112
|
+
imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? void 0 : imageHistoryTurns,
|
|
113
|
+
memoryEnabled: envMemoryEnabled,
|
|
114
|
+
memoryDbPath: envMemoryDbPath,
|
|
115
|
+
memoryMaxAgeDays: envMemoryMaxAgeDays,
|
|
116
|
+
memoryMaxEntries: envMemoryMaxEntries,
|
|
117
|
+
memoryEmbeddingModel: envMemoryEmbeddingModel,
|
|
118
|
+
plumbingModel: envPlumbingModel,
|
|
119
|
+
codeMode: envCodeMode,
|
|
120
|
+
costAttribution: envCostAttribution ?? false,
|
|
121
|
+
filePicker: envFilePicker ?? true
|
|
122
|
+
};
|
|
123
|
+
}
|
|
99
124
|
if (envAccount && envToken) {
|
|
100
125
|
return {
|
|
101
126
|
accountId: envAccount,
|
|
@@ -128,6 +153,31 @@ async function loadConfig() {
|
|
|
128
153
|
try {
|
|
129
154
|
const raw = await readFile(configPath(), "utf8");
|
|
130
155
|
const parsed = JSON.parse(raw);
|
|
156
|
+
if (parsed.cloudMode) {
|
|
157
|
+
return {
|
|
158
|
+
accountId: envAccount ?? parsed.accountId ?? "",
|
|
159
|
+
apiToken: envToken ?? parsed.apiToken ?? "",
|
|
160
|
+
model: envModel ?? parsed.model ?? DEFAULT_MODEL,
|
|
161
|
+
cloudMode: true,
|
|
162
|
+
reasoningEffort: envEffort ?? parsed.reasoningEffort,
|
|
163
|
+
coauthor: envCoauthor?.enabled ?? parsed.coauthor ?? true,
|
|
164
|
+
coauthorName: envCoauthor?.name ?? parsed.coauthorName,
|
|
165
|
+
coauthorEmail: envCoauthor?.email ?? parsed.coauthorEmail,
|
|
166
|
+
mcpServers: parsed.mcpServers,
|
|
167
|
+
cacheStablePrompts: parsed.cacheStablePrompts ?? cacheStablePrompts,
|
|
168
|
+
compiledContext: parsed.compiledContext ?? compiledContext,
|
|
169
|
+
imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? parsed.imageHistoryTurns : imageHistoryTurns,
|
|
170
|
+
memoryEnabled: envMemoryEnabled ?? parsed.memoryEnabled,
|
|
171
|
+
memoryDbPath: envMemoryDbPath ?? parsed.memoryDbPath,
|
|
172
|
+
memoryMaxAgeDays: envMemoryMaxAgeDays ?? parsed.memoryMaxAgeDays,
|
|
173
|
+
memoryMaxEntries: envMemoryMaxEntries ?? parsed.memoryMaxEntries,
|
|
174
|
+
memoryEmbeddingModel: envMemoryEmbeddingModel ?? parsed.memoryEmbeddingModel,
|
|
175
|
+
plumbingModel: envPlumbingModel ?? parsed.plumbingModel,
|
|
176
|
+
codeMode: envCodeMode ?? parsed.codeMode,
|
|
177
|
+
costAttribution: envCostAttribution ?? parsed.costAttribution ?? false,
|
|
178
|
+
filePicker: envFilePicker ?? parsed.filePicker ?? true
|
|
179
|
+
};
|
|
180
|
+
}
|
|
131
181
|
if (parsed.accountId && parsed.apiToken) {
|
|
132
182
|
return {
|
|
133
183
|
accountId: envAccount ?? parsed.accountId,
|
|
@@ -155,7 +205,8 @@ async function loadConfig() {
|
|
|
155
205
|
memoryExtractionModel: envMemoryExtractionModel ?? parsed.memoryExtractionModel,
|
|
156
206
|
codeMode: envCodeMode ?? parsed.codeMode ?? true,
|
|
157
207
|
costAttribution: envCostAttribution ?? parsed.costAttribution ?? true,
|
|
158
|
-
filePicker: envFilePicker ?? parsed.filePicker ?? true
|
|
208
|
+
filePicker: envFilePicker ?? parsed.filePicker ?? true,
|
|
209
|
+
cloudMode: envCloudMode ?? parsed.cloudMode
|
|
159
210
|
};
|
|
160
211
|
}
|
|
161
212
|
} catch {
|
|
@@ -443,7 +494,7 @@ async function* runKimi(opts2) {
|
|
|
443
494
|
let res;
|
|
444
495
|
try {
|
|
445
496
|
const headers = {
|
|
446
|
-
Authorization: `Bearer ${opts2.apiToken}`,
|
|
497
|
+
Authorization: `Bearer ${opts2.cloudMode && opts2.cloudToken ? opts2.cloudToken : opts2.apiToken}`,
|
|
447
498
|
"Content-Type": "application/json",
|
|
448
499
|
"User-Agent": getUserAgent(),
|
|
449
500
|
...gatewayHeaders
|
|
@@ -500,6 +551,12 @@ function validateModelId(model) {
|
|
|
500
551
|
}
|
|
501
552
|
function buildKimiRequestTarget(opts2) {
|
|
502
553
|
validateModelId(opts2.model);
|
|
554
|
+
if (opts2.cloudMode) {
|
|
555
|
+
return {
|
|
556
|
+
url: "https://api.kimiflare.com/v1/chat",
|
|
557
|
+
headers: opts2.cloudToken ? { Authorization: `Bearer ${opts2.cloudToken}` } : {}
|
|
558
|
+
};
|
|
559
|
+
}
|
|
503
560
|
if (!opts2.gateway?.id) {
|
|
504
561
|
return {
|
|
505
562
|
url: `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(opts2.accountId)}/ai/run/${opts2.model}`,
|
|
@@ -1326,6 +1383,8 @@ var init_api_generator = __esm({
|
|
|
1326
1383
|
});
|
|
1327
1384
|
|
|
1328
1385
|
// src/code-mode/sandbox.ts
|
|
1386
|
+
import { join as join6, dirname as dirname3 } from "path";
|
|
1387
|
+
import { pathToFileURL } from "url";
|
|
1329
1388
|
function stripTypescript(code) {
|
|
1330
1389
|
let js = code;
|
|
1331
1390
|
js = js.replace(/interface\s+\w+\s*\{[\s\S]*?\n\}/g, "");
|
|
@@ -1342,6 +1401,36 @@ function stripTypescript(code) {
|
|
|
1342
1401
|
js = js.replace(/\n{3,}/g, "\n\n");
|
|
1343
1402
|
return js.trim();
|
|
1344
1403
|
}
|
|
1404
|
+
async function loadTypescript(cwd) {
|
|
1405
|
+
let dir = cwd;
|
|
1406
|
+
while (dir !== dirname3(dir)) {
|
|
1407
|
+
try {
|
|
1408
|
+
const tsPath = join6(dir, "node_modules", "typescript", "lib", "typescript.js");
|
|
1409
|
+
return await import(pathToFileURL(tsPath).href);
|
|
1410
|
+
} catch {
|
|
1411
|
+
}
|
|
1412
|
+
dir = dirname3(dir);
|
|
1413
|
+
}
|
|
1414
|
+
return null;
|
|
1415
|
+
}
|
|
1416
|
+
async function transpileOrStrip(code, cwd) {
|
|
1417
|
+
const ts = await loadTypescript(cwd);
|
|
1418
|
+
if (ts) {
|
|
1419
|
+
const result = ts.transpileModule(code, {
|
|
1420
|
+
compilerOptions: {
|
|
1421
|
+
module: ts.ModuleKind.ES2022,
|
|
1422
|
+
target: ts.ScriptTarget.ES2022,
|
|
1423
|
+
esModuleInterop: true,
|
|
1424
|
+
isolatedModules: true
|
|
1425
|
+
}
|
|
1426
|
+
});
|
|
1427
|
+
return { js: result.outputText, warnings: [] };
|
|
1428
|
+
}
|
|
1429
|
+
return {
|
|
1430
|
+
js: stripTypescript(code),
|
|
1431
|
+
warnings: ["TypeScript not found in node_modules. Using fallback parser; install typescript for reliable transpilation."]
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1345
1434
|
async function runWithIsolatedVm(opts2) {
|
|
1346
1435
|
const { Isolate } = await import("isolated-vm");
|
|
1347
1436
|
const isolate = new Isolate({ memoryLimit: opts2.memoryLimitMB ?? 128 });
|
|
@@ -1389,7 +1478,7 @@ async function runWithIsolatedVm(opts2) {
|
|
|
1389
1478
|
await context.eval(`var api = {
|
|
1390
1479
|
${apiMethods}
|
|
1391
1480
|
};`);
|
|
1392
|
-
const jsCode =
|
|
1481
|
+
const { js: jsCode, warnings } = await transpileOrStrip(opts2.code, opts2.ctx.cwd);
|
|
1393
1482
|
const wrapped = `(async function() {
|
|
1394
1483
|
${jsCode}
|
|
1395
1484
|
})();`;
|
|
@@ -1400,11 +1489,11 @@ ${jsCode}
|
|
|
1400
1489
|
await new Promise((r) => setTimeout(r, 10));
|
|
1401
1490
|
} catch (err) {
|
|
1402
1491
|
const message2 = err instanceof Error ? err.message : String(err);
|
|
1403
|
-
return { output: "", logs, error: message2, toolCalls };
|
|
1492
|
+
return { output: "", logs, error: message2, toolCalls, warnings };
|
|
1404
1493
|
} finally {
|
|
1405
1494
|
isolate.dispose();
|
|
1406
1495
|
}
|
|
1407
|
-
return { output: logs.join("\n"), logs, toolCalls };
|
|
1496
|
+
return { output: logs.join("\n"), logs, toolCalls, warnings };
|
|
1408
1497
|
}
|
|
1409
1498
|
async function runWithNodeVm(opts2) {
|
|
1410
1499
|
const { runInNewContext } = await import("vm");
|
|
@@ -1472,7 +1561,7 @@ async function runWithNodeVm(opts2) {
|
|
|
1472
1561
|
return result.content;
|
|
1473
1562
|
};
|
|
1474
1563
|
}
|
|
1475
|
-
const jsCode =
|
|
1564
|
+
const { js: jsCode, warnings } = await transpileOrStrip(opts2.code, opts2.ctx.cwd);
|
|
1476
1565
|
const wrapped = `"use strict";
|
|
1477
1566
|
(async function() {
|
|
1478
1567
|
${jsCode}
|
|
@@ -1483,9 +1572,9 @@ ${jsCode}
|
|
|
1483
1572
|
await new Promise((r) => setTimeout(r, 10));
|
|
1484
1573
|
} catch (err) {
|
|
1485
1574
|
const message2 = err instanceof Error ? err.message : String(err);
|
|
1486
|
-
return { output: "", logs, error: message2, toolCalls };
|
|
1575
|
+
return { output: "", logs, error: message2, toolCalls, warnings };
|
|
1487
1576
|
}
|
|
1488
|
-
return { output: logs.join("\n"), logs, toolCalls };
|
|
1577
|
+
return { output: logs.join("\n"), logs, toolCalls, warnings };
|
|
1489
1578
|
}
|
|
1490
1579
|
async function runInSandbox(opts2) {
|
|
1491
1580
|
try {
|
|
@@ -1646,7 +1735,9 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1646
1735
|
maxCompletionTokens: opts2.maxCompletionTokens,
|
|
1647
1736
|
reasoningEffort: opts2.reasoningEffort,
|
|
1648
1737
|
sessionId: opts2.sessionId,
|
|
1649
|
-
gateway: opts2.gateway
|
|
1738
|
+
gateway: opts2.gateway,
|
|
1739
|
+
cloudMode: opts2.cloudMode,
|
|
1740
|
+
cloudToken: opts2.cloudToken
|
|
1650
1741
|
});
|
|
1651
1742
|
for await (const ev of events) {
|
|
1652
1743
|
switch (ev.type) {
|
|
@@ -1825,10 +1916,13 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1825
1916
|
toolResults.push(toolResult);
|
|
1826
1917
|
opts2.callbacks.onToolResult?.(toolResult);
|
|
1827
1918
|
}
|
|
1828
|
-
const
|
|
1919
|
+
const warningPrefix = sandboxResult.warnings?.length ? `Warning: ${sandboxResult.warnings.join(" ")}
|
|
1920
|
+
|
|
1921
|
+
` : "";
|
|
1922
|
+
const resultContent = sandboxResult.error ? `${warningPrefix}Error: ${sandboxResult.error}
|
|
1829
1923
|
|
|
1830
1924
|
Output:
|
|
1831
|
-
${sandboxResult.output}` : sandboxResult.output
|
|
1925
|
+
${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
|
|
1832
1926
|
const result = {
|
|
1833
1927
|
tool_call_id: tc.id,
|
|
1834
1928
|
name: "execute_code",
|
|
@@ -2180,11 +2274,11 @@ var init_mode = __esm({
|
|
|
2180
2274
|
|
|
2181
2275
|
// src/agent/system-prompt.ts
|
|
2182
2276
|
import { platform, release, homedir as homedir3 } from "os";
|
|
2183
|
-
import { basename, join as
|
|
2277
|
+
import { basename, join as join7 } from "path";
|
|
2184
2278
|
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
2185
2279
|
function loadContextFile(cwd) {
|
|
2186
2280
|
for (const name of CONTEXT_FILENAMES) {
|
|
2187
|
-
const path =
|
|
2281
|
+
const path = join7(cwd, name);
|
|
2188
2282
|
try {
|
|
2189
2283
|
const s = statSync(path);
|
|
2190
2284
|
if (!s.isFile() || s.size > MAX_CONTEXT_BYTES) continue;
|
|
@@ -2339,7 +2433,7 @@ var init_read = __esm({
|
|
|
2339
2433
|
|
|
2340
2434
|
// src/tools/write.ts
|
|
2341
2435
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
2342
|
-
import { dirname as
|
|
2436
|
+
import { dirname as dirname4 } from "path";
|
|
2343
2437
|
var writeTool;
|
|
2344
2438
|
var init_write = __esm({
|
|
2345
2439
|
"src/tools/write.ts"() {
|
|
@@ -2369,7 +2463,7 @@ var init_write = __esm({
|
|
|
2369
2463
|
before = await readFile4(abs, "utf8");
|
|
2370
2464
|
} catch {
|
|
2371
2465
|
}
|
|
2372
|
-
await mkdir4(
|
|
2466
|
+
await mkdir4(dirname4(abs), { recursive: true });
|
|
2373
2467
|
await writeFile3(abs, args.content, "utf8");
|
|
2374
2468
|
const verb = before ? "Overwrote" : "Created";
|
|
2375
2469
|
return `${verb} ${args.path} (${args.content.length} chars).`;
|
|
@@ -2436,7 +2530,7 @@ var init_edit = __esm({
|
|
|
2436
2530
|
// src/tools/bash.ts
|
|
2437
2531
|
import { spawn } from "child_process";
|
|
2438
2532
|
import { tmpdir } from "os";
|
|
2439
|
-
import { join as
|
|
2533
|
+
import { join as join8 } from "path";
|
|
2440
2534
|
function formatBashTitle(raw) {
|
|
2441
2535
|
let cmd = (raw ?? "").trim();
|
|
2442
2536
|
const m = cmd.match(/^cd\s+([^\s&;]+)\s*(?:&&|;)\s*(.*)$/);
|
|
@@ -2454,7 +2548,7 @@ function injectCoauthor(command, coauthor) {
|
|
|
2454
2548
|
const mentionsGit = /\bgit\b/.test(trimmed);
|
|
2455
2549
|
if (!createsCommit && !isRebaseContinue && !mentionsGit) return command;
|
|
2456
2550
|
if (movesHeadOnly) return command;
|
|
2457
|
-
const tmpFile =
|
|
2551
|
+
const tmpFile = join8(tmpdir(), `kf-coauthor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
|
|
2458
2552
|
const amendBlock = `
|
|
2459
2553
|
if ! git log -1 --pretty=%B 2>/dev/null | grep -qF "${trailer}"; then
|
|
2460
2554
|
git log -1 --pretty=%B | git interpret-trailers --trailer "${trailer}" > "${tmpFile}" && git commit --amend -F "${tmpFile}" --no-edit && rm -f "${tmpFile}"
|
|
@@ -3618,16 +3712,16 @@ var init_executor = __esm({
|
|
|
3618
3712
|
// src/util/update-check.ts
|
|
3619
3713
|
import { readFile as readFile7, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
3620
3714
|
import { homedir as homedir5 } from "os";
|
|
3621
|
-
import { join as
|
|
3715
|
+
import { join as join9, dirname as dirname5 } from "path";
|
|
3622
3716
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3623
3717
|
function cachePath() {
|
|
3624
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
3625
|
-
return
|
|
3718
|
+
const xdg = process.env.XDG_CONFIG_HOME || join9(homedir5(), ".config");
|
|
3719
|
+
return join9(xdg, "kimiflare", "update-check.json");
|
|
3626
3720
|
}
|
|
3627
3721
|
async function findPackageJson(startDir) {
|
|
3628
3722
|
let dir = startDir;
|
|
3629
3723
|
while (true) {
|
|
3630
|
-
const candidate =
|
|
3724
|
+
const candidate = join9(dir, "package.json");
|
|
3631
3725
|
try {
|
|
3632
3726
|
const raw = await readFile7(candidate, "utf8");
|
|
3633
3727
|
const parsed = JSON.parse(raw);
|
|
@@ -3636,14 +3730,14 @@ async function findPackageJson(startDir) {
|
|
|
3636
3730
|
}
|
|
3637
3731
|
} catch {
|
|
3638
3732
|
}
|
|
3639
|
-
const parent =
|
|
3733
|
+
const parent = dirname5(dir);
|
|
3640
3734
|
if (parent === dir) break;
|
|
3641
3735
|
dir = parent;
|
|
3642
3736
|
}
|
|
3643
3737
|
return null;
|
|
3644
3738
|
}
|
|
3645
3739
|
async function readLocalVersion() {
|
|
3646
|
-
const here =
|
|
3740
|
+
const here = dirname5(fileURLToPath2(import.meta.url));
|
|
3647
3741
|
const found = await findPackageJson(here);
|
|
3648
3742
|
return found?.version ?? null;
|
|
3649
3743
|
}
|
|
@@ -3660,7 +3754,7 @@ async function readCache() {
|
|
|
3660
3754
|
}
|
|
3661
3755
|
async function writeCache(entry) {
|
|
3662
3756
|
const p = cachePath();
|
|
3663
|
-
await mkdir5(
|
|
3757
|
+
await mkdir5(dirname5(p), { recursive: true });
|
|
3664
3758
|
await writeFile5(p, JSON.stringify(entry), "utf8");
|
|
3665
3759
|
}
|
|
3666
3760
|
async function fetchLatestVersion() {
|
|
@@ -3720,20 +3814,20 @@ var init_update_check = __esm({
|
|
|
3720
3814
|
// src/remote/session-store.ts
|
|
3721
3815
|
import { readFile as readFile8, writeFile as writeFile6, mkdir as mkdir6, readdir as readdir2 } from "fs/promises";
|
|
3722
3816
|
import { homedir as homedir6 } from "os";
|
|
3723
|
-
import { join as
|
|
3817
|
+
import { join as join10 } from "path";
|
|
3724
3818
|
function remoteDir() {
|
|
3725
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
3726
|
-
return
|
|
3819
|
+
const xdg = process.env.XDG_DATA_HOME || join10(homedir6(), ".config");
|
|
3820
|
+
return join10(xdg, "kimiflare", "remote");
|
|
3727
3821
|
}
|
|
3728
3822
|
async function saveRemoteSession(session) {
|
|
3729
3823
|
const dir = remoteDir();
|
|
3730
3824
|
await mkdir6(dir, { recursive: true });
|
|
3731
|
-
const path =
|
|
3825
|
+
const path = join10(dir, `${session.sessionId}.json`);
|
|
3732
3826
|
await writeFile6(path, JSON.stringify(session, null, 2) + "\n", "utf8");
|
|
3733
3827
|
}
|
|
3734
3828
|
async function loadRemoteSession(sessionId) {
|
|
3735
3829
|
try {
|
|
3736
|
-
const path =
|
|
3830
|
+
const path = join10(remoteDir(), `${sessionId}.json`);
|
|
3737
3831
|
const raw = await readFile8(path, "utf8");
|
|
3738
3832
|
return JSON.parse(raw);
|
|
3739
3833
|
} catch {
|
|
@@ -3748,7 +3842,7 @@ async function listRemoteSessions() {
|
|
|
3748
3842
|
for (const file of files) {
|
|
3749
3843
|
if (!file.endsWith(".json")) continue;
|
|
3750
3844
|
try {
|
|
3751
|
-
const raw = await readFile8(
|
|
3845
|
+
const raw = await readFile8(join10(dir, file), "utf8");
|
|
3752
3846
|
sessions.push(JSON.parse(raw));
|
|
3753
3847
|
} catch {
|
|
3754
3848
|
}
|
|
@@ -3770,7 +3864,7 @@ var init_session_store = __esm({
|
|
|
3770
3864
|
|
|
3771
3865
|
// src/remote/deploy.ts
|
|
3772
3866
|
import { execSync } from "child_process";
|
|
3773
|
-
import { join as
|
|
3867
|
+
import { join as join11, dirname as dirname6 } from "path";
|
|
3774
3868
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3775
3869
|
import { randomBytes } from "crypto";
|
|
3776
3870
|
function generateSecret() {
|
|
@@ -3805,7 +3899,7 @@ async function* deployForTui() {
|
|
|
3805
3899
|
yield { message: "Docker OK" };
|
|
3806
3900
|
yield { message: "Building remote agent bundle..." };
|
|
3807
3901
|
try {
|
|
3808
|
-
runCapture("npm run build:remote-agent",
|
|
3902
|
+
runCapture("npm run build:remote-agent", join11(REMOTE_DIR, ".."));
|
|
3809
3903
|
yield { message: "Agent bundle built" };
|
|
3810
3904
|
} catch (err) {
|
|
3811
3905
|
yield { message: `Build failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
|
|
@@ -3934,9 +4028,9 @@ var init_deploy = __esm({
|
|
|
3934
4028
|
"src/remote/deploy.ts"() {
|
|
3935
4029
|
"use strict";
|
|
3936
4030
|
init_config();
|
|
3937
|
-
__dirname =
|
|
3938
|
-
REMOTE_DIR =
|
|
3939
|
-
WORKER_DIR =
|
|
4031
|
+
__dirname = dirname6(fileURLToPath3(import.meta.url));
|
|
4032
|
+
REMOTE_DIR = join11(__dirname, "..", "..", "..", "remote");
|
|
4033
|
+
WORKER_DIR = join11(REMOTE_DIR, "worker");
|
|
3940
4034
|
}
|
|
3941
4035
|
});
|
|
3942
4036
|
|
|
@@ -4360,11 +4454,11 @@ var init_heuristic = __esm({
|
|
|
4360
4454
|
|
|
4361
4455
|
// src/cost-attribution/classify-from-session.ts
|
|
4362
4456
|
import { readFile as readFile9 } from "fs/promises";
|
|
4363
|
-
import { join as
|
|
4457
|
+
import { join as join12 } from "path";
|
|
4364
4458
|
import { homedir as homedir7 } from "os";
|
|
4365
4459
|
function sessionsDir() {
|
|
4366
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
4367
|
-
return
|
|
4460
|
+
const xdg = process.env.XDG_DATA_HOME || join12(homedir7(), ".local", "share");
|
|
4461
|
+
return join12(xdg, "kimiflare", "sessions");
|
|
4368
4462
|
}
|
|
4369
4463
|
function parseToolCalls(calls) {
|
|
4370
4464
|
return calls.map((c) => {
|
|
@@ -4378,7 +4472,7 @@ function parseToolCalls(calls) {
|
|
|
4378
4472
|
}
|
|
4379
4473
|
async function classifyFromSessionFile(sessionId) {
|
|
4380
4474
|
try {
|
|
4381
|
-
const raw = await readFile9(
|
|
4475
|
+
const raw = await readFile9(join12(sessionsDir(), `${sessionId}.json`), "utf8");
|
|
4382
4476
|
const session = JSON.parse(raw);
|
|
4383
4477
|
const messages = session.messages ?? [];
|
|
4384
4478
|
const turns = [];
|
|
@@ -4412,14 +4506,14 @@ __export(cli_exports, {
|
|
|
4412
4506
|
runCostCommand: () => runCostCommand
|
|
4413
4507
|
});
|
|
4414
4508
|
import { readFile as readFile10 } from "fs/promises";
|
|
4415
|
-
import { join as
|
|
4509
|
+
import { join as join13 } from "path";
|
|
4416
4510
|
import { homedir as homedir8 } from "os";
|
|
4417
4511
|
function usageDir() {
|
|
4418
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
4419
|
-
return
|
|
4512
|
+
const xdg = process.env.XDG_DATA_HOME || join13(homedir8(), ".local", "share");
|
|
4513
|
+
return join13(xdg, "kimiflare");
|
|
4420
4514
|
}
|
|
4421
4515
|
function usagePath() {
|
|
4422
|
-
return
|
|
4516
|
+
return join13(usageDir(), "usage.json");
|
|
4423
4517
|
}
|
|
4424
4518
|
function today() {
|
|
4425
4519
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -4517,6 +4611,98 @@ var init_cli = __esm({
|
|
|
4517
4611
|
}
|
|
4518
4612
|
});
|
|
4519
4613
|
|
|
4614
|
+
// src/cloud/auth.ts
|
|
4615
|
+
var auth_exports = {};
|
|
4616
|
+
__export(auth_exports, {
|
|
4617
|
+
authenticateDevice: () => authenticateDevice,
|
|
4618
|
+
clearCloudCredentials: () => clearCloudCredentials,
|
|
4619
|
+
loadCloudCredentials: () => loadCloudCredentials,
|
|
4620
|
+
saveCloudCredentials: () => saveCloudCredentials
|
|
4621
|
+
});
|
|
4622
|
+
import { readFile as readFile11, writeFile as writeFile7 } from "fs/promises";
|
|
4623
|
+
import { homedir as homedir9 } from "os";
|
|
4624
|
+
import { join as join14 } from "path";
|
|
4625
|
+
function cloudCredPath() {
|
|
4626
|
+
const xdg = process.env.XDG_CONFIG_HOME || join14(homedir9(), ".config");
|
|
4627
|
+
return join14(xdg, "kimiflare", "cloud.json");
|
|
4628
|
+
}
|
|
4629
|
+
function generateCode() {
|
|
4630
|
+
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
4631
|
+
let out = "";
|
|
4632
|
+
for (let i = 0; i < 8; i++) {
|
|
4633
|
+
out += chars[Math.floor(Math.random() * chars.length)];
|
|
4634
|
+
}
|
|
4635
|
+
return out;
|
|
4636
|
+
}
|
|
4637
|
+
async function loadCloudCredentials() {
|
|
4638
|
+
try {
|
|
4639
|
+
const raw = await readFile11(cloudCredPath(), "utf8");
|
|
4640
|
+
const parsed = JSON.parse(raw);
|
|
4641
|
+
if (parsed.expiresAt && parsed.expiresAt > Date.now() / 1e3) {
|
|
4642
|
+
return parsed;
|
|
4643
|
+
}
|
|
4644
|
+
} catch {
|
|
4645
|
+
}
|
|
4646
|
+
return null;
|
|
4647
|
+
}
|
|
4648
|
+
async function saveCloudCredentials(creds) {
|
|
4649
|
+
const p = cloudCredPath();
|
|
4650
|
+
await writeFile7(p, JSON.stringify(creds, null, 2), "utf8");
|
|
4651
|
+
}
|
|
4652
|
+
async function clearCloudCredentials() {
|
|
4653
|
+
try {
|
|
4654
|
+
const { unlink: unlink4 } = await import("fs/promises");
|
|
4655
|
+
await unlink4(cloudCredPath());
|
|
4656
|
+
} catch {
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
async function authenticateDevice(onStatus) {
|
|
4660
|
+
const deviceCode = `device-${generateCode()}-${Date.now()}`;
|
|
4661
|
+
const userCode = `${generateCode()}-${generateCode()}`;
|
|
4662
|
+
const registerRes = await fetch(`${CLOUD_API_URL}/auth/device`, {
|
|
4663
|
+
method: "POST",
|
|
4664
|
+
headers: { "Content-Type": "application/json" },
|
|
4665
|
+
body: JSON.stringify({ device_code: deviceCode, user_code: userCode })
|
|
4666
|
+
});
|
|
4667
|
+
if (!registerRes.ok) {
|
|
4668
|
+
const err = await registerRes.json().catch(() => ({}));
|
|
4669
|
+
throw new Error(`Failed to register device: ${err.error || registerRes.statusText}`);
|
|
4670
|
+
}
|
|
4671
|
+
const authUrl = `${CLOUD_API_URL}/auth/github?code=${encodeURIComponent(userCode)}`;
|
|
4672
|
+
onStatus({ url: authUrl, userCode, polling: false });
|
|
4673
|
+
const startTime = Date.now();
|
|
4674
|
+
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
4675
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
4676
|
+
onStatus({ url: authUrl, userCode, polling: true });
|
|
4677
|
+
const pollRes = await fetch(`${CLOUD_API_URL}/auth/poll`, {
|
|
4678
|
+
method: "POST",
|
|
4679
|
+
headers: { "Content-Type": "application/json" },
|
|
4680
|
+
body: JSON.stringify({ device_code: deviceCode })
|
|
4681
|
+
});
|
|
4682
|
+
if (!pollRes.ok) continue;
|
|
4683
|
+
const pollData = await pollRes.json();
|
|
4684
|
+
if (pollData.status === "approved" && pollData.access_token) {
|
|
4685
|
+
const creds = {
|
|
4686
|
+
accessToken: pollData.access_token,
|
|
4687
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 7 * 24 * 60 * 60
|
|
4688
|
+
// 7 days
|
|
4689
|
+
};
|
|
4690
|
+
await saveCloudCredentials(creds);
|
|
4691
|
+
return creds;
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
throw new Error("Authentication timed out. Please try again.");
|
|
4695
|
+
}
|
|
4696
|
+
var CLOUD_API_URL, POLL_INTERVAL_MS, POLL_TIMEOUT_MS;
|
|
4697
|
+
var init_auth = __esm({
|
|
4698
|
+
"src/cloud/auth.ts"() {
|
|
4699
|
+
"use strict";
|
|
4700
|
+
CLOUD_API_URL = "https://api.kimiflare.com";
|
|
4701
|
+
POLL_INTERVAL_MS = 5e3;
|
|
4702
|
+
POLL_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
4703
|
+
}
|
|
4704
|
+
});
|
|
4705
|
+
|
|
4520
4706
|
// src/remote/tui-auth.ts
|
|
4521
4707
|
var tui_auth_exports = {};
|
|
4522
4708
|
__export(tui_auth_exports, {
|
|
@@ -5426,9 +5612,9 @@ var init_connection = __esm({
|
|
|
5426
5612
|
});
|
|
5427
5613
|
|
|
5428
5614
|
// src/lsp/protocol.ts
|
|
5429
|
-
import { pathToFileURL, fileURLToPath as fileURLToPath4 } from "url";
|
|
5615
|
+
import { pathToFileURL as pathToFileURL2, fileURLToPath as fileURLToPath4 } from "url";
|
|
5430
5616
|
function toUri(path) {
|
|
5431
|
-
return
|
|
5617
|
+
return pathToFileURL2(path).href;
|
|
5432
5618
|
}
|
|
5433
5619
|
function fromUri(uri) {
|
|
5434
5620
|
return fileURLToPath4(uri);
|
|
@@ -6568,7 +6754,7 @@ import { useEffect, useState } from "react";
|
|
|
6568
6754
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
6569
6755
|
import Spinner3 from "ink-spinner";
|
|
6570
6756
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6571
|
-
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode }) {
|
|
6757
|
+
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode }) {
|
|
6572
6758
|
const theme = useTheme();
|
|
6573
6759
|
const [now2, setNow] = useState(Date.now());
|
|
6574
6760
|
const modeColor = mode === "plan" ? theme.modeBadge.plan : mode === "auto" ? theme.modeBadge.auto : theme.modeBadge.edit;
|
|
@@ -6580,6 +6766,7 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
6580
6766
|
}, [thinking, turnStartedAt]);
|
|
6581
6767
|
const elapsed = turnStartedAt !== null ? formatElapsed(now2 - turnStartedAt) : null;
|
|
6582
6768
|
const leftParts = [`${shortModel(model)}`, effort];
|
|
6769
|
+
if (cloudMode) leftParts.push("CLOUD");
|
|
6583
6770
|
if (codeMode) leftParts.push("CODE");
|
|
6584
6771
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
6585
6772
|
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
@@ -7634,15 +7821,25 @@ var init_text_input = __esm({
|
|
|
7634
7821
|
// src/ui/onboarding.tsx
|
|
7635
7822
|
import { useState as useState5 } from "react";
|
|
7636
7823
|
import { Box as Box9, Text as Text10 } from "ink";
|
|
7824
|
+
import SelectInput3 from "ink-select-input";
|
|
7637
7825
|
import { Fragment, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
7638
7826
|
function Onboarding({ onDone }) {
|
|
7639
7827
|
const theme = useTheme();
|
|
7640
|
-
const [step, setStep] = useState5("
|
|
7828
|
+
const [step, setStep] = useState5("mode");
|
|
7829
|
+
const [mode, setMode] = useState5("byok");
|
|
7641
7830
|
const [accountId, setAccountId] = useState5("");
|
|
7642
7831
|
const [apiToken, setApiToken] = useState5("");
|
|
7643
7832
|
const [model, setModel] = useState5(DEFAULT_MODEL);
|
|
7644
7833
|
const [savedPath, setSavedPath] = useState5(null);
|
|
7645
|
-
const
|
|
7834
|
+
const handleModeSelect = (item) => {
|
|
7835
|
+
if (item.value === "cloud") {
|
|
7836
|
+
setMode("cloud");
|
|
7837
|
+
setStep("cloudDone");
|
|
7838
|
+
} else {
|
|
7839
|
+
setMode("byok");
|
|
7840
|
+
setStep("accountId");
|
|
7841
|
+
}
|
|
7842
|
+
};
|
|
7646
7843
|
const handleAccountIdSubmit = (value) => {
|
|
7647
7844
|
const trimmed = value.trim();
|
|
7648
7845
|
if (!trimmed) return;
|
|
@@ -7661,7 +7858,17 @@ function Onboarding({ onDone }) {
|
|
|
7661
7858
|
setStep("confirm");
|
|
7662
7859
|
};
|
|
7663
7860
|
const handleConfirm = async () => {
|
|
7664
|
-
const cfg = { accountId, apiToken, model };
|
|
7861
|
+
const cfg = mode === "cloud" ? { accountId: "", apiToken: "", model, cloudMode: true } : { accountId, apiToken, model };
|
|
7862
|
+
try {
|
|
7863
|
+
const path = await saveConfig(cfg);
|
|
7864
|
+
setSavedPath(path);
|
|
7865
|
+
onDone(cfg);
|
|
7866
|
+
} catch (e) {
|
|
7867
|
+
setSavedPath(`error: ${e.message}`);
|
|
7868
|
+
}
|
|
7869
|
+
};
|
|
7870
|
+
const handleCloudSave = async () => {
|
|
7871
|
+
const cfg = { accountId: "", apiToken: "", model: DEFAULT_MODEL, cloudMode: true };
|
|
7665
7872
|
try {
|
|
7666
7873
|
const path = await saveConfig(cfg);
|
|
7667
7874
|
setSavedPath(path);
|
|
@@ -7670,6 +7877,9 @@ function Onboarding({ onDone }) {
|
|
|
7670
7877
|
setSavedPath(`error: ${e.message}`);
|
|
7671
7878
|
}
|
|
7672
7879
|
};
|
|
7880
|
+
const byokSteps = ["accountId", "apiToken", "model", "confirm"];
|
|
7881
|
+
const stepIndex = step === "mode" ? 1 : step === "cloudDone" ? 2 : byokSteps.indexOf(step) + 2;
|
|
7882
|
+
const totalSteps = mode === "cloud" ? 2 : byokSteps.length + 1;
|
|
7673
7883
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingY: 1, children: [
|
|
7674
7884
|
/* @__PURE__ */ jsxs9(Box9, { marginBottom: 1, children: [
|
|
7675
7885
|
/* @__PURE__ */ jsx11(Text10, { bold: true, color: theme.palette.primary, children: "kimiflare" }),
|
|
@@ -7682,9 +7892,22 @@ function Onboarding({ onDone }) {
|
|
|
7682
7892
|
"Step ",
|
|
7683
7893
|
stepIndex,
|
|
7684
7894
|
" of ",
|
|
7685
|
-
|
|
7895
|
+
totalSteps
|
|
7686
7896
|
] }),
|
|
7687
7897
|
/* @__PURE__ */ jsxs9(Box9, { marginTop: 1, flexDirection: "column", children: [
|
|
7898
|
+
step === "mode" && /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
7899
|
+
/* @__PURE__ */ jsx11(Text10, { children: "How do you want to connect?" }),
|
|
7900
|
+
/* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(
|
|
7901
|
+
SelectInput3,
|
|
7902
|
+
{
|
|
7903
|
+
items: [
|
|
7904
|
+
{ label: "Cloud (managed) \u2014 no API key needed", value: "cloud" },
|
|
7905
|
+
{ label: "BYOK \u2014 bring your own Cloudflare key", value: "byok" }
|
|
7906
|
+
],
|
|
7907
|
+
onSelect: handleModeSelect
|
|
7908
|
+
}
|
|
7909
|
+
) })
|
|
7910
|
+
] }),
|
|
7688
7911
|
step === "accountId" && /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
7689
7912
|
/* @__PURE__ */ jsx11(Text10, { children: "Enter your Cloudflare Account ID" }),
|
|
7690
7913
|
/* @__PURE__ */ jsxs9(Box9, { marginTop: 1, children: [
|
|
@@ -7774,6 +7997,23 @@ function Onboarding({ onDone }) {
|
|
|
7774
7997
|
)
|
|
7775
7998
|
] })
|
|
7776
7999
|
] }),
|
|
8000
|
+
step === "cloudDone" && /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
8001
|
+
/* @__PURE__ */ jsx11(Text10, { children: "Cloud mode selected" }),
|
|
8002
|
+
/* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "No API key needed. Run `kimiflare auth cloud` to sign in." }),
|
|
8003
|
+
/* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { children: "Press Enter to save, or Ctrl+C to cancel" }) }),
|
|
8004
|
+
/* @__PURE__ */ jsxs9(Box9, { marginTop: 1, children: [
|
|
8005
|
+
/* @__PURE__ */ jsx11(Text10, { color: theme.palette.primary, children: "\u203A " }),
|
|
8006
|
+
/* @__PURE__ */ jsx11(
|
|
8007
|
+
CustomTextInput,
|
|
8008
|
+
{
|
|
8009
|
+
value: "",
|
|
8010
|
+
onChange: () => {
|
|
8011
|
+
},
|
|
8012
|
+
onSubmit: handleCloudSave
|
|
8013
|
+
}
|
|
8014
|
+
)
|
|
8015
|
+
] })
|
|
8016
|
+
] }),
|
|
7777
8017
|
savedPath && /* @__PURE__ */ jsxs9(Text10, { color: theme.palette.success, children: [
|
|
7778
8018
|
"Config saved to ",
|
|
7779
8019
|
savedPath
|
|
@@ -7781,14 +8021,12 @@ function Onboarding({ onDone }) {
|
|
|
7781
8021
|
] })
|
|
7782
8022
|
] });
|
|
7783
8023
|
}
|
|
7784
|
-
var STEPS;
|
|
7785
8024
|
var init_onboarding = __esm({
|
|
7786
8025
|
"src/ui/onboarding.tsx"() {
|
|
7787
8026
|
"use strict";
|
|
7788
8027
|
init_text_input();
|
|
7789
8028
|
init_config();
|
|
7790
8029
|
init_theme_context();
|
|
7791
|
-
STEPS = ["accountId", "apiToken", "model", "confirm"];
|
|
7792
8030
|
}
|
|
7793
8031
|
});
|
|
7794
8032
|
|
|
@@ -7839,9 +8077,9 @@ var init_welcome = __esm({
|
|
|
7839
8077
|
// src/ui/help-menu.tsx
|
|
7840
8078
|
import { useState as useState6 } from "react";
|
|
7841
8079
|
import { Box as Box11, Text as Text12, useInput as useInput2 } from "ink";
|
|
7842
|
-
import
|
|
8080
|
+
import SelectInput4 from "ink-select-input";
|
|
7843
8081
|
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
7844
|
-
function HelpMenu({ customCommands, costAttributionEnabled, onDone, onCommand }) {
|
|
8082
|
+
function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, onCommand }) {
|
|
7845
8083
|
const theme = useTheme();
|
|
7846
8084
|
const [page, setPage] = useState6("main");
|
|
7847
8085
|
const customs = customCommands ?? [];
|
|
@@ -7858,8 +8096,9 @@ function HelpMenu({ customCommands, costAttributionEnabled, onDone, onCommand })
|
|
|
7858
8096
|
onCommand(command);
|
|
7859
8097
|
onDone();
|
|
7860
8098
|
};
|
|
8099
|
+
const categories = cloudMode ? CATEGORIES.filter((c) => c.key !== "gateway") : CATEGORIES;
|
|
7861
8100
|
if (page === "main") {
|
|
7862
|
-
const items2 =
|
|
8101
|
+
const items2 = categories.map((cat) => ({
|
|
7863
8102
|
label: cat.label,
|
|
7864
8103
|
value: cat.key,
|
|
7865
8104
|
key: cat.key
|
|
@@ -7872,7 +8111,7 @@ function HelpMenu({ customCommands, costAttributionEnabled, onDone, onCommand })
|
|
|
7872
8111
|
/* @__PURE__ */ jsx13(Text12, { color: theme.accent, bold: true, children: "Help" }),
|
|
7873
8112
|
/* @__PURE__ */ jsx13(Text12, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to close." }),
|
|
7874
8113
|
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
|
|
7875
|
-
|
|
8114
|
+
SelectInput4,
|
|
7876
8115
|
{
|
|
7877
8116
|
items: items2,
|
|
7878
8117
|
onSelect: (item) => {
|
|
@@ -7899,7 +8138,7 @@ function HelpMenu({ customCommands, costAttributionEnabled, onDone, onCommand })
|
|
|
7899
8138
|
/* @__PURE__ */ jsx13(Text12, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
7900
8139
|
/* @__PURE__ */ jsx13(Text12, { color: theme.info.color, dimColor: false, children: customs.length === 0 ? "no custom commands found in .kimiflare/commands/" : "Arrow keys to navigate, Enter to run, Esc to go back." }),
|
|
7901
8140
|
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
|
|
7902
|
-
|
|
8141
|
+
SelectInput4,
|
|
7903
8142
|
{
|
|
7904
8143
|
items: items2,
|
|
7905
8144
|
onSelect: (item) => {
|
|
@@ -7913,7 +8152,7 @@ function HelpMenu({ customCommands, costAttributionEnabled, onDone, onCommand })
|
|
|
7913
8152
|
) })
|
|
7914
8153
|
] });
|
|
7915
8154
|
}
|
|
7916
|
-
const category =
|
|
8155
|
+
const category = categories.find((c) => c.key === page);
|
|
7917
8156
|
const selectable = category.commands.filter((cmd) => cmd.selectable !== false);
|
|
7918
8157
|
const staticCmds = category.commands.filter((cmd) => cmd.selectable === false);
|
|
7919
8158
|
const items = selectable.map((cmd) => ({
|
|
@@ -7926,7 +8165,7 @@ function HelpMenu({ customCommands, costAttributionEnabled, onDone, onCommand })
|
|
|
7926
8165
|
/* @__PURE__ */ jsx13(Text12, { color: theme.accent, bold: true, children: category.label }),
|
|
7927
8166
|
/* @__PURE__ */ jsx13(Text12, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to execute, Esc to go back." }),
|
|
7928
8167
|
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
|
|
7929
|
-
|
|
8168
|
+
SelectInput4,
|
|
7930
8169
|
{
|
|
7931
8170
|
items,
|
|
7932
8171
|
onSelect: (item) => {
|
|
@@ -8172,7 +8411,7 @@ var init_tui_deploy = __esm({
|
|
|
8172
8411
|
// src/ui/remote-dashboard.tsx
|
|
8173
8412
|
import { useEffect as useEffect4, useState as useState7 } from "react";
|
|
8174
8413
|
import { Box as Box12, Text as Text13, useInput as useInput3 } from "ink";
|
|
8175
|
-
import
|
|
8414
|
+
import SelectInput5 from "ink-select-input";
|
|
8176
8415
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
8177
8416
|
function RemoteDashboard({ onSelect, onCancel }) {
|
|
8178
8417
|
const theme = useTheme();
|
|
@@ -8253,7 +8492,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8253
8492
|
refreshing ? "(refreshing...)" : ""
|
|
8254
8493
|
] }),
|
|
8255
8494
|
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8256
|
-
|
|
8495
|
+
SelectInput5,
|
|
8257
8496
|
{
|
|
8258
8497
|
items,
|
|
8259
8498
|
onSelect: (item) => {
|
|
@@ -8424,12 +8663,12 @@ __export(sessions_exports, {
|
|
|
8424
8663
|
pruneSessions: () => pruneSessions,
|
|
8425
8664
|
saveSession: () => saveSession
|
|
8426
8665
|
});
|
|
8427
|
-
import { readFile as
|
|
8428
|
-
import { homedir as
|
|
8429
|
-
import { join as
|
|
8666
|
+
import { readFile as readFile12, writeFile as writeFile8, mkdir as mkdir7, readdir as readdir3, stat as stat4 } from "fs/promises";
|
|
8667
|
+
import { homedir as homedir10 } from "os";
|
|
8668
|
+
import { join as join15 } from "path";
|
|
8430
8669
|
function sessionsDir2() {
|
|
8431
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
8432
|
-
return
|
|
8670
|
+
const xdg = process.env.XDG_DATA_HOME || join15(homedir10(), ".local", "share");
|
|
8671
|
+
return join15(xdg, "kimiflare", "sessions");
|
|
8433
8672
|
}
|
|
8434
8673
|
function sanitize(text) {
|
|
8435
8674
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
@@ -8442,8 +8681,8 @@ function makeSessionId(firstPrompt) {
|
|
|
8442
8681
|
async function saveSession(file) {
|
|
8443
8682
|
const dir = sessionsDir2();
|
|
8444
8683
|
await mkdir7(dir, { recursive: true });
|
|
8445
|
-
const path =
|
|
8446
|
-
await
|
|
8684
|
+
const path = join15(dir, `${file.id}.json`);
|
|
8685
|
+
await writeFile8(path, JSON.stringify(file, null, 2), "utf8");
|
|
8447
8686
|
return path;
|
|
8448
8687
|
}
|
|
8449
8688
|
async function pruneSessions() {
|
|
@@ -8462,9 +8701,9 @@ async function listSessions(limit = 30, cwd) {
|
|
|
8462
8701
|
const summaries = [];
|
|
8463
8702
|
for (const name of entries) {
|
|
8464
8703
|
if (!name.endsWith(".json")) continue;
|
|
8465
|
-
const path =
|
|
8704
|
+
const path = join15(dir, name);
|
|
8466
8705
|
try {
|
|
8467
|
-
const [s, raw] = await Promise.all([stat4(path),
|
|
8706
|
+
const [s, raw] = await Promise.all([stat4(path), readFile12(path, "utf8")]);
|
|
8468
8707
|
const parsed = JSON.parse(raw);
|
|
8469
8708
|
if (cwd && parsed.cwd !== cwd) continue;
|
|
8470
8709
|
const firstUser = parsed.messages.find((m) => m.role === "user");
|
|
@@ -8484,7 +8723,7 @@ async function listSessions(limit = 30, cwd) {
|
|
|
8484
8723
|
return summaries.slice(0, limit);
|
|
8485
8724
|
}
|
|
8486
8725
|
async function loadSession(filePath) {
|
|
8487
|
-
const raw = await
|
|
8726
|
+
const raw = await readFile12(filePath, "utf8");
|
|
8488
8727
|
return JSON.parse(raw);
|
|
8489
8728
|
}
|
|
8490
8729
|
var init_sessions = __esm({
|
|
@@ -8495,10 +8734,10 @@ var init_sessions = __esm({
|
|
|
8495
8734
|
});
|
|
8496
8735
|
|
|
8497
8736
|
// src/util/image.ts
|
|
8498
|
-
import { readFile as
|
|
8737
|
+
import { readFile as readFile13 } from "fs/promises";
|
|
8499
8738
|
import { basename as basename3 } from "path";
|
|
8500
8739
|
async function encodeImageFile(filePath) {
|
|
8501
|
-
const buf = await
|
|
8740
|
+
const buf = await readFile13(filePath);
|
|
8502
8741
|
if (buf.byteLength > MAX_IMAGE_BYTES) {
|
|
8503
8742
|
throw new Error(
|
|
8504
8743
|
`image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
|
|
@@ -8534,15 +8773,15 @@ var init_image = __esm({
|
|
|
8534
8773
|
});
|
|
8535
8774
|
|
|
8536
8775
|
// src/usage-tracker.ts
|
|
8537
|
-
import { readFile as
|
|
8538
|
-
import { homedir as
|
|
8539
|
-
import { join as
|
|
8776
|
+
import { readFile as readFile14, writeFile as writeFile9, mkdir as mkdir8 } from "fs/promises";
|
|
8777
|
+
import { homedir as homedir11 } from "os";
|
|
8778
|
+
import { join as join16 } from "path";
|
|
8540
8779
|
function usageDir2() {
|
|
8541
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
8542
|
-
return
|
|
8780
|
+
const xdg = process.env.XDG_DATA_HOME || join16(homedir11(), ".local", "share");
|
|
8781
|
+
return join16(xdg, "kimiflare");
|
|
8543
8782
|
}
|
|
8544
8783
|
function usagePath2() {
|
|
8545
|
-
return
|
|
8784
|
+
return join16(usageDir2(), "usage.json");
|
|
8546
8785
|
}
|
|
8547
8786
|
function today2() {
|
|
8548
8787
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -8553,7 +8792,7 @@ function cutoffDate(daysBack) {
|
|
|
8553
8792
|
}
|
|
8554
8793
|
async function loadLog2() {
|
|
8555
8794
|
try {
|
|
8556
|
-
const raw = await
|
|
8795
|
+
const raw = await readFile14(usagePath2(), "utf8");
|
|
8557
8796
|
const parsed = JSON.parse(raw);
|
|
8558
8797
|
if (parsed.version === LOG_VERSION2) return parsed;
|
|
8559
8798
|
} catch {
|
|
@@ -8562,7 +8801,7 @@ async function loadLog2() {
|
|
|
8562
8801
|
}
|
|
8563
8802
|
async function saveLog(log) {
|
|
8564
8803
|
await mkdir8(usageDir2(), { recursive: true });
|
|
8565
|
-
await
|
|
8804
|
+
await writeFile9(usagePath2(), JSON.stringify(log, null, 2), "utf8");
|
|
8566
8805
|
}
|
|
8567
8806
|
function getOrCreateDay(log, date) {
|
|
8568
8807
|
let day = log.days.find((d) => d.date === date);
|
|
@@ -8768,7 +9007,7 @@ __export(db_exports, {
|
|
|
8768
9007
|
updateMemoryEmbedding: () => updateMemoryEmbedding
|
|
8769
9008
|
});
|
|
8770
9009
|
import Database from "better-sqlite3";
|
|
8771
|
-
import { dirname as
|
|
9010
|
+
import { dirname as dirname7 } from "path";
|
|
8772
9011
|
import { mkdirSync, statSync as statSync2 } from "fs";
|
|
8773
9012
|
function initSchema(db) {
|
|
8774
9013
|
db.exec(`
|
|
@@ -8853,7 +9092,7 @@ function openMemoryDb(dbPath) {
|
|
|
8853
9092
|
if (dbInstance) {
|
|
8854
9093
|
dbInstance.close();
|
|
8855
9094
|
}
|
|
8856
|
-
mkdirSync(
|
|
9095
|
+
mkdirSync(dirname7(dbPath), { recursive: true });
|
|
8857
9096
|
dbInstance = new Database(dbPath);
|
|
8858
9097
|
dbInstance.pragma("journal_mode = WAL");
|
|
8859
9098
|
dbInstance.pragma("foreign_keys = ON");
|
|
@@ -9792,16 +10031,16 @@ Context: This memory was explicitly provided by the user during a conversation.`
|
|
|
9792
10031
|
});
|
|
9793
10032
|
|
|
9794
10033
|
// src/util/state.ts
|
|
9795
|
-
import { readFile as
|
|
9796
|
-
import { homedir as
|
|
9797
|
-
import { join as
|
|
10034
|
+
import { readFile as readFile15, writeFile as writeFile10, mkdir as mkdir9 } from "fs/promises";
|
|
10035
|
+
import { homedir as homedir12 } from "os";
|
|
10036
|
+
import { join as join18 } from "path";
|
|
9798
10037
|
function statePath() {
|
|
9799
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
9800
|
-
return
|
|
10038
|
+
const xdg = process.env.XDG_CONFIG_HOME || join18(homedir12(), ".config");
|
|
10039
|
+
return join18(xdg, "kimiflare", "state.json");
|
|
9801
10040
|
}
|
|
9802
10041
|
async function readState() {
|
|
9803
10042
|
try {
|
|
9804
|
-
const raw = await
|
|
10043
|
+
const raw = await readFile15(statePath(), "utf8");
|
|
9805
10044
|
return JSON.parse(raw);
|
|
9806
10045
|
} catch {
|
|
9807
10046
|
return {};
|
|
@@ -9809,8 +10048,8 @@ async function readState() {
|
|
|
9809
10048
|
}
|
|
9810
10049
|
async function writeState(state) {
|
|
9811
10050
|
const path = statePath();
|
|
9812
|
-
await mkdir9(
|
|
9813
|
-
await
|
|
10051
|
+
await mkdir9(join18(path, ".."), { recursive: true });
|
|
10052
|
+
await writeFile10(path, JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
9814
10053
|
}
|
|
9815
10054
|
async function markCreatorMessageSeen(version) {
|
|
9816
10055
|
const state = await readState();
|
|
@@ -9883,15 +10122,15 @@ var init_frontmatter = __esm({
|
|
|
9883
10122
|
|
|
9884
10123
|
// src/commands/loader.ts
|
|
9885
10124
|
import { open, realpath } from "fs/promises";
|
|
9886
|
-
import { homedir as
|
|
9887
|
-
import { join as
|
|
10125
|
+
import { homedir as homedir13 } from "os";
|
|
10126
|
+
import { join as join19, relative as relative4, sep as sep2 } from "path";
|
|
9888
10127
|
import fg3 from "fast-glob";
|
|
9889
10128
|
function projectCommandsDir(cwd = process.cwd()) {
|
|
9890
|
-
return
|
|
10129
|
+
return join19(cwd, ".kimiflare", "commands");
|
|
9891
10130
|
}
|
|
9892
10131
|
function globalCommandsDir() {
|
|
9893
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
9894
|
-
return
|
|
10132
|
+
const xdg = process.env.XDG_CONFIG_HOME || join19(homedir13(), ".config");
|
|
10133
|
+
return join19(xdg, "kimiflare", "commands");
|
|
9895
10134
|
}
|
|
9896
10135
|
async function loadCustomCommands(cwd = process.cwd()) {
|
|
9897
10136
|
const warnings = [];
|
|
@@ -10267,8 +10506,8 @@ var init_builtins = __esm({
|
|
|
10267
10506
|
});
|
|
10268
10507
|
|
|
10269
10508
|
// src/commands/save.ts
|
|
10270
|
-
import { mkdir as mkdir10, writeFile as
|
|
10271
|
-
import { dirname as
|
|
10509
|
+
import { mkdir as mkdir10, writeFile as writeFile11, unlink as unlink2 } from "fs/promises";
|
|
10510
|
+
import { dirname as dirname8 } from "path";
|
|
10272
10511
|
async function saveCustomCommand(opts2) {
|
|
10273
10512
|
const dir = opts2.source === "project" ? projectCommandsDir(opts2.cwd) : globalCommandsDir();
|
|
10274
10513
|
const filepath = `${dir}/${opts2.name}.md`;
|
|
@@ -10279,8 +10518,8 @@ async function saveCustomCommand(opts2) {
|
|
|
10279
10518
|
if (opts2.effort) data.effort = opts2.effort;
|
|
10280
10519
|
const frontmatter = serializeFrontmatter(data);
|
|
10281
10520
|
const content = frontmatter + opts2.template;
|
|
10282
|
-
await mkdir10(
|
|
10283
|
-
await
|
|
10521
|
+
await mkdir10(dirname8(filepath), { recursive: true });
|
|
10522
|
+
await writeFile11(filepath, content, "utf8");
|
|
10284
10523
|
return { filepath };
|
|
10285
10524
|
}
|
|
10286
10525
|
async function deleteCustomCommand(cmd) {
|
|
@@ -10297,7 +10536,7 @@ var init_save = __esm({
|
|
|
10297
10536
|
// src/ui/command-wizard.tsx
|
|
10298
10537
|
import { useState as useState8 } from "react";
|
|
10299
10538
|
import { Box as Box13, Text as Text14, useInput as useInput4, useWindowSize as useWindowSize2 } from "ink";
|
|
10300
|
-
import
|
|
10539
|
+
import SelectInput6 from "ink-select-input";
|
|
10301
10540
|
import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
10302
10541
|
function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
|
|
10303
10542
|
const theme = useTheme();
|
|
@@ -10550,7 +10789,7 @@ ${template}`;
|
|
|
10550
10789
|
")"
|
|
10551
10790
|
] }),
|
|
10552
10791
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10553
|
-
|
|
10792
|
+
SelectInput6,
|
|
10554
10793
|
{
|
|
10555
10794
|
items,
|
|
10556
10795
|
onSelect: (item) => {
|
|
@@ -10579,7 +10818,7 @@ ${template}`;
|
|
|
10579
10818
|
] }),
|
|
10580
10819
|
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
|
|
10581
10820
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10582
|
-
|
|
10821
|
+
SelectInput6,
|
|
10583
10822
|
{
|
|
10584
10823
|
items,
|
|
10585
10824
|
onSelect: (item) => {
|
|
@@ -10607,7 +10846,7 @@ ${template}`;
|
|
|
10607
10846
|
")"
|
|
10608
10847
|
] }),
|
|
10609
10848
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10610
|
-
|
|
10849
|
+
SelectInput6,
|
|
10611
10850
|
{
|
|
10612
10851
|
items,
|
|
10613
10852
|
onSelect: (item) => {
|
|
@@ -10653,7 +10892,7 @@ ${template}`;
|
|
|
10653
10892
|
")"
|
|
10654
10893
|
] }),
|
|
10655
10894
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10656
|
-
|
|
10895
|
+
SelectInput6,
|
|
10657
10896
|
{
|
|
10658
10897
|
items,
|
|
10659
10898
|
onSelect: (item) => {
|
|
@@ -10686,7 +10925,7 @@ ${template}`;
|
|
|
10686
10925
|
] }),
|
|
10687
10926
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: line || " " }, i)) }),
|
|
10688
10927
|
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10689
|
-
|
|
10928
|
+
SelectInput6,
|
|
10690
10929
|
{
|
|
10691
10930
|
items,
|
|
10692
10931
|
onSelect: (item) => handleConfirm(item.value)
|
|
@@ -10710,7 +10949,7 @@ var init_command_wizard = __esm({
|
|
|
10710
10949
|
|
|
10711
10950
|
// src/ui/command-picker.tsx
|
|
10712
10951
|
import { Box as Box14, Text as Text15 } from "ink";
|
|
10713
|
-
import
|
|
10952
|
+
import SelectInput7 from "ink-select-input";
|
|
10714
10953
|
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
10715
10954
|
function CommandPicker({ commands, title, onPick }) {
|
|
10716
10955
|
const theme = useTheme();
|
|
@@ -10724,7 +10963,7 @@ function CommandPicker({ commands, title, onPick }) {
|
|
|
10724
10963
|
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: title }),
|
|
10725
10964
|
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
10726
10965
|
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10727
|
-
|
|
10966
|
+
SelectInput7,
|
|
10728
10967
|
{
|
|
10729
10968
|
items,
|
|
10730
10969
|
onSelect: (item) => {
|
|
@@ -10821,7 +11060,7 @@ var init_command_list = __esm({
|
|
|
10821
11060
|
// src/ui/lsp-wizard.tsx
|
|
10822
11061
|
import { useState as useState9 } from "react";
|
|
10823
11062
|
import { Box as Box16, Text as Text17 } from "ink";
|
|
10824
|
-
import
|
|
11063
|
+
import SelectInput8 from "ink-select-input";
|
|
10825
11064
|
import { spawn as spawn3 } from "child_process";
|
|
10826
11065
|
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
10827
11066
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
@@ -10938,7 +11177,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10938
11177
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "LSP Servers" }),
|
|
10939
11178
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
10940
11179
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10941
|
-
|
|
11180
|
+
SelectInput8,
|
|
10942
11181
|
{
|
|
10943
11182
|
items: mainItems,
|
|
10944
11183
|
onSelect: (item) => {
|
|
@@ -10969,7 +11208,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10969
11208
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Add LSP Server" }),
|
|
10970
11209
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
|
|
10971
11210
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10972
|
-
|
|
11211
|
+
SelectInput8,
|
|
10973
11212
|
{
|
|
10974
11213
|
items,
|
|
10975
11214
|
onSelect: (item) => {
|
|
@@ -11008,7 +11247,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11008
11247
|
] }),
|
|
11009
11248
|
installState.output && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx18(Text17, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
|
|
11010
11249
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11011
|
-
|
|
11250
|
+
SelectInput8,
|
|
11012
11251
|
{
|
|
11013
11252
|
items,
|
|
11014
11253
|
onSelect: (item) => {
|
|
@@ -11049,7 +11288,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11049
11288
|
)
|
|
11050
11289
|
] }),
|
|
11051
11290
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11052
|
-
|
|
11291
|
+
SelectInput8,
|
|
11053
11292
|
{
|
|
11054
11293
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11055
11294
|
onSelect: () => setPage("add")
|
|
@@ -11078,7 +11317,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11078
11317
|
)
|
|
11079
11318
|
] }),
|
|
11080
11319
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11081
|
-
|
|
11320
|
+
SelectInput8,
|
|
11082
11321
|
{
|
|
11083
11322
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11084
11323
|
onSelect: () => setPage("custom-name")
|
|
@@ -11105,7 +11344,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11105
11344
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Save LSP Config" }),
|
|
11106
11345
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
|
|
11107
11346
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11108
|
-
|
|
11347
|
+
SelectInput8,
|
|
11109
11348
|
{
|
|
11110
11349
|
items,
|
|
11111
11350
|
onSelect: (item) => {
|
|
@@ -11127,7 +11366,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11127
11366
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
11128
11367
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }),
|
|
11129
11368
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11130
|
-
|
|
11369
|
+
SelectInput8,
|
|
11131
11370
|
{
|
|
11132
11371
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11133
11372
|
onSelect: () => setPage("main")
|
|
@@ -11151,7 +11390,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11151
11390
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
11152
11391
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
|
|
11153
11392
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11154
|
-
|
|
11393
|
+
SelectInput8,
|
|
11155
11394
|
{
|
|
11156
11395
|
items,
|
|
11157
11396
|
onSelect: (item) => {
|
|
@@ -11172,7 +11411,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11172
11411
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
11173
11412
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }),
|
|
11174
11413
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11175
|
-
|
|
11414
|
+
SelectInput8,
|
|
11176
11415
|
{
|
|
11177
11416
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11178
11417
|
onSelect: () => setPage("main")
|
|
@@ -11192,7 +11431,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11192
11431
|
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
11193
11432
|
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
|
|
11194
11433
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11195
|
-
|
|
11434
|
+
SelectInput8,
|
|
11196
11435
|
{
|
|
11197
11436
|
items,
|
|
11198
11437
|
onSelect: (item) => {
|
|
@@ -11216,7 +11455,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11216
11455
|
return /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
|
|
11217
11456
|
}) }),
|
|
11218
11457
|
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11219
|
-
|
|
11458
|
+
SelectInput8,
|
|
11220
11459
|
{
|
|
11221
11460
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11222
11461
|
onSelect: () => setPage("main")
|
|
@@ -11343,7 +11582,7 @@ var init_lsp_wizard = __esm({
|
|
|
11343
11582
|
|
|
11344
11583
|
// src/ui/theme-picker.tsx
|
|
11345
11584
|
import { Box as Box17, Text as Text18 } from "ink";
|
|
11346
|
-
import
|
|
11585
|
+
import SelectInput9 from "ink-select-input";
|
|
11347
11586
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11348
11587
|
function PaletteSwatches({ palette }) {
|
|
11349
11588
|
const colors = [
|
|
@@ -11363,7 +11602,7 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
11363
11602
|
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
|
|
11364
11603
|
/* @__PURE__ */ jsx19(Text18, { color: current.accent, bold: true, children: "Pick a theme" }),
|
|
11365
11604
|
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11366
|
-
|
|
11605
|
+
SelectInput9,
|
|
11367
11606
|
{
|
|
11368
11607
|
items,
|
|
11369
11608
|
onHighlight: (item) => {
|
|
@@ -11701,15 +11940,15 @@ var tui_report_exports = {};
|
|
|
11701
11940
|
__export(tui_report_exports, {
|
|
11702
11941
|
getCategoryReportText: () => getCategoryReportText
|
|
11703
11942
|
});
|
|
11704
|
-
import { readFile as
|
|
11705
|
-
import { join as
|
|
11706
|
-
import { homedir as
|
|
11943
|
+
import { readFile as readFile16 } from "fs/promises";
|
|
11944
|
+
import { join as join20 } from "path";
|
|
11945
|
+
import { homedir as homedir14 } from "os";
|
|
11707
11946
|
function usageDir3() {
|
|
11708
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
11709
|
-
return
|
|
11947
|
+
const xdg = process.env.XDG_DATA_HOME || join20(homedir14(), ".local", "share");
|
|
11948
|
+
return join20(xdg, "kimiflare");
|
|
11710
11949
|
}
|
|
11711
11950
|
function usagePath3() {
|
|
11712
|
-
return
|
|
11951
|
+
return join20(usageDir3(), "usage.json");
|
|
11713
11952
|
}
|
|
11714
11953
|
function today3() {
|
|
11715
11954
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -11721,7 +11960,7 @@ function daysAgo2(n) {
|
|
|
11721
11960
|
}
|
|
11722
11961
|
async function loadLog3() {
|
|
11723
11962
|
try {
|
|
11724
|
-
const raw = await
|
|
11963
|
+
const raw = await readFile16(usagePath3(), "utf8");
|
|
11725
11964
|
return JSON.parse(raw);
|
|
11726
11965
|
} catch {
|
|
11727
11966
|
return { version: 1, days: [], sessions: [] };
|
|
@@ -11789,9 +12028,9 @@ __export(app_exports, {
|
|
|
11789
12028
|
});
|
|
11790
12029
|
import React14, { useState as useState10, useRef as useRef3, useEffect as useEffect5, useCallback } from "react";
|
|
11791
12030
|
import { Box as Box20, Text as Text21, useApp, useInput as useInput6, render } from "ink";
|
|
11792
|
-
import
|
|
12031
|
+
import SelectInput10 from "ink-select-input";
|
|
11793
12032
|
import { existsSync as existsSync2, statSync as statSync3 } from "fs";
|
|
11794
|
-
import { join as
|
|
12033
|
+
import { join as join21 } from "path";
|
|
11795
12034
|
import { unlink as unlink3 } from "fs/promises";
|
|
11796
12035
|
import { execSync as execSync2 } from "child_process";
|
|
11797
12036
|
import { spawn as spawn4 } from "child_process";
|
|
@@ -11869,7 +12108,7 @@ function buildFilePickerIgnoreList(cwd) {
|
|
|
11869
12108
|
];
|
|
11870
12109
|
const gitignorePatterns = [];
|
|
11871
12110
|
try {
|
|
11872
|
-
const gitignorePath =
|
|
12111
|
+
const gitignorePath = join21(cwd, ".gitignore");
|
|
11873
12112
|
const stats = statSync3(gitignorePath);
|
|
11874
12113
|
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
11875
12114
|
return hardcoded;
|
|
@@ -12022,7 +12261,8 @@ function App({
|
|
|
12022
12261
|
initialCfg,
|
|
12023
12262
|
initialUpdateResult,
|
|
12024
12263
|
initialLspScope,
|
|
12025
|
-
initialLspProjectPath
|
|
12264
|
+
initialLspProjectPath,
|
|
12265
|
+
initialCloudToken
|
|
12026
12266
|
}) {
|
|
12027
12267
|
const { exit } = useApp();
|
|
12028
12268
|
const [cfg, setCfg] = useState10(initialCfg);
|
|
@@ -12286,7 +12526,7 @@ function App({
|
|
|
12286
12526
|
}
|
|
12287
12527
|
});
|
|
12288
12528
|
if (cfg.memoryEnabled) {
|
|
12289
|
-
const dbPath = cfg.memoryDbPath ??
|
|
12529
|
+
const dbPath = cfg.memoryDbPath ?? join21(process.cwd(), ".kimiflare", "memory.db");
|
|
12290
12530
|
const manager = new MemoryManager({
|
|
12291
12531
|
dbPath,
|
|
12292
12532
|
accountId: cfg.accountId,
|
|
@@ -12935,7 +13175,7 @@ function App({
|
|
|
12935
13175
|
return;
|
|
12936
13176
|
}
|
|
12937
13177
|
const cwd = process.cwd();
|
|
12938
|
-
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find((n) => existsSync2(
|
|
13178
|
+
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find((n) => existsSync2(join21(cwd, n)));
|
|
12939
13179
|
const isRefresh = existingName !== void 0;
|
|
12940
13180
|
const promptParts = [
|
|
12941
13181
|
isRefresh ? `Regenerate ${existingName} at the repository root to refresh project context. If the file already exists, read it first and preserve anything still accurate, updating only what has changed.` : "Generate a KIMI.md at the repository root so future agents have project context.",
|
|
@@ -12986,13 +13226,15 @@ function App({
|
|
|
12986
13226
|
sessionId: ensureSessionId(),
|
|
12987
13227
|
memoryManager: memoryManagerRef.current,
|
|
12988
13228
|
codeMode: effectiveCodeMode,
|
|
13229
|
+
cloudMode: cfg.cloudMode,
|
|
13230
|
+
cloudToken: initialCloudToken,
|
|
12989
13231
|
onIterationEnd,
|
|
12990
13232
|
onFileChange: (path, content) => {
|
|
12991
13233
|
if (content) {
|
|
12992
13234
|
lspManagerRef.current.notifyChange(path, content);
|
|
12993
13235
|
} else {
|
|
12994
13236
|
void import("fs/promises").then(
|
|
12995
|
-
({ readFile:
|
|
13237
|
+
({ readFile: readFile17 }) => readFile17(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
|
|
12996
13238
|
})
|
|
12997
13239
|
);
|
|
12998
13240
|
}
|
|
@@ -13086,7 +13328,7 @@ function App({
|
|
|
13086
13328
|
})
|
|
13087
13329
|
}
|
|
13088
13330
|
});
|
|
13089
|
-
if (existsSync2(
|
|
13331
|
+
if (existsSync2(join21(cwd, "KIMI.md"))) {
|
|
13090
13332
|
if (cacheStableRef.current) {
|
|
13091
13333
|
messagesRef.current[1] = {
|
|
13092
13334
|
role: "system",
|
|
@@ -13315,6 +13557,10 @@ function App({
|
|
|
13315
13557
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "no config loaded" }]);
|
|
13316
13558
|
return true;
|
|
13317
13559
|
}
|
|
13560
|
+
if (cfg.cloudMode) {
|
|
13561
|
+
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "AI Gateway is managed by Kimiflare Cloud" }]);
|
|
13562
|
+
return true;
|
|
13563
|
+
}
|
|
13318
13564
|
const sub = rest[0]?.toLowerCase() ?? "";
|
|
13319
13565
|
const subArg = rest.slice(1).join(" ").trim();
|
|
13320
13566
|
if (!sub || sub === "status") {
|
|
@@ -14185,6 +14431,8 @@ ${lines.join("\n")}` }]);
|
|
|
14185
14431
|
memoryManager: memoryManagerRef.current,
|
|
14186
14432
|
keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
|
|
14187
14433
|
codeMode: effectiveCodeMode,
|
|
14434
|
+
cloudMode: cfg.cloudMode,
|
|
14435
|
+
cloudToken: initialCloudToken,
|
|
14188
14436
|
onIterationEnd,
|
|
14189
14437
|
intentClassification: classification,
|
|
14190
14438
|
onFileChange: (path, content2) => {
|
|
@@ -14192,7 +14440,7 @@ ${lines.join("\n")}` }]);
|
|
|
14192
14440
|
lspManagerRef.current.notifyChange(path, content2);
|
|
14193
14441
|
} else {
|
|
14194
14442
|
void import("fs/promises").then(
|
|
14195
|
-
({ readFile:
|
|
14443
|
+
({ readFile: readFile17 }) => readFile17(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
|
|
14196
14444
|
})
|
|
14197
14445
|
);
|
|
14198
14446
|
}
|
|
@@ -14373,12 +14621,28 @@ ${lines.join("\n")}` }]);
|
|
|
14373
14621
|
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(
|
|
14374
14622
|
Onboarding,
|
|
14375
14623
|
{
|
|
14376
|
-
onDone: (newCfg) => {
|
|
14624
|
+
onDone: async (newCfg) => {
|
|
14377
14625
|
setCfg(newCfg);
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
|
|
14626
|
+
if (newCfg.cloudMode) {
|
|
14627
|
+
const { loadCloudCredentials: loadCloudCredentials2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
14628
|
+
const creds = await loadCloudCredentials2();
|
|
14629
|
+
if (creds) {
|
|
14630
|
+
setEvents((e) => [
|
|
14631
|
+
...e,
|
|
14632
|
+
{ kind: "info", key: mkKey(), text: "configuration saved \u2014 welcome to kimiflare! (cloud mode)" }
|
|
14633
|
+
]);
|
|
14634
|
+
} else {
|
|
14635
|
+
setEvents((e) => [
|
|
14636
|
+
...e,
|
|
14637
|
+
{ kind: "info", key: mkKey(), text: "cloud mode configured \u2014 run `kimiflare auth cloud` to sign in" }
|
|
14638
|
+
]);
|
|
14639
|
+
}
|
|
14640
|
+
} else {
|
|
14641
|
+
setEvents((e) => [
|
|
14642
|
+
...e,
|
|
14643
|
+
{ kind: "info", key: mkKey(), text: "configuration saved \u2014 welcome to kimiflare!" }
|
|
14644
|
+
]);
|
|
14645
|
+
}
|
|
14382
14646
|
}
|
|
14383
14647
|
}
|
|
14384
14648
|
) });
|
|
@@ -14424,6 +14688,7 @@ ${lines.join("\n")}` }]);
|
|
|
14424
14688
|
{
|
|
14425
14689
|
customCommands: customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({ name: c.name, description: c.description })),
|
|
14426
14690
|
costAttributionEnabled: cfg?.costAttribution,
|
|
14691
|
+
cloudMode: cfg?.cloudMode,
|
|
14427
14692
|
onDone: () => setShowHelpMenu(false),
|
|
14428
14693
|
onCommand: handleHelpCommand
|
|
14429
14694
|
}
|
|
@@ -14435,7 +14700,7 @@ ${lines.join("\n")}` }]);
|
|
|
14435
14700
|
{
|
|
14436
14701
|
servers: cfg?.lspServers ?? {},
|
|
14437
14702
|
currentScope: lspScope,
|
|
14438
|
-
hasProjectDir: existsSync2(
|
|
14703
|
+
hasProjectDir: existsSync2(join21(process.cwd(), ".kimiflare")),
|
|
14439
14704
|
onDone: () => setShowLspWizard(false),
|
|
14440
14705
|
onSave: (servers, enabled, scope) => {
|
|
14441
14706
|
setCfg((c) => c ? { ...c, lspEnabled: enabled, lspServers: servers } : c);
|
|
@@ -14506,7 +14771,7 @@ ${lines.join("\n")}` }]);
|
|
|
14506
14771
|
] }),
|
|
14507
14772
|
/* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: commandToDelete.filepath }),
|
|
14508
14773
|
/* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
|
|
14509
|
-
|
|
14774
|
+
SelectInput10,
|
|
14510
14775
|
{
|
|
14511
14776
|
items: [
|
|
14512
14777
|
{ label: "Yes, delete", value: "yes", key: "yes" },
|
|
@@ -14576,7 +14841,8 @@ ${lines.join("\n")}` }]);
|
|
|
14576
14841
|
hasUpdate,
|
|
14577
14842
|
latestVersion,
|
|
14578
14843
|
gatewayMeta,
|
|
14579
|
-
codeMode
|
|
14844
|
+
codeMode,
|
|
14845
|
+
cloudMode: cfg.cloudMode
|
|
14580
14846
|
}
|
|
14581
14847
|
),
|
|
14582
14848
|
activePicker?.kind === "file" && /* @__PURE__ */ jsx22(
|
|
@@ -14652,7 +14918,7 @@ ${lines.join("\n")}` }]);
|
|
|
14652
14918
|
] })
|
|
14653
14919
|
] }) });
|
|
14654
14920
|
}
|
|
14655
|
-
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null) {
|
|
14921
|
+
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken) {
|
|
14656
14922
|
const instance = render(
|
|
14657
14923
|
/* @__PURE__ */ jsx22(
|
|
14658
14924
|
App,
|
|
@@ -14660,7 +14926,8 @@ async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath
|
|
|
14660
14926
|
initialCfg: cfg,
|
|
14661
14927
|
initialUpdateResult: updateResult,
|
|
14662
14928
|
initialLspScope: lspScope,
|
|
14663
|
-
initialLspProjectPath: lspProjectPath
|
|
14929
|
+
initialLspProjectPath: lspProjectPath,
|
|
14930
|
+
initialCloudToken: cloudToken
|
|
14664
14931
|
}
|
|
14665
14932
|
),
|
|
14666
14933
|
{
|
|
@@ -14851,7 +15118,7 @@ function createRemoteCommand() {
|
|
|
14851
15118
|
|
|
14852
15119
|
// src/index.tsx
|
|
14853
15120
|
var program = new Command2();
|
|
14854
|
-
program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.6 on Cloudflare Workers AI.").version(getAppVersion()).option("-p, --print <prompt>", "one-shot mode: send prompt, stream reply to stdout, exit").option("-m, --model <id>", "model id (defaults to @cf/moonshotai/kimi-k2.6)").option("--dangerously-allow-all", "auto-approve every permission prompt (print mode only)").option("--reasoning", "include reasoning in stdout (print mode only)").option("--continue-on-limit", "reset tool-call counter and continue when the 50-call limit is hit (print mode only)").option("--max-input-tokens <n>", "cumulative prompt token budget; exits 42 when exhausted (print mode only)", (v) => parseInt(v, 10));
|
|
15121
|
+
program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.6 on Cloudflare Workers AI.").version(getAppVersion()).option("-p, --print <prompt>", "one-shot mode: send prompt, stream reply to stdout, exit").option("-m, --model <id>", "model id (defaults to @cf/moonshotai/kimi-k2.6)").option("--cloud", "use Kimiflare Cloud (api.kimiflare.com) instead of direct Workers AI").option("--dangerously-allow-all", "auto-approve every permission prompt (print mode only)").option("--reasoning", "include reasoning in stdout (print mode only)").option("--continue-on-limit", "reset tool-call counter and continue when the 50-call limit is hit (print mode only)").option("--max-input-tokens <n>", "cumulative prompt token budget; exits 42 when exhausted (print mode only)", (v) => parseInt(v, 10));
|
|
14855
15122
|
program.command("cost").description("Show cost attribution by task type (requires costAttribution enabled)").option("-w, --week", "last 7 days (default)").option("-m, --month", "last 30 days").option("-d, --day", "today only").option("-s, --session <id>", "single session detail").option("-c, --category <name>", "filter by category").option("--json", "machine-readable output").option("--reclassify", "re-run classification on all sessions").option("--local-only", "skip Cloudflare reconciliation").action(async (cmdOpts) => {
|
|
14856
15123
|
const cfg = await loadConfig();
|
|
14857
15124
|
const enabled = cfg?.costAttribution ?? false;
|
|
@@ -14864,6 +15131,25 @@ program.command("cost").description("Show cost attribution by task type (require
|
|
|
14864
15131
|
const { runCostCommand: runCostCommand2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
14865
15132
|
await runCostCommand2({ ...cmdOpts, config: cfg });
|
|
14866
15133
|
});
|
|
15134
|
+
program.command("usage").description("Show Kimiflare Cloud token usage (requires cloud authentication)").action(async () => {
|
|
15135
|
+
const { loadCloudCredentials: loadCloudCredentials2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15136
|
+
const creds = await loadCloudCredentials2();
|
|
15137
|
+
if (!creds) {
|
|
15138
|
+
console.error("Not authenticated with Kimiflare Cloud. Run: kimiflare auth cloud");
|
|
15139
|
+
process.exit(1);
|
|
15140
|
+
}
|
|
15141
|
+
const res = await fetch("https://api.kimiflare.com/v1/usage", {
|
|
15142
|
+
headers: { Authorization: `Bearer ${creds.accessToken}` }
|
|
15143
|
+
});
|
|
15144
|
+
if (!res.ok) {
|
|
15145
|
+
console.error(`Failed to fetch usage: ${res.status} ${res.statusText}`);
|
|
15146
|
+
process.exit(1);
|
|
15147
|
+
}
|
|
15148
|
+
const usage = await res.json();
|
|
15149
|
+
console.log(`Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
|
|
15150
|
+
console.log(`Used: ${usage.input_tokens_used.toLocaleString()}`);
|
|
15151
|
+
console.log(`Grant expires: ${usage.expires_at}`);
|
|
15152
|
+
});
|
|
14867
15153
|
program.addCommand(createRemoteCommand());
|
|
14868
15154
|
program.command("auth").description("Authenticate with external services").addCommand(
|
|
14869
15155
|
new Command2("github").description("Authenticate with GitHub via OAuth device flow").action(async () => {
|
|
@@ -14880,6 +15166,37 @@ Open: ${step.url}`);
|
|
|
14880
15166
|
if (step.error) process.exit(1);
|
|
14881
15167
|
}
|
|
14882
15168
|
})
|
|
15169
|
+
).addCommand(
|
|
15170
|
+
new Command2("cloud").description("Authenticate with Kimiflare Cloud").action(async () => {
|
|
15171
|
+
const { authenticateDevice: authenticateDevice2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15172
|
+
try {
|
|
15173
|
+
const creds = await authenticateDevice2(({ url, userCode, polling }) => {
|
|
15174
|
+
if (!polling) {
|
|
15175
|
+
console.log(`
|
|
15176
|
+
Kimiflare Cloud Authentication`);
|
|
15177
|
+
console.log(`
|
|
15178
|
+
1. Open this URL in your browser:`);
|
|
15179
|
+
console.log(` ${url}`);
|
|
15180
|
+
console.log(`
|
|
15181
|
+
2. Sign in with GitHub
|
|
15182
|
+
`);
|
|
15183
|
+
}
|
|
15184
|
+
});
|
|
15185
|
+
console.log(`Authenticated! Token expires at ${new Date(creds.expiresAt * 1e3).toISOString()}`);
|
|
15186
|
+
const usageRes = await fetch("https://api.kimiflare.com/v1/usage", {
|
|
15187
|
+
headers: { Authorization: `Bearer ${creds.accessToken}` }
|
|
15188
|
+
});
|
|
15189
|
+
if (usageRes.ok) {
|
|
15190
|
+
const usage = await usageRes.json();
|
|
15191
|
+
console.log(`
|
|
15192
|
+
Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
|
|
15193
|
+
console.log(`Grant expires: ${usage.expires_at}`);
|
|
15194
|
+
}
|
|
15195
|
+
} catch (err) {
|
|
15196
|
+
console.error("Authentication failed:", err instanceof Error ? err.message : String(err));
|
|
15197
|
+
process.exit(1);
|
|
15198
|
+
}
|
|
15199
|
+
})
|
|
14883
15200
|
);
|
|
14884
15201
|
program.action(async () => {
|
|
14885
15202
|
await main();
|
|
@@ -14902,10 +15219,25 @@ async function main() {
|
|
|
14902
15219
|
lspScope = resolved.scope;
|
|
14903
15220
|
lspProjectPath = resolved.projectPath;
|
|
14904
15221
|
}
|
|
15222
|
+
const cloudMode = opts.cloud ?? cfg?.cloudMode ?? false;
|
|
15223
|
+
let cloudToken;
|
|
15224
|
+
if (cloudMode) {
|
|
15225
|
+
const { loadCloudCredentials: loadCloudCredentials2, authenticateDevice: authenticateDevice2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15226
|
+
let cloudCreds = await loadCloudCredentials2();
|
|
15227
|
+
if (!cloudCreds) {
|
|
15228
|
+
console.error("kimiflare: cloud mode requires authentication.\nRun: kimiflare auth cloud\n");
|
|
15229
|
+
process.exit(2);
|
|
15230
|
+
}
|
|
15231
|
+
cloudToken = cloudCreds.accessToken;
|
|
15232
|
+
cfg = {
|
|
15233
|
+
...cfg ?? { accountId: "", apiToken: "", model: DEFAULT_MODEL },
|
|
15234
|
+
cloudMode: true
|
|
15235
|
+
};
|
|
15236
|
+
}
|
|
14905
15237
|
if (opts.print !== void 0) {
|
|
14906
15238
|
if (!cfg) {
|
|
14907
15239
|
console.error(
|
|
14908
|
-
'kimiflare: missing credentials.\nSet CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN, or write them to\n ~/.config/kimiflare/config.json (chmod 600)\n { "accountId": "...", "apiToken": "...", "model": "@cf/moonshotai/kimi-k2.6" }'
|
|
15240
|
+
'kimiflare: missing credentials.\nSet CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN, or write them to\n ~/.config/kimiflare/config.json (chmod 600)\n { "accountId": "...", "apiToken": "...", "model": "@cf/moonshotai/kimi-k2.6" }\nOr use cloud mode: kimiflare --cloud -p "..."'
|
|
14909
15241
|
);
|
|
14910
15242
|
process.exit(2);
|
|
14911
15243
|
}
|
|
@@ -14917,6 +15249,7 @@ async function main() {
|
|
|
14917
15249
|
allowAll: !!opts.dangerouslyAllowAll,
|
|
14918
15250
|
showReasoning: !!opts.reasoning,
|
|
14919
15251
|
codeMode: cfg.codeMode,
|
|
15252
|
+
cloudToken,
|
|
14920
15253
|
continueOnLimit: !!opts.continueOnLimit,
|
|
14921
15254
|
maxInputTokens: opts.maxInputTokens,
|
|
14922
15255
|
updateResult
|
|
@@ -14932,9 +15265,9 @@ async function main() {
|
|
|
14932
15265
|
const { renderApp: renderApp2 } = await Promise.resolve().then(() => (init_app(), app_exports));
|
|
14933
15266
|
if (cfg) {
|
|
14934
15267
|
const model = opts.model ?? cfg.model ?? DEFAULT_MODEL;
|
|
14935
|
-
await renderApp2({ ...cfg, model }, updateResult, lspScope, lspProjectPath);
|
|
15268
|
+
await renderApp2({ ...cfg, model }, updateResult, lspScope, lspProjectPath, cloudToken);
|
|
14936
15269
|
} else {
|
|
14937
|
-
await renderApp2(null, updateResult, lspScope, lspProjectPath);
|
|
15270
|
+
await renderApp2(null, updateResult, lspScope, lspProjectPath, cloudToken);
|
|
14938
15271
|
}
|
|
14939
15272
|
}
|
|
14940
15273
|
function gatewayFromPrintOpts(opts2) {
|
|
@@ -14948,6 +15281,10 @@ function gatewayFromPrintOpts(opts2) {
|
|
|
14948
15281
|
};
|
|
14949
15282
|
}
|
|
14950
15283
|
async function runPrintMode(opts2) {
|
|
15284
|
+
if (opts2.cloudMode) {
|
|
15285
|
+
process.stderr.write(`[cloud mode: api.kimiflare.com]
|
|
15286
|
+
`);
|
|
15287
|
+
}
|
|
14951
15288
|
if (opts2.updateResult.hasUpdate) {
|
|
14952
15289
|
process.stderr.write(
|
|
14953
15290
|
`\x1B[33mkimiflare update available: ${opts2.updateResult.localVersion} \u2192 ${opts2.updateResult.latestVersion}\x1B[0m
|
|
@@ -14980,6 +15317,8 @@ async function runPrintMode(opts2) {
|
|
|
14980
15317
|
codeMode: opts2.codeMode,
|
|
14981
15318
|
continueOnLimit: opts2.continueOnLimit,
|
|
14982
15319
|
maxInputTokens: opts2.maxInputTokens,
|
|
15320
|
+
cloudMode: opts2.cloudMode,
|
|
15321
|
+
cloudToken: opts2.cloudToken,
|
|
14983
15322
|
coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
14984
15323
|
callbacks: {
|
|
14985
15324
|
onReasoningDelta: opts2.showReasoning ? (delta) => {
|