kimiflare 0.33.0 → 0.34.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 +1519 -394
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -9,6 +9,15 @@ var __export = (target, all) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
// src/config.ts
|
|
12
|
+
var config_exports = {};
|
|
13
|
+
__export(config_exports, {
|
|
14
|
+
DEFAULT_MODEL: () => DEFAULT_MODEL,
|
|
15
|
+
DEFAULT_REASONING_EFFORT: () => DEFAULT_REASONING_EFFORT,
|
|
16
|
+
EFFORTS: () => EFFORTS,
|
|
17
|
+
configPath: () => configPath,
|
|
18
|
+
loadConfig: () => loadConfig,
|
|
19
|
+
saveConfig: () => saveConfig
|
|
20
|
+
});
|
|
12
21
|
import { readFile, mkdir, writeFile, chmod } from "fs/promises";
|
|
13
22
|
import { homedir } from "os";
|
|
14
23
|
import { join } from "path";
|
|
@@ -933,7 +942,10 @@ async function logTurnDebug(ctx) {
|
|
|
933
942
|
toolSavingsPct: toolTotalRaw > 0 ? Math.round((toolTotalRaw - toolTotalReduced) / toolTotalRaw * 100) : 0,
|
|
934
943
|
cacheDiagnostics,
|
|
935
944
|
compaction: ctx.compaction,
|
|
936
|
-
shadowStrip: ctx.shadowStrip
|
|
945
|
+
shadowStrip: ctx.shadowStrip,
|
|
946
|
+
durationMs: ctx.durationMs,
|
|
947
|
+
intentClassification: ctx.intentClassification,
|
|
948
|
+
codeMode: ctx.codeMode
|
|
937
949
|
});
|
|
938
950
|
}
|
|
939
951
|
var LOG_VERSION;
|
|
@@ -1356,6 +1368,7 @@ var init_code_mode = __esm({
|
|
|
1356
1368
|
|
|
1357
1369
|
// src/agent/loop.ts
|
|
1358
1370
|
async function runAgentTurn(opts2) {
|
|
1371
|
+
const turnStart = performance.now();
|
|
1359
1372
|
const max = opts2.maxToolIterations ?? 50;
|
|
1360
1373
|
const codeMode = opts2.codeMode ?? false;
|
|
1361
1374
|
let toolDefs;
|
|
@@ -1728,6 +1741,10 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
1728
1741
|
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
1729
1742
|
}
|
|
1730
1743
|
}
|
|
1744
|
+
if (opts2.onIterationEnd) {
|
|
1745
|
+
opts2.messages = await opts2.onIterationEnd(opts2.messages, opts2.signal);
|
|
1746
|
+
if (opts2.signal.aborted) throw new DOMException("aborted", "AbortError");
|
|
1747
|
+
}
|
|
1731
1748
|
if (opts2.sessionId && lastUsage) {
|
|
1732
1749
|
void logTurnDebug({
|
|
1733
1750
|
sessionId: opts2.sessionId,
|
|
@@ -1736,7 +1753,10 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
1736
1753
|
previousMessages,
|
|
1737
1754
|
toolResults,
|
|
1738
1755
|
usage: lastUsage,
|
|
1739
|
-
shadowStrip: shadowStripMetrics
|
|
1756
|
+
shadowStrip: shadowStripMetrics,
|
|
1757
|
+
durationMs: Math.round(performance.now() - turnStart),
|
|
1758
|
+
intentClassification: opts2.intentClassification,
|
|
1759
|
+
codeMode: opts2.codeMode
|
|
1740
1760
|
});
|
|
1741
1761
|
}
|
|
1742
1762
|
if (budgetExhausted) {
|
|
@@ -3531,6 +3551,229 @@ var init_update_check = __esm({
|
|
|
3531
3551
|
}
|
|
3532
3552
|
});
|
|
3533
3553
|
|
|
3554
|
+
// src/remote/session-store.ts
|
|
3555
|
+
import { readFile as readFile8, writeFile as writeFile6, mkdir as mkdir6, readdir as readdir2 } from "fs/promises";
|
|
3556
|
+
import { homedir as homedir6 } from "os";
|
|
3557
|
+
import { join as join9 } from "path";
|
|
3558
|
+
function remoteDir() {
|
|
3559
|
+
const xdg = process.env.XDG_DATA_HOME || join9(homedir6(), ".config");
|
|
3560
|
+
return join9(xdg, "kimiflare", "remote");
|
|
3561
|
+
}
|
|
3562
|
+
async function saveRemoteSession(session) {
|
|
3563
|
+
const dir = remoteDir();
|
|
3564
|
+
await mkdir6(dir, { recursive: true });
|
|
3565
|
+
const path = join9(dir, `${session.sessionId}.json`);
|
|
3566
|
+
await writeFile6(path, JSON.stringify(session, null, 2) + "\n", "utf8");
|
|
3567
|
+
}
|
|
3568
|
+
async function loadRemoteSession(sessionId) {
|
|
3569
|
+
try {
|
|
3570
|
+
const path = join9(remoteDir(), `${sessionId}.json`);
|
|
3571
|
+
const raw = await readFile8(path, "utf8");
|
|
3572
|
+
return JSON.parse(raw);
|
|
3573
|
+
} catch {
|
|
3574
|
+
return null;
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
async function listRemoteSessions() {
|
|
3578
|
+
const dir = remoteDir();
|
|
3579
|
+
try {
|
|
3580
|
+
const files = await readdir2(dir);
|
|
3581
|
+
const sessions = [];
|
|
3582
|
+
for (const file of files) {
|
|
3583
|
+
if (!file.endsWith(".json")) continue;
|
|
3584
|
+
try {
|
|
3585
|
+
const raw = await readFile8(join9(dir, file), "utf8");
|
|
3586
|
+
sessions.push(JSON.parse(raw));
|
|
3587
|
+
} catch {
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
return sessions.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
3591
|
+
} catch {
|
|
3592
|
+
return [];
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
async function getMostRecentRemoteSession() {
|
|
3596
|
+
const sessions = await listRemoteSessions();
|
|
3597
|
+
return sessions[0] ?? null;
|
|
3598
|
+
}
|
|
3599
|
+
var init_session_store = __esm({
|
|
3600
|
+
"src/remote/session-store.ts"() {
|
|
3601
|
+
"use strict";
|
|
3602
|
+
}
|
|
3603
|
+
});
|
|
3604
|
+
|
|
3605
|
+
// src/remote/deploy.ts
|
|
3606
|
+
import { execSync } from "child_process";
|
|
3607
|
+
import { join as join10, dirname as dirname5 } from "path";
|
|
3608
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3609
|
+
import { randomBytes } from "crypto";
|
|
3610
|
+
function generateSecret() {
|
|
3611
|
+
return randomBytes(32).toString("hex");
|
|
3612
|
+
}
|
|
3613
|
+
function runCapture(cmd, cwd) {
|
|
3614
|
+
return execSync(cmd, { cwd, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
3615
|
+
}
|
|
3616
|
+
async function* deployForTui() {
|
|
3617
|
+
yield { message: "Checking prerequisites..." };
|
|
3618
|
+
try {
|
|
3619
|
+
runCapture("wrangler --version");
|
|
3620
|
+
} catch {
|
|
3621
|
+
yield { message: "wrangler not found. Install: npm install -g wrangler", error: true };
|
|
3622
|
+
yield { message: "Then run: wrangler login", error: true };
|
|
3623
|
+
throw new Error("wrangler not installed");
|
|
3624
|
+
}
|
|
3625
|
+
yield { message: "wrangler OK" };
|
|
3626
|
+
try {
|
|
3627
|
+
runCapture("wrangler whoami");
|
|
3628
|
+
} catch {
|
|
3629
|
+
yield { message: "wrangler not authenticated. Run: wrangler login", error: true };
|
|
3630
|
+
throw new Error("wrangler not authenticated");
|
|
3631
|
+
}
|
|
3632
|
+
yield { message: "wrangler authenticated" };
|
|
3633
|
+
try {
|
|
3634
|
+
runCapture("docker --version");
|
|
3635
|
+
} catch {
|
|
3636
|
+
yield { message: "Docker not found. Install: https://docs.docker.com/get-docker/", error: true };
|
|
3637
|
+
throw new Error("docker not installed");
|
|
3638
|
+
}
|
|
3639
|
+
yield { message: "Docker OK" };
|
|
3640
|
+
yield { message: "Building remote agent bundle..." };
|
|
3641
|
+
try {
|
|
3642
|
+
runCapture("npm run build:remote-agent", join10(REMOTE_DIR, ".."));
|
|
3643
|
+
yield { message: "Agent bundle built" };
|
|
3644
|
+
} catch (err) {
|
|
3645
|
+
yield { message: `Build failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
|
|
3646
|
+
throw err;
|
|
3647
|
+
}
|
|
3648
|
+
yield { message: "Deploying Worker to Cloudflare..." };
|
|
3649
|
+
try {
|
|
3650
|
+
runCapture("wrangler deploy", WORKER_DIR);
|
|
3651
|
+
yield { message: "Worker deployed" };
|
|
3652
|
+
} catch (err) {
|
|
3653
|
+
yield { message: `Deploy failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
|
|
3654
|
+
throw err;
|
|
3655
|
+
}
|
|
3656
|
+
let workerUrl;
|
|
3657
|
+
try {
|
|
3658
|
+
const info = runCapture("wrangler info", WORKER_DIR);
|
|
3659
|
+
const match = info.match(/https:\/\/[^\s]+\.workers\.dev/);
|
|
3660
|
+
if (match) workerUrl = match[0];
|
|
3661
|
+
} catch {
|
|
3662
|
+
}
|
|
3663
|
+
if (!workerUrl) {
|
|
3664
|
+
yield { message: "Could not auto-detect Worker URL", error: true };
|
|
3665
|
+
throw new Error("Worker URL not found");
|
|
3666
|
+
}
|
|
3667
|
+
yield { message: `Worker URL: ${workerUrl}` };
|
|
3668
|
+
const authSecret = generateSecret();
|
|
3669
|
+
const cfg = await loadConfig();
|
|
3670
|
+
const cfToken = process.env.CF_API_TOKEN ?? cfg?.apiToken;
|
|
3671
|
+
if (!cfToken) {
|
|
3672
|
+
yield { message: "CF_API_TOKEN not found. Set CF_API_TOKEN env var or apiToken in config", error: true };
|
|
3673
|
+
throw new Error("CF_API_TOKEN missing");
|
|
3674
|
+
}
|
|
3675
|
+
yield { message: "Setting Worker secrets..." };
|
|
3676
|
+
try {
|
|
3677
|
+
execSync(`wrangler secret put REMOTE_AUTH_SECRET`, {
|
|
3678
|
+
cwd: WORKER_DIR,
|
|
3679
|
+
input: authSecret,
|
|
3680
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
3681
|
+
});
|
|
3682
|
+
execSync(`wrangler secret put CF_API_TOKEN`, {
|
|
3683
|
+
cwd: WORKER_DIR,
|
|
3684
|
+
input: cfToken,
|
|
3685
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
3686
|
+
});
|
|
3687
|
+
yield { message: "Secrets set" };
|
|
3688
|
+
} catch (err) {
|
|
3689
|
+
yield { message: `Secret setup failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
|
|
3690
|
+
throw err;
|
|
3691
|
+
}
|
|
3692
|
+
const imageTag = "ghcr.io/sinameraji/kimiflare-remote-agent:latest";
|
|
3693
|
+
yield { message: "Building container image..." };
|
|
3694
|
+
try {
|
|
3695
|
+
runCapture(`docker build -t ${imageTag} .`, REMOTE_DIR);
|
|
3696
|
+
yield { message: "Image built" };
|
|
3697
|
+
} catch (err) {
|
|
3698
|
+
yield { message: `Image build failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
|
|
3699
|
+
throw err;
|
|
3700
|
+
}
|
|
3701
|
+
yield { message: `Pushing ${imageTag}...` };
|
|
3702
|
+
try {
|
|
3703
|
+
runCapture(`docker push ${imageTag}`, REMOTE_DIR);
|
|
3704
|
+
yield { message: "Image pushed" };
|
|
3705
|
+
} catch (err) {
|
|
3706
|
+
yield { message: `Push failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
|
|
3707
|
+
yield { message: "Make sure you're logged into ghcr.io: docker login ghcr.io -u USERNAME -p GITHUB_TOKEN", error: true };
|
|
3708
|
+
throw err;
|
|
3709
|
+
}
|
|
3710
|
+
const nextCfg = {
|
|
3711
|
+
...cfg ?? { accountId: "", apiToken: "", model: "@cf/moonshotai/kimi-k2.6" },
|
|
3712
|
+
remoteWorkerUrl: workerUrl,
|
|
3713
|
+
remoteAuthSecret: authSecret
|
|
3714
|
+
};
|
|
3715
|
+
await saveConfig(nextCfg);
|
|
3716
|
+
yield { message: "Config saved" };
|
|
3717
|
+
yield { message: "Remote infrastructure ready!", done: true };
|
|
3718
|
+
return { workerUrl, authSecret };
|
|
3719
|
+
}
|
|
3720
|
+
async function runDeploy() {
|
|
3721
|
+
console.log("kimiflare remote deploy\n");
|
|
3722
|
+
try {
|
|
3723
|
+
for await (const step of deployForTui()) {
|
|
3724
|
+
console.log(step.message);
|
|
3725
|
+
if (step.done) break;
|
|
3726
|
+
if (step.error) process.exit(1);
|
|
3727
|
+
}
|
|
3728
|
+
console.log("\nDeploy complete!");
|
|
3729
|
+
} catch (err) {
|
|
3730
|
+
console.error(`Deploy failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
3731
|
+
process.exit(1);
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
async function checkDeployStatus() {
|
|
3735
|
+
let wrangler = false;
|
|
3736
|
+
let wranglerAuth = false;
|
|
3737
|
+
let docker = false;
|
|
3738
|
+
let workerUrl;
|
|
3739
|
+
try {
|
|
3740
|
+
execSync("wrangler --version", { stdio: "pipe" });
|
|
3741
|
+
wrangler = true;
|
|
3742
|
+
} catch {
|
|
3743
|
+
}
|
|
3744
|
+
if (wrangler) {
|
|
3745
|
+
try {
|
|
3746
|
+
execSync("wrangler whoami", { stdio: "pipe" });
|
|
3747
|
+
wranglerAuth = true;
|
|
3748
|
+
} catch {
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
try {
|
|
3752
|
+
execSync("docker --version", { stdio: "pipe" });
|
|
3753
|
+
docker = true;
|
|
3754
|
+
} catch {
|
|
3755
|
+
}
|
|
3756
|
+
const cfg = await loadConfig();
|
|
3757
|
+
if (cfg?.remoteWorkerUrl) {
|
|
3758
|
+
try {
|
|
3759
|
+
const res = await fetch(`${cfg.remoteWorkerUrl}/health`, { signal: AbortSignal.timeout(5e3) });
|
|
3760
|
+
if (res.ok) workerUrl = cfg.remoteWorkerUrl;
|
|
3761
|
+
} catch {
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
return { wrangler, wranglerAuth, docker, workerUrl };
|
|
3765
|
+
}
|
|
3766
|
+
var __dirname, REMOTE_DIR, WORKER_DIR;
|
|
3767
|
+
var init_deploy = __esm({
|
|
3768
|
+
"src/remote/deploy.ts"() {
|
|
3769
|
+
"use strict";
|
|
3770
|
+
init_config();
|
|
3771
|
+
__dirname = dirname5(fileURLToPath3(import.meta.url));
|
|
3772
|
+
REMOTE_DIR = join10(__dirname, "..", "..", "..", "remote");
|
|
3773
|
+
WORKER_DIR = join10(REMOTE_DIR, "worker");
|
|
3774
|
+
}
|
|
3775
|
+
});
|
|
3776
|
+
|
|
3534
3777
|
// src/cost-attribution/types.ts
|
|
3535
3778
|
var ALL_CATEGORIES;
|
|
3536
3779
|
var init_types = __esm({
|
|
@@ -3950,12 +4193,12 @@ var init_heuristic = __esm({
|
|
|
3950
4193
|
});
|
|
3951
4194
|
|
|
3952
4195
|
// src/cost-attribution/classify-from-session.ts
|
|
3953
|
-
import { readFile as
|
|
3954
|
-
import { join as
|
|
3955
|
-
import { homedir as
|
|
4196
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
4197
|
+
import { join as join11 } from "path";
|
|
4198
|
+
import { homedir as homedir7 } from "os";
|
|
3956
4199
|
function sessionsDir() {
|
|
3957
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
3958
|
-
return
|
|
4200
|
+
const xdg = process.env.XDG_DATA_HOME || join11(homedir7(), ".local", "share");
|
|
4201
|
+
return join11(xdg, "kimiflare", "sessions");
|
|
3959
4202
|
}
|
|
3960
4203
|
function parseToolCalls(calls) {
|
|
3961
4204
|
return calls.map((c) => {
|
|
@@ -3969,7 +4212,7 @@ function parseToolCalls(calls) {
|
|
|
3969
4212
|
}
|
|
3970
4213
|
async function classifyFromSessionFile(sessionId) {
|
|
3971
4214
|
try {
|
|
3972
|
-
const raw = await
|
|
4215
|
+
const raw = await readFile9(join11(sessionsDir(), `${sessionId}.json`), "utf8");
|
|
3973
4216
|
const session = JSON.parse(raw);
|
|
3974
4217
|
const messages = session.messages ?? [];
|
|
3975
4218
|
const turns = [];
|
|
@@ -4002,15 +4245,15 @@ var cli_exports = {};
|
|
|
4002
4245
|
__export(cli_exports, {
|
|
4003
4246
|
runCostCommand: () => runCostCommand
|
|
4004
4247
|
});
|
|
4005
|
-
import { readFile as
|
|
4006
|
-
import { join as
|
|
4007
|
-
import { homedir as
|
|
4248
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
4249
|
+
import { join as join12 } from "path";
|
|
4250
|
+
import { homedir as homedir8 } from "os";
|
|
4008
4251
|
function usageDir() {
|
|
4009
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
4010
|
-
return
|
|
4252
|
+
const xdg = process.env.XDG_DATA_HOME || join12(homedir8(), ".local", "share");
|
|
4253
|
+
return join12(xdg, "kimiflare");
|
|
4011
4254
|
}
|
|
4012
4255
|
function usagePath() {
|
|
4013
|
-
return
|
|
4256
|
+
return join12(usageDir(), "usage.json");
|
|
4014
4257
|
}
|
|
4015
4258
|
function today() {
|
|
4016
4259
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -4022,7 +4265,7 @@ function daysAgo(n) {
|
|
|
4022
4265
|
}
|
|
4023
4266
|
async function loadLog() {
|
|
4024
4267
|
try {
|
|
4025
|
-
const raw = await
|
|
4268
|
+
const raw = await readFile10(usagePath(), "utf8");
|
|
4026
4269
|
return JSON.parse(raw);
|
|
4027
4270
|
} catch {
|
|
4028
4271
|
return { version: 1, days: [], sessions: [] };
|
|
@@ -4108,6 +4351,94 @@ var init_cli = __esm({
|
|
|
4108
4351
|
}
|
|
4109
4352
|
});
|
|
4110
4353
|
|
|
4354
|
+
// src/remote/tui-auth.ts
|
|
4355
|
+
var tui_auth_exports = {};
|
|
4356
|
+
__export(tui_auth_exports, {
|
|
4357
|
+
authGitHubForTui: () => authGitHubForTui
|
|
4358
|
+
});
|
|
4359
|
+
function sleep2(ms) {
|
|
4360
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
4361
|
+
}
|
|
4362
|
+
async function* authGitHubForTui() {
|
|
4363
|
+
yield { message: "Starting GitHub OAuth device flow..." };
|
|
4364
|
+
const deviceRes = await fetch(GITHUB_DEVICE_AUTH_URL, {
|
|
4365
|
+
method: "POST",
|
|
4366
|
+
headers: {
|
|
4367
|
+
Accept: "application/json",
|
|
4368
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
4369
|
+
},
|
|
4370
|
+
body: new URLSearchParams({ client_id: CLIENT_ID, scope: "repo" })
|
|
4371
|
+
});
|
|
4372
|
+
if (!deviceRes.ok) {
|
|
4373
|
+
yield { message: `Failed to request device code: ${deviceRes.status}`, error: true };
|
|
4374
|
+
throw new Error("Device code request failed");
|
|
4375
|
+
}
|
|
4376
|
+
const deviceData = await deviceRes.json();
|
|
4377
|
+
yield {
|
|
4378
|
+
message: `Open ${deviceData.verification_uri} and enter code: ${deviceData.user_code}`,
|
|
4379
|
+
url: deviceData.verification_uri,
|
|
4380
|
+
code: deviceData.user_code
|
|
4381
|
+
};
|
|
4382
|
+
const startTime = Date.now();
|
|
4383
|
+
const expiresIn = deviceData.expires_in * 1e3;
|
|
4384
|
+
const interval = deviceData.interval * 1e3;
|
|
4385
|
+
while (Date.now() - startTime < expiresIn) {
|
|
4386
|
+
await sleep2(interval);
|
|
4387
|
+
const tokenRes = await fetch(GITHUB_ACCESS_TOKEN_URL, {
|
|
4388
|
+
method: "POST",
|
|
4389
|
+
headers: {
|
|
4390
|
+
Accept: "application/json",
|
|
4391
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
4392
|
+
},
|
|
4393
|
+
body: new URLSearchParams({
|
|
4394
|
+
client_id: CLIENT_ID,
|
|
4395
|
+
device_code: deviceData.device_code,
|
|
4396
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
4397
|
+
})
|
|
4398
|
+
});
|
|
4399
|
+
if (!tokenRes.ok) continue;
|
|
4400
|
+
const tokenData = await tokenRes.json();
|
|
4401
|
+
if (tokenData.error === "authorization_pending") {
|
|
4402
|
+
continue;
|
|
4403
|
+
}
|
|
4404
|
+
if (tokenData.error === "slow_down") {
|
|
4405
|
+
await sleep2(interval * 2);
|
|
4406
|
+
continue;
|
|
4407
|
+
}
|
|
4408
|
+
if (tokenData.error) {
|
|
4409
|
+
yield { message: `OAuth error: ${tokenData.error}`, error: true };
|
|
4410
|
+
throw new Error(tokenData.error);
|
|
4411
|
+
}
|
|
4412
|
+
if (tokenData.access_token) {
|
|
4413
|
+
const cfg = await loadConfig() ?? {
|
|
4414
|
+
accountId: "",
|
|
4415
|
+
apiToken: "",
|
|
4416
|
+
model: "@cf/moonshotai/kimi-k2.6"
|
|
4417
|
+
};
|
|
4418
|
+
await saveConfig({
|
|
4419
|
+
...cfg,
|
|
4420
|
+
githubOAuthToken: tokenData.access_token,
|
|
4421
|
+
githubRefreshToken: tokenData.refresh_token,
|
|
4422
|
+
githubTokenExpiry: tokenData.expires_in ? Date.now() + tokenData.expires_in * 1e3 : void 0
|
|
4423
|
+
});
|
|
4424
|
+
yield { message: "GitHub authentication successful!", done: true };
|
|
4425
|
+
return;
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
yield { message: "Device flow expired. Please try again.", error: true };
|
|
4429
|
+
throw new Error("Device flow expired");
|
|
4430
|
+
}
|
|
4431
|
+
var GITHUB_DEVICE_AUTH_URL, GITHUB_ACCESS_TOKEN_URL, CLIENT_ID;
|
|
4432
|
+
var init_tui_auth = __esm({
|
|
4433
|
+
"src/remote/tui-auth.ts"() {
|
|
4434
|
+
"use strict";
|
|
4435
|
+
init_config();
|
|
4436
|
+
GITHUB_DEVICE_AUTH_URL = "https://github.com/login/device/code";
|
|
4437
|
+
GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
4438
|
+
CLIENT_ID = process.env.KIMIFLARE_GITHUB_CLIENT_ID ?? "Ov23liM7lJX1xE2V1sVK";
|
|
4439
|
+
}
|
|
4440
|
+
});
|
|
4441
|
+
|
|
4111
4442
|
// src/agent/compact.ts
|
|
4112
4443
|
function indexOfNthUserFromEnd(messages, n) {
|
|
4113
4444
|
let seen = 0;
|
|
@@ -4929,12 +5260,12 @@ var init_connection = __esm({
|
|
|
4929
5260
|
});
|
|
4930
5261
|
|
|
4931
5262
|
// src/lsp/protocol.ts
|
|
4932
|
-
import { pathToFileURL, fileURLToPath as
|
|
5263
|
+
import { pathToFileURL, fileURLToPath as fileURLToPath4 } from "url";
|
|
4933
5264
|
function toUri(path) {
|
|
4934
5265
|
return pathToFileURL(path).href;
|
|
4935
5266
|
}
|
|
4936
5267
|
function fromUri(uri) {
|
|
4937
|
-
return
|
|
5268
|
+
return fileURLToPath4(uri);
|
|
4938
5269
|
}
|
|
4939
5270
|
function symbolKindName(kind) {
|
|
4940
5271
|
const names = {
|
|
@@ -7569,6 +7900,355 @@ var init_help_menu = __esm({
|
|
|
7569
7900
|
}
|
|
7570
7901
|
});
|
|
7571
7902
|
|
|
7903
|
+
// src/remote/worker-client.ts
|
|
7904
|
+
var worker_client_exports = {};
|
|
7905
|
+
__export(worker_client_exports, {
|
|
7906
|
+
cancelRemoteSession: () => cancelRemoteSession,
|
|
7907
|
+
getRemoteStatus: () => getRemoteStatus,
|
|
7908
|
+
startRemoteSession: () => startRemoteSession,
|
|
7909
|
+
streamRemoteProgress: () => streamRemoteProgress
|
|
7910
|
+
});
|
|
7911
|
+
async function startRemoteSession(opts2) {
|
|
7912
|
+
const workerUrl = opts2.cfg.remoteWorkerUrl;
|
|
7913
|
+
if (!workerUrl) {
|
|
7914
|
+
throw new Error("Remote worker URL not configured. Set remoteWorkerUrl in config.");
|
|
7915
|
+
}
|
|
7916
|
+
const githubToken = opts2.cfg.githubOAuthToken;
|
|
7917
|
+
if (!githubToken) {
|
|
7918
|
+
throw new Error("GitHub token not found. Run `kimiflare auth github` first.");
|
|
7919
|
+
}
|
|
7920
|
+
const res = await fetch(`${workerUrl}/remote/start`, {
|
|
7921
|
+
method: "POST",
|
|
7922
|
+
headers: {
|
|
7923
|
+
"Content-Type": "application/json",
|
|
7924
|
+
Authorization: `Bearer ${opts2.cfg.remoteAuthSecret ?? ""}`
|
|
7925
|
+
},
|
|
7926
|
+
body: JSON.stringify({
|
|
7927
|
+
prompt: opts2.prompt,
|
|
7928
|
+
repo: opts2.repo,
|
|
7929
|
+
githubToken,
|
|
7930
|
+
accountId: opts2.cfg.accountId,
|
|
7931
|
+
apiToken: opts2.cfg.apiToken,
|
|
7932
|
+
model: opts2.cfg.model,
|
|
7933
|
+
reasoningEffort: opts2.cfg.reasoningEffort,
|
|
7934
|
+
ttlMinutes: opts2.ttlMinutes ?? opts2.cfg.remoteTtlMinutes,
|
|
7935
|
+
tokensBudget: opts2.tokensBudget ?? opts2.cfg.remoteMaxInputTokens
|
|
7936
|
+
})
|
|
7937
|
+
});
|
|
7938
|
+
if (!res.ok) {
|
|
7939
|
+
const text = await res.text();
|
|
7940
|
+
throw new Error(`Failed to start remote session: ${res.status} ${text}`);
|
|
7941
|
+
}
|
|
7942
|
+
const data = await res.json();
|
|
7943
|
+
await saveRemoteSession({
|
|
7944
|
+
sessionId: data.sessionId,
|
|
7945
|
+
prompt: opts2.prompt,
|
|
7946
|
+
repo: `${opts2.repo.owner}/${opts2.repo.name}`,
|
|
7947
|
+
workerUrl,
|
|
7948
|
+
status: "running",
|
|
7949
|
+
branch: `kimiflare/remote/${data.sessionId}`,
|
|
7950
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7951
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7952
|
+
});
|
|
7953
|
+
return data;
|
|
7954
|
+
}
|
|
7955
|
+
async function* streamRemoteProgress(workerUrl, sessionId, signal) {
|
|
7956
|
+
const res = await fetch(`${workerUrl}/remote/stream/${sessionId}`, { signal });
|
|
7957
|
+
if (!res.ok) {
|
|
7958
|
+
throw new Error(`Failed to connect to stream: ${res.status}`);
|
|
7959
|
+
}
|
|
7960
|
+
if (!res.body) {
|
|
7961
|
+
throw new Error("No response body");
|
|
7962
|
+
}
|
|
7963
|
+
for await (const line of readSSE(res.body, signal)) {
|
|
7964
|
+
try {
|
|
7965
|
+
yield JSON.parse(line);
|
|
7966
|
+
} catch {
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
}
|
|
7970
|
+
async function getRemoteStatus(workerUrl, sessionId, authSecret) {
|
|
7971
|
+
const res = await fetch(`${workerUrl}/remote/status/${sessionId}`, {
|
|
7972
|
+
headers: authSecret ? { Authorization: `Bearer ${authSecret}` } : {}
|
|
7973
|
+
});
|
|
7974
|
+
if (!res.ok) {
|
|
7975
|
+
const text = await res.text();
|
|
7976
|
+
throw new Error(`Failed to get status: ${res.status} ${text}`);
|
|
7977
|
+
}
|
|
7978
|
+
return res.json();
|
|
7979
|
+
}
|
|
7980
|
+
async function cancelRemoteSession(workerUrl, sessionId, authSecret) {
|
|
7981
|
+
const res = await fetch(`${workerUrl}/remote/cancel/${sessionId}`, {
|
|
7982
|
+
method: "POST",
|
|
7983
|
+
headers: authSecret ? { Authorization: `Bearer ${authSecret}` } : {}
|
|
7984
|
+
});
|
|
7985
|
+
if (!res.ok) {
|
|
7986
|
+
const text = await res.text();
|
|
7987
|
+
throw new Error(`Failed to cancel session: ${res.status} ${text}`);
|
|
7988
|
+
}
|
|
7989
|
+
}
|
|
7990
|
+
var init_worker_client = __esm({
|
|
7991
|
+
"src/remote/worker-client.ts"() {
|
|
7992
|
+
"use strict";
|
|
7993
|
+
init_session_store();
|
|
7994
|
+
init_sse();
|
|
7995
|
+
}
|
|
7996
|
+
});
|
|
7997
|
+
|
|
7998
|
+
// src/remote/tui-deploy.ts
|
|
7999
|
+
var init_tui_deploy = __esm({
|
|
8000
|
+
"src/remote/tui-deploy.ts"() {
|
|
8001
|
+
"use strict";
|
|
8002
|
+
init_deploy();
|
|
8003
|
+
}
|
|
8004
|
+
});
|
|
8005
|
+
|
|
8006
|
+
// src/ui/remote-dashboard.tsx
|
|
8007
|
+
import { useEffect as useEffect4, useState as useState7 } from "react";
|
|
8008
|
+
import { Box as Box12, Text as Text13, useInput as useInput3 } from "ink";
|
|
8009
|
+
import SelectInput4 from "ink-select-input";
|
|
8010
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
8011
|
+
function RemoteDashboard({ onSelect, onCancel }) {
|
|
8012
|
+
const theme = useTheme();
|
|
8013
|
+
const [sessions, setSessions] = useState7([]);
|
|
8014
|
+
const [loading, setLoading] = useState7(true);
|
|
8015
|
+
const [error, setError] = useState7(null);
|
|
8016
|
+
const [refreshing, setRefreshing] = useState7(false);
|
|
8017
|
+
useEffect4(() => {
|
|
8018
|
+
loadSessions();
|
|
8019
|
+
}, []);
|
|
8020
|
+
async function loadSessions() {
|
|
8021
|
+
try {
|
|
8022
|
+
setRefreshing(true);
|
|
8023
|
+
const list = await listRemoteSessions();
|
|
8024
|
+
const updated = await Promise.all(
|
|
8025
|
+
list.map(async (s) => {
|
|
8026
|
+
if (s.status === "running" || s.status === "pending") {
|
|
8027
|
+
try {
|
|
8028
|
+
const status = await getRemoteStatus(s.workerUrl, s.sessionId);
|
|
8029
|
+
return {
|
|
8030
|
+
...s,
|
|
8031
|
+
status: status.status,
|
|
8032
|
+
prUrl: status.prUrl ?? s.prUrl,
|
|
8033
|
+
tokensUsed: status.tokensUsed ?? s.tokensUsed,
|
|
8034
|
+
tokensBudget: status.tokensBudget ?? s.tokensBudget,
|
|
8035
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8036
|
+
};
|
|
8037
|
+
} catch {
|
|
8038
|
+
return s;
|
|
8039
|
+
}
|
|
8040
|
+
}
|
|
8041
|
+
return s;
|
|
8042
|
+
})
|
|
8043
|
+
);
|
|
8044
|
+
setSessions(updated.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()));
|
|
8045
|
+
setError(null);
|
|
8046
|
+
} catch (err) {
|
|
8047
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
8048
|
+
} finally {
|
|
8049
|
+
setLoading(false);
|
|
8050
|
+
setRefreshing(false);
|
|
8051
|
+
}
|
|
8052
|
+
}
|
|
8053
|
+
useInput3((input, key) => {
|
|
8054
|
+
if (input === "r" || input === "R") {
|
|
8055
|
+
void loadSessions();
|
|
8056
|
+
}
|
|
8057
|
+
if (key.escape && onCancel) {
|
|
8058
|
+
onCancel();
|
|
8059
|
+
}
|
|
8060
|
+
});
|
|
8061
|
+
const items = sessions.map((s) => ({
|
|
8062
|
+
label: formatSessionLine(s),
|
|
8063
|
+
value: s.sessionId
|
|
8064
|
+
}));
|
|
8065
|
+
if (loading) {
|
|
8066
|
+
return /* @__PURE__ */ jsx14(Box12, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx14(Text13, { color: theme.accent, children: "Loading remote sessions..." }) });
|
|
8067
|
+
}
|
|
8068
|
+
if (error) {
|
|
8069
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
|
|
8070
|
+
/* @__PURE__ */ jsxs12(Text13, { color: theme.error, children: [
|
|
8071
|
+
"Error: ",
|
|
8072
|
+
error
|
|
8073
|
+
] }),
|
|
8074
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Press R to retry, Esc to close" })
|
|
8075
|
+
] });
|
|
8076
|
+
}
|
|
8077
|
+
if (sessions.length === 0) {
|
|
8078
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
|
|
8079
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, children: "No remote sessions yet." }),
|
|
8080
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Type /remote <prompt> to start one." }),
|
|
8081
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Press Esc to close" })
|
|
8082
|
+
] });
|
|
8083
|
+
}
|
|
8084
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
|
|
8085
|
+
/* @__PURE__ */ jsxs12(Text13, { bold: true, color: theme.accent, children: [
|
|
8086
|
+
"Recent remote tasks ",
|
|
8087
|
+
refreshing ? "(refreshing...)" : ""
|
|
8088
|
+
] }),
|
|
8089
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8090
|
+
SelectInput4,
|
|
8091
|
+
{
|
|
8092
|
+
items,
|
|
8093
|
+
onSelect: (item) => {
|
|
8094
|
+
const session = sessions.find((s) => s.sessionId === item.value);
|
|
8095
|
+
if (session) onSelect?.(session);
|
|
8096
|
+
}
|
|
8097
|
+
}
|
|
8098
|
+
) }),
|
|
8099
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
|
|
8100
|
+
] });
|
|
8101
|
+
}
|
|
8102
|
+
function formatSessionLine(s) {
|
|
8103
|
+
const icon = s.status === "done" ? "\u2705" : s.status === "error" ? "\u274C" : s.status === "cancelled" ? "\u23F9\uFE0F" : s.status === "running" ? "\u23F3" : "\u23F8";
|
|
8104
|
+
const ago = formatAgo(new Date(s.updatedAt));
|
|
8105
|
+
const prompt = s.prompt.slice(0, 30) + (s.prompt.length > 30 ? "\u2026" : "");
|
|
8106
|
+
const outcome = s.prUrl ? `PR ${s.prUrl.split("/").pop()}` : s.status;
|
|
8107
|
+
const cost = s.tokensUsed && s.tokensBudget ? ` (${formatTokens2(s.tokensUsed)}/${formatTokens2(s.tokensBudget)})` : s.tokensUsed ? ` (${formatTokens2(s.tokensUsed)})` : "";
|
|
8108
|
+
return `${icon} ${prompt} \u2192 ${outcome} ${ago}${cost}`;
|
|
8109
|
+
}
|
|
8110
|
+
function formatAgo(date) {
|
|
8111
|
+
const ms = Date.now() - date.getTime();
|
|
8112
|
+
const minutes = Math.floor(ms / 6e4);
|
|
8113
|
+
const hours = Math.floor(minutes / 60);
|
|
8114
|
+
const days = Math.floor(hours / 24);
|
|
8115
|
+
if (days > 0) return `${days}d ago`;
|
|
8116
|
+
if (hours > 0) return `${hours}h ago`;
|
|
8117
|
+
if (minutes > 0) return `${minutes}m ago`;
|
|
8118
|
+
return "just now";
|
|
8119
|
+
}
|
|
8120
|
+
function formatTokens2(n) {
|
|
8121
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
8122
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
8123
|
+
return String(n);
|
|
8124
|
+
}
|
|
8125
|
+
function RemoteSessionDetail({
|
|
8126
|
+
session,
|
|
8127
|
+
onBack,
|
|
8128
|
+
onCancel
|
|
8129
|
+
}) {
|
|
8130
|
+
const theme = useTheme();
|
|
8131
|
+
const [cancelling, setCancelling] = useState7(false);
|
|
8132
|
+
useInput3((input, key) => {
|
|
8133
|
+
if (key.escape) {
|
|
8134
|
+
onBack();
|
|
8135
|
+
}
|
|
8136
|
+
if ((input === "c" || input === "C") && onCancel && (session.status === "running" || session.status === "pending")) {
|
|
8137
|
+
void handleCancel();
|
|
8138
|
+
}
|
|
8139
|
+
});
|
|
8140
|
+
async function handleCancel() {
|
|
8141
|
+
if (!onCancel) return;
|
|
8142
|
+
setCancelling(true);
|
|
8143
|
+
try {
|
|
8144
|
+
await cancelRemoteSession(session.workerUrl, session.sessionId);
|
|
8145
|
+
onCancel(session);
|
|
8146
|
+
} catch {
|
|
8147
|
+
} finally {
|
|
8148
|
+
setCancelling(false);
|
|
8149
|
+
}
|
|
8150
|
+
}
|
|
8151
|
+
const isRunning = session.status === "running" || session.status === "pending";
|
|
8152
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
|
|
8153
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, color: theme.accent, children: "Remote Session" }),
|
|
8154
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
|
|
8155
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8156
|
+
"ID: ",
|
|
8157
|
+
session.sessionId
|
|
8158
|
+
] }),
|
|
8159
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8160
|
+
"Repo: ",
|
|
8161
|
+
session.repo
|
|
8162
|
+
] }),
|
|
8163
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8164
|
+
"Status: ",
|
|
8165
|
+
session.status
|
|
8166
|
+
] }),
|
|
8167
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8168
|
+
"Prompt: ",
|
|
8169
|
+
session.prompt
|
|
8170
|
+
] }),
|
|
8171
|
+
session.prUrl && /* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8172
|
+
"PR: ",
|
|
8173
|
+
session.prUrl
|
|
8174
|
+
] }),
|
|
8175
|
+
session.errorMessage && /* @__PURE__ */ jsxs12(Text13, { color: theme.error, children: [
|
|
8176
|
+
"Error: ",
|
|
8177
|
+
session.errorMessage
|
|
8178
|
+
] }),
|
|
8179
|
+
session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8180
|
+
"Tokens: ",
|
|
8181
|
+
formatTokens2(session.tokensUsed),
|
|
8182
|
+
session.tokensBudget ? ` / ${formatTokens2(session.tokensBudget)}` : ""
|
|
8183
|
+
] }),
|
|
8184
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8185
|
+
"Created: ",
|
|
8186
|
+
new Date(session.createdAt).toLocaleString()
|
|
8187
|
+
] }),
|
|
8188
|
+
session.finishedAt && /* @__PURE__ */ jsxs12(Text13, { children: [
|
|
8189
|
+
"Finished: ",
|
|
8190
|
+
new Date(session.finishedAt).toLocaleString()
|
|
8191
|
+
] })
|
|
8192
|
+
] }),
|
|
8193
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", gap: 2, children: [
|
|
8194
|
+
isRunning && onCancel && /* @__PURE__ */ jsx14(Text13, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
|
|
8195
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Esc back" })
|
|
8196
|
+
] })
|
|
8197
|
+
] });
|
|
8198
|
+
}
|
|
8199
|
+
var init_remote_dashboard = __esm({
|
|
8200
|
+
"src/ui/remote-dashboard.tsx"() {
|
|
8201
|
+
"use strict";
|
|
8202
|
+
init_theme_context();
|
|
8203
|
+
init_session_store();
|
|
8204
|
+
init_worker_client();
|
|
8205
|
+
}
|
|
8206
|
+
});
|
|
8207
|
+
|
|
8208
|
+
// src/intent/classify.ts
|
|
8209
|
+
function classifyIntent(prompt) {
|
|
8210
|
+
let intentScore = 0;
|
|
8211
|
+
let matchedIntent = "other";
|
|
8212
|
+
for (const [intent, pattern] of Object.entries(INTENT_PATTERNS)) {
|
|
8213
|
+
const matches = (prompt.match(pattern) || []).length;
|
|
8214
|
+
if (matches > intentScore) {
|
|
8215
|
+
intentScore = matches;
|
|
8216
|
+
matchedIntent = intent;
|
|
8217
|
+
}
|
|
8218
|
+
}
|
|
8219
|
+
const hasFileMentions = (prompt.match(/@\w+|\b[\w/-]+\.(ts|tsx|js|jsx|py|go|rs)\b/g) || []).length;
|
|
8220
|
+
const hasMutatingVerb = /\b(add|create|write|edit|delete|remove|rename|migrate|implement)\b/i.test(prompt);
|
|
8221
|
+
const isQuestion = prompt.trim().endsWith("?") || /\b(what|how|why|is|does|can)\b/i.test(prompt.split(" ")[0] || "");
|
|
8222
|
+
const rawScore = Math.min(
|
|
8223
|
+
1,
|
|
8224
|
+
intentScore * 0.25 + (hasFileMentions > 2 ? 0.3 : hasFileMentions * 0.1) + (hasMutatingVerb ? 0.25 : 0) + (isQuestion ? 0 : 0.1)
|
|
8225
|
+
);
|
|
8226
|
+
const tier = rawScore < 0.3 ? "light" : rawScore < 0.65 ? "medium" : "heavy";
|
|
8227
|
+
return {
|
|
8228
|
+
intent: matchedIntent,
|
|
8229
|
+
rawScore,
|
|
8230
|
+
tier,
|
|
8231
|
+
confidence: 0.5 + (intentScore > 0 ? 0.3 : 0) + (hasFileMentions > 0 ? 0.1 : 0)
|
|
8232
|
+
};
|
|
8233
|
+
}
|
|
8234
|
+
var INTENT_PATTERNS;
|
|
8235
|
+
var init_classify = __esm({
|
|
8236
|
+
"src/intent/classify.ts"() {
|
|
8237
|
+
"use strict";
|
|
8238
|
+
INTENT_PATTERNS = {
|
|
8239
|
+
qa: /\b(what|how|why|explain|describe|what's|what is)\b/i,
|
|
8240
|
+
diagnose: /\b(broken|failing|error|bug|crash|why.*fail|not working)\b/i,
|
|
8241
|
+
verify: /\b(correct|right|verify|review|check|is this|does this)\b/i,
|
|
8242
|
+
polish: /\b(rename|refactor|extract|move|clean|lint|format)\b/i,
|
|
8243
|
+
small_edit: /\b(add|change|update|fix|remove|delete)\b.+\b(line|here|this|variable|function)\b/i,
|
|
8244
|
+
feature_bounded: /\b(add|implement|create|support)\b.+\b(flag|option|param|arg|field)\b/i,
|
|
8245
|
+
feature_exploratory: /\b(add|implement|migrate|integrate|build)\b.+\b(module|system|auth|oauth|framework|service)\b/i,
|
|
8246
|
+
explore: /\b(how.*work|architecture|structure|where.*used|find.*all|understand)\b/i,
|
|
8247
|
+
meta: /\b(plan|design|strategy|ontology|roadmap|approach)\b/i
|
|
8248
|
+
};
|
|
8249
|
+
}
|
|
8250
|
+
});
|
|
8251
|
+
|
|
7572
8252
|
// src/sessions.ts
|
|
7573
8253
|
var sessions_exports = {};
|
|
7574
8254
|
__export(sessions_exports, {
|
|
@@ -7578,12 +8258,12 @@ __export(sessions_exports, {
|
|
|
7578
8258
|
pruneSessions: () => pruneSessions,
|
|
7579
8259
|
saveSession: () => saveSession
|
|
7580
8260
|
});
|
|
7581
|
-
import { readFile as
|
|
7582
|
-
import { homedir as
|
|
7583
|
-
import { join as
|
|
8261
|
+
import { readFile as readFile11, writeFile as writeFile7, mkdir as mkdir7, readdir as readdir3, stat as stat4 } from "fs/promises";
|
|
8262
|
+
import { homedir as homedir9 } from "os";
|
|
8263
|
+
import { join as join13 } from "path";
|
|
7584
8264
|
function sessionsDir2() {
|
|
7585
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
7586
|
-
return
|
|
8265
|
+
const xdg = process.env.XDG_DATA_HOME || join13(homedir9(), ".local", "share");
|
|
8266
|
+
return join13(xdg, "kimiflare", "sessions");
|
|
7587
8267
|
}
|
|
7588
8268
|
function sanitize(text) {
|
|
7589
8269
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
@@ -7595,9 +8275,9 @@ function makeSessionId(firstPrompt) {
|
|
|
7595
8275
|
}
|
|
7596
8276
|
async function saveSession(file) {
|
|
7597
8277
|
const dir = sessionsDir2();
|
|
7598
|
-
await
|
|
7599
|
-
const path =
|
|
7600
|
-
await
|
|
8278
|
+
await mkdir7(dir, { recursive: true });
|
|
8279
|
+
const path = join13(dir, `${file.id}.json`);
|
|
8280
|
+
await writeFile7(path, JSON.stringify(file, null, 2), "utf8");
|
|
7601
8281
|
return path;
|
|
7602
8282
|
}
|
|
7603
8283
|
async function pruneSessions() {
|
|
@@ -7605,21 +8285,22 @@ async function pruneSessions() {
|
|
|
7605
8285
|
const files = await listFilesByMtime(dir, /\.json$/);
|
|
7606
8286
|
return pruneFiles(files, RETENTION.sessionMaxAgeDays, RETENTION.sessionMaxCount);
|
|
7607
8287
|
}
|
|
7608
|
-
async function listSessions(limit = 30) {
|
|
8288
|
+
async function listSessions(limit = 30, cwd) {
|
|
7609
8289
|
const dir = sessionsDir2();
|
|
7610
8290
|
let entries;
|
|
7611
8291
|
try {
|
|
7612
|
-
entries = await
|
|
8292
|
+
entries = await readdir3(dir);
|
|
7613
8293
|
} catch {
|
|
7614
8294
|
return [];
|
|
7615
8295
|
}
|
|
7616
8296
|
const summaries = [];
|
|
7617
8297
|
for (const name of entries) {
|
|
7618
8298
|
if (!name.endsWith(".json")) continue;
|
|
7619
|
-
const path =
|
|
8299
|
+
const path = join13(dir, name);
|
|
7620
8300
|
try {
|
|
7621
|
-
const [s, raw] = await Promise.all([
|
|
8301
|
+
const [s, raw] = await Promise.all([stat4(path), readFile11(path, "utf8")]);
|
|
7622
8302
|
const parsed = JSON.parse(raw);
|
|
8303
|
+
if (cwd && parsed.cwd !== cwd) continue;
|
|
7623
8304
|
const firstUser = parsed.messages.find((m) => m.role === "user");
|
|
7624
8305
|
const firstPrompt = typeof firstUser?.content === "string" ? firstUser.content : firstUser?.content ? firstUser.content.find((p) => p.type === "text")?.text ?? "(no prompt)" : "(no prompt)";
|
|
7625
8306
|
summaries.push({
|
|
@@ -7637,7 +8318,7 @@ async function listSessions(limit = 30) {
|
|
|
7637
8318
|
return summaries.slice(0, limit);
|
|
7638
8319
|
}
|
|
7639
8320
|
async function loadSession(filePath) {
|
|
7640
|
-
const raw = await
|
|
8321
|
+
const raw = await readFile11(filePath, "utf8");
|
|
7641
8322
|
return JSON.parse(raw);
|
|
7642
8323
|
}
|
|
7643
8324
|
var init_sessions = __esm({
|
|
@@ -7648,10 +8329,10 @@ var init_sessions = __esm({
|
|
|
7648
8329
|
});
|
|
7649
8330
|
|
|
7650
8331
|
// src/util/image.ts
|
|
7651
|
-
import { readFile as
|
|
8332
|
+
import { readFile as readFile12 } from "fs/promises";
|
|
7652
8333
|
import { basename as basename3 } from "path";
|
|
7653
8334
|
async function encodeImageFile(filePath) {
|
|
7654
|
-
const buf = await
|
|
8335
|
+
const buf = await readFile12(filePath);
|
|
7655
8336
|
if (buf.byteLength > MAX_IMAGE_BYTES) {
|
|
7656
8337
|
throw new Error(
|
|
7657
8338
|
`image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
|
|
@@ -7687,15 +8368,15 @@ var init_image = __esm({
|
|
|
7687
8368
|
});
|
|
7688
8369
|
|
|
7689
8370
|
// src/usage-tracker.ts
|
|
7690
|
-
import { readFile as
|
|
7691
|
-
import { homedir as
|
|
7692
|
-
import { join as
|
|
8371
|
+
import { readFile as readFile13, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
|
|
8372
|
+
import { homedir as homedir10 } from "os";
|
|
8373
|
+
import { join as join14 } from "path";
|
|
7693
8374
|
function usageDir2() {
|
|
7694
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
7695
|
-
return
|
|
8375
|
+
const xdg = process.env.XDG_DATA_HOME || join14(homedir10(), ".local", "share");
|
|
8376
|
+
return join14(xdg, "kimiflare");
|
|
7696
8377
|
}
|
|
7697
8378
|
function usagePath2() {
|
|
7698
|
-
return
|
|
8379
|
+
return join14(usageDir2(), "usage.json");
|
|
7699
8380
|
}
|
|
7700
8381
|
function today2() {
|
|
7701
8382
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -7706,7 +8387,7 @@ function cutoffDate(daysBack) {
|
|
|
7706
8387
|
}
|
|
7707
8388
|
async function loadLog2() {
|
|
7708
8389
|
try {
|
|
7709
|
-
const raw = await
|
|
8390
|
+
const raw = await readFile13(usagePath2(), "utf8");
|
|
7710
8391
|
const parsed = JSON.parse(raw);
|
|
7711
8392
|
if (parsed.version === LOG_VERSION2) return parsed;
|
|
7712
8393
|
} catch {
|
|
@@ -7714,8 +8395,8 @@ async function loadLog2() {
|
|
|
7714
8395
|
return { version: LOG_VERSION2, days: [], sessions: [] };
|
|
7715
8396
|
}
|
|
7716
8397
|
async function saveLog(log) {
|
|
7717
|
-
await
|
|
7718
|
-
await
|
|
8398
|
+
await mkdir8(usageDir2(), { recursive: true });
|
|
8399
|
+
await writeFile8(usagePath2(), JSON.stringify(log, null, 2), "utf8");
|
|
7719
8400
|
}
|
|
7720
8401
|
function getOrCreateDay(log, date) {
|
|
7721
8402
|
let day = log.days.find((d) => d.date === date);
|
|
@@ -7921,7 +8602,7 @@ __export(db_exports, {
|
|
|
7921
8602
|
updateMemoryEmbedding: () => updateMemoryEmbedding
|
|
7922
8603
|
});
|
|
7923
8604
|
import Database from "better-sqlite3";
|
|
7924
|
-
import { dirname as
|
|
8605
|
+
import { dirname as dirname6 } from "path";
|
|
7925
8606
|
import { mkdirSync, statSync as statSync2 } from "fs";
|
|
7926
8607
|
function initSchema(db) {
|
|
7927
8608
|
db.exec(`
|
|
@@ -8006,7 +8687,7 @@ function openMemoryDb(dbPath) {
|
|
|
8006
8687
|
if (dbInstance) {
|
|
8007
8688
|
dbInstance.close();
|
|
8008
8689
|
}
|
|
8009
|
-
mkdirSync(
|
|
8690
|
+
mkdirSync(dirname6(dbPath), { recursive: true });
|
|
8010
8691
|
dbInstance = new Database(dbPath);
|
|
8011
8692
|
dbInstance.pragma("journal_mode = WAL");
|
|
8012
8693
|
dbInstance.pragma("foreign_keys = ON");
|
|
@@ -8300,7 +8981,7 @@ function truncateForEmbedding(text) {
|
|
|
8300
8981
|
if (text.length <= MAX_EMBED_CHARS) return text;
|
|
8301
8982
|
return text.slice(0, MAX_EMBED_CHARS);
|
|
8302
8983
|
}
|
|
8303
|
-
async function
|
|
8984
|
+
async function sleep3(ms) {
|
|
8304
8985
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
8305
8986
|
}
|
|
8306
8987
|
async function fetchWithRetry(url, init, retries = 3) {
|
|
@@ -8311,7 +8992,7 @@ async function fetchWithRetry(url, init, retries = 3) {
|
|
|
8311
8992
|
if (res.ok) return res;
|
|
8312
8993
|
if (res.status === 429 || res.status >= 500) {
|
|
8313
8994
|
const delay = 1e3 * 2 ** i;
|
|
8314
|
-
await
|
|
8995
|
+
await sleep3(delay);
|
|
8315
8996
|
continue;
|
|
8316
8997
|
}
|
|
8317
8998
|
const errText = await res.text().catch(() => "unknown error");
|
|
@@ -8319,7 +9000,7 @@ async function fetchWithRetry(url, init, retries = 3) {
|
|
|
8319
9000
|
} catch (e) {
|
|
8320
9001
|
lastError = e;
|
|
8321
9002
|
if (i < retries - 1) {
|
|
8322
|
-
await
|
|
9003
|
+
await sleep3(1e3 * 2 ** i);
|
|
8323
9004
|
}
|
|
8324
9005
|
}
|
|
8325
9006
|
}
|
|
@@ -8933,16 +9614,16 @@ Context: This memory was explicitly provided by the user during a conversation.`
|
|
|
8933
9614
|
});
|
|
8934
9615
|
|
|
8935
9616
|
// src/util/state.ts
|
|
8936
|
-
import { readFile as
|
|
8937
|
-
import { homedir as
|
|
8938
|
-
import { join as
|
|
9617
|
+
import { readFile as readFile14, writeFile as writeFile9, mkdir as mkdir9 } from "fs/promises";
|
|
9618
|
+
import { homedir as homedir11 } from "os";
|
|
9619
|
+
import { join as join16 } from "path";
|
|
8939
9620
|
function statePath() {
|
|
8940
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
8941
|
-
return
|
|
9621
|
+
const xdg = process.env.XDG_CONFIG_HOME || join16(homedir11(), ".config");
|
|
9622
|
+
return join16(xdg, "kimiflare", "state.json");
|
|
8942
9623
|
}
|
|
8943
9624
|
async function readState() {
|
|
8944
9625
|
try {
|
|
8945
|
-
const raw = await
|
|
9626
|
+
const raw = await readFile14(statePath(), "utf8");
|
|
8946
9627
|
return JSON.parse(raw);
|
|
8947
9628
|
} catch {
|
|
8948
9629
|
return {};
|
|
@@ -8950,8 +9631,8 @@ async function readState() {
|
|
|
8950
9631
|
}
|
|
8951
9632
|
async function writeState(state) {
|
|
8952
9633
|
const path = statePath();
|
|
8953
|
-
await
|
|
8954
|
-
await
|
|
9634
|
+
await mkdir9(join16(path, ".."), { recursive: true });
|
|
9635
|
+
await writeFile9(path, JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
8955
9636
|
}
|
|
8956
9637
|
async function markCreatorMessageSeen(version) {
|
|
8957
9638
|
const state = await readState();
|
|
@@ -9024,15 +9705,15 @@ var init_frontmatter = __esm({
|
|
|
9024
9705
|
|
|
9025
9706
|
// src/commands/loader.ts
|
|
9026
9707
|
import { open, realpath } from "fs/promises";
|
|
9027
|
-
import { homedir as
|
|
9028
|
-
import { join as
|
|
9708
|
+
import { homedir as homedir12 } from "os";
|
|
9709
|
+
import { join as join17, relative as relative4, sep as sep2 } from "path";
|
|
9029
9710
|
import fg3 from "fast-glob";
|
|
9030
9711
|
function projectCommandsDir(cwd = process.cwd()) {
|
|
9031
|
-
return
|
|
9712
|
+
return join17(cwd, ".kimiflare", "commands");
|
|
9032
9713
|
}
|
|
9033
9714
|
function globalCommandsDir() {
|
|
9034
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
9035
|
-
return
|
|
9715
|
+
const xdg = process.env.XDG_CONFIG_HOME || join17(homedir12(), ".config");
|
|
9716
|
+
return join17(xdg, "kimiflare", "commands");
|
|
9036
9717
|
}
|
|
9037
9718
|
async function loadCustomCommands(cwd = process.cwd()) {
|
|
9038
9719
|
const warnings = [];
|
|
@@ -9394,6 +10075,7 @@ var init_builtins = __esm({
|
|
|
9394
10075
|
{ name: "compact", description: "Summarize old turns to free context", source: "builtin" },
|
|
9395
10076
|
{ name: "clear", description: "Clear current conversation", source: "builtin" },
|
|
9396
10077
|
{ name: "init", description: "Scan repo and write KIMI.md", source: "builtin" },
|
|
10078
|
+
{ name: "remote", argHint: "<prompt>", description: "Run a remote session on Cloudflare", source: "builtin" },
|
|
9397
10079
|
{ name: "update", description: "Check for updates", source: "builtin" },
|
|
9398
10080
|
{ name: "hello", description: "Send a voice note to the creator", source: "builtin" },
|
|
9399
10081
|
{ name: "logout", description: "Clear stored credentials", source: "builtin" },
|
|
@@ -9407,8 +10089,8 @@ var init_builtins = __esm({
|
|
|
9407
10089
|
});
|
|
9408
10090
|
|
|
9409
10091
|
// src/commands/save.ts
|
|
9410
|
-
import { mkdir as
|
|
9411
|
-
import { dirname as
|
|
10092
|
+
import { mkdir as mkdir10, writeFile as writeFile10, unlink as unlink2 } from "fs/promises";
|
|
10093
|
+
import { dirname as dirname7 } from "path";
|
|
9412
10094
|
async function saveCustomCommand(opts2) {
|
|
9413
10095
|
const dir = opts2.source === "project" ? projectCommandsDir(opts2.cwd) : globalCommandsDir();
|
|
9414
10096
|
const filepath = `${dir}/${opts2.name}.md`;
|
|
@@ -9419,8 +10101,8 @@ async function saveCustomCommand(opts2) {
|
|
|
9419
10101
|
if (opts2.effort) data.effort = opts2.effort;
|
|
9420
10102
|
const frontmatter = serializeFrontmatter(data);
|
|
9421
10103
|
const content = frontmatter + opts2.template;
|
|
9422
|
-
await
|
|
9423
|
-
await
|
|
10104
|
+
await mkdir10(dirname7(filepath), { recursive: true });
|
|
10105
|
+
await writeFile10(filepath, content, "utf8");
|
|
9424
10106
|
return { filepath };
|
|
9425
10107
|
}
|
|
9426
10108
|
async function deleteCustomCommand(cmd) {
|
|
@@ -9435,21 +10117,21 @@ var init_save = __esm({
|
|
|
9435
10117
|
});
|
|
9436
10118
|
|
|
9437
10119
|
// src/ui/command-wizard.tsx
|
|
9438
|
-
import { useState as
|
|
9439
|
-
import { Box as
|
|
9440
|
-
import
|
|
9441
|
-
import { Fragment as Fragment2, jsx as
|
|
10120
|
+
import { useState as useState8 } from "react";
|
|
10121
|
+
import { Box as Box13, Text as Text14, useInput as useInput4, useWindowSize as useWindowSize2 } from "ink";
|
|
10122
|
+
import SelectInput5 from "ink-select-input";
|
|
10123
|
+
import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
9442
10124
|
function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
|
|
9443
10125
|
const theme = useTheme();
|
|
9444
|
-
const [step, setStep] =
|
|
9445
|
-
const [name, setName] =
|
|
9446
|
-
const [description, setDescription] =
|
|
9447
|
-
const [template, setTemplate] =
|
|
9448
|
-
const [cmdMode, setCmdMode] =
|
|
9449
|
-
const [cmdEffort, setCmdEffort] =
|
|
9450
|
-
const [cmdModel, setCmdModel] =
|
|
9451
|
-
const [source, setSource] =
|
|
9452
|
-
const [error, setError] =
|
|
10126
|
+
const [step, setStep] = useState8("name");
|
|
10127
|
+
const [name, setName] = useState8(initial?.name ?? "");
|
|
10128
|
+
const [description, setDescription] = useState8(initial?.description ?? "");
|
|
10129
|
+
const [template, setTemplate] = useState8(initial?.template ?? "");
|
|
10130
|
+
const [cmdMode, setCmdMode] = useState8(initial?.mode);
|
|
10131
|
+
const [cmdEffort, setCmdEffort] = useState8(initial?.effort);
|
|
10132
|
+
const [cmdModel, setCmdModel] = useState8(initial?.model);
|
|
10133
|
+
const [source, setSource] = useState8(initial?.source ?? "project");
|
|
10134
|
+
const [error, setError] = useState8(null);
|
|
9453
10135
|
const { columns } = useWindowSize2();
|
|
9454
10136
|
const totalSteps = 5;
|
|
9455
10137
|
const stepIndex = step === "name" ? 1 : step === "description" ? 2 : step === "template" ? 3 : step === "advanced" || step === "mode" || step === "effort" || step === "model" ? 4 : step === "location" ? 4 : 5;
|
|
@@ -9462,7 +10144,7 @@ function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onS
|
|
|
9462
10144
|
if (existingNames.includes(trimmed) && !isEditingSelf(trimmed)) return `/${trimmed} already exists`;
|
|
9463
10145
|
return null;
|
|
9464
10146
|
};
|
|
9465
|
-
|
|
10147
|
+
useInput4((_input, key) => {
|
|
9466
10148
|
if (key.escape) {
|
|
9467
10149
|
onDone();
|
|
9468
10150
|
}
|
|
@@ -9562,8 +10244,8 @@ ${template}`;
|
|
|
9562
10244
|
const renderStep = () => {
|
|
9563
10245
|
switch (step) {
|
|
9564
10246
|
case "name":
|
|
9565
|
-
return /* @__PURE__ */
|
|
9566
|
-
/* @__PURE__ */
|
|
10247
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10248
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9567
10249
|
mode === "create" ? "Create" : "Edit",
|
|
9568
10250
|
" custom command \u2014 Name (",
|
|
9569
10251
|
stepIndex,
|
|
@@ -9571,8 +10253,8 @@ ${template}`;
|
|
|
9571
10253
|
totalSteps,
|
|
9572
10254
|
")"
|
|
9573
10255
|
] }),
|
|
9574
|
-
error && /* @__PURE__ */
|
|
9575
|
-
/* @__PURE__ */
|
|
10256
|
+
error && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: error }),
|
|
10257
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
9576
10258
|
CustomTextInput,
|
|
9577
10259
|
{
|
|
9578
10260
|
value: name,
|
|
@@ -9581,11 +10263,11 @@ ${template}`;
|
|
|
9581
10263
|
focus: true
|
|
9582
10264
|
}
|
|
9583
10265
|
) }),
|
|
9584
|
-
/* @__PURE__ */
|
|
10266
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
|
|
9585
10267
|
] });
|
|
9586
10268
|
case "description":
|
|
9587
|
-
return /* @__PURE__ */
|
|
9588
|
-
/* @__PURE__ */
|
|
10269
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10270
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9589
10271
|
mode === "create" ? "Create" : "Edit",
|
|
9590
10272
|
" custom command \u2014 Description (",
|
|
9591
10273
|
stepIndex,
|
|
@@ -9593,7 +10275,7 @@ ${template}`;
|
|
|
9593
10275
|
totalSteps,
|
|
9594
10276
|
")"
|
|
9595
10277
|
] }),
|
|
9596
|
-
/* @__PURE__ */
|
|
10278
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
9597
10279
|
CustomTextInput,
|
|
9598
10280
|
{
|
|
9599
10281
|
value: description,
|
|
@@ -9602,49 +10284,49 @@ ${template}`;
|
|
|
9602
10284
|
focus: true
|
|
9603
10285
|
}
|
|
9604
10286
|
) }),
|
|
9605
|
-
/* @__PURE__ */
|
|
10287
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Press Enter to skip" })
|
|
9606
10288
|
] });
|
|
9607
10289
|
case "template": {
|
|
9608
|
-
const guide = /* @__PURE__ */
|
|
9609
|
-
/* @__PURE__ */
|
|
9610
|
-
/* @__PURE__ */
|
|
9611
|
-
/* @__PURE__ */
|
|
10290
|
+
const guide = /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingLeft: 1, children: [
|
|
10291
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "What is this?" }),
|
|
10292
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
|
|
10293
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
|
|
9612
10294
|
"When you type /",
|
|
9613
10295
|
name || "yourcommand",
|
|
9614
10296
|
" later, this gets sent to the model."
|
|
9615
10297
|
] }),
|
|
9616
|
-
/* @__PURE__ */
|
|
9617
|
-
/* @__PURE__ */
|
|
9618
|
-
/* @__PURE__ */
|
|
10298
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
10299
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "Variables" }),
|
|
10300
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
|
|
9619
10301
|
" ",
|
|
9620
10302
|
"$1, $2 ... \u2192 arguments you type"
|
|
9621
10303
|
] }),
|
|
9622
|
-
/* @__PURE__ */
|
|
10304
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
|
|
9623
10305
|
" ",
|
|
9624
10306
|
"$ARGUMENTS \u2192 everything after the command"
|
|
9625
10307
|
] })
|
|
9626
10308
|
] }),
|
|
9627
|
-
/* @__PURE__ */
|
|
9628
|
-
/* @__PURE__ */
|
|
9629
|
-
/* @__PURE__ */
|
|
10309
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
10310
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
|
|
10311
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
|
|
9630
10312
|
" ",
|
|
9631
10313
|
"!`git diff` \u2192 shell output inlined"
|
|
9632
10314
|
] }),
|
|
9633
|
-
/* @__PURE__ */
|
|
10315
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
|
|
9634
10316
|
" ",
|
|
9635
10317
|
"@README.md \u2192 file contents inlined"
|
|
9636
10318
|
] })
|
|
9637
10319
|
] }),
|
|
9638
|
-
/* @__PURE__ */
|
|
9639
|
-
/* @__PURE__ */
|
|
9640
|
-
/* @__PURE__ */
|
|
9641
|
-
/* @__PURE__ */
|
|
9642
|
-
/* @__PURE__ */
|
|
10320
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
10321
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "Example" }),
|
|
10322
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Review this PR diff:" }),
|
|
10323
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
|
|
10324
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Focus on: $1" })
|
|
9643
10325
|
] })
|
|
9644
10326
|
] });
|
|
9645
|
-
const inputArea = /* @__PURE__ */
|
|
9646
|
-
error && /* @__PURE__ */
|
|
9647
|
-
/* @__PURE__ */
|
|
10327
|
+
const inputArea = /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", flexGrow: 1, children: [
|
|
10328
|
+
error && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: error }),
|
|
10329
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
9648
10330
|
CustomTextInput,
|
|
9649
10331
|
{
|
|
9650
10332
|
value: template,
|
|
@@ -9654,13 +10336,13 @@ ${template}`;
|
|
|
9654
10336
|
enablePaste: true
|
|
9655
10337
|
}
|
|
9656
10338
|
) }),
|
|
9657
|
-
columns < 100 && /* @__PURE__ */
|
|
9658
|
-
/* @__PURE__ */
|
|
9659
|
-
/* @__PURE__ */
|
|
10339
|
+
columns < 100 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10340
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
|
|
10341
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
|
|
9660
10342
|
] })
|
|
9661
10343
|
] });
|
|
9662
|
-
return /* @__PURE__ */
|
|
9663
|
-
/* @__PURE__ */
|
|
10344
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10345
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9664
10346
|
mode === "create" ? "Create" : "Edit",
|
|
9665
10347
|
" custom command \u2014 Template (",
|
|
9666
10348
|
stepIndex,
|
|
@@ -9668,10 +10350,10 @@ ${template}`;
|
|
|
9668
10350
|
totalSteps,
|
|
9669
10351
|
")"
|
|
9670
10352
|
] }),
|
|
9671
|
-
columns >= 100 ? /* @__PURE__ */
|
|
9672
|
-
/* @__PURE__ */
|
|
9673
|
-
/* @__PURE__ */
|
|
9674
|
-
] }) : /* @__PURE__ */
|
|
10353
|
+
columns >= 100 ? /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", marginTop: 1, children: [
|
|
10354
|
+
/* @__PURE__ */ jsx15(Box13, { flexDirection: "column", width: "50%", children: inputArea }),
|
|
10355
|
+
/* @__PURE__ */ jsx15(Box13, { flexDirection: "column", width: "50%", children: guide })
|
|
10356
|
+
] }) : /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", marginTop: 1, children: inputArea })
|
|
9675
10357
|
] });
|
|
9676
10358
|
}
|
|
9677
10359
|
case "advanced": {
|
|
@@ -9680,8 +10362,8 @@ ${template}`;
|
|
|
9680
10362
|
{ label: "Skip", value: "skip", key: "skip" },
|
|
9681
10363
|
{ label: "\u2190 Cancel", value: "cancel", key: "cancel" }
|
|
9682
10364
|
];
|
|
9683
|
-
return /* @__PURE__ */
|
|
9684
|
-
/* @__PURE__ */
|
|
10365
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10366
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9685
10367
|
mode === "create" ? "Create" : "Edit",
|
|
9686
10368
|
" custom command \u2014 Options (",
|
|
9687
10369
|
stepIndex,
|
|
@@ -9689,8 +10371,8 @@ ${template}`;
|
|
|
9689
10371
|
totalSteps,
|
|
9690
10372
|
")"
|
|
9691
10373
|
] }),
|
|
9692
|
-
/* @__PURE__ */
|
|
9693
|
-
|
|
10374
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10375
|
+
SelectInput5,
|
|
9694
10376
|
{
|
|
9695
10377
|
items,
|
|
9696
10378
|
onSelect: (item) => {
|
|
@@ -9709,17 +10391,17 @@ ${template}`;
|
|
|
9709
10391
|
{ label: cmdMode === "auto" ? "auto \xB7 current" : "auto", value: "auto", key: "auto" },
|
|
9710
10392
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
9711
10393
|
];
|
|
9712
|
-
return /* @__PURE__ */
|
|
9713
|
-
/* @__PURE__ */
|
|
10394
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10395
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9714
10396
|
"Mode override (",
|
|
9715
10397
|
stepIndex,
|
|
9716
10398
|
"/",
|
|
9717
10399
|
totalSteps,
|
|
9718
10400
|
")"
|
|
9719
10401
|
] }),
|
|
9720
|
-
/* @__PURE__ */
|
|
9721
|
-
/* @__PURE__ */
|
|
9722
|
-
|
|
10402
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
|
|
10403
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10404
|
+
SelectInput5,
|
|
9723
10405
|
{
|
|
9724
10406
|
items,
|
|
9725
10407
|
onSelect: (item) => {
|
|
@@ -9738,16 +10420,16 @@ ${template}`;
|
|
|
9738
10420
|
{ label: cmdEffort === "high" ? "high \xB7 current" : "high", value: "high", key: "high" },
|
|
9739
10421
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
9740
10422
|
];
|
|
9741
|
-
return /* @__PURE__ */
|
|
9742
|
-
/* @__PURE__ */
|
|
10423
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10424
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9743
10425
|
"Reasoning effort (",
|
|
9744
10426
|
stepIndex,
|
|
9745
10427
|
"/",
|
|
9746
10428
|
totalSteps,
|
|
9747
10429
|
")"
|
|
9748
10430
|
] }),
|
|
9749
|
-
/* @__PURE__ */
|
|
9750
|
-
|
|
10431
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10432
|
+
SelectInput5,
|
|
9751
10433
|
{
|
|
9752
10434
|
items,
|
|
9753
10435
|
onSelect: (item) => {
|
|
@@ -9759,15 +10441,15 @@ ${template}`;
|
|
|
9759
10441
|
] });
|
|
9760
10442
|
}
|
|
9761
10443
|
case "model":
|
|
9762
|
-
return /* @__PURE__ */
|
|
9763
|
-
/* @__PURE__ */
|
|
10444
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10445
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9764
10446
|
"Model override (",
|
|
9765
10447
|
stepIndex,
|
|
9766
10448
|
"/",
|
|
9767
10449
|
totalSteps,
|
|
9768
10450
|
")"
|
|
9769
10451
|
] }),
|
|
9770
|
-
/* @__PURE__ */
|
|
10452
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
9771
10453
|
CustomTextInput,
|
|
9772
10454
|
{
|
|
9773
10455
|
value: cmdModel ?? "",
|
|
@@ -9776,7 +10458,7 @@ ${template}`;
|
|
|
9776
10458
|
focus: true
|
|
9777
10459
|
}
|
|
9778
10460
|
) }),
|
|
9779
|
-
/* @__PURE__ */
|
|
10461
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Press Enter to skip" })
|
|
9780
10462
|
] });
|
|
9781
10463
|
case "location": {
|
|
9782
10464
|
const items = [
|
|
@@ -9784,16 +10466,16 @@ ${template}`;
|
|
|
9784
10466
|
{ label: source === "global" ? "Global \xB7 current" : "Global", value: "global", key: "global" },
|
|
9785
10467
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
9786
10468
|
];
|
|
9787
|
-
return /* @__PURE__ */
|
|
9788
|
-
/* @__PURE__ */
|
|
10469
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10470
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9789
10471
|
"Save location (",
|
|
9790
10472
|
stepIndex,
|
|
9791
10473
|
"/",
|
|
9792
10474
|
totalSteps,
|
|
9793
10475
|
")"
|
|
9794
10476
|
] }),
|
|
9795
|
-
/* @__PURE__ */
|
|
9796
|
-
|
|
10477
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10478
|
+
SelectInput5,
|
|
9797
10479
|
{
|
|
9798
10480
|
items,
|
|
9799
10481
|
onSelect: (item) => {
|
|
@@ -9802,7 +10484,7 @@ ${template}`;
|
|
|
9802
10484
|
}
|
|
9803
10485
|
}
|
|
9804
10486
|
) }),
|
|
9805
|
-
/* @__PURE__ */
|
|
10487
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
|
|
9806
10488
|
] });
|
|
9807
10489
|
}
|
|
9808
10490
|
case "confirm": {
|
|
@@ -9810,8 +10492,8 @@ ${template}`;
|
|
|
9810
10492
|
{ label: "Save", value: "save", key: "save" },
|
|
9811
10493
|
{ label: "Cancel", value: "cancel", key: "cancel" }
|
|
9812
10494
|
];
|
|
9813
|
-
return /* @__PURE__ */
|
|
9814
|
-
/* @__PURE__ */
|
|
10495
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
10496
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
|
|
9815
10497
|
mode === "create" ? "Create" : "Edit",
|
|
9816
10498
|
" custom command \u2014 Confirm (",
|
|
9817
10499
|
stepIndex,
|
|
@@ -9819,14 +10501,14 @@ ${template}`;
|
|
|
9819
10501
|
totalSteps,
|
|
9820
10502
|
")"
|
|
9821
10503
|
] }),
|
|
9822
|
-
/* @__PURE__ */
|
|
10504
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
|
|
9823
10505
|
source === "project" ? ".kimiflare/commands/" : "~/.config/kimiflare/commands/",
|
|
9824
10506
|
name,
|
|
9825
10507
|
".md"
|
|
9826
10508
|
] }),
|
|
9827
|
-
/* @__PURE__ */
|
|
9828
|
-
/* @__PURE__ */
|
|
9829
|
-
|
|
10509
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: line || " " }, i)) }),
|
|
10510
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
10511
|
+
SelectInput5,
|
|
9830
10512
|
{
|
|
9831
10513
|
items,
|
|
9832
10514
|
onSelect: (item) => handleConfirm(item.value)
|
|
@@ -9836,7 +10518,7 @@ ${template}`;
|
|
|
9836
10518
|
}
|
|
9837
10519
|
}
|
|
9838
10520
|
};
|
|
9839
|
-
return /* @__PURE__ */
|
|
10521
|
+
return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
|
|
9840
10522
|
}
|
|
9841
10523
|
var NAME_RE;
|
|
9842
10524
|
var init_command_wizard = __esm({
|
|
@@ -9849,9 +10531,9 @@ var init_command_wizard = __esm({
|
|
|
9849
10531
|
});
|
|
9850
10532
|
|
|
9851
10533
|
// src/ui/command-picker.tsx
|
|
9852
|
-
import { Box as
|
|
9853
|
-
import
|
|
9854
|
-
import { jsx as
|
|
10534
|
+
import { Box as Box14, Text as Text15 } from "ink";
|
|
10535
|
+
import SelectInput6 from "ink-select-input";
|
|
10536
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
9855
10537
|
function CommandPicker({ commands, title, onPick }) {
|
|
9856
10538
|
const theme = useTheme();
|
|
9857
10539
|
const items = commands.map((cmd) => ({
|
|
@@ -9860,11 +10542,11 @@ function CommandPicker({ commands, title, onPick }) {
|
|
|
9860
10542
|
key: cmd.name
|
|
9861
10543
|
}));
|
|
9862
10544
|
items.push({ label: "\u2190 Cancel", value: null, key: "__cancel__" });
|
|
9863
|
-
return /* @__PURE__ */
|
|
9864
|
-
/* @__PURE__ */
|
|
9865
|
-
/* @__PURE__ */
|
|
9866
|
-
/* @__PURE__ */
|
|
9867
|
-
|
|
10545
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10546
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: title }),
|
|
10547
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
10548
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10549
|
+
SelectInput6,
|
|
9868
10550
|
{
|
|
9869
10551
|
items,
|
|
9870
10552
|
onSelect: (item) => {
|
|
@@ -9886,64 +10568,64 @@ var init_command_picker = __esm({
|
|
|
9886
10568
|
});
|
|
9887
10569
|
|
|
9888
10570
|
// src/ui/command-list.tsx
|
|
9889
|
-
import { Box as
|
|
9890
|
-
import { jsx as
|
|
10571
|
+
import { Box as Box15, Text as Text16, useInput as useInput5 } from "ink";
|
|
10572
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
9891
10573
|
function CommandList({ commands, onDone }) {
|
|
9892
10574
|
const theme = useTheme();
|
|
9893
|
-
|
|
10575
|
+
useInput5((_input, key) => {
|
|
9894
10576
|
if (key.escape) {
|
|
9895
10577
|
onDone();
|
|
9896
10578
|
}
|
|
9897
10579
|
});
|
|
9898
|
-
return /* @__PURE__ */
|
|
9899
|
-
/* @__PURE__ */
|
|
9900
|
-
/* @__PURE__ */
|
|
9901
|
-
/* @__PURE__ */
|
|
9902
|
-
commands.length === 0 && /* @__PURE__ */
|
|
9903
|
-
commands.map((cmd) => /* @__PURE__ */
|
|
9904
|
-
/* @__PURE__ */
|
|
10580
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10581
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
10582
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
|
|
10583
|
+
/* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "column", children: [
|
|
10584
|
+
commands.length === 0 && /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, children: "No custom commands found." }),
|
|
10585
|
+
commands.map((cmd) => /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginBottom: 1, children: [
|
|
10586
|
+
/* @__PURE__ */ jsxs15(Text16, { color: theme.accent, bold: true, children: [
|
|
9905
10587
|
"/",
|
|
9906
10588
|
cmd.name
|
|
9907
10589
|
] }),
|
|
9908
|
-
/* @__PURE__ */
|
|
10590
|
+
/* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9909
10591
|
" ",
|
|
9910
10592
|
"source: ",
|
|
9911
10593
|
cmd.source
|
|
9912
10594
|
] }),
|
|
9913
|
-
/* @__PURE__ */
|
|
10595
|
+
/* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9914
10596
|
" ",
|
|
9915
10597
|
"path: ",
|
|
9916
10598
|
cmd.filepath
|
|
9917
10599
|
] }),
|
|
9918
|
-
cmd.description && /* @__PURE__ */
|
|
10600
|
+
cmd.description && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9919
10601
|
" ",
|
|
9920
10602
|
"desc: ",
|
|
9921
10603
|
cmd.description
|
|
9922
10604
|
] }),
|
|
9923
|
-
cmd.mode && /* @__PURE__ */
|
|
10605
|
+
cmd.mode && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9924
10606
|
" ",
|
|
9925
10607
|
"mode: ",
|
|
9926
10608
|
cmd.mode
|
|
9927
10609
|
] }),
|
|
9928
|
-
cmd.effort && /* @__PURE__ */
|
|
10610
|
+
cmd.effort && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9929
10611
|
" ",
|
|
9930
10612
|
"effort: ",
|
|
9931
10613
|
cmd.effort
|
|
9932
10614
|
] }),
|
|
9933
|
-
cmd.model && /* @__PURE__ */
|
|
10615
|
+
cmd.model && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9934
10616
|
" ",
|
|
9935
10617
|
"model: ",
|
|
9936
10618
|
cmd.model
|
|
9937
10619
|
] }),
|
|
9938
|
-
/* @__PURE__ */
|
|
10620
|
+
/* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9939
10621
|
" ",
|
|
9940
10622
|
"template:"
|
|
9941
10623
|
] }),
|
|
9942
|
-
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */
|
|
10624
|
+
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9943
10625
|
" ",
|
|
9944
10626
|
line || " "
|
|
9945
10627
|
] }, i)),
|
|
9946
|
-
cmd.template.split("\n").length > 5 && /* @__PURE__ */
|
|
10628
|
+
cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
|
|
9947
10629
|
" ",
|
|
9948
10630
|
"..."
|
|
9949
10631
|
] })
|
|
@@ -9959,20 +10641,20 @@ var init_command_list = __esm({
|
|
|
9959
10641
|
});
|
|
9960
10642
|
|
|
9961
10643
|
// src/ui/lsp-wizard.tsx
|
|
9962
|
-
import { useState as
|
|
9963
|
-
import { Box as
|
|
9964
|
-
import
|
|
10644
|
+
import { useState as useState9 } from "react";
|
|
10645
|
+
import { Box as Box16, Text as Text17 } from "ink";
|
|
10646
|
+
import SelectInput7 from "ink-select-input";
|
|
9965
10647
|
import { spawn as spawn3 } from "child_process";
|
|
9966
|
-
import { jsx as
|
|
10648
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
9967
10649
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
9968
10650
|
const theme = useTheme();
|
|
9969
|
-
const [page, setPage] =
|
|
9970
|
-
const [selectedPreset, setSelectedPreset] =
|
|
9971
|
-
const [customName, setCustomName] =
|
|
9972
|
-
const [customCommand, setCustomCommand] =
|
|
9973
|
-
const [installState, setInstallState] =
|
|
9974
|
-
const [pendingServers, setPendingServers] =
|
|
9975
|
-
const [pendingEnabled, setPendingEnabled] =
|
|
10651
|
+
const [page, setPage] = useState9("main");
|
|
10652
|
+
const [selectedPreset, setSelectedPreset] = useState9(null);
|
|
10653
|
+
const [customName, setCustomName] = useState9("");
|
|
10654
|
+
const [customCommand, setCustomCommand] = useState9("");
|
|
10655
|
+
const [installState, setInstallState] = useState9({ status: "idle", output: "" });
|
|
10656
|
+
const [pendingServers, setPendingServers] = useState9(null);
|
|
10657
|
+
const [pendingEnabled, setPendingEnabled] = useState9(true);
|
|
9976
10658
|
const runInstall = (command) => {
|
|
9977
10659
|
setInstallState({ status: "running", output: "Installing..." });
|
|
9978
10660
|
const child = spawn3("bash", ["-lc", command], {
|
|
@@ -10074,11 +10756,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10074
10756
|
{ label: "(close)", value: "__close__", key: "__close__" }
|
|
10075
10757
|
];
|
|
10076
10758
|
if (page === "main") {
|
|
10077
|
-
return /* @__PURE__ */
|
|
10078
|
-
/* @__PURE__ */
|
|
10079
|
-
/* @__PURE__ */
|
|
10080
|
-
/* @__PURE__ */
|
|
10081
|
-
|
|
10759
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10760
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "LSP Servers" }),
|
|
10761
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
10762
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10763
|
+
SelectInput7,
|
|
10082
10764
|
{
|
|
10083
10765
|
items: mainItems,
|
|
10084
10766
|
onSelect: (item) => {
|
|
@@ -10105,11 +10787,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10105
10787
|
}),
|
|
10106
10788
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10107
10789
|
];
|
|
10108
|
-
return /* @__PURE__ */
|
|
10109
|
-
/* @__PURE__ */
|
|
10110
|
-
/* @__PURE__ */
|
|
10111
|
-
/* @__PURE__ */
|
|
10112
|
-
|
|
10790
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10791
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Add LSP Server" }),
|
|
10792
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
|
|
10793
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10794
|
+
SelectInput7,
|
|
10113
10795
|
{
|
|
10114
10796
|
items,
|
|
10115
10797
|
onSelect: (item) => {
|
|
@@ -10136,19 +10818,19 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10136
10818
|
{ label: isSuccess ? "Save to config \u2713" : "Save anyway", value: "save", key: "save" },
|
|
10137
10819
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10138
10820
|
];
|
|
10139
|
-
return /* @__PURE__ */
|
|
10140
|
-
/* @__PURE__ */
|
|
10821
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10822
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
|
|
10141
10823
|
"Install ",
|
|
10142
10824
|
selectedPreset.name
|
|
10143
10825
|
] }),
|
|
10144
|
-
/* @__PURE__ */
|
|
10145
|
-
/* @__PURE__ */
|
|
10146
|
-
/* @__PURE__ */
|
|
10147
|
-
/* @__PURE__ */
|
|
10826
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
|
|
10827
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
|
|
10828
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Command:" }),
|
|
10829
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
|
|
10148
10830
|
] }),
|
|
10149
|
-
installState.output && /* @__PURE__ */
|
|
10150
|
-
/* @__PURE__ */
|
|
10151
|
-
|
|
10831
|
+
installState.output && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx18(Text17, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
|
|
10832
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10833
|
+
SelectInput7,
|
|
10152
10834
|
{
|
|
10153
10835
|
items,
|
|
10154
10836
|
onSelect: (item) => {
|
|
@@ -10165,16 +10847,16 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10165
10847
|
}
|
|
10166
10848
|
}
|
|
10167
10849
|
) }),
|
|
10168
|
-
isSuccess && /* @__PURE__ */
|
|
10850
|
+
isSuccess && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
|
|
10169
10851
|
] });
|
|
10170
10852
|
}
|
|
10171
10853
|
if (page === "custom-name") {
|
|
10172
|
-
return /* @__PURE__ */
|
|
10173
|
-
/* @__PURE__ */
|
|
10174
|
-
/* @__PURE__ */
|
|
10175
|
-
/* @__PURE__ */
|
|
10176
|
-
/* @__PURE__ */
|
|
10177
|
-
/* @__PURE__ */
|
|
10854
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10855
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
|
|
10856
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
|
|
10857
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, children: [
|
|
10858
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "\u203A " }),
|
|
10859
|
+
/* @__PURE__ */ jsx18(
|
|
10178
10860
|
CustomTextInput,
|
|
10179
10861
|
{
|
|
10180
10862
|
value: customName,
|
|
@@ -10188,8 +10870,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10188
10870
|
}
|
|
10189
10871
|
)
|
|
10190
10872
|
] }),
|
|
10191
|
-
/* @__PURE__ */
|
|
10192
|
-
|
|
10873
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10874
|
+
SelectInput7,
|
|
10193
10875
|
{
|
|
10194
10876
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
10195
10877
|
onSelect: () => setPage("add")
|
|
@@ -10198,12 +10880,12 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10198
10880
|
] });
|
|
10199
10881
|
}
|
|
10200
10882
|
if (page === "custom-command") {
|
|
10201
|
-
return /* @__PURE__ */
|
|
10202
|
-
/* @__PURE__ */
|
|
10203
|
-
/* @__PURE__ */
|
|
10204
|
-
/* @__PURE__ */
|
|
10205
|
-
/* @__PURE__ */
|
|
10206
|
-
/* @__PURE__ */
|
|
10883
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10884
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
|
|
10885
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
|
|
10886
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, children: [
|
|
10887
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "\u203A " }),
|
|
10888
|
+
/* @__PURE__ */ jsx18(
|
|
10207
10889
|
CustomTextInput,
|
|
10208
10890
|
{
|
|
10209
10891
|
value: customCommand,
|
|
@@ -10217,8 +10899,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10217
10899
|
}
|
|
10218
10900
|
)
|
|
10219
10901
|
] }),
|
|
10220
|
-
/* @__PURE__ */
|
|
10221
|
-
|
|
10902
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10903
|
+
SelectInput7,
|
|
10222
10904
|
{
|
|
10223
10905
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
10224
10906
|
onSelect: () => setPage("custom-name")
|
|
@@ -10241,11 +10923,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10241
10923
|
},
|
|
10242
10924
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10243
10925
|
];
|
|
10244
|
-
return /* @__PURE__ */
|
|
10245
|
-
/* @__PURE__ */
|
|
10246
|
-
/* @__PURE__ */
|
|
10247
|
-
/* @__PURE__ */
|
|
10248
|
-
|
|
10926
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10927
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Save LSP Config" }),
|
|
10928
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
|
|
10929
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10930
|
+
SelectInput7,
|
|
10249
10931
|
{
|
|
10250
10932
|
items,
|
|
10251
10933
|
onSelect: (item) => {
|
|
@@ -10263,11 +10945,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10263
10945
|
if (page === "edit") {
|
|
10264
10946
|
const keys = Object.keys(servers);
|
|
10265
10947
|
if (keys.length === 0) {
|
|
10266
|
-
return /* @__PURE__ */
|
|
10267
|
-
/* @__PURE__ */
|
|
10268
|
-
/* @__PURE__ */
|
|
10269
|
-
/* @__PURE__ */
|
|
10270
|
-
|
|
10948
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10949
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
10950
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }),
|
|
10951
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10952
|
+
SelectInput7,
|
|
10271
10953
|
{
|
|
10272
10954
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
10273
10955
|
onSelect: () => setPage("main")
|
|
@@ -10287,11 +10969,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10287
10969
|
}),
|
|
10288
10970
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10289
10971
|
];
|
|
10290
|
-
return /* @__PURE__ */
|
|
10291
|
-
/* @__PURE__ */
|
|
10292
|
-
/* @__PURE__ */
|
|
10293
|
-
/* @__PURE__ */
|
|
10294
|
-
|
|
10972
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10973
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
10974
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
|
|
10975
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10976
|
+
SelectInput7,
|
|
10295
10977
|
{
|
|
10296
10978
|
items,
|
|
10297
10979
|
onSelect: (item) => {
|
|
@@ -10308,11 +10990,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10308
10990
|
if (page === "delete") {
|
|
10309
10991
|
const keys = Object.keys(servers);
|
|
10310
10992
|
if (keys.length === 0) {
|
|
10311
|
-
return /* @__PURE__ */
|
|
10312
|
-
/* @__PURE__ */
|
|
10313
|
-
/* @__PURE__ */
|
|
10314
|
-
/* @__PURE__ */
|
|
10315
|
-
|
|
10993
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
10994
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
10995
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }),
|
|
10996
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
10997
|
+
SelectInput7,
|
|
10316
10998
|
{
|
|
10317
10999
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
10318
11000
|
onSelect: () => setPage("main")
|
|
@@ -10328,11 +11010,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10328
11010
|
})),
|
|
10329
11011
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10330
11012
|
];
|
|
10331
|
-
return /* @__PURE__ */
|
|
10332
|
-
/* @__PURE__ */
|
|
10333
|
-
/* @__PURE__ */
|
|
10334
|
-
/* @__PURE__ */
|
|
10335
|
-
|
|
11013
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11014
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
11015
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
|
|
11016
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11017
|
+
SelectInput7,
|
|
10336
11018
|
{
|
|
10337
11019
|
items,
|
|
10338
11020
|
onSelect: (item) => {
|
|
@@ -10348,15 +11030,15 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
10348
11030
|
}
|
|
10349
11031
|
if (page === "list") {
|
|
10350
11032
|
const keys = Object.keys(servers);
|
|
10351
|
-
return /* @__PURE__ */
|
|
10352
|
-
/* @__PURE__ */
|
|
10353
|
-
keys.length === 0 ? /* @__PURE__ */
|
|
11033
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11034
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
|
|
11035
|
+
keys.length === 0 ? /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx18(Box16, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
|
|
10354
11036
|
const s = servers[k];
|
|
10355
11037
|
const status = s.enabled !== false ? "enabled" : "disabled";
|
|
10356
|
-
return /* @__PURE__ */
|
|
11038
|
+
return /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
|
|
10357
11039
|
}) }),
|
|
10358
|
-
/* @__PURE__ */
|
|
10359
|
-
|
|
11040
|
+
/* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
|
|
11041
|
+
SelectInput7,
|
|
10360
11042
|
{
|
|
10361
11043
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
10362
11044
|
onSelect: () => setPage("main")
|
|
@@ -10482,9 +11164,9 @@ var init_lsp_wizard = __esm({
|
|
|
10482
11164
|
});
|
|
10483
11165
|
|
|
10484
11166
|
// src/ui/theme-picker.tsx
|
|
10485
|
-
import { Box as
|
|
10486
|
-
import
|
|
10487
|
-
import { jsx as
|
|
11167
|
+
import { Box as Box17, Text as Text18 } from "ink";
|
|
11168
|
+
import SelectInput8 from "ink-select-input";
|
|
11169
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
10488
11170
|
function PaletteSwatches({ palette }) {
|
|
10489
11171
|
const colors = [
|
|
10490
11172
|
palette.primary,
|
|
@@ -10492,7 +11174,7 @@ function PaletteSwatches({ palette }) {
|
|
|
10492
11174
|
palette.success,
|
|
10493
11175
|
palette.error
|
|
10494
11176
|
];
|
|
10495
|
-
return /* @__PURE__ */
|
|
11177
|
+
return /* @__PURE__ */ jsx19(Box17, { children: colors.map((c, i) => /* @__PURE__ */ jsx19(Text18, { color: c, children: "\u2588" }, i)) });
|
|
10496
11178
|
}
|
|
10497
11179
|
function ThemePicker({ themes, onPick, onPreview }) {
|
|
10498
11180
|
const current = useTheme();
|
|
@@ -10500,10 +11182,10 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
10500
11182
|
...themes.map((t) => ({ label: t.label, value: t.name })),
|
|
10501
11183
|
{ label: "< Back", value: "__back__" }
|
|
10502
11184
|
];
|
|
10503
|
-
return /* @__PURE__ */
|
|
10504
|
-
/* @__PURE__ */
|
|
10505
|
-
/* @__PURE__ */
|
|
10506
|
-
|
|
11185
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
|
|
11186
|
+
/* @__PURE__ */ jsx19(Text18, { color: current.accent, bold: true, children: "Pick a theme" }),
|
|
11187
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11188
|
+
SelectInput8,
|
|
10507
11189
|
{
|
|
10508
11190
|
items,
|
|
10509
11191
|
onHighlight: (item) => {
|
|
@@ -10522,9 +11204,9 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
10522
11204
|
itemComponent: ({ label, isSelected }) => {
|
|
10523
11205
|
const t = themes.find((x) => x.label === label);
|
|
10524
11206
|
const color = t?.accent ?? current.accent;
|
|
10525
|
-
return /* @__PURE__ */
|
|
10526
|
-
/* @__PURE__ */
|
|
10527
|
-
t && /* @__PURE__ */
|
|
11207
|
+
return /* @__PURE__ */ jsxs17(Box17, { children: [
|
|
11208
|
+
/* @__PURE__ */ jsx19(Text18, { color, bold: isSelected, dimColor: !isSelected, children: label }),
|
|
11209
|
+
t && /* @__PURE__ */ jsx19(Box17, { marginLeft: 1, children: /* @__PURE__ */ jsx19(PaletteSwatches, { palette: t.palette }) })
|
|
10528
11210
|
] });
|
|
10529
11211
|
}
|
|
10530
11212
|
}
|
|
@@ -10668,8 +11350,8 @@ var init_lsp_nudge = __esm({
|
|
|
10668
11350
|
});
|
|
10669
11351
|
|
|
10670
11352
|
// src/ui/file-picker.tsx
|
|
10671
|
-
import { Box as
|
|
10672
|
-
import { jsx as
|
|
11353
|
+
import { Box as Box18, Text as Text19 } from "ink";
|
|
11354
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
10673
11355
|
function FilePicker({ items, selectedIndex, query }) {
|
|
10674
11356
|
const theme = useTheme();
|
|
10675
11357
|
let startIndex = 0;
|
|
@@ -10679,12 +11361,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
10679
11361
|
const visible = items.slice(startIndex, startIndex + VISIBLE_LIMIT);
|
|
10680
11362
|
const hasMoreAbove = startIndex > 0;
|
|
10681
11363
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT;
|
|
10682
|
-
return /* @__PURE__ */
|
|
10683
|
-
/* @__PURE__ */
|
|
10684
|
-
/* @__PURE__ */
|
|
10685
|
-
/* @__PURE__ */
|
|
10686
|
-
visible.length === 0 && /* @__PURE__ */
|
|
10687
|
-
hasMoreAbove && /* @__PURE__ */
|
|
11364
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11365
|
+
/* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
|
|
11366
|
+
/* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
11367
|
+
/* @__PURE__ */ jsxs18(Box18, { marginTop: 1, flexDirection: "column", children: [
|
|
11368
|
+
visible.length === 0 && /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, children: "No matches" }),
|
|
11369
|
+
hasMoreAbove && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
|
|
10688
11370
|
"\u2026 ",
|
|
10689
11371
|
startIndex,
|
|
10690
11372
|
" more above"
|
|
@@ -10693,12 +11375,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
10693
11375
|
const actualIndex = startIndex + i;
|
|
10694
11376
|
const isSelected = actualIndex === selectedIndex;
|
|
10695
11377
|
const label = item.isDirectory ? `${item.name}/` : item.name;
|
|
10696
|
-
return /* @__PURE__ */
|
|
11378
|
+
return /* @__PURE__ */ jsxs18(Text19, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
10697
11379
|
isSelected ? "\u203A " : " ",
|
|
10698
11380
|
label
|
|
10699
11381
|
] }, item.name);
|
|
10700
11382
|
}),
|
|
10701
|
-
hasMoreBelow && /* @__PURE__ */
|
|
11383
|
+
hasMoreBelow && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
|
|
10702
11384
|
"\u2026 ",
|
|
10703
11385
|
items.length - (startIndex + VISIBLE_LIMIT),
|
|
10704
11386
|
" more below"
|
|
@@ -10716,8 +11398,8 @@ var init_file_picker = __esm({
|
|
|
10716
11398
|
});
|
|
10717
11399
|
|
|
10718
11400
|
// src/ui/slash-picker.tsx
|
|
10719
|
-
import { Box as
|
|
10720
|
-
import { jsx as
|
|
11401
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
11402
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
10721
11403
|
function sourceBadge(source) {
|
|
10722
11404
|
if (source === "builtin") return "";
|
|
10723
11405
|
if (source === "project") return "project";
|
|
@@ -10737,12 +11419,12 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
10737
11419
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT2;
|
|
10738
11420
|
const longestLabel = visible.reduce((m, it) => Math.max(m, commandLabel(it).length), 0);
|
|
10739
11421
|
const nameColWidth = Math.max(NAME_COL_MIN_WIDTH, longestLabel + NAME_DESC_GAP);
|
|
10740
|
-
return /* @__PURE__ */
|
|
10741
|
-
/* @__PURE__ */
|
|
10742
|
-
/* @__PURE__ */
|
|
10743
|
-
/* @__PURE__ */
|
|
10744
|
-
visible.length === 0 && /* @__PURE__ */
|
|
10745
|
-
hasMoreAbove && /* @__PURE__ */
|
|
11422
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11423
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
|
|
11424
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
11425
|
+
/* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
11426
|
+
visible.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No matches" }),
|
|
11427
|
+
hasMoreAbove && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
10746
11428
|
"\u2026 ",
|
|
10747
11429
|
startIndex,
|
|
10748
11430
|
" more above"
|
|
@@ -10752,16 +11434,16 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
10752
11434
|
const isSelected = actualIndex === selectedIndex;
|
|
10753
11435
|
const nameCol = commandLabel(item).padEnd(nameColWidth);
|
|
10754
11436
|
const badge = sourceBadge(item.source);
|
|
10755
|
-
return /* @__PURE__ */
|
|
11437
|
+
return /* @__PURE__ */ jsxs19(Text20, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
10756
11438
|
isSelected ? "\u203A " : " ",
|
|
10757
11439
|
nameCol,
|
|
10758
|
-
/* @__PURE__ */
|
|
11440
|
+
/* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
10759
11441
|
item.description,
|
|
10760
11442
|
badge && ` [${badge}]`
|
|
10761
11443
|
] })
|
|
10762
11444
|
] }, item.name);
|
|
10763
11445
|
}),
|
|
10764
|
-
hasMoreBelow && /* @__PURE__ */
|
|
11446
|
+
hasMoreBelow && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
10765
11447
|
"\u2026 ",
|
|
10766
11448
|
items.length - (startIndex + VISIBLE_LIMIT2),
|
|
10767
11449
|
" more below"
|
|
@@ -10841,15 +11523,15 @@ var tui_report_exports = {};
|
|
|
10841
11523
|
__export(tui_report_exports, {
|
|
10842
11524
|
getCategoryReportText: () => getCategoryReportText
|
|
10843
11525
|
});
|
|
10844
|
-
import { readFile as
|
|
10845
|
-
import { join as
|
|
10846
|
-
import { homedir as
|
|
11526
|
+
import { readFile as readFile15 } from "fs/promises";
|
|
11527
|
+
import { join as join18 } from "path";
|
|
11528
|
+
import { homedir as homedir13 } from "os";
|
|
10847
11529
|
function usageDir3() {
|
|
10848
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
10849
|
-
return
|
|
11530
|
+
const xdg = process.env.XDG_DATA_HOME || join18(homedir13(), ".local", "share");
|
|
11531
|
+
return join18(xdg, "kimiflare");
|
|
10850
11532
|
}
|
|
10851
11533
|
function usagePath3() {
|
|
10852
|
-
return
|
|
11534
|
+
return join18(usageDir3(), "usage.json");
|
|
10853
11535
|
}
|
|
10854
11536
|
function today3() {
|
|
10855
11537
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -10861,7 +11543,7 @@ function daysAgo2(n) {
|
|
|
10861
11543
|
}
|
|
10862
11544
|
async function loadLog3() {
|
|
10863
11545
|
try {
|
|
10864
|
-
const raw = await
|
|
11546
|
+
const raw = await readFile15(usagePath3(), "utf8");
|
|
10865
11547
|
return JSON.parse(raw);
|
|
10866
11548
|
} catch {
|
|
10867
11549
|
return { version: 1, days: [], sessions: [] };
|
|
@@ -10927,17 +11609,18 @@ __export(app_exports, {
|
|
|
10927
11609
|
shouldOpenMentionPicker: () => shouldOpenMentionPicker,
|
|
10928
11610
|
shouldOpenSlashPicker: () => shouldOpenSlashPicker
|
|
10929
11611
|
});
|
|
10930
|
-
import
|
|
10931
|
-
import { Box as
|
|
10932
|
-
import
|
|
11612
|
+
import React14, { useState as useState10, useRef as useRef3, useEffect as useEffect5, useCallback } from "react";
|
|
11613
|
+
import { Box as Box20, Text as Text21, useApp, useInput as useInput6, render } from "ink";
|
|
11614
|
+
import SelectInput9 from "ink-select-input";
|
|
10933
11615
|
import { existsSync as existsSync2, statSync as statSync3 } from "fs";
|
|
10934
|
-
import { join as
|
|
11616
|
+
import { join as join19 } from "path";
|
|
10935
11617
|
import { unlink as unlink3 } from "fs/promises";
|
|
11618
|
+
import { execSync as execSync2 } from "child_process";
|
|
10936
11619
|
import { spawn as spawn4 } from "child_process";
|
|
10937
11620
|
import { platform as platform2 } from "os";
|
|
10938
11621
|
import fg4 from "fast-glob";
|
|
10939
11622
|
import { readFileSync as readFileSync3 } from "fs";
|
|
10940
|
-
import { jsx as
|
|
11623
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
10941
11624
|
function buildFilePickerIgnoreList(cwd) {
|
|
10942
11625
|
const hardcoded = [
|
|
10943
11626
|
// Dependencies
|
|
@@ -11008,7 +11691,7 @@ function buildFilePickerIgnoreList(cwd) {
|
|
|
11008
11691
|
];
|
|
11009
11692
|
const gitignorePatterns = [];
|
|
11010
11693
|
try {
|
|
11011
|
-
const gitignorePath =
|
|
11694
|
+
const gitignorePath = join19(cwd, ".gitignore");
|
|
11012
11695
|
const stats = statSync3(gitignorePath);
|
|
11013
11696
|
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
11014
11697
|
return hardcoded;
|
|
@@ -11082,6 +11765,26 @@ function openBrowser(url) {
|
|
|
11082
11765
|
const child = spawn4(cmd, [url], { detached: true, stdio: "ignore" });
|
|
11083
11766
|
child.unref();
|
|
11084
11767
|
}
|
|
11768
|
+
function detectGitHubRepo(cachedRepo) {
|
|
11769
|
+
if (cachedRepo) {
|
|
11770
|
+
const parts = cachedRepo.split("/");
|
|
11771
|
+
if (parts.length === 2) return { owner: parts[0], name: parts[1] };
|
|
11772
|
+
}
|
|
11773
|
+
try {
|
|
11774
|
+
const remoteUrl = execSync2("git remote get-url origin", { cwd: process.cwd(), encoding: "utf8" }).trim();
|
|
11775
|
+
const httpsMatch = remoteUrl.match(/github\.com\/([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
11776
|
+
if (httpsMatch) return { owner: httpsMatch[1], name: httpsMatch[2] };
|
|
11777
|
+
const sshMatch = remoteUrl.match(/github\.com:([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
11778
|
+
if (sshMatch) return { owner: sshMatch[1], name: sshMatch[2] };
|
|
11779
|
+
} catch {
|
|
11780
|
+
}
|
|
11781
|
+
return null;
|
|
11782
|
+
}
|
|
11783
|
+
function formatTokens3(n) {
|
|
11784
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
11785
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
11786
|
+
return String(n);
|
|
11787
|
+
}
|
|
11085
11788
|
function capEvents(prev) {
|
|
11086
11789
|
if (prev.length <= MAX_EVENTS) return prev;
|
|
11087
11790
|
return prev.slice(prev.length - MAX_EVENTS);
|
|
@@ -11144,10 +11847,10 @@ function App({
|
|
|
11144
11847
|
initialLspProjectPath
|
|
11145
11848
|
}) {
|
|
11146
11849
|
const { exit } = useApp();
|
|
11147
|
-
const [cfg, setCfg] =
|
|
11148
|
-
const [lspScope, setLspScope] =
|
|
11149
|
-
const [lspProjectPath, setLspProjectPath] =
|
|
11150
|
-
const [events, setRawEvents] =
|
|
11850
|
+
const [cfg, setCfg] = useState10(initialCfg);
|
|
11851
|
+
const [lspScope, setLspScope] = useState10(initialLspScope);
|
|
11852
|
+
const [lspProjectPath, setLspProjectPath] = useState10(initialLspProjectPath);
|
|
11853
|
+
const [events, setRawEvents] = useState10([]);
|
|
11151
11854
|
const setEvents = useCallback(
|
|
11152
11855
|
(updater) => {
|
|
11153
11856
|
setRawEvents((prev) => {
|
|
@@ -11157,45 +11860,47 @@ function App({
|
|
|
11157
11860
|
},
|
|
11158
11861
|
[]
|
|
11159
11862
|
);
|
|
11160
|
-
const [input, setInput] =
|
|
11161
|
-
const [busy, setBusy] =
|
|
11162
|
-
const [usage, setUsage] =
|
|
11163
|
-
const [sessionUsage, setSessionUsage] =
|
|
11164
|
-
const [gatewayMeta, setGatewayMeta] =
|
|
11165
|
-
const [showReasoning, setShowReasoning] =
|
|
11166
|
-
const [perm, setPerm] =
|
|
11167
|
-
const [queue, setQueue] =
|
|
11168
|
-
const [history, setHistory] =
|
|
11169
|
-
const [historyIndex, setHistoryIndex] =
|
|
11170
|
-
const [draftInput, setDraftInput] =
|
|
11171
|
-
const [mode, setMode] =
|
|
11172
|
-
const [codeMode, setCodeMode] =
|
|
11863
|
+
const [input, setInput] = useState10("");
|
|
11864
|
+
const [busy, setBusy] = useState10(false);
|
|
11865
|
+
const [usage, setUsage] = useState10(null);
|
|
11866
|
+
const [sessionUsage, setSessionUsage] = useState10(null);
|
|
11867
|
+
const [gatewayMeta, setGatewayMeta] = useState10(null);
|
|
11868
|
+
const [showReasoning, setShowReasoning] = useState10(false);
|
|
11869
|
+
const [perm, setPerm] = useState10(null);
|
|
11870
|
+
const [queue, setQueue] = useState10([]);
|
|
11871
|
+
const [history, setHistory] = useState10([]);
|
|
11872
|
+
const [historyIndex, setHistoryIndex] = useState10(-1);
|
|
11873
|
+
const [draftInput, setDraftInput] = useState10("");
|
|
11874
|
+
const [mode, setMode] = useState10("edit");
|
|
11875
|
+
const [codeMode, setCodeMode] = useState10(false);
|
|
11173
11876
|
const filePickerEnabled = initialCfg?.filePicker ?? true;
|
|
11174
|
-
const [effort, setEffort] =
|
|
11877
|
+
const [effort, setEffort] = useState10(
|
|
11175
11878
|
initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
|
|
11176
11879
|
);
|
|
11177
|
-
const [resumeSessions, setResumeSessions] =
|
|
11178
|
-
const [showHelpMenu, setShowHelpMenu] =
|
|
11179
|
-
const [commandWizard, setCommandWizard] =
|
|
11180
|
-
const [commandPicker, setCommandPicker] =
|
|
11181
|
-
const [commandToDelete, setCommandToDelete] =
|
|
11182
|
-
const [showCommandList, setShowCommandList] =
|
|
11183
|
-
const [showLspWizard, setShowLspWizard] =
|
|
11184
|
-
const [
|
|
11185
|
-
const [
|
|
11186
|
-
const [
|
|
11187
|
-
const [
|
|
11188
|
-
const [
|
|
11189
|
-
const [
|
|
11190
|
-
const [
|
|
11191
|
-
const [
|
|
11192
|
-
const [
|
|
11193
|
-
const [
|
|
11194
|
-
const [
|
|
11195
|
-
const [
|
|
11196
|
-
const [
|
|
11880
|
+
const [resumeSessions, setResumeSessions] = useState10(null);
|
|
11881
|
+
const [showHelpMenu, setShowHelpMenu] = useState10(false);
|
|
11882
|
+
const [commandWizard, setCommandWizard] = useState10(null);
|
|
11883
|
+
const [commandPicker, setCommandPicker] = useState10(null);
|
|
11884
|
+
const [commandToDelete, setCommandToDelete] = useState10(null);
|
|
11885
|
+
const [showCommandList, setShowCommandList] = useState10(false);
|
|
11886
|
+
const [showLspWizard, setShowLspWizard] = useState10(false);
|
|
11887
|
+
const [showRemoteDashboard, setShowRemoteDashboard] = useState10(false);
|
|
11888
|
+
const [selectedRemoteSession, setSelectedRemoteSession] = useState10(null);
|
|
11889
|
+
const [tasks, setTasks] = useState10([]);
|
|
11890
|
+
const [tasksStartedAt, setTasksStartedAt] = useState10(null);
|
|
11891
|
+
const [tasksStartTokens, setTasksStartTokens] = useState10(0);
|
|
11892
|
+
const [turnStartedAt, setTurnStartedAt] = useState10(null);
|
|
11893
|
+
const [verbose, setVerbose] = useState10(false);
|
|
11894
|
+
const [hasUpdate, setHasUpdate] = useState10(initialUpdateResult?.hasUpdate ?? false);
|
|
11895
|
+
const [latestVersion, setLatestVersion] = useState10(initialUpdateResult?.latestVersion ?? null);
|
|
11896
|
+
const [theme, setTheme] = useState10(resolveTheme(initialCfg?.theme));
|
|
11897
|
+
const [showThemePicker, setShowThemePicker] = useState10(false);
|
|
11898
|
+
const [originalTheme, setOriginalTheme] = useState10(null);
|
|
11899
|
+
const [cursorOffset, setCursorOffset] = useState10(0);
|
|
11900
|
+
const [activePicker, setActivePicker] = useState10(null);
|
|
11901
|
+
const [filePickerItems, setFilePickerItems] = useState10([]);
|
|
11197
11902
|
const filePickerLoadedRef = useRef3(false);
|
|
11198
|
-
const [customCommandsVersion, setCustomCommandsVersion] =
|
|
11903
|
+
const [customCommandsVersion, setCustomCommandsVersion] = useState10(0);
|
|
11199
11904
|
const cacheStableRef = useRef3(initialCfg?.cacheStablePrompts !== false);
|
|
11200
11905
|
const messagesRef = useRef3(
|
|
11201
11906
|
makePrefixMessages(cacheStableRef.current, cfg?.model ?? DEFAULT_MODEL, "edit", ALL_TOOLS)
|
|
@@ -11233,15 +11938,15 @@ function App({
|
|
|
11233
11938
|
const pickerCancelRef = useRef3(null);
|
|
11234
11939
|
const pickerAnchor = activePicker?.anchor ?? null;
|
|
11235
11940
|
const pickerKind = activePicker?.kind ?? null;
|
|
11236
|
-
const pickerQuery =
|
|
11941
|
+
const pickerQuery = React14.useMemo(() => {
|
|
11237
11942
|
if (pickerAnchor === null) return null;
|
|
11238
11943
|
return input.slice(pickerAnchor + 1, cursorOffset);
|
|
11239
11944
|
}, [input, cursorOffset, pickerAnchor]);
|
|
11240
|
-
const filteredFileItems =
|
|
11945
|
+
const filteredFileItems = React14.useMemo(() => {
|
|
11241
11946
|
if (pickerKind !== "file" || pickerQuery === null) return [];
|
|
11242
11947
|
return filterPickerItems(filePickerItems, pickerQuery);
|
|
11243
11948
|
}, [pickerKind, filePickerItems, pickerQuery]);
|
|
11244
|
-
const allSlashCommands =
|
|
11949
|
+
const allSlashCommands = React14.useMemo(() => {
|
|
11245
11950
|
const customs = customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({
|
|
11246
11951
|
name: c.name,
|
|
11247
11952
|
description: c.description ?? "",
|
|
@@ -11249,11 +11954,11 @@ function App({
|
|
|
11249
11954
|
}));
|
|
11250
11955
|
return [...BUILTIN_COMMANDS, ...customs];
|
|
11251
11956
|
}, [customCommandsVersion]);
|
|
11252
|
-
const filteredSlashItems =
|
|
11957
|
+
const filteredSlashItems = React14.useMemo(() => {
|
|
11253
11958
|
if (pickerKind !== "slash" || pickerQuery === null) return [];
|
|
11254
11959
|
return fuzzyFilter(allSlashCommands, pickerQuery, (c) => c.name).slice(0, 50);
|
|
11255
11960
|
}, [pickerKind, allSlashCommands, pickerQuery]);
|
|
11256
|
-
|
|
11961
|
+
useEffect5(() => {
|
|
11257
11962
|
if (activePicker !== null) {
|
|
11258
11963
|
const trigger = activePicker.kind === "file" ? "@" : "/";
|
|
11259
11964
|
if (cursorOffset < activePicker.anchor) {
|
|
@@ -11310,14 +12015,14 @@ function App({
|
|
|
11310
12015
|
return;
|
|
11311
12016
|
}
|
|
11312
12017
|
}, [input, cursorOffset, activePicker, filePickerEnabled]);
|
|
11313
|
-
|
|
12018
|
+
useEffect5(() => {
|
|
11314
12019
|
if (activePicker?.kind !== "file") return;
|
|
11315
12020
|
const max = Math.max(0, filteredFileItems.length - 1);
|
|
11316
12021
|
if (activePicker.selected > max) {
|
|
11317
12022
|
setActivePicker({ ...activePicker, selected: max });
|
|
11318
12023
|
}
|
|
11319
12024
|
}, [filteredFileItems.length, activePicker]);
|
|
11320
|
-
|
|
12025
|
+
useEffect5(() => {
|
|
11321
12026
|
if (activePicker?.kind !== "slash") return;
|
|
11322
12027
|
const max = Math.max(0, filteredSlashItems.length - 1);
|
|
11323
12028
|
if (activePicker.selected > max) {
|
|
@@ -11361,7 +12066,7 @@ function App({
|
|
|
11361
12066
|
pickerCancelRef.current = cursorOffset;
|
|
11362
12067
|
setActivePicker(null);
|
|
11363
12068
|
}, [cursorOffset]);
|
|
11364
|
-
|
|
12069
|
+
useEffect5(() => {
|
|
11365
12070
|
const modalActive = showHelpMenu || commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null;
|
|
11366
12071
|
if (modalActive && activePicker !== null) {
|
|
11367
12072
|
setActivePicker(null);
|
|
@@ -11377,7 +12082,7 @@ function App({
|
|
|
11377
12082
|
perm,
|
|
11378
12083
|
activePicker
|
|
11379
12084
|
]);
|
|
11380
|
-
|
|
12085
|
+
useEffect5(() => {
|
|
11381
12086
|
if (!cfg) return;
|
|
11382
12087
|
void Promise.resolve().then(() => (init_sessions(), sessions_exports)).then(
|
|
11383
12088
|
({ pruneSessions: pruneSessions2 }) => pruneSessions2().then((removed) => {
|
|
@@ -11403,7 +12108,7 @@ function App({
|
|
|
11403
12108
|
}
|
|
11404
12109
|
});
|
|
11405
12110
|
if (cfg.memoryEnabled) {
|
|
11406
|
-
const dbPath = cfg.memoryDbPath ??
|
|
12111
|
+
const dbPath = cfg.memoryDbPath ?? join19(process.cwd(), ".kimiflare", "memory.db");
|
|
11407
12112
|
const manager = new MemoryManager({
|
|
11408
12113
|
dbPath,
|
|
11409
12114
|
accountId: cfg.accountId,
|
|
@@ -11470,7 +12175,7 @@ function App({
|
|
|
11470
12175
|
}
|
|
11471
12176
|
});
|
|
11472
12177
|
}, [cfg, setEvents]);
|
|
11473
|
-
|
|
12178
|
+
useEffect5(() => {
|
|
11474
12179
|
const id = setInterval(() => {
|
|
11475
12180
|
try {
|
|
11476
12181
|
performance.clearMarks();
|
|
@@ -11495,7 +12200,7 @@ function App({
|
|
|
11495
12200
|
]);
|
|
11496
12201
|
}
|
|
11497
12202
|
}, [setEvents]);
|
|
11498
|
-
|
|
12203
|
+
useEffect5(() => {
|
|
11499
12204
|
if (!cfg || updateCheckedRef.current) return;
|
|
11500
12205
|
updateCheckedRef.current = true;
|
|
11501
12206
|
if (initialUpdateResult) {
|
|
@@ -11546,7 +12251,7 @@ function App({
|
|
|
11546
12251
|
}
|
|
11547
12252
|
});
|
|
11548
12253
|
}, [cfg, initialUpdateResult]);
|
|
11549
|
-
|
|
12254
|
+
useEffect5(() => {
|
|
11550
12255
|
modeRef.current = mode;
|
|
11551
12256
|
if (cacheStableRef.current) {
|
|
11552
12257
|
messagesRef.current[1] = {
|
|
@@ -11573,10 +12278,10 @@ function App({
|
|
|
11573
12278
|
executorRef.current.clearSessionPermissions();
|
|
11574
12279
|
}
|
|
11575
12280
|
}, [mode, cfg?.model]);
|
|
11576
|
-
|
|
12281
|
+
useEffect5(() => {
|
|
11577
12282
|
effortRef.current = effort;
|
|
11578
12283
|
}, [effort]);
|
|
11579
|
-
|
|
12284
|
+
useEffect5(() => {
|
|
11580
12285
|
if (!cfg) return;
|
|
11581
12286
|
const id = setInterval(() => {
|
|
11582
12287
|
void checkForUpdate().then((result) => {
|
|
@@ -11731,7 +12436,7 @@ function App({
|
|
|
11731
12436
|
]);
|
|
11732
12437
|
}
|
|
11733
12438
|
}, [cfg]);
|
|
11734
|
-
|
|
12439
|
+
useEffect5(() => {
|
|
11735
12440
|
if (cfg && !mcpInitRef.current) {
|
|
11736
12441
|
void initMcp();
|
|
11737
12442
|
}
|
|
@@ -11769,7 +12474,85 @@ function App({
|
|
|
11769
12474
|
} catch {
|
|
11770
12475
|
}
|
|
11771
12476
|
}, [cfg, ensureSessionId]);
|
|
11772
|
-
|
|
12477
|
+
const onIterationEnd = useCallback(
|
|
12478
|
+
async (messages, signal) => {
|
|
12479
|
+
if (signal.aborted) return messages;
|
|
12480
|
+
if (!shouldCompact({ messages })) return messages;
|
|
12481
|
+
if (compiledContextRef.current) {
|
|
12482
|
+
const store = artifactStoreRef.current;
|
|
12483
|
+
const result = compactMessages2({
|
|
12484
|
+
messages,
|
|
12485
|
+
state: sessionStateRef.current,
|
|
12486
|
+
store
|
|
12487
|
+
});
|
|
12488
|
+
if (result.metrics.rawTurnsRemoved > 0) {
|
|
12489
|
+
sessionStateRef.current = result.newState;
|
|
12490
|
+
setEvents((e) => [
|
|
12491
|
+
...e,
|
|
12492
|
+
{
|
|
12493
|
+
kind: "info",
|
|
12494
|
+
key: mkKey(),
|
|
12495
|
+
text: `auto-compacted: ${result.metrics.estimatedTokensBefore} \u2192 ${result.metrics.estimatedTokensAfter} tokens (${result.metrics.archivedArtifacts} artifacts)`
|
|
12496
|
+
}
|
|
12497
|
+
]);
|
|
12498
|
+
await saveSessionSafe();
|
|
12499
|
+
}
|
|
12500
|
+
const manager = memoryManagerRef.current;
|
|
12501
|
+
if (manager && !signal.aborted) {
|
|
12502
|
+
try {
|
|
12503
|
+
const cwd = process.cwd();
|
|
12504
|
+
const queryText = sessionStateRef.current.task || cwd;
|
|
12505
|
+
const results = await manager.recall({ text: queryText, repoPath: cwd, limit: 5 });
|
|
12506
|
+
if (results.length > 0 && !signal.aborted) {
|
|
12507
|
+
const text = await manager.synthesizeRecalled(results);
|
|
12508
|
+
const lastSystemIdx = result.newMessages.findLastIndex((m) => m.role === "system");
|
|
12509
|
+
const insertIdx = lastSystemIdx >= 0 ? lastSystemIdx + 1 : result.newMessages.length;
|
|
12510
|
+
result.newMessages.splice(insertIdx, 0, { role: "system", content: text });
|
|
12511
|
+
setEvents((e) => [
|
|
12512
|
+
...e,
|
|
12513
|
+
{
|
|
12514
|
+
kind: "memory",
|
|
12515
|
+
key: mkKey(),
|
|
12516
|
+
text: `recalled ${results.length} memory${results.length === 1 ? "" : "ies"} after compaction`
|
|
12517
|
+
}
|
|
12518
|
+
]);
|
|
12519
|
+
await saveSessionSafe();
|
|
12520
|
+
}
|
|
12521
|
+
} catch {
|
|
12522
|
+
}
|
|
12523
|
+
}
|
|
12524
|
+
return result.newMessages;
|
|
12525
|
+
}
|
|
12526
|
+
if (cfg && !signal.aborted) {
|
|
12527
|
+
try {
|
|
12528
|
+
const result = await compactMessages({
|
|
12529
|
+
accountId: cfg.accountId,
|
|
12530
|
+
apiToken: cfg.apiToken,
|
|
12531
|
+
model: cfg.model,
|
|
12532
|
+
messages,
|
|
12533
|
+
signal,
|
|
12534
|
+
gateway: gatewayFromConfig(cfg)
|
|
12535
|
+
});
|
|
12536
|
+
if (result.replacedCount > 0) {
|
|
12537
|
+
setEvents((e) => [
|
|
12538
|
+
...e,
|
|
12539
|
+
{
|
|
12540
|
+
kind: "info",
|
|
12541
|
+
key: mkKey(),
|
|
12542
|
+
text: `auto-compacted: ${result.replacedCount} messages summarized`
|
|
12543
|
+
}
|
|
12544
|
+
]);
|
|
12545
|
+
await saveSessionSafe();
|
|
12546
|
+
}
|
|
12547
|
+
return result.newMessages;
|
|
12548
|
+
} catch {
|
|
12549
|
+
}
|
|
12550
|
+
}
|
|
12551
|
+
return messages;
|
|
12552
|
+
},
|
|
12553
|
+
[cfg]
|
|
12554
|
+
);
|
|
12555
|
+
useInput6((inputChar, key) => {
|
|
11773
12556
|
if (key.ctrl && inputChar === "c") {
|
|
11774
12557
|
const hadPerm = permResolveRef.current !== null;
|
|
11775
12558
|
if (hadPerm) {
|
|
@@ -11812,10 +12595,6 @@ function App({
|
|
|
11812
12595
|
setVerbose((v) => !v);
|
|
11813
12596
|
return;
|
|
11814
12597
|
}
|
|
11815
|
-
if (key.ctrl && inputChar === "m") {
|
|
11816
|
-
setCodeMode((c) => !c);
|
|
11817
|
-
return;
|
|
11818
|
-
}
|
|
11819
12598
|
});
|
|
11820
12599
|
const flushAssistantUpdates = useCallback(() => {
|
|
11821
12600
|
flushTimeoutRef.current = null;
|
|
@@ -11967,7 +12746,7 @@ function App({
|
|
|
11967
12746
|
}
|
|
11968
12747
|
}, [cfg, busy, saveSessionSafe]);
|
|
11969
12748
|
const openResumePicker = useCallback(async () => {
|
|
11970
|
-
const sessions = await listSessions(200);
|
|
12749
|
+
const sessions = await listSessions(200, process.cwd());
|
|
11971
12750
|
setResumeSessions(sessions);
|
|
11972
12751
|
}, []);
|
|
11973
12752
|
const runInit = useCallback(async () => {
|
|
@@ -11977,7 +12756,7 @@ function App({
|
|
|
11977
12756
|
return;
|
|
11978
12757
|
}
|
|
11979
12758
|
const cwd = process.cwd();
|
|
11980
|
-
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find((n) => existsSync2(
|
|
12759
|
+
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find((n) => existsSync2(join19(cwd, n)));
|
|
11981
12760
|
const isRefresh = existingName !== void 0;
|
|
11982
12761
|
const promptParts = [
|
|
11983
12762
|
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.",
|
|
@@ -12002,6 +12781,15 @@ function App({
|
|
|
12002
12781
|
setTurnStartedAt(Date.now());
|
|
12003
12782
|
const controller = new AbortController();
|
|
12004
12783
|
activeControllerRef.current = controller;
|
|
12784
|
+
const initClassification = classifyIntent(prompt);
|
|
12785
|
+
const initEffortForTier = {
|
|
12786
|
+
light: "low",
|
|
12787
|
+
medium: "medium",
|
|
12788
|
+
heavy: "high"
|
|
12789
|
+
};
|
|
12790
|
+
const initReasoningEffort = initEffortForTier[initClassification.tier] ?? effortRef.current;
|
|
12791
|
+
const effectiveCodeMode = initClassification.tier === "heavy";
|
|
12792
|
+
setCodeMode(effectiveCodeMode);
|
|
12005
12793
|
try {
|
|
12006
12794
|
await runAgentTurn({
|
|
12007
12795
|
accountId: cfg.accountId,
|
|
@@ -12013,17 +12801,21 @@ function App({
|
|
|
12013
12801
|
executor: executorRef.current,
|
|
12014
12802
|
cwd,
|
|
12015
12803
|
signal: controller.signal,
|
|
12016
|
-
reasoningEffort:
|
|
12804
|
+
reasoningEffort: initReasoningEffort,
|
|
12805
|
+
intentClassification: initClassification,
|
|
12017
12806
|
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
12018
12807
|
sessionId: ensureSessionId(),
|
|
12019
12808
|
memoryManager: memoryManagerRef.current,
|
|
12020
|
-
codeMode,
|
|
12809
|
+
codeMode: effectiveCodeMode,
|
|
12810
|
+
maxInputTokens: effectiveCodeMode ? 2e5 : void 0,
|
|
12811
|
+
continueOnLimit: effectiveCodeMode ? true : void 0,
|
|
12812
|
+
onIterationEnd,
|
|
12021
12813
|
onFileChange: (path, content) => {
|
|
12022
12814
|
if (content) {
|
|
12023
12815
|
lspManagerRef.current.notifyChange(path, content);
|
|
12024
12816
|
} else {
|
|
12025
12817
|
void import("fs/promises").then(
|
|
12026
|
-
({ readFile:
|
|
12818
|
+
({ readFile: readFile16 }) => readFile16(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
|
|
12027
12819
|
})
|
|
12028
12820
|
);
|
|
12029
12821
|
}
|
|
@@ -12117,7 +12909,7 @@ function App({
|
|
|
12117
12909
|
})
|
|
12118
12910
|
}
|
|
12119
12911
|
});
|
|
12120
|
-
if (existsSync2(
|
|
12912
|
+
if (existsSync2(join19(cwd, "KIMI.md"))) {
|
|
12121
12913
|
if (cacheStableRef.current) {
|
|
12122
12914
|
messagesRef.current[1] = {
|
|
12123
12915
|
role: "system",
|
|
@@ -12164,6 +12956,7 @@ function App({
|
|
|
12164
12956
|
]);
|
|
12165
12957
|
}
|
|
12166
12958
|
} finally {
|
|
12959
|
+
setCodeMode(false);
|
|
12167
12960
|
const asstId = activeAsstIdRef.current;
|
|
12168
12961
|
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
12169
12962
|
setBusy(false);
|
|
@@ -12774,13 +13567,177 @@ ${lines.join("\n")}` }]);
|
|
|
12774
13567
|
]);
|
|
12775
13568
|
return true;
|
|
12776
13569
|
}
|
|
13570
|
+
if (c === "/remote") {
|
|
13571
|
+
if (arg === "status" || arg === "cancel") {
|
|
13572
|
+
setEvents((e) => [
|
|
13573
|
+
...e,
|
|
13574
|
+
{ kind: "info", key: mkKey(), text: `Use \`kimiflare remote ${arg}\` from your shell.` }
|
|
13575
|
+
]);
|
|
13576
|
+
return true;
|
|
13577
|
+
}
|
|
13578
|
+
const prompt = rest.join(" ").trim();
|
|
13579
|
+
if (!prompt) {
|
|
13580
|
+
setShowRemoteDashboard(true);
|
|
13581
|
+
return true;
|
|
13582
|
+
}
|
|
13583
|
+
const repo = detectGitHubRepo(cfg?.githubRepo);
|
|
13584
|
+
if (!repo) {
|
|
13585
|
+
setEvents((e) => [
|
|
13586
|
+
...e,
|
|
13587
|
+
{ kind: "info", key: mkKey(), text: "Could not detect GitHub repo. Run from a repo with a GitHub remote, or set githubRepo in config." }
|
|
13588
|
+
]);
|
|
13589
|
+
return true;
|
|
13590
|
+
}
|
|
13591
|
+
(async () => {
|
|
13592
|
+
if (!cfg?.remoteWorkerUrl) {
|
|
13593
|
+
setEvents((e) => [
|
|
13594
|
+
...e,
|
|
13595
|
+
{ kind: "info", key: mkKey(), text: "Remote infrastructure not deployed yet. Setting up now (~2 min)..." }
|
|
13596
|
+
]);
|
|
13597
|
+
try {
|
|
13598
|
+
for await (const step of deployForTui()) {
|
|
13599
|
+
setEvents((e) => [
|
|
13600
|
+
...e,
|
|
13601
|
+
{ kind: step.error ? "error" : "info", key: mkKey(), text: step.message }
|
|
13602
|
+
]);
|
|
13603
|
+
if (step.done) break;
|
|
13604
|
+
}
|
|
13605
|
+
} catch {
|
|
13606
|
+
setEvents((e) => [
|
|
13607
|
+
...e,
|
|
13608
|
+
{ kind: "error", key: mkKey(), text: "Deploy failed. Fix the issue above and try /remote again." }
|
|
13609
|
+
]);
|
|
13610
|
+
return;
|
|
13611
|
+
}
|
|
13612
|
+
const { loadConfig: reloadConfig } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
13613
|
+
const newCfg = await reloadConfig();
|
|
13614
|
+
if (newCfg) setCfg(newCfg);
|
|
13615
|
+
}
|
|
13616
|
+
const currentCfg = cfg ?? await loadConfig();
|
|
13617
|
+
if (!currentCfg?.remoteWorkerUrl) {
|
|
13618
|
+
setEvents((e) => [
|
|
13619
|
+
...e,
|
|
13620
|
+
{ kind: "error", key: mkKey(), text: "Deploy seemed to succeed but config wasn't saved. Try again." }
|
|
13621
|
+
]);
|
|
13622
|
+
return;
|
|
13623
|
+
}
|
|
13624
|
+
if (!currentCfg.githubOAuthToken) {
|
|
13625
|
+
setEvents((e) => [
|
|
13626
|
+
...e,
|
|
13627
|
+
{ kind: "info", key: mkKey(), text: "GitHub not authenticated. Starting OAuth device flow..." }
|
|
13628
|
+
]);
|
|
13629
|
+
try {
|
|
13630
|
+
for await (const step of authGitHubForTui()) {
|
|
13631
|
+
setEvents((e) => [
|
|
13632
|
+
...e,
|
|
13633
|
+
{ kind: step.error ? "error" : "info", key: mkKey(), text: step.message }
|
|
13634
|
+
]);
|
|
13635
|
+
if (step.done) break;
|
|
13636
|
+
}
|
|
13637
|
+
} catch {
|
|
13638
|
+
setEvents((e) => [
|
|
13639
|
+
...e,
|
|
13640
|
+
{ kind: "error", key: mkKey(), text: "GitHub auth failed. Try `kimiflare auth github` from shell." }
|
|
13641
|
+
]);
|
|
13642
|
+
return;
|
|
13643
|
+
}
|
|
13644
|
+
const { loadConfig: reloadConfig } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
13645
|
+
const newCfg = await reloadConfig();
|
|
13646
|
+
if (newCfg) setCfg(newCfg);
|
|
13647
|
+
}
|
|
13648
|
+
const finalCfg = await loadConfig() ?? currentCfg;
|
|
13649
|
+
const ttl = finalCfg.remoteTtlMinutes ?? 30;
|
|
13650
|
+
const budget = finalCfg.remoteMaxInputTokens ?? 5e6;
|
|
13651
|
+
setEvents((e) => [
|
|
13652
|
+
...e,
|
|
13653
|
+
{ kind: "info", key: mkKey(), text: `Starting remote session for ${repo.owner}/${repo.name}...` },
|
|
13654
|
+
{ kind: "info", key: mkKey(), text: `Budget: ${formatTokens3(budget)} tokens. TTL: ${ttl} min.` }
|
|
13655
|
+
]);
|
|
13656
|
+
try {
|
|
13657
|
+
const data = await startRemoteSession({
|
|
13658
|
+
prompt,
|
|
13659
|
+
repo,
|
|
13660
|
+
cfg: finalCfg,
|
|
13661
|
+
ttlMinutes: finalCfg.remoteTtlMinutes,
|
|
13662
|
+
tokensBudget: finalCfg.remoteMaxInputTokens
|
|
13663
|
+
});
|
|
13664
|
+
setEvents((e) => [
|
|
13665
|
+
...e,
|
|
13666
|
+
{ kind: "info", key: mkKey(), text: `Session started: ${data.sessionId}` }
|
|
13667
|
+
]);
|
|
13668
|
+
for await (const ev of streamRemoteProgress(
|
|
13669
|
+
finalCfg.remoteWorkerUrl,
|
|
13670
|
+
data.sessionId,
|
|
13671
|
+
activeControllerRef.current?.signal
|
|
13672
|
+
)) {
|
|
13673
|
+
const event = ev;
|
|
13674
|
+
if (event.type === "text_delta") {
|
|
13675
|
+
setEvents((e) => [
|
|
13676
|
+
...e,
|
|
13677
|
+
{ kind: "info", key: mkKey(), text: String(event.text ?? "") }
|
|
13678
|
+
]);
|
|
13679
|
+
} else if (event.type === "tool_call") {
|
|
13680
|
+
setEvents((e) => [
|
|
13681
|
+
...e,
|
|
13682
|
+
{ kind: "info", key: mkKey(), text: `\u2192 ${String(event.name ?? "")}` }
|
|
13683
|
+
]);
|
|
13684
|
+
} else if (event.type === "done") {
|
|
13685
|
+
const prUrl = event.prUrl;
|
|
13686
|
+
const tokensUsed = event.tokensUsed;
|
|
13687
|
+
const tokensBudget = event.tokensBudget;
|
|
13688
|
+
setEvents((e) => [
|
|
13689
|
+
...e,
|
|
13690
|
+
{ kind: "info", key: mkKey(), text: prUrl ? `Done \u2014 PR: ${prUrl}` : "Done" }
|
|
13691
|
+
]);
|
|
13692
|
+
await saveRemoteSession({
|
|
13693
|
+
sessionId: data.sessionId,
|
|
13694
|
+
prompt,
|
|
13695
|
+
repo: `${repo.owner}/${repo.name}`,
|
|
13696
|
+
workerUrl: finalCfg.remoteWorkerUrl,
|
|
13697
|
+
status: "done",
|
|
13698
|
+
prUrl,
|
|
13699
|
+
tokensUsed,
|
|
13700
|
+
tokensBudget,
|
|
13701
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13702
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13703
|
+
});
|
|
13704
|
+
} else if (event.type === "error") {
|
|
13705
|
+
const message2 = String(event.message ?? "");
|
|
13706
|
+
const category = event.category;
|
|
13707
|
+
setEvents((e) => [
|
|
13708
|
+
...e,
|
|
13709
|
+
{ kind: "error", key: mkKey(), text: `Remote error: ${message2}` }
|
|
13710
|
+
]);
|
|
13711
|
+
await saveRemoteSession({
|
|
13712
|
+
sessionId: data.sessionId,
|
|
13713
|
+
prompt,
|
|
13714
|
+
repo: `${repo.owner}/${repo.name}`,
|
|
13715
|
+
workerUrl: finalCfg.remoteWorkerUrl,
|
|
13716
|
+
status: "error",
|
|
13717
|
+
errorCategory: category ?? "unknown",
|
|
13718
|
+
errorSummary: message2,
|
|
13719
|
+
errorMessage: message2,
|
|
13720
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13721
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13722
|
+
});
|
|
13723
|
+
}
|
|
13724
|
+
}
|
|
13725
|
+
} catch (err) {
|
|
13726
|
+
setEvents((e) => [
|
|
13727
|
+
...e,
|
|
13728
|
+
{ kind: "error", key: mkKey(), text: `Failed: ${err instanceof Error ? err.message : String(err)}` }
|
|
13729
|
+
]);
|
|
13730
|
+
}
|
|
13731
|
+
})();
|
|
13732
|
+
return true;
|
|
13733
|
+
}
|
|
12777
13734
|
if (c === "/help") {
|
|
12778
13735
|
setShowHelpMenu(true);
|
|
12779
13736
|
return true;
|
|
12780
13737
|
}
|
|
12781
13738
|
return false;
|
|
12782
13739
|
},
|
|
12783
|
-
[cfg, exit, usage, effort, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg]
|
|
13740
|
+
[cfg, exit, usage, effort, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
|
|
12784
13741
|
);
|
|
12785
13742
|
const handleHelpCommand = useCallback(
|
|
12786
13743
|
(command) => {
|
|
@@ -12923,6 +13880,15 @@ ${lines.join("\n")}` }]);
|
|
|
12923
13880
|
gatewayMetaRef.current = null;
|
|
12924
13881
|
setGatewayMeta(null);
|
|
12925
13882
|
setTurnStartedAt(Date.now());
|
|
13883
|
+
const classification = classifyIntent(trimmed);
|
|
13884
|
+
const effortForTier = {
|
|
13885
|
+
light: "low",
|
|
13886
|
+
medium: "medium",
|
|
13887
|
+
heavy: "high"
|
|
13888
|
+
};
|
|
13889
|
+
const turnReasoningEffort = overrideEffort ?? effortForTier[classification.tier] ?? effortRef.current;
|
|
13890
|
+
const effectiveCodeMode = classification.tier === "heavy";
|
|
13891
|
+
setCodeMode(effectiveCodeMode);
|
|
12926
13892
|
const controller = new AbortController();
|
|
12927
13893
|
activeControllerRef.current = controller;
|
|
12928
13894
|
const sharedCallbacks = {
|
|
@@ -13036,18 +14002,22 @@ ${lines.join("\n")}` }]);
|
|
|
13036
14002
|
executor: executorRef.current,
|
|
13037
14003
|
cwd: process.cwd(),
|
|
13038
14004
|
signal: controller.signal,
|
|
13039
|
-
reasoningEffort:
|
|
14005
|
+
reasoningEffort: turnReasoningEffort,
|
|
13040
14006
|
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
13041
14007
|
sessionId: ensureSessionId(),
|
|
13042
14008
|
memoryManager: memoryManagerRef.current,
|
|
13043
14009
|
keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
|
|
13044
|
-
codeMode,
|
|
14010
|
+
codeMode: effectiveCodeMode,
|
|
14011
|
+
maxInputTokens: effectiveCodeMode ? 2e5 : void 0,
|
|
14012
|
+
continueOnLimit: effectiveCodeMode ? true : void 0,
|
|
14013
|
+
onIterationEnd,
|
|
14014
|
+
intentClassification: classification,
|
|
13045
14015
|
onFileChange: (path, content2) => {
|
|
13046
14016
|
if (content2) {
|
|
13047
14017
|
lspManagerRef.current.notifyChange(path, content2);
|
|
13048
14018
|
} else {
|
|
13049
14019
|
void import("fs/promises").then(
|
|
13050
|
-
({ readFile:
|
|
14020
|
+
({ readFile: readFile16 }) => readFile16(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
|
|
13051
14021
|
})
|
|
13052
14022
|
);
|
|
13053
14023
|
}
|
|
@@ -13169,6 +14139,7 @@ ${lines.join("\n")}` }]);
|
|
|
13169
14139
|
}
|
|
13170
14140
|
}
|
|
13171
14141
|
} finally {
|
|
14142
|
+
setCodeMode(false);
|
|
13172
14143
|
const asstId = activeAsstIdRef.current;
|
|
13173
14144
|
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
13174
14145
|
setBusy(false);
|
|
@@ -13181,7 +14152,7 @@ ${lines.join("\n")}` }]);
|
|
|
13181
14152
|
},
|
|
13182
14153
|
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta]
|
|
13183
14154
|
);
|
|
13184
|
-
|
|
14155
|
+
useEffect5(() => {
|
|
13185
14156
|
if (!busy && queue.length > 0) {
|
|
13186
14157
|
const next = queue[0];
|
|
13187
14158
|
setQueue((q) => q.slice(1));
|
|
@@ -13209,7 +14180,7 @@ ${lines.join("\n")}` }]);
|
|
|
13209
14180
|
[busy, processMessage]
|
|
13210
14181
|
);
|
|
13211
14182
|
submitRef.current = submit;
|
|
13212
|
-
|
|
14183
|
+
useEffect5(() => {
|
|
13213
14184
|
if (compactSuggestedRef.current) return;
|
|
13214
14185
|
if (usage && usage.prompt_tokens / CONTEXT_LIMIT >= AUTO_COMPACT_SUGGEST_PCT) {
|
|
13215
14186
|
compactSuggestedRef.current = true;
|
|
@@ -13224,7 +14195,7 @@ ${lines.join("\n")}` }]);
|
|
|
13224
14195
|
}
|
|
13225
14196
|
}, [usage]);
|
|
13226
14197
|
if (!cfg) {
|
|
13227
|
-
return /* @__PURE__ */
|
|
14198
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(
|
|
13228
14199
|
Onboarding,
|
|
13229
14200
|
{
|
|
13230
14201
|
onDone: (newCfg) => {
|
|
@@ -13238,10 +14209,42 @@ ${lines.join("\n")}` }]);
|
|
|
13238
14209
|
) });
|
|
13239
14210
|
}
|
|
13240
14211
|
if (resumeSessions !== null) {
|
|
13241
|
-
return /* @__PURE__ */
|
|
14212
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
|
|
14213
|
+
}
|
|
14214
|
+
if (showRemoteDashboard) {
|
|
14215
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx22(
|
|
14216
|
+
RemoteSessionDetail,
|
|
14217
|
+
{
|
|
14218
|
+
session: selectedRemoteSession,
|
|
14219
|
+
onBack: () => setSelectedRemoteSession(null),
|
|
14220
|
+
onCancel: async (session) => {
|
|
14221
|
+
try {
|
|
14222
|
+
const { cancelRemoteSession: cancelRemoteSession2 } = await Promise.resolve().then(() => (init_worker_client(), worker_client_exports));
|
|
14223
|
+
await cancelRemoteSession2(session.workerUrl, session.sessionId);
|
|
14224
|
+
setEvents((e) => [
|
|
14225
|
+
...e,
|
|
14226
|
+
{ kind: "info", key: mkKey(), text: `Cancelled session ${session.sessionId}` }
|
|
14227
|
+
]);
|
|
14228
|
+
} catch (err) {
|
|
14229
|
+
setEvents((e) => [
|
|
14230
|
+
...e,
|
|
14231
|
+
{ kind: "error", key: mkKey(), text: `Failed to cancel: ${err instanceof Error ? err.message : String(err)}` }
|
|
14232
|
+
]);
|
|
14233
|
+
}
|
|
14234
|
+
setSelectedRemoteSession(null);
|
|
14235
|
+
setShowRemoteDashboard(false);
|
|
14236
|
+
}
|
|
14237
|
+
}
|
|
14238
|
+
) : /* @__PURE__ */ jsx22(
|
|
14239
|
+
RemoteDashboard,
|
|
14240
|
+
{
|
|
14241
|
+
onSelect: (session) => setSelectedRemoteSession(session),
|
|
14242
|
+
onCancel: () => setShowRemoteDashboard(false)
|
|
14243
|
+
}
|
|
14244
|
+
) }) });
|
|
13242
14245
|
}
|
|
13243
14246
|
if (showHelpMenu) {
|
|
13244
|
-
return /* @__PURE__ */
|
|
14247
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
|
|
13245
14248
|
HelpMenu,
|
|
13246
14249
|
{
|
|
13247
14250
|
customCommands: customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({ name: c.name, description: c.description })),
|
|
@@ -13252,12 +14255,12 @@ ${lines.join("\n")}` }]);
|
|
|
13252
14255
|
) }) });
|
|
13253
14256
|
}
|
|
13254
14257
|
if (showLspWizard) {
|
|
13255
|
-
return /* @__PURE__ */
|
|
14258
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
|
|
13256
14259
|
LspWizard,
|
|
13257
14260
|
{
|
|
13258
14261
|
servers: cfg?.lspServers ?? {},
|
|
13259
14262
|
currentScope: lspScope,
|
|
13260
|
-
hasProjectDir: existsSync2(
|
|
14263
|
+
hasProjectDir: existsSync2(join19(process.cwd(), ".kimiflare")),
|
|
13261
14264
|
onDone: () => setShowLspWizard(false),
|
|
13262
14265
|
onSave: (servers, enabled, scope) => {
|
|
13263
14266
|
setCfg((c) => c ? { ...c, lspEnabled: enabled, lspServers: servers } : c);
|
|
@@ -13289,7 +14292,7 @@ ${lines.join("\n")}` }]);
|
|
|
13289
14292
|
) }) });
|
|
13290
14293
|
}
|
|
13291
14294
|
if (commandWizard) {
|
|
13292
|
-
return /* @__PURE__ */
|
|
14295
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
|
|
13293
14296
|
CommandWizard,
|
|
13294
14297
|
{
|
|
13295
14298
|
mode: commandWizard.mode,
|
|
@@ -13302,7 +14305,7 @@ ${lines.join("\n")}` }]);
|
|
|
13302
14305
|
) }) });
|
|
13303
14306
|
}
|
|
13304
14307
|
if (commandPicker) {
|
|
13305
|
-
return /* @__PURE__ */
|
|
14308
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
|
|
13306
14309
|
CommandPicker,
|
|
13307
14310
|
{
|
|
13308
14311
|
commands: customCommandsRef.current,
|
|
@@ -13320,15 +14323,15 @@ ${lines.join("\n")}` }]);
|
|
|
13320
14323
|
) }) });
|
|
13321
14324
|
}
|
|
13322
14325
|
if (commandToDelete) {
|
|
13323
|
-
return /* @__PURE__ */
|
|
13324
|
-
/* @__PURE__ */
|
|
14326
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
14327
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.accent, bold: true, children: [
|
|
13325
14328
|
"Delete /",
|
|
13326
14329
|
commandToDelete.name,
|
|
13327
14330
|
"?"
|
|
13328
14331
|
] }),
|
|
13329
|
-
/* @__PURE__ */
|
|
13330
|
-
/* @__PURE__ */
|
|
13331
|
-
|
|
14332
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: commandToDelete.filepath }),
|
|
14333
|
+
/* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
|
|
14334
|
+
SelectInput9,
|
|
13332
14335
|
{
|
|
13333
14336
|
items: [
|
|
13334
14337
|
{ label: "Yes, delete", value: "yes", key: "yes" },
|
|
@@ -13346,7 +14349,7 @@ ${lines.join("\n")}` }]);
|
|
|
13346
14349
|
] }) });
|
|
13347
14350
|
}
|
|
13348
14351
|
if (showCommandList) {
|
|
13349
|
-
return /* @__PURE__ */
|
|
14352
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
|
|
13350
14353
|
CommandList,
|
|
13351
14354
|
{
|
|
13352
14355
|
commands: customCommandsRef.current,
|
|
@@ -13355,12 +14358,12 @@ ${lines.join("\n")}` }]);
|
|
|
13355
14358
|
) }) });
|
|
13356
14359
|
}
|
|
13357
14360
|
if (showThemePicker) {
|
|
13358
|
-
return /* @__PURE__ */
|
|
14361
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(ThemePicker, { themes: themeList(), onPick: handleThemePick, onPreview: (t) => setTheme(t) }) }) });
|
|
13359
14362
|
}
|
|
13360
14363
|
const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
|
|
13361
|
-
return /* @__PURE__ */
|
|
13362
|
-
!hasConversation && events.length === 0 ? /* @__PURE__ */
|
|
13363
|
-
perm ? /* @__PURE__ */
|
|
14364
|
+
return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
14365
|
+
!hasConversation && events.length === 0 ? /* @__PURE__ */ jsx22(Welcome, { accountId: cfg.accountId }) : /* @__PURE__ */ jsx22(ChatView, { events, showReasoning, verbose }),
|
|
14366
|
+
perm ? /* @__PURE__ */ jsx22(
|
|
13364
14367
|
PermissionModal,
|
|
13365
14368
|
{
|
|
13366
14369
|
tool: perm.tool,
|
|
@@ -13371,8 +14374,8 @@ ${lines.join("\n")}` }]);
|
|
|
13371
14374
|
setPerm(null);
|
|
13372
14375
|
}
|
|
13373
14376
|
}
|
|
13374
|
-
) : /* @__PURE__ */
|
|
13375
|
-
tasks.length > 0 && /* @__PURE__ */
|
|
14377
|
+
) : /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginTop: 1, children: [
|
|
14378
|
+
tasks.length > 0 && /* @__PURE__ */ jsx22(
|
|
13376
14379
|
TaskList,
|
|
13377
14380
|
{
|
|
13378
14381
|
tasks,
|
|
@@ -13380,11 +14383,11 @@ ${lines.join("\n")}` }]);
|
|
|
13380
14383
|
tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
|
|
13381
14384
|
}
|
|
13382
14385
|
),
|
|
13383
|
-
queue.length > 0 && /* @__PURE__ */
|
|
14386
|
+
queue.length > 0 && /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
13384
14387
|
"\u23F3 ",
|
|
13385
14388
|
q.display
|
|
13386
14389
|
] }, `queue_${i}`)) }),
|
|
13387
|
-
/* @__PURE__ */
|
|
14390
|
+
/* @__PURE__ */ jsx22(
|
|
13388
14391
|
StatusBar,
|
|
13389
14392
|
{
|
|
13390
14393
|
model: cfg.model,
|
|
@@ -13401,7 +14404,7 @@ ${lines.join("\n")}` }]);
|
|
|
13401
14404
|
codeMode
|
|
13402
14405
|
}
|
|
13403
14406
|
),
|
|
13404
|
-
activePicker?.kind === "file" && /* @__PURE__ */
|
|
14407
|
+
activePicker?.kind === "file" && /* @__PURE__ */ jsx22(
|
|
13405
14408
|
FilePicker,
|
|
13406
14409
|
{
|
|
13407
14410
|
items: filteredFileItems,
|
|
@@ -13409,7 +14412,7 @@ ${lines.join("\n")}` }]);
|
|
|
13409
14412
|
query: pickerQuery ?? ""
|
|
13410
14413
|
}
|
|
13411
14414
|
),
|
|
13412
|
-
activePicker?.kind === "slash" && /* @__PURE__ */
|
|
14415
|
+
activePicker?.kind === "slash" && /* @__PURE__ */ jsx22(
|
|
13413
14416
|
SlashPicker,
|
|
13414
14417
|
{
|
|
13415
14418
|
items: filteredSlashItems,
|
|
@@ -13417,9 +14420,9 @@ ${lines.join("\n")}` }]);
|
|
|
13417
14420
|
query: pickerQuery ?? ""
|
|
13418
14421
|
}
|
|
13419
14422
|
),
|
|
13420
|
-
/* @__PURE__ */
|
|
13421
|
-
/* @__PURE__ */
|
|
13422
|
-
/* @__PURE__ */
|
|
14423
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, children: [
|
|
14424
|
+
/* @__PURE__ */ jsx22(Text21, { color: "#d699b6", children: "\u203A " }),
|
|
14425
|
+
/* @__PURE__ */ jsx22(
|
|
13423
14426
|
CustomTextInput,
|
|
13424
14427
|
{
|
|
13425
14428
|
value: input,
|
|
@@ -13476,7 +14479,7 @@ ${lines.join("\n")}` }]);
|
|
|
13476
14479
|
}
|
|
13477
14480
|
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null) {
|
|
13478
14481
|
const instance = render(
|
|
13479
|
-
/* @__PURE__ */
|
|
14482
|
+
/* @__PURE__ */ jsx22(
|
|
13480
14483
|
App,
|
|
13481
14484
|
{
|
|
13482
14485
|
initialCfg: cfg,
|
|
@@ -13517,7 +14520,13 @@ var init_app = __esm({
|
|
|
13517
14520
|
init_welcome();
|
|
13518
14521
|
init_help_menu();
|
|
13519
14522
|
init_config();
|
|
14523
|
+
init_worker_client();
|
|
14524
|
+
init_session_store();
|
|
14525
|
+
init_tui_deploy();
|
|
14526
|
+
init_tui_auth();
|
|
14527
|
+
init_remote_dashboard();
|
|
13520
14528
|
init_mode();
|
|
14529
|
+
init_classify();
|
|
13521
14530
|
init_sessions();
|
|
13522
14531
|
init_image();
|
|
13523
14532
|
init_usage_tracker();
|
|
@@ -13566,8 +14575,107 @@ init_system_prompt();
|
|
|
13566
14575
|
init_executor();
|
|
13567
14576
|
init_update_check();
|
|
13568
14577
|
init_version();
|
|
14578
|
+
import { Command as Command2 } from "commander";
|
|
14579
|
+
|
|
14580
|
+
// src/remote/cli.ts
|
|
14581
|
+
init_config();
|
|
14582
|
+
init_session_store();
|
|
14583
|
+
init_deploy();
|
|
13569
14584
|
import { Command } from "commander";
|
|
13570
|
-
|
|
14585
|
+
function createRemoteCommand() {
|
|
14586
|
+
const remote = new Command("remote").description("Manage remote sessions");
|
|
14587
|
+
remote.command("deploy").description("Deploy the remote Worker and container image to Cloudflare").action(async () => {
|
|
14588
|
+
await runDeploy();
|
|
14589
|
+
});
|
|
14590
|
+
remote.command("setup").description("Check remote deployment status and prerequisites").action(async () => {
|
|
14591
|
+
const status = await checkDeployStatus();
|
|
14592
|
+
console.log("Remote deployment status:\n");
|
|
14593
|
+
console.log(` wrangler CLI: ${status.wrangler ? "yes" : "no"}`);
|
|
14594
|
+
console.log(` wrangler auth: ${status.wranglerAuth ? "yes" : "no"}`);
|
|
14595
|
+
console.log(` Docker: ${status.docker ? "yes" : "no"}`);
|
|
14596
|
+
console.log(` Worker URL: ${status.workerUrl ?? "not deployed"}`);
|
|
14597
|
+
console.log("\nRun `kimiflare remote deploy` to deploy.");
|
|
14598
|
+
});
|
|
14599
|
+
remote.command("list").description("List remote sessions").action(async () => {
|
|
14600
|
+
const sessions = await listRemoteSessions();
|
|
14601
|
+
if (sessions.length === 0) {
|
|
14602
|
+
console.log("No remote sessions found.");
|
|
14603
|
+
return;
|
|
14604
|
+
}
|
|
14605
|
+
console.log(`Remote sessions (${sessions.length} total):
|
|
14606
|
+
`);
|
|
14607
|
+
for (const s of sessions.slice(0, 20)) {
|
|
14608
|
+
const date = new Date(s.createdAt).toLocaleString();
|
|
14609
|
+
const statusIcon = s.status === "done" ? "\u2705" : s.status === "error" ? "\u274C" : s.status === "running" ? "\u23F3" : "\u23F9\uFE0F";
|
|
14610
|
+
console.log(` ${statusIcon} ${s.sessionId.slice(0, 8)}\u2026 ${s.status.padEnd(10)} ${date} ${s.prompt.slice(0, 50)}`);
|
|
14611
|
+
if (s.prUrl) {
|
|
14612
|
+
console.log(` PR: ${s.prUrl}`);
|
|
14613
|
+
}
|
|
14614
|
+
}
|
|
14615
|
+
});
|
|
14616
|
+
remote.command("status").description("Show remote session status").argument("[session-id]", "Session ID (defaults to most recent)").action(async (sessionId) => {
|
|
14617
|
+
const session = sessionId ? await loadRemoteSession(sessionId) : await getMostRecentRemoteSession();
|
|
14618
|
+
if (!session) {
|
|
14619
|
+
console.log(sessionId ? `Session ${sessionId} not found.` : "No remote sessions found.");
|
|
14620
|
+
return;
|
|
14621
|
+
}
|
|
14622
|
+
const cfg = await loadConfig();
|
|
14623
|
+
const workerUrl = cfg?.remoteWorkerUrl;
|
|
14624
|
+
if (!workerUrl) {
|
|
14625
|
+
console.log("Remote worker not configured.");
|
|
14626
|
+
return;
|
|
14627
|
+
}
|
|
14628
|
+
try {
|
|
14629
|
+
const res = await fetch(`${workerUrl}/remote/status/${session.sessionId}`, {
|
|
14630
|
+
headers: {
|
|
14631
|
+
Authorization: `Bearer ${cfg.remoteAuthSecret ?? ""}`
|
|
14632
|
+
}
|
|
14633
|
+
});
|
|
14634
|
+
if (!res.ok) {
|
|
14635
|
+
console.log(`Failed to fetch status: ${res.status}`);
|
|
14636
|
+
return;
|
|
14637
|
+
}
|
|
14638
|
+
const data = await res.json();
|
|
14639
|
+
console.log(`Session: ${data.sessionId}`);
|
|
14640
|
+
console.log(`Status: ${data.status}`);
|
|
14641
|
+
console.log(`Prompt: ${data.prompt}`);
|
|
14642
|
+
console.log(`Repo: ${data.repo?.owner}/${data.repo?.name}`);
|
|
14643
|
+
console.log(`Branch: ${data.branch}`);
|
|
14644
|
+
console.log(`Turns: ${data.currentTurn} / ${data.maxTurns}`);
|
|
14645
|
+
if (data.prUrl) console.log(`PR: ${data.prUrl}`);
|
|
14646
|
+
if (data.errorMessage) console.log(`Error: ${data.errorMessage}`);
|
|
14647
|
+
} catch (err) {
|
|
14648
|
+
console.log(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
14649
|
+
}
|
|
14650
|
+
});
|
|
14651
|
+
remote.command("cancel").description("Cancel a remote session").argument("<session-id>", "Session ID").action(async (sessionId) => {
|
|
14652
|
+
const cfg = await loadConfig();
|
|
14653
|
+
const workerUrl = cfg?.remoteWorkerUrl;
|
|
14654
|
+
if (!workerUrl) {
|
|
14655
|
+
console.log("Remote worker not configured.");
|
|
14656
|
+
return;
|
|
14657
|
+
}
|
|
14658
|
+
try {
|
|
14659
|
+
const res = await fetch(`${workerUrl}/remote/cancel/${sessionId}`, {
|
|
14660
|
+
method: "POST",
|
|
14661
|
+
headers: {
|
|
14662
|
+
Authorization: `Bearer ${cfg.remoteAuthSecret ?? ""}`
|
|
14663
|
+
}
|
|
14664
|
+
});
|
|
14665
|
+
if (!res.ok) {
|
|
14666
|
+
console.log(`Failed to cancel: ${res.status}`);
|
|
14667
|
+
return;
|
|
14668
|
+
}
|
|
14669
|
+
console.log(`Session ${sessionId} cancelled.`);
|
|
14670
|
+
} catch (err) {
|
|
14671
|
+
console.log(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
14672
|
+
}
|
|
14673
|
+
});
|
|
14674
|
+
return remote;
|
|
14675
|
+
}
|
|
14676
|
+
|
|
14677
|
+
// src/index.tsx
|
|
14678
|
+
var program = new Command2();
|
|
13571
14679
|
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));
|
|
13572
14680
|
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) => {
|
|
13573
14681
|
const cfg = await loadConfig();
|
|
@@ -13581,6 +14689,23 @@ program.command("cost").description("Show cost attribution by task type (require
|
|
|
13581
14689
|
const { runCostCommand: runCostCommand2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
13582
14690
|
await runCostCommand2({ ...cmdOpts, config: cfg });
|
|
13583
14691
|
});
|
|
14692
|
+
program.addCommand(createRemoteCommand());
|
|
14693
|
+
program.command("auth").description("Authenticate with external services").addCommand(
|
|
14694
|
+
new Command2("github").description("Authenticate with GitHub via OAuth device flow").action(async () => {
|
|
14695
|
+
const { authGitHubForTui: authGitHubForTui2 } = await Promise.resolve().then(() => (init_tui_auth(), tui_auth_exports));
|
|
14696
|
+
for await (const step of authGitHubForTui2()) {
|
|
14697
|
+
console.log(step.message);
|
|
14698
|
+
if (step.url && step.code) {
|
|
14699
|
+
console.log(`
|
|
14700
|
+
Open: ${step.url}`);
|
|
14701
|
+
console.log(`Code: ${step.code}
|
|
14702
|
+
`);
|
|
14703
|
+
}
|
|
14704
|
+
if (step.done) break;
|
|
14705
|
+
if (step.error) process.exit(1);
|
|
14706
|
+
}
|
|
14707
|
+
})
|
|
14708
|
+
);
|
|
13584
14709
|
program.action(async () => {
|
|
13585
14710
|
await main();
|
|
13586
14711
|
});
|