kimiflare 0.35.0 → 0.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1312 -554
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
3
9
|
var __esm = (fn, res) => function __init() {
|
|
4
10
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
11
|
};
|
|
@@ -321,10 +327,8 @@ async function* readSSE(stream, signal) {
|
|
|
321
327
|
const decoder = new TextDecoder("utf-8");
|
|
322
328
|
let buffer = "";
|
|
323
329
|
const onAbort = () => {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
} catch {
|
|
327
|
-
}
|
|
330
|
+
reader.cancel(new DOMException("aborted", "AbortError")).catch(() => {
|
|
331
|
+
});
|
|
328
332
|
};
|
|
329
333
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
330
334
|
try {
|
|
@@ -479,6 +483,9 @@ function isRetryable(err, attempt) {
|
|
|
479
483
|
return false;
|
|
480
484
|
}
|
|
481
485
|
async function* runKimi(opts2) {
|
|
486
|
+
if (opts2.cloudMode && !opts2.cloudToken) {
|
|
487
|
+
throw new KimiApiError("kimiflare: cloud mode requires a cloud token. Run `kimiflare auth cloud` to authenticate.", void 0, 401);
|
|
488
|
+
}
|
|
482
489
|
const { url, headers: gatewayHeaders } = buildKimiRequestTarget(opts2);
|
|
483
490
|
const body = {
|
|
484
491
|
messages: sanitizeMessagesForApi(opts2.messages),
|
|
@@ -1402,6 +1409,11 @@ function stripTypescript(code) {
|
|
|
1402
1409
|
return js.trim();
|
|
1403
1410
|
}
|
|
1404
1411
|
async function loadTypescript(cwd) {
|
|
1412
|
+
try {
|
|
1413
|
+
const tsPath = await import.meta.resolve("typescript");
|
|
1414
|
+
return await import(tsPath);
|
|
1415
|
+
} catch {
|
|
1416
|
+
}
|
|
1405
1417
|
let dir = cwd;
|
|
1406
1418
|
while (dir !== dirname3(dir)) {
|
|
1407
1419
|
try {
|
|
@@ -1669,7 +1681,18 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1669
1681
|
});
|
|
1670
1682
|
}
|
|
1671
1683
|
if (iter >= max) {
|
|
1672
|
-
if (opts2.
|
|
1684
|
+
if (opts2.callbacks.onToolLimitReached) {
|
|
1685
|
+
const decision = await opts2.callbacks.onToolLimitReached();
|
|
1686
|
+
if (decision === "continue") {
|
|
1687
|
+
opts2.messages.push({
|
|
1688
|
+
role: "system",
|
|
1689
|
+
content: "You have reached the tool-call limit for this session. The counter has been reset so you can continue working. Please proceed with your task."
|
|
1690
|
+
});
|
|
1691
|
+
iter = 0;
|
|
1692
|
+
} else {
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1695
|
+
} else if (opts2.continueOnLimit) {
|
|
1673
1696
|
opts2.messages.push({
|
|
1674
1697
|
role: "system",
|
|
1675
1698
|
content: "You have reached the tool-call limit for this session. The counter has been reset so you can continue working. Please proceed with your task."
|
|
@@ -4614,9 +4637,16 @@ var init_cli = __esm({
|
|
|
4614
4637
|
// src/cloud/auth.ts
|
|
4615
4638
|
var auth_exports = {};
|
|
4616
4639
|
__export(auth_exports, {
|
|
4640
|
+
CLOUD_API_URL: () => CLOUD_API_URL,
|
|
4641
|
+
POLL_INTERVAL_MS: () => POLL_INTERVAL_MS,
|
|
4642
|
+
POLL_TIMEOUT_MS: () => POLL_TIMEOUT_MS,
|
|
4617
4643
|
authenticateDevice: () => authenticateDevice,
|
|
4618
4644
|
clearCloudCredentials: () => clearCloudCredentials,
|
|
4645
|
+
fetchCloudUsage: () => fetchCloudUsage,
|
|
4646
|
+
generateDeviceCodes: () => generateDeviceCodes,
|
|
4619
4647
|
loadCloudCredentials: () => loadCloudCredentials,
|
|
4648
|
+
pollForToken: () => pollForToken,
|
|
4649
|
+
registerDevice: () => registerDevice,
|
|
4620
4650
|
saveCloudCredentials: () => saveCloudCredentials
|
|
4621
4651
|
});
|
|
4622
4652
|
import { readFile as readFile11, writeFile as writeFile7 } from "fs/promises";
|
|
@@ -4634,6 +4664,58 @@ function generateCode() {
|
|
|
4634
4664
|
}
|
|
4635
4665
|
return out;
|
|
4636
4666
|
}
|
|
4667
|
+
function generateDeviceCodes() {
|
|
4668
|
+
const deviceCode = `device-${generateCode()}-${Date.now()}`;
|
|
4669
|
+
const userCode = `${generateCode()}-${generateCode()}`;
|
|
4670
|
+
const authUrl = `${CLOUD_API_URL}/auth/github?code=${encodeURIComponent(userCode)}`;
|
|
4671
|
+
return { deviceCode, userCode, authUrl };
|
|
4672
|
+
}
|
|
4673
|
+
async function registerDevice(codes) {
|
|
4674
|
+
const registerRes = await fetch(`${CLOUD_API_URL}/auth/device`, {
|
|
4675
|
+
method: "POST",
|
|
4676
|
+
headers: { "Content-Type": "application/json" },
|
|
4677
|
+
body: JSON.stringify({ device_code: codes.deviceCode, user_code: codes.userCode })
|
|
4678
|
+
});
|
|
4679
|
+
if (!registerRes.ok) {
|
|
4680
|
+
const err = await registerRes.json().catch(() => ({}));
|
|
4681
|
+
throw new Error(`Failed to register device: ${err.error || registerRes.statusText}`);
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
async function pollForToken(deviceCode) {
|
|
4685
|
+
const pollRes = await fetch(`${CLOUD_API_URL}/auth/poll`, {
|
|
4686
|
+
method: "POST",
|
|
4687
|
+
headers: { "Content-Type": "application/json" },
|
|
4688
|
+
body: JSON.stringify({ device_code: deviceCode })
|
|
4689
|
+
});
|
|
4690
|
+
if (!pollRes.ok) return null;
|
|
4691
|
+
const pollData = await pollRes.json();
|
|
4692
|
+
if (pollData.status === "approved" && pollData.access_token) {
|
|
4693
|
+
const creds = {
|
|
4694
|
+
accessToken: pollData.access_token,
|
|
4695
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 7 * 24 * 60 * 60
|
|
4696
|
+
// 7 days
|
|
4697
|
+
};
|
|
4698
|
+
await saveCloudCredentials(creds);
|
|
4699
|
+
return creds;
|
|
4700
|
+
}
|
|
4701
|
+
return null;
|
|
4702
|
+
}
|
|
4703
|
+
async function fetchCloudUsage(token) {
|
|
4704
|
+
const res = await fetch(`${CLOUD_API_URL}/v1/usage`, {
|
|
4705
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
4706
|
+
});
|
|
4707
|
+
if (!res.ok) return null;
|
|
4708
|
+
const data = await res.json();
|
|
4709
|
+
if (typeof data.remaining !== "number" || typeof data.input_token_limit !== "number" || typeof data.input_tokens_used !== "number" || typeof data.expires_at !== "string") {
|
|
4710
|
+
return null;
|
|
4711
|
+
}
|
|
4712
|
+
return {
|
|
4713
|
+
input_token_limit: data.input_token_limit,
|
|
4714
|
+
input_tokens_used: data.input_tokens_used,
|
|
4715
|
+
remaining: data.remaining,
|
|
4716
|
+
expires_at: data.expires_at
|
|
4717
|
+
};
|
|
4718
|
+
}
|
|
4637
4719
|
async function loadCloudCredentials() {
|
|
4638
4720
|
try {
|
|
4639
4721
|
const raw = await readFile11(cloudCredPath(), "utf8");
|
|
@@ -4657,39 +4739,15 @@ async function clearCloudCredentials() {
|
|
|
4657
4739
|
}
|
|
4658
4740
|
}
|
|
4659
4741
|
async function authenticateDevice(onStatus) {
|
|
4660
|
-
const
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
method: "POST",
|
|
4664
|
-
headers: { "Content-Type": "application/json" },
|
|
4665
|
-
body: JSON.stringify({ device_code: deviceCode, user_code: userCode })
|
|
4666
|
-
});
|
|
4667
|
-
if (!registerRes.ok) {
|
|
4668
|
-
const err = await registerRes.json().catch(() => ({}));
|
|
4669
|
-
throw new Error(`Failed to register device: ${err.error || registerRes.statusText}`);
|
|
4670
|
-
}
|
|
4671
|
-
const authUrl = `${CLOUD_API_URL}/auth/github?code=${encodeURIComponent(userCode)}`;
|
|
4672
|
-
onStatus({ url: authUrl, userCode, polling: false });
|
|
4742
|
+
const codes = generateDeviceCodes();
|
|
4743
|
+
await registerDevice(codes);
|
|
4744
|
+
onStatus({ url: codes.authUrl, userCode: codes.userCode, polling: false });
|
|
4673
4745
|
const startTime = Date.now();
|
|
4674
4746
|
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
4675
4747
|
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
4676
|
-
onStatus({ url: authUrl, userCode, polling: true });
|
|
4677
|
-
const
|
|
4678
|
-
|
|
4679
|
-
headers: { "Content-Type": "application/json" },
|
|
4680
|
-
body: JSON.stringify({ device_code: deviceCode })
|
|
4681
|
-
});
|
|
4682
|
-
if (!pollRes.ok) continue;
|
|
4683
|
-
const pollData = await pollRes.json();
|
|
4684
|
-
if (pollData.status === "approved" && pollData.access_token) {
|
|
4685
|
-
const creds = {
|
|
4686
|
-
accessToken: pollData.access_token,
|
|
4687
|
-
expiresAt: Math.floor(Date.now() / 1e3) + 7 * 24 * 60 * 60
|
|
4688
|
-
// 7 days
|
|
4689
|
-
};
|
|
4690
|
-
await saveCloudCredentials(creds);
|
|
4691
|
-
return creds;
|
|
4692
|
-
}
|
|
4748
|
+
onStatus({ url: codes.authUrl, userCode: codes.userCode, polling: true });
|
|
4749
|
+
const creds = await pollForToken(codes.deviceCode);
|
|
4750
|
+
if (creds) return creds;
|
|
4693
4751
|
}
|
|
4694
4752
|
throw new Error("Authentication timed out. Please try again.");
|
|
4695
4753
|
}
|
|
@@ -4699,7 +4757,7 @@ var init_auth = __esm({
|
|
|
4699
4757
|
"use strict";
|
|
4700
4758
|
CLOUD_API_URL = "https://api.kimiflare.com";
|
|
4701
4759
|
POLL_INTERVAL_MS = 5e3;
|
|
4702
|
-
POLL_TIMEOUT_MS =
|
|
4760
|
+
POLL_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
4703
4761
|
}
|
|
4704
4762
|
});
|
|
4705
4763
|
|
|
@@ -6754,7 +6812,7 @@ import { useEffect, useState } from "react";
|
|
|
6754
6812
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
6755
6813
|
import Spinner3 from "ink-spinner";
|
|
6756
6814
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
6757
|
-
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode }) {
|
|
6815
|
+
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget }) {
|
|
6758
6816
|
const theme = useTheme();
|
|
6759
6817
|
const [now2, setNow] = useState(Date.now());
|
|
6760
6818
|
const modeColor = mode === "plan" ? theme.modeBadge.plan : mode === "auto" ? theme.modeBadge.auto : theme.modeBadge.edit;
|
|
@@ -6787,7 +6845,7 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
6787
6845
|
] })
|
|
6788
6846
|
] }),
|
|
6789
6847
|
usage && /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
6790
|
-
/* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta).join(" \xB7 ") }),
|
|
6848
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
|
|
6791
6849
|
warn ? /* @__PURE__ */ jsxs5(Text5, { color: theme.warn, bold: true, children: [
|
|
6792
6850
|
" \xB7 ",
|
|
6793
6851
|
"/compact recommended"
|
|
@@ -6801,7 +6859,7 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
6801
6859
|
] })
|
|
6802
6860
|
] });
|
|
6803
6861
|
}
|
|
6804
|
-
function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta) {
|
|
6862
|
+
function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget) {
|
|
6805
6863
|
const pct = Math.round(usage.prompt_tokens / contextLimit * 100);
|
|
6806
6864
|
const parts = [];
|
|
6807
6865
|
if (sessionUsage) {
|
|
@@ -6809,19 +6867,35 @@ function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta) {
|
|
|
6809
6867
|
parts.push(`in ${sessionUsage.promptTokens}${cached ? ` (${cached} cached)` : ""}`);
|
|
6810
6868
|
parts.push(`out ${sessionUsage.completionTokens}`);
|
|
6811
6869
|
parts.push(`ctx ${pct}%`);
|
|
6812
|
-
|
|
6870
|
+
if (cloudMode) {
|
|
6871
|
+
parts.push(`\x1B[9m${sessionUsage.cost.toFixed(5)}\x1B[29m`);
|
|
6872
|
+
} else {
|
|
6873
|
+
parts.push(`${sessionUsage.cost.toFixed(5)}`);
|
|
6874
|
+
}
|
|
6813
6875
|
} else {
|
|
6814
6876
|
const cached = usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
6815
6877
|
const cost = calculateCost(usage.prompt_tokens, usage.completion_tokens, cached);
|
|
6816
6878
|
parts.push(`in ${usage.prompt_tokens}${cached ? ` (${cached} cached)` : ""}`);
|
|
6817
6879
|
parts.push(`out ${usage.completion_tokens}`);
|
|
6818
6880
|
parts.push(`ctx ${pct}%`);
|
|
6819
|
-
|
|
6881
|
+
if (cloudMode) {
|
|
6882
|
+
parts.push(`\x1B[9m${cost.total.toFixed(5)}\x1B[29m`);
|
|
6883
|
+
} else {
|
|
6884
|
+
parts.push(`${cost.total.toFixed(5)}`);
|
|
6885
|
+
}
|
|
6886
|
+
}
|
|
6887
|
+
if (cloudMode && cloudBudget) {
|
|
6888
|
+
parts.push(`${formatTokens(cloudBudget.remaining)}/${formatTokens(cloudBudget.limit)} tokens`);
|
|
6820
6889
|
}
|
|
6821
6890
|
const gatewayCache = formatGatewayCacheStatus(gatewayMeta);
|
|
6822
6891
|
if (gatewayCache) parts.push(gatewayCache);
|
|
6823
6892
|
return parts;
|
|
6824
6893
|
}
|
|
6894
|
+
function formatTokens(n) {
|
|
6895
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
6896
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
6897
|
+
return String(n);
|
|
6898
|
+
}
|
|
6825
6899
|
function formatGatewayCacheStatus(gatewayMeta) {
|
|
6826
6900
|
const status = gatewayMeta?.cacheStatus?.trim();
|
|
6827
6901
|
return status ? `AI Gateway \xB7 cache ${status.toLowerCase()}` : null;
|
|
@@ -6882,11 +6956,48 @@ var init_permission = __esm({
|
|
|
6882
6956
|
}
|
|
6883
6957
|
});
|
|
6884
6958
|
|
|
6885
|
-
// src/ui/
|
|
6886
|
-
import {
|
|
6887
|
-
import { Box as Box7, Text as Text7, useWindowSize } from "ink";
|
|
6959
|
+
// src/ui/limit-modal.tsx
|
|
6960
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
6888
6961
|
import SelectInput2 from "ink-select-input";
|
|
6889
6962
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
6963
|
+
function LimitModal({ limit, onDecide }) {
|
|
6964
|
+
const theme = useTheme();
|
|
6965
|
+
const items = [
|
|
6966
|
+
{ label: "Continue", value: "continue" },
|
|
6967
|
+
{ label: "Stop", value: "stop" }
|
|
6968
|
+
];
|
|
6969
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
|
|
6970
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.error, bold: true, children: [
|
|
6971
|
+
"Tool-call limit reached (",
|
|
6972
|
+
limit,
|
|
6973
|
+
")"
|
|
6974
|
+
] }),
|
|
6975
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
6976
|
+
"This session has made ",
|
|
6977
|
+
limit,
|
|
6978
|
+
" tool calls. What would you like to do?"
|
|
6979
|
+
] }),
|
|
6980
|
+
/* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
6981
|
+
SelectInput2,
|
|
6982
|
+
{
|
|
6983
|
+
items,
|
|
6984
|
+
onSelect: (item) => onDecide(item.value)
|
|
6985
|
+
}
|
|
6986
|
+
) })
|
|
6987
|
+
] });
|
|
6988
|
+
}
|
|
6989
|
+
var init_limit_modal = __esm({
|
|
6990
|
+
"src/ui/limit-modal.tsx"() {
|
|
6991
|
+
"use strict";
|
|
6992
|
+
init_theme_context();
|
|
6993
|
+
}
|
|
6994
|
+
});
|
|
6995
|
+
|
|
6996
|
+
// src/ui/resume-picker.tsx
|
|
6997
|
+
import { useState as useState2 } from "react";
|
|
6998
|
+
import { Box as Box8, Text as Text8, useWindowSize } from "ink";
|
|
6999
|
+
import SelectInput3 from "ink-select-input";
|
|
7000
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6890
7001
|
function ResumePicker({ sessions, onPick }) {
|
|
6891
7002
|
const theme = useTheme();
|
|
6892
7003
|
const { rows } = useWindowSize();
|
|
@@ -6895,11 +7006,11 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
6895
7006
|
const totalPages = Math.max(1, Math.ceil(sessions.length / pageSize));
|
|
6896
7007
|
const safePage = Math.min(page, totalPages - 1);
|
|
6897
7008
|
if (sessions.length === 0) {
|
|
6898
|
-
return /* @__PURE__ */
|
|
6899
|
-
/* @__PURE__ */
|
|
6900
|
-
/* @__PURE__ */
|
|
6901
|
-
/* @__PURE__ */
|
|
6902
|
-
|
|
7009
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
7010
|
+
/* @__PURE__ */ jsx9(Text8, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
7011
|
+
/* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
|
|
7012
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(
|
|
7013
|
+
SelectInput3,
|
|
6903
7014
|
{
|
|
6904
7015
|
items: [{ label: "(back)", value: "__cancel__" }],
|
|
6905
7016
|
onSelect: () => onPick(null)
|
|
@@ -6921,9 +7032,9 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
6921
7032
|
items.push({ label: "\u2192 next page", value: "__next__" });
|
|
6922
7033
|
}
|
|
6923
7034
|
items.push({ label: "(cancel)", value: "__cancel__" });
|
|
6924
|
-
return /* @__PURE__ */
|
|
6925
|
-
/* @__PURE__ */
|
|
6926
|
-
/* @__PURE__ */
|
|
7035
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
7036
|
+
/* @__PURE__ */ jsx9(Text8, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
7037
|
+
/* @__PURE__ */ jsxs8(Text8, { color: theme.info.color, children: [
|
|
6927
7038
|
"Arrow keys to select, Enter to confirm. Page ",
|
|
6928
7039
|
safePage + 1,
|
|
6929
7040
|
" of ",
|
|
@@ -6932,8 +7043,8 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
6932
7043
|
sessions.length,
|
|
6933
7044
|
" total)"
|
|
6934
7045
|
] }),
|
|
6935
|
-
/* @__PURE__ */
|
|
6936
|
-
|
|
7046
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(
|
|
7047
|
+
SelectInput3,
|
|
6937
7048
|
{
|
|
6938
7049
|
items,
|
|
6939
7050
|
onSelect: (item) => {
|
|
@@ -6973,9 +7084,9 @@ var init_resume_picker = __esm({
|
|
|
6973
7084
|
|
|
6974
7085
|
// src/ui/task-list.tsx
|
|
6975
7086
|
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
6976
|
-
import { Box as
|
|
7087
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
6977
7088
|
import Spinner4 from "ink-spinner";
|
|
6978
|
-
import { jsx as
|
|
7089
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
6979
7090
|
function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
6980
7091
|
const theme = useTheme();
|
|
6981
7092
|
const [now2, setNow] = useState3(Date.now());
|
|
@@ -6999,21 +7110,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
6999
7110
|
const allDone = done === total;
|
|
7000
7111
|
const header = active ? active.title : allDone ? `${total} tasks done` : `${done}/${total}`;
|
|
7001
7112
|
const elapsed = startedAt ? formatElapsed2(now2 - startedAt) : null;
|
|
7002
|
-
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${
|
|
7113
|
+
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens2(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
|
|
7003
7114
|
const visibleTasks = tasks.slice(0, MAX_VISIBLE);
|
|
7004
7115
|
const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
|
|
7005
|
-
return /* @__PURE__ */
|
|
7006
|
-
/* @__PURE__ */
|
|
7007
|
-
/* @__PURE__ */
|
|
7008
|
-
headerStats && /* @__PURE__ */
|
|
7116
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginBottom: 1, children: [
|
|
7117
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
7118
|
+
/* @__PURE__ */ jsx10(Text9, { color: allDone ? "green" : theme.accent, bold: true, children: header }),
|
|
7119
|
+
headerStats && /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7009
7120
|
" ",
|
|
7010
7121
|
"(",
|
|
7011
7122
|
headerStats,
|
|
7012
7123
|
")"
|
|
7013
7124
|
] })
|
|
7014
7125
|
] }),
|
|
7015
|
-
visibleTasks.map((t) => /* @__PURE__ */
|
|
7016
|
-
hiddenPending > 0 && /* @__PURE__ */
|
|
7126
|
+
visibleTasks.map((t) => /* @__PURE__ */ jsx10(TaskRow, { task: t }, t.id)),
|
|
7127
|
+
hiddenPending > 0 && /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7017
7128
|
" ",
|
|
7018
7129
|
"\u2026 +",
|
|
7019
7130
|
hiddenPending,
|
|
@@ -7024,21 +7135,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
7024
7135
|
function TaskRow({ task }) {
|
|
7025
7136
|
const theme = useTheme();
|
|
7026
7137
|
if (task.status === "completed") {
|
|
7027
|
-
return /* @__PURE__ */
|
|
7138
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7028
7139
|
" ",
|
|
7029
7140
|
"\u2713 ",
|
|
7030
|
-
/* @__PURE__ */
|
|
7141
|
+
/* @__PURE__ */ jsx10(Text9, { strikethrough: true, children: task.title })
|
|
7031
7142
|
] });
|
|
7032
7143
|
}
|
|
7033
7144
|
if (task.status === "in_progress") {
|
|
7034
|
-
return /* @__PURE__ */
|
|
7145
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.accent, bold: true, children: [
|
|
7035
7146
|
" ",
|
|
7036
|
-
/* @__PURE__ */
|
|
7147
|
+
/* @__PURE__ */ jsx10(Spinner4, { type: "dots" }),
|
|
7037
7148
|
" ",
|
|
7038
7149
|
task.title
|
|
7039
7150
|
] });
|
|
7040
7151
|
}
|
|
7041
|
-
return /* @__PURE__ */
|
|
7152
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7042
7153
|
" ",
|
|
7043
7154
|
"\u2610 ",
|
|
7044
7155
|
task.title
|
|
@@ -7051,7 +7162,7 @@ function formatElapsed2(ms) {
|
|
|
7051
7162
|
if (m === 0) return `${s}s`;
|
|
7052
7163
|
return `${m}m ${s}s`;
|
|
7053
7164
|
}
|
|
7054
|
-
function
|
|
7165
|
+
function formatTokens2(n) {
|
|
7055
7166
|
if (n < 1e3) return String(n);
|
|
7056
7167
|
return `${(n / 1e3).toFixed(1)}k`;
|
|
7057
7168
|
}
|
|
@@ -7586,8 +7697,8 @@ var init_source = __esm({
|
|
|
7586
7697
|
|
|
7587
7698
|
// src/ui/text-input.tsx
|
|
7588
7699
|
import { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
7589
|
-
import { Text as
|
|
7590
|
-
import { jsx as
|
|
7700
|
+
import { Text as Text10, useInput } from "ink";
|
|
7701
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
7591
7702
|
function shouldTreatAsPaste(input) {
|
|
7592
7703
|
if (input.length >= PASTE_CHAR_THRESHOLD) return true;
|
|
7593
7704
|
const newlines = (input.match(/\n/g) ?? []).length;
|
|
@@ -7797,7 +7908,7 @@ function CustomTextInput({
|
|
|
7797
7908
|
} else if (cursorOffset === displayValue.length) {
|
|
7798
7909
|
renderedValue += source_default.inverse(" ");
|
|
7799
7910
|
}
|
|
7800
|
-
return /* @__PURE__ */
|
|
7911
|
+
return /* @__PURE__ */ jsx11(Text10, { children: renderedValue });
|
|
7801
7912
|
}
|
|
7802
7913
|
function findPasteTokenEndingAt(value, pos, pastes) {
|
|
7803
7914
|
if (pos <= 0 || value[pos - 1] !== "]") return -1;
|
|
@@ -7819,11 +7930,28 @@ var init_text_input = __esm({
|
|
|
7819
7930
|
});
|
|
7820
7931
|
|
|
7821
7932
|
// src/ui/onboarding.tsx
|
|
7822
|
-
import { useState as useState5 } from "react";
|
|
7823
|
-
import { Box as
|
|
7824
|
-
import
|
|
7825
|
-
import
|
|
7826
|
-
|
|
7933
|
+
import { useState as useState5, useEffect as useEffect4, useCallback } from "react";
|
|
7934
|
+
import { Box as Box10, Text as Text11, useInput as useInput2 } from "ink";
|
|
7935
|
+
import SelectInput4 from "ink-select-input";
|
|
7936
|
+
import Spinner5 from "ink-spinner";
|
|
7937
|
+
import { exec } from "child_process";
|
|
7938
|
+
import { promisify as promisify2 } from "util";
|
|
7939
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
7940
|
+
function openBrowser(url) {
|
|
7941
|
+
const platform3 = process.platform;
|
|
7942
|
+
const cmd = platform3 === "darwin" ? `open "${url}"` : platform3 === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
|
|
7943
|
+
exec(cmd, (err) => {
|
|
7944
|
+
if (err) {
|
|
7945
|
+
}
|
|
7946
|
+
});
|
|
7947
|
+
}
|
|
7948
|
+
function formatRemaining(ms) {
|
|
7949
|
+
const totalSeconds = Math.ceil(ms / 1e3);
|
|
7950
|
+
const mins = Math.floor(totalSeconds / 60);
|
|
7951
|
+
const secs = totalSeconds % 60;
|
|
7952
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
7953
|
+
}
|
|
7954
|
+
function Onboarding({ onDone, onCancel }) {
|
|
7827
7955
|
const theme = useTheme();
|
|
7828
7956
|
const [step, setStep] = useState5("mode");
|
|
7829
7957
|
const [mode, setMode] = useState5("byok");
|
|
@@ -7831,15 +7959,109 @@ function Onboarding({ onDone }) {
|
|
|
7831
7959
|
const [apiToken, setApiToken] = useState5("");
|
|
7832
7960
|
const [model, setModel] = useState5(DEFAULT_MODEL);
|
|
7833
7961
|
const [savedPath, setSavedPath] = useState5(null);
|
|
7962
|
+
const [cloudAuth, setCloudAuth] = useState5(null);
|
|
7963
|
+
const [pollTick, setPollTick] = useState5(0);
|
|
7964
|
+
useEffect4(() => {
|
|
7965
|
+
if (step !== "cloudAuth" || !cloudAuth) return;
|
|
7966
|
+
if (cloudAuth.phase !== "polling") return;
|
|
7967
|
+
let cancelled = false;
|
|
7968
|
+
const tick = setInterval(() => {
|
|
7969
|
+
setPollTick((t) => t + 1);
|
|
7970
|
+
}, 1e3);
|
|
7971
|
+
const poll = async () => {
|
|
7972
|
+
while (!cancelled) {
|
|
7973
|
+
const elapsed = Date.now() - cloudAuth.startTime;
|
|
7974
|
+
if (elapsed >= POLL_TIMEOUT_MS) {
|
|
7975
|
+
if (!cancelled) {
|
|
7976
|
+
setCloudAuth({ phase: "error", message: "Authentication timed out. Please try again." });
|
|
7977
|
+
}
|
|
7978
|
+
return;
|
|
7979
|
+
}
|
|
7980
|
+
try {
|
|
7981
|
+
const creds = await pollForToken(cloudAuth.codes.deviceCode);
|
|
7982
|
+
if (creds && !cancelled) {
|
|
7983
|
+
const usage = await fetchCloudUsage(creds.accessToken);
|
|
7984
|
+
if (usage && !cancelled) {
|
|
7985
|
+
setCloudAuth({
|
|
7986
|
+
phase: "success",
|
|
7987
|
+
creds,
|
|
7988
|
+
usage
|
|
7989
|
+
});
|
|
7990
|
+
} else if (!cancelled) {
|
|
7991
|
+
setCloudAuth({ phase: "error", message: "Authenticated but failed to fetch usage." });
|
|
7992
|
+
}
|
|
7993
|
+
return;
|
|
7994
|
+
}
|
|
7995
|
+
} catch {
|
|
7996
|
+
}
|
|
7997
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
7998
|
+
}
|
|
7999
|
+
};
|
|
8000
|
+
poll();
|
|
8001
|
+
return () => {
|
|
8002
|
+
cancelled = true;
|
|
8003
|
+
clearInterval(tick);
|
|
8004
|
+
};
|
|
8005
|
+
}, [step, cloudAuth]);
|
|
8006
|
+
useInput2(
|
|
8007
|
+
useCallback(
|
|
8008
|
+
(_input, key) => {
|
|
8009
|
+
if (key.escape && onCancel) {
|
|
8010
|
+
onCancel();
|
|
8011
|
+
}
|
|
8012
|
+
},
|
|
8013
|
+
[onCancel]
|
|
8014
|
+
)
|
|
8015
|
+
);
|
|
8016
|
+
const startCloudAuth = useCallback(async () => {
|
|
8017
|
+
try {
|
|
8018
|
+
const codes = generateDeviceCodes();
|
|
8019
|
+
await registerDevice(codes);
|
|
8020
|
+
setCloudAuth({ phase: "ready", codes });
|
|
8021
|
+
setStep("cloudAuth");
|
|
8022
|
+
} catch (err) {
|
|
8023
|
+
setCloudAuth({
|
|
8024
|
+
phase: "error",
|
|
8025
|
+
message: err instanceof Error ? err.message : "Failed to start authentication"
|
|
8026
|
+
});
|
|
8027
|
+
setStep("cloudAuth");
|
|
8028
|
+
}
|
|
8029
|
+
}, []);
|
|
7834
8030
|
const handleModeSelect = (item) => {
|
|
7835
8031
|
if (item.value === "cloud") {
|
|
7836
8032
|
setMode("cloud");
|
|
7837
|
-
|
|
8033
|
+
void startCloudAuth();
|
|
7838
8034
|
} else {
|
|
7839
8035
|
setMode("byok");
|
|
7840
8036
|
setStep("accountId");
|
|
7841
8037
|
}
|
|
7842
8038
|
};
|
|
8039
|
+
const handleOpenBrowser = () => {
|
|
8040
|
+
if (cloudAuth?.phase === "ready") {
|
|
8041
|
+
openBrowser(cloudAuth.codes.authUrl);
|
|
8042
|
+
setCloudAuth({ phase: "polling", codes: cloudAuth.codes, startTime: Date.now() });
|
|
8043
|
+
}
|
|
8044
|
+
};
|
|
8045
|
+
const handleCloudSuccess = async () => {
|
|
8046
|
+
if (cloudAuth?.phase !== "success") return;
|
|
8047
|
+
const cfg = { accountId: "", apiToken: "", model: DEFAULT_MODEL, cloudMode: true };
|
|
8048
|
+
try {
|
|
8049
|
+
const path = await saveConfig(cfg);
|
|
8050
|
+
setSavedPath(path);
|
|
8051
|
+
onDone(cfg);
|
|
8052
|
+
} catch (e) {
|
|
8053
|
+
setSavedPath(`error: ${e.message}`);
|
|
8054
|
+
}
|
|
8055
|
+
};
|
|
8056
|
+
const handleCloudRetry = () => {
|
|
8057
|
+
setCloudAuth(null);
|
|
8058
|
+
void startCloudAuth();
|
|
8059
|
+
};
|
|
8060
|
+
const handleCloudSwitchToByok = () => {
|
|
8061
|
+
setCloudAuth(null);
|
|
8062
|
+
setMode("byok");
|
|
8063
|
+
setStep("accountId");
|
|
8064
|
+
};
|
|
7843
8065
|
const handleAccountIdSubmit = (value) => {
|
|
7844
8066
|
const trimmed = value.trim();
|
|
7845
8067
|
if (!trimmed) return;
|
|
@@ -7858,17 +8080,7 @@ function Onboarding({ onDone }) {
|
|
|
7858
8080
|
setStep("confirm");
|
|
7859
8081
|
};
|
|
7860
8082
|
const handleConfirm = async () => {
|
|
7861
|
-
const cfg =
|
|
7862
|
-
try {
|
|
7863
|
-
const path = await saveConfig(cfg);
|
|
7864
|
-
setSavedPath(path);
|
|
7865
|
-
onDone(cfg);
|
|
7866
|
-
} catch (e) {
|
|
7867
|
-
setSavedPath(`error: ${e.message}`);
|
|
7868
|
-
}
|
|
7869
|
-
};
|
|
7870
|
-
const handleCloudSave = async () => {
|
|
7871
|
-
const cfg = { accountId: "", apiToken: "", model: DEFAULT_MODEL, cloudMode: true };
|
|
8083
|
+
const cfg = { accountId, apiToken, model };
|
|
7872
8084
|
try {
|
|
7873
8085
|
const path = await saveConfig(cfg);
|
|
7874
8086
|
setSavedPath(path);
|
|
@@ -7878,27 +8090,27 @@ function Onboarding({ onDone }) {
|
|
|
7878
8090
|
}
|
|
7879
8091
|
};
|
|
7880
8092
|
const byokSteps = ["accountId", "apiToken", "model", "confirm"];
|
|
7881
|
-
const stepIndex = step === "mode" ? 1 : step === "
|
|
8093
|
+
const stepIndex = step === "mode" ? 1 : step === "cloudAuth" ? 2 : byokSteps.indexOf(step) + 2;
|
|
7882
8094
|
const totalSteps = mode === "cloud" ? 2 : byokSteps.length + 1;
|
|
7883
|
-
return /* @__PURE__ */
|
|
7884
|
-
/* @__PURE__ */
|
|
7885
|
-
/* @__PURE__ */
|
|
7886
|
-
/* @__PURE__ */
|
|
8095
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingY: 1, children: [
|
|
8096
|
+
/* @__PURE__ */ jsxs10(Box10, { marginBottom: 1, children: [
|
|
8097
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: theme.palette.primary, children: "kimiflare" }),
|
|
8098
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7887
8099
|
" ",
|
|
7888
8100
|
"Terminal coding agent"
|
|
7889
8101
|
] })
|
|
7890
8102
|
] }),
|
|
7891
|
-
/* @__PURE__ */
|
|
8103
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7892
8104
|
"Step ",
|
|
7893
8105
|
stepIndex,
|
|
7894
8106
|
" of ",
|
|
7895
8107
|
totalSteps
|
|
7896
8108
|
] }),
|
|
7897
|
-
/* @__PURE__ */
|
|
7898
|
-
step === "mode" && /* @__PURE__ */
|
|
7899
|
-
/* @__PURE__ */
|
|
7900
|
-
/* @__PURE__ */
|
|
7901
|
-
|
|
8109
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
8110
|
+
step === "mode" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8111
|
+
/* @__PURE__ */ jsx12(Text11, { children: "How do you want to connect?" }),
|
|
8112
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
|
|
8113
|
+
SelectInput4,
|
|
7902
8114
|
{
|
|
7903
8115
|
items: [
|
|
7904
8116
|
{ label: "Cloud (managed) \u2014 no API key needed", value: "cloud" },
|
|
@@ -7908,11 +8120,102 @@ function Onboarding({ onDone }) {
|
|
|
7908
8120
|
}
|
|
7909
8121
|
) })
|
|
7910
8122
|
] }),
|
|
7911
|
-
step === "
|
|
7912
|
-
/* @__PURE__ */
|
|
7913
|
-
/* @__PURE__ */
|
|
7914
|
-
/* @__PURE__ */
|
|
7915
|
-
/* @__PURE__ */
|
|
8123
|
+
step === "cloudAuth" && cloudAuth?.phase === "ready" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8124
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Authenticating with Kimiflare Cloud..." }),
|
|
8125
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
8126
|
+
/* @__PURE__ */ jsx12(Text11, { children: "1. Open this URL in your browser:" }),
|
|
8127
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: cloudAuth.codes.authUrl })
|
|
8128
|
+
] }),
|
|
8129
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8130
|
+
/* @__PURE__ */ jsx12(Text11, { children: "2. " }),
|
|
8131
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "[Press Enter to open browser]" })
|
|
8132
|
+
] }),
|
|
8133
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8134
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8135
|
+
/* @__PURE__ */ jsx12(
|
|
8136
|
+
CustomTextInput,
|
|
8137
|
+
{
|
|
8138
|
+
value: "",
|
|
8139
|
+
onChange: () => {
|
|
8140
|
+
},
|
|
8141
|
+
onSubmit: handleOpenBrowser
|
|
8142
|
+
}
|
|
8143
|
+
)
|
|
8144
|
+
] })
|
|
8145
|
+
] }),
|
|
8146
|
+
step === "cloudAuth" && cloudAuth?.phase === "polling" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8147
|
+
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
8148
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.spinner, children: /* @__PURE__ */ jsx12(Spinner5, { type: "dots" }) }),
|
|
8149
|
+
" ",
|
|
8150
|
+
"Waiting for authentication..."
|
|
8151
|
+
] }),
|
|
8152
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
8153
|
+
"Expires in ",
|
|
8154
|
+
formatRemaining(POLL_TIMEOUT_MS - (Date.now() - cloudAuth.startTime))
|
|
8155
|
+
] }),
|
|
8156
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
8157
|
+
"URL: ",
|
|
8158
|
+
cloudAuth.codes.authUrl
|
|
8159
|
+
] })
|
|
8160
|
+
] }),
|
|
8161
|
+
step === "cloudAuth" && cloudAuth?.phase === "success" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8162
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.success, children: "Authenticated!" }),
|
|
8163
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
8164
|
+
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
8165
|
+
"Token budget:",
|
|
8166
|
+
" ",
|
|
8167
|
+
/* @__PURE__ */ jsxs10(Text11, { bold: true, children: [
|
|
8168
|
+
cloudAuth.usage.remaining.toLocaleString(),
|
|
8169
|
+
" /",
|
|
8170
|
+
" ",
|
|
8171
|
+
cloudAuth.usage.input_token_limit.toLocaleString()
|
|
8172
|
+
] }),
|
|
8173
|
+
" ",
|
|
8174
|
+
"remaining"
|
|
8175
|
+
] }),
|
|
8176
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
8177
|
+
"Grant expires: ",
|
|
8178
|
+
cloudAuth.usage.expires_at
|
|
8179
|
+
] })
|
|
8180
|
+
] }),
|
|
8181
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text11, { children: "[Press Enter to continue]" }) }),
|
|
8182
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8183
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8184
|
+
/* @__PURE__ */ jsx12(
|
|
8185
|
+
CustomTextInput,
|
|
8186
|
+
{
|
|
8187
|
+
value: "",
|
|
8188
|
+
onChange: () => {
|
|
8189
|
+
},
|
|
8190
|
+
onSubmit: handleCloudSuccess
|
|
8191
|
+
}
|
|
8192
|
+
)
|
|
8193
|
+
] })
|
|
8194
|
+
] }),
|
|
8195
|
+
step === "cloudAuth" && cloudAuth?.phase === "error" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8196
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.error, children: "Authentication failed" }),
|
|
8197
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.info.color, children: cloudAuth.message }),
|
|
8198
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
|
|
8199
|
+
SelectInput4,
|
|
8200
|
+
{
|
|
8201
|
+
items: [
|
|
8202
|
+
{ label: "Retry", value: "retry" },
|
|
8203
|
+
{ label: "Switch to BYOK", value: "byok" },
|
|
8204
|
+
{ label: "Cancel", value: "cancel" }
|
|
8205
|
+
],
|
|
8206
|
+
onSelect: (item) => {
|
|
8207
|
+
if (item.value === "retry") handleCloudRetry();
|
|
8208
|
+
else if (item.value === "byok") handleCloudSwitchToByok();
|
|
8209
|
+
else if (onCancel) onCancel();
|
|
8210
|
+
}
|
|
8211
|
+
}
|
|
8212
|
+
) })
|
|
8213
|
+
] }),
|
|
8214
|
+
step === "accountId" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8215
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Enter your Cloudflare Account ID" }),
|
|
8216
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8217
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8218
|
+
/* @__PURE__ */ jsx12(
|
|
7916
8219
|
CustomTextInput,
|
|
7917
8220
|
{
|
|
7918
8221
|
value: accountId,
|
|
@@ -7922,12 +8225,12 @@ function Onboarding({ onDone }) {
|
|
|
7922
8225
|
)
|
|
7923
8226
|
] })
|
|
7924
8227
|
] }),
|
|
7925
|
-
step === "apiToken" && /* @__PURE__ */
|
|
7926
|
-
/* @__PURE__ */
|
|
7927
|
-
/* @__PURE__ */
|
|
7928
|
-
/* @__PURE__ */
|
|
7929
|
-
/* @__PURE__ */
|
|
7930
|
-
/* @__PURE__ */
|
|
8228
|
+
step === "apiToken" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8229
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Enter your Cloudflare API Token" }),
|
|
8230
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.info.color, children: "Create one at https://dash.cloudflare.com/profile/api-tokens" }),
|
|
8231
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8232
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8233
|
+
/* @__PURE__ */ jsx12(
|
|
7931
8234
|
CustomTextInput,
|
|
7932
8235
|
{
|
|
7933
8236
|
value: apiToken,
|
|
@@ -7938,15 +8241,15 @@ function Onboarding({ onDone }) {
|
|
|
7938
8241
|
)
|
|
7939
8242
|
] })
|
|
7940
8243
|
] }),
|
|
7941
|
-
step === "model" && /* @__PURE__ */
|
|
7942
|
-
/* @__PURE__ */
|
|
7943
|
-
/* @__PURE__ */
|
|
8244
|
+
step === "model" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8245
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Model ID (press Enter for default)" }),
|
|
8246
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7944
8247
|
"default: ",
|
|
7945
8248
|
DEFAULT_MODEL
|
|
7946
8249
|
] }),
|
|
7947
|
-
/* @__PURE__ */
|
|
7948
|
-
/* @__PURE__ */
|
|
7949
|
-
/* @__PURE__ */
|
|
8250
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8251
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8252
|
+
/* @__PURE__ */ jsx12(
|
|
7950
8253
|
CustomTextInput,
|
|
7951
8254
|
{
|
|
7952
8255
|
value: model,
|
|
@@ -7956,10 +8259,10 @@ function Onboarding({ onDone }) {
|
|
|
7956
8259
|
)
|
|
7957
8260
|
] })
|
|
7958
8261
|
] }),
|
|
7959
|
-
step === "confirm" && /* @__PURE__ */
|
|
7960
|
-
/* @__PURE__ */
|
|
7961
|
-
/* @__PURE__ */
|
|
7962
|
-
|
|
8262
|
+
step === "confirm" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8263
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Ready to save configuration" }),
|
|
8264
|
+
/* @__PURE__ */ jsxs10(
|
|
8265
|
+
Box10,
|
|
7963
8266
|
{
|
|
7964
8267
|
flexDirection: "column",
|
|
7965
8268
|
marginTop: 1,
|
|
@@ -7968,25 +8271,25 @@ function Onboarding({ onDone }) {
|
|
|
7968
8271
|
borderColor: theme.info.color,
|
|
7969
8272
|
paddingX: 1,
|
|
7970
8273
|
children: [
|
|
7971
|
-
/* @__PURE__ */
|
|
8274
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7972
8275
|
"Account ID: ",
|
|
7973
8276
|
accountId
|
|
7974
8277
|
] }),
|
|
7975
|
-
/* @__PURE__ */
|
|
8278
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7976
8279
|
"API Token: ",
|
|
7977
8280
|
"\u2022".repeat(apiToken.length)
|
|
7978
8281
|
] }),
|
|
7979
|
-
/* @__PURE__ */
|
|
8282
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7980
8283
|
"Model: ",
|
|
7981
8284
|
model
|
|
7982
8285
|
] })
|
|
7983
8286
|
]
|
|
7984
8287
|
}
|
|
7985
8288
|
),
|
|
7986
|
-
/* @__PURE__ */
|
|
7987
|
-
/* @__PURE__ */
|
|
7988
|
-
/* @__PURE__ */
|
|
7989
|
-
/* @__PURE__ */
|
|
8289
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Press Enter to confirm, or Ctrl+C to cancel" }),
|
|
8290
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8291
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8292
|
+
/* @__PURE__ */ jsx12(
|
|
7990
8293
|
CustomTextInput,
|
|
7991
8294
|
{
|
|
7992
8295
|
value: "",
|
|
@@ -7997,68 +8300,54 @@ function Onboarding({ onDone }) {
|
|
|
7997
8300
|
)
|
|
7998
8301
|
] })
|
|
7999
8302
|
] }),
|
|
8000
|
-
|
|
8001
|
-
/* @__PURE__ */ jsx11(Text10, { children: "Cloud mode selected" }),
|
|
8002
|
-
/* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "No API key needed. Run `kimiflare auth cloud` to sign in." }),
|
|
8003
|
-
/* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { children: "Press Enter to save, or Ctrl+C to cancel" }) }),
|
|
8004
|
-
/* @__PURE__ */ jsxs9(Box9, { marginTop: 1, children: [
|
|
8005
|
-
/* @__PURE__ */ jsx11(Text10, { color: theme.palette.primary, children: "\u203A " }),
|
|
8006
|
-
/* @__PURE__ */ jsx11(
|
|
8007
|
-
CustomTextInput,
|
|
8008
|
-
{
|
|
8009
|
-
value: "",
|
|
8010
|
-
onChange: () => {
|
|
8011
|
-
},
|
|
8012
|
-
onSubmit: handleCloudSave
|
|
8013
|
-
}
|
|
8014
|
-
)
|
|
8015
|
-
] })
|
|
8016
|
-
] }),
|
|
8017
|
-
savedPath && /* @__PURE__ */ jsxs9(Text10, { color: theme.palette.success, children: [
|
|
8303
|
+
savedPath && /* @__PURE__ */ jsxs10(Text11, { color: theme.palette.success, children: [
|
|
8018
8304
|
"Config saved to ",
|
|
8019
8305
|
savedPath
|
|
8020
8306
|
] })
|
|
8021
8307
|
] })
|
|
8022
8308
|
] });
|
|
8023
8309
|
}
|
|
8310
|
+
var execAsync;
|
|
8024
8311
|
var init_onboarding = __esm({
|
|
8025
8312
|
"src/ui/onboarding.tsx"() {
|
|
8026
8313
|
"use strict";
|
|
8027
8314
|
init_text_input();
|
|
8028
8315
|
init_config();
|
|
8029
8316
|
init_theme_context();
|
|
8317
|
+
init_auth();
|
|
8318
|
+
execAsync = promisify2(exec);
|
|
8030
8319
|
}
|
|
8031
8320
|
});
|
|
8032
8321
|
|
|
8033
8322
|
// src/ui/welcome.tsx
|
|
8034
|
-
import { Box as
|
|
8035
|
-
import { jsx as
|
|
8323
|
+
import { Box as Box11, Text as Text12 } from "ink";
|
|
8324
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
8036
8325
|
function Welcome({ accountId }) {
|
|
8037
8326
|
const theme = useTheme();
|
|
8038
|
-
return /* @__PURE__ */
|
|
8039
|
-
/* @__PURE__ */
|
|
8040
|
-
/* @__PURE__ */
|
|
8041
|
-
/* @__PURE__ */
|
|
8327
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
|
|
8328
|
+
/* @__PURE__ */ jsxs11(Box11, { marginBottom: 1, children: [
|
|
8329
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.accent, children: "kimiflare" }),
|
|
8330
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
8042
8331
|
" ",
|
|
8043
8332
|
"Ready when you are."
|
|
8044
8333
|
] })
|
|
8045
8334
|
] }),
|
|
8046
|
-
accountId && /* @__PURE__ */
|
|
8335
|
+
accountId && /* @__PURE__ */ jsx13(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
8047
8336
|
" ",
|
|
8048
8337
|
"Check your Cloudflare billing: https://dash.cloudflare.com/",
|
|
8049
8338
|
accountId,
|
|
8050
8339
|
"/billing/billable-usage"
|
|
8051
8340
|
] }) }),
|
|
8052
|
-
/* @__PURE__ */
|
|
8053
|
-
/* @__PURE__ */
|
|
8341
|
+
/* @__PURE__ */ jsx13(Box11, { flexDirection: "column", children: SUGGESTIONS.map((s, i) => /* @__PURE__ */ jsxs11(Box11, { children: [
|
|
8342
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
8054
8343
|
" ",
|
|
8055
8344
|
"\u203A",
|
|
8056
8345
|
" "
|
|
8057
8346
|
] }),
|
|
8058
|
-
/* @__PURE__ */
|
|
8347
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.user, children: s })
|
|
8059
8348
|
] }, i)) }),
|
|
8060
|
-
/* @__PURE__ */
|
|
8061
|
-
/* @__PURE__ */
|
|
8349
|
+
/* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: "Type a message or /help for commands \xB7 ctrl-c to exit \xB7 shift+tab to cycle modes" }) }),
|
|
8350
|
+
/* @__PURE__ */ jsx13(Box11, { children: /* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: "Tip: type /hello to send feedback to the creator" }) })
|
|
8062
8351
|
] });
|
|
8063
8352
|
}
|
|
8064
8353
|
var SUGGESTIONS;
|
|
@@ -8076,14 +8365,14 @@ var init_welcome = __esm({
|
|
|
8076
8365
|
|
|
8077
8366
|
// src/ui/help-menu.tsx
|
|
8078
8367
|
import { useState as useState6 } from "react";
|
|
8079
|
-
import { Box as
|
|
8080
|
-
import
|
|
8081
|
-
import { jsx as
|
|
8368
|
+
import { Box as Box12, Text as Text13, useInput as useInput3 } from "ink";
|
|
8369
|
+
import SelectInput5 from "ink-select-input";
|
|
8370
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
8082
8371
|
function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, onCommand }) {
|
|
8083
8372
|
const theme = useTheme();
|
|
8084
8373
|
const [page, setPage] = useState6("main");
|
|
8085
8374
|
const customs = customCommands ?? [];
|
|
8086
|
-
|
|
8375
|
+
useInput3((_input, key) => {
|
|
8087
8376
|
if (key.escape) {
|
|
8088
8377
|
if (page !== "main") {
|
|
8089
8378
|
setPage("main");
|
|
@@ -8107,11 +8396,11 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8107
8396
|
items2.push({ label: "Run custom commands", value: "custom", key: "custom" });
|
|
8108
8397
|
}
|
|
8109
8398
|
items2.push({ label: "(close)", value: "__close__", key: "__close__" });
|
|
8110
|
-
return /* @__PURE__ */
|
|
8111
|
-
/* @__PURE__ */
|
|
8112
|
-
/* @__PURE__ */
|
|
8113
|
-
/* @__PURE__ */
|
|
8114
|
-
|
|
8399
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8400
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: "Help" }),
|
|
8401
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to close." }),
|
|
8402
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8403
|
+
SelectInput5,
|
|
8115
8404
|
{
|
|
8116
8405
|
items: items2,
|
|
8117
8406
|
onSelect: (item) => {
|
|
@@ -8123,8 +8412,8 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8123
8412
|
}
|
|
8124
8413
|
}
|
|
8125
8414
|
) }),
|
|
8126
|
-
/* @__PURE__ */
|
|
8127
|
-
/* @__PURE__ */
|
|
8415
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, flexDirection: "column", children: SINGLE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: ` ${cmd.command.padEnd(20)} ${cmd.description}` }, cmd.command)) }),
|
|
8416
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "keys: ctrl-c interrupt/exit \xB7 ctrl-r toggle reasoning \xB7 ctrl-o verbose \xB7 shift+tab cycle mode \xB7 \u2191/\u2193 history" }) })
|
|
8128
8417
|
] });
|
|
8129
8418
|
}
|
|
8130
8419
|
if (page === "custom") {
|
|
@@ -8134,11 +8423,11 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8134
8423
|
key: c.name
|
|
8135
8424
|
}));
|
|
8136
8425
|
items2.push({ label: "\u2190 Back", value: "__back__", key: "__back__" });
|
|
8137
|
-
return /* @__PURE__ */
|
|
8138
|
-
/* @__PURE__ */
|
|
8139
|
-
/* @__PURE__ */
|
|
8140
|
-
/* @__PURE__ */
|
|
8141
|
-
|
|
8426
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8427
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
8428
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: customs.length === 0 ? "no custom commands found in .kimiflare/commands/" : "Arrow keys to navigate, Enter to run, Esc to go back." }),
|
|
8429
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8430
|
+
SelectInput5,
|
|
8142
8431
|
{
|
|
8143
8432
|
items: items2,
|
|
8144
8433
|
onSelect: (item) => {
|
|
@@ -8161,11 +8450,11 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8161
8450
|
key: cmd.command
|
|
8162
8451
|
}));
|
|
8163
8452
|
items.push({ label: "\u2190 Back", value: "__back__", key: "__back__" });
|
|
8164
|
-
return /* @__PURE__ */
|
|
8165
|
-
/* @__PURE__ */
|
|
8166
|
-
/* @__PURE__ */
|
|
8167
|
-
/* @__PURE__ */
|
|
8168
|
-
|
|
8453
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8454
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: category.label }),
|
|
8455
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to execute, Esc to go back." }),
|
|
8456
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8457
|
+
SelectInput5,
|
|
8169
8458
|
{
|
|
8170
8459
|
items,
|
|
8171
8460
|
onSelect: (item) => {
|
|
@@ -8177,7 +8466,7 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8177
8466
|
}
|
|
8178
8467
|
}
|
|
8179
8468
|
) }),
|
|
8180
|
-
staticCmds.length > 0 && /* @__PURE__ */
|
|
8469
|
+
staticCmds.length > 0 && /* @__PURE__ */ jsx14(Box12, { marginTop: 1, flexDirection: "column", children: staticCmds.map((cmd) => /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, children: ` ${cmd.command.padEnd(28)} ${cmd.description}` }, cmd.command)) })
|
|
8181
8470
|
] });
|
|
8182
8471
|
}
|
|
8183
8472
|
var CATEGORIES, SINGLE_COMMANDS;
|
|
@@ -8409,17 +8698,17 @@ var init_tui_deploy = __esm({
|
|
|
8409
8698
|
});
|
|
8410
8699
|
|
|
8411
8700
|
// src/ui/remote-dashboard.tsx
|
|
8412
|
-
import { useEffect as
|
|
8413
|
-
import { Box as
|
|
8414
|
-
import
|
|
8415
|
-
import { jsx as
|
|
8701
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
8702
|
+
import { Box as Box13, Text as Text14, useInput as useInput4 } from "ink";
|
|
8703
|
+
import SelectInput6 from "ink-select-input";
|
|
8704
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
8416
8705
|
function RemoteDashboard({ onSelect, onCancel }) {
|
|
8417
8706
|
const theme = useTheme();
|
|
8418
8707
|
const [sessions, setSessions] = useState7([]);
|
|
8419
8708
|
const [loading, setLoading] = useState7(true);
|
|
8420
8709
|
const [error, setError] = useState7(null);
|
|
8421
8710
|
const [refreshing, setRefreshing] = useState7(false);
|
|
8422
|
-
|
|
8711
|
+
useEffect5(() => {
|
|
8423
8712
|
loadSessions();
|
|
8424
8713
|
}, []);
|
|
8425
8714
|
async function loadSessions() {
|
|
@@ -8455,7 +8744,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8455
8744
|
setRefreshing(false);
|
|
8456
8745
|
}
|
|
8457
8746
|
}
|
|
8458
|
-
|
|
8747
|
+
useInput4((input, key) => {
|
|
8459
8748
|
if (input === "r" || input === "R") {
|
|
8460
8749
|
void loadSessions();
|
|
8461
8750
|
}
|
|
@@ -8468,31 +8757,31 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8468
8757
|
value: s.sessionId
|
|
8469
8758
|
}));
|
|
8470
8759
|
if (loading) {
|
|
8471
|
-
return /* @__PURE__ */
|
|
8760
|
+
return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "Loading remote sessions..." }) });
|
|
8472
8761
|
}
|
|
8473
8762
|
if (error) {
|
|
8474
|
-
return /* @__PURE__ */
|
|
8475
|
-
/* @__PURE__ */
|
|
8763
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8764
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
|
|
8476
8765
|
"Error: ",
|
|
8477
8766
|
error
|
|
8478
8767
|
] }),
|
|
8479
|
-
/* @__PURE__ */
|
|
8768
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press R to retry, Esc to close" })
|
|
8480
8769
|
] });
|
|
8481
8770
|
}
|
|
8482
8771
|
if (sessions.length === 0) {
|
|
8483
|
-
return /* @__PURE__ */
|
|
8484
|
-
/* @__PURE__ */
|
|
8485
|
-
/* @__PURE__ */
|
|
8486
|
-
/* @__PURE__ */
|
|
8772
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8773
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "No remote sessions yet." }),
|
|
8774
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Type /remote <prompt> to start one." }),
|
|
8775
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press Esc to close" })
|
|
8487
8776
|
] });
|
|
8488
8777
|
}
|
|
8489
|
-
return /* @__PURE__ */
|
|
8490
|
-
/* @__PURE__ */
|
|
8778
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8779
|
+
/* @__PURE__ */ jsxs13(Text14, { bold: true, color: theme.accent, children: [
|
|
8491
8780
|
"Recent remote tasks ",
|
|
8492
8781
|
refreshing ? "(refreshing...)" : ""
|
|
8493
8782
|
] }),
|
|
8494
|
-
/* @__PURE__ */
|
|
8495
|
-
|
|
8783
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
8784
|
+
SelectInput6,
|
|
8496
8785
|
{
|
|
8497
8786
|
items,
|
|
8498
8787
|
onSelect: (item) => {
|
|
@@ -8501,7 +8790,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8501
8790
|
}
|
|
8502
8791
|
}
|
|
8503
8792
|
) }),
|
|
8504
|
-
/* @__PURE__ */
|
|
8793
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
|
|
8505
8794
|
] });
|
|
8506
8795
|
}
|
|
8507
8796
|
function formatSessionLine(s) {
|
|
@@ -8509,7 +8798,7 @@ function formatSessionLine(s) {
|
|
|
8509
8798
|
const ago = formatAgo(new Date(s.updatedAt));
|
|
8510
8799
|
const prompt = s.prompt.slice(0, 30) + (s.prompt.length > 30 ? "\u2026" : "");
|
|
8511
8800
|
const outcome = s.prUrl ? `PR ${s.prUrl.split("/").pop()}` : s.status;
|
|
8512
|
-
const cost = s.tokensUsed && s.tokensBudget ? ` (${
|
|
8801
|
+
const cost = s.tokensUsed && s.tokensBudget ? ` (${formatTokens3(s.tokensUsed)}/${formatTokens3(s.tokensBudget)})` : s.tokensUsed ? ` (${formatTokens3(s.tokensUsed)})` : "";
|
|
8513
8802
|
return `${icon} ${prompt} \u2192 ${outcome} ${ago}${cost}`;
|
|
8514
8803
|
}
|
|
8515
8804
|
function formatAgo(date) {
|
|
@@ -8522,7 +8811,7 @@ function formatAgo(date) {
|
|
|
8522
8811
|
if (minutes > 0) return `${minutes}m ago`;
|
|
8523
8812
|
return "just now";
|
|
8524
8813
|
}
|
|
8525
|
-
function
|
|
8814
|
+
function formatTokens3(n) {
|
|
8526
8815
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
8527
8816
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
8528
8817
|
return String(n);
|
|
@@ -8534,7 +8823,7 @@ function RemoteSessionDetail({
|
|
|
8534
8823
|
}) {
|
|
8535
8824
|
const theme = useTheme();
|
|
8536
8825
|
const [cancelling, setCancelling] = useState7(false);
|
|
8537
|
-
|
|
8826
|
+
useInput4((input, key) => {
|
|
8538
8827
|
if (key.escape) {
|
|
8539
8828
|
onBack();
|
|
8540
8829
|
}
|
|
@@ -8554,50 +8843,50 @@ function RemoteSessionDetail({
|
|
|
8554
8843
|
}
|
|
8555
8844
|
}
|
|
8556
8845
|
const isRunning = session.status === "running" || session.status === "pending";
|
|
8557
|
-
return /* @__PURE__ */
|
|
8558
|
-
/* @__PURE__ */
|
|
8559
|
-
/* @__PURE__ */
|
|
8560
|
-
/* @__PURE__ */
|
|
8846
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8847
|
+
/* @__PURE__ */ jsx15(Text14, { bold: true, color: theme.accent, children: "Remote Session" }),
|
|
8848
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
8849
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8561
8850
|
"ID: ",
|
|
8562
8851
|
session.sessionId
|
|
8563
8852
|
] }),
|
|
8564
|
-
/* @__PURE__ */
|
|
8853
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8565
8854
|
"Repo: ",
|
|
8566
8855
|
session.repo
|
|
8567
8856
|
] }),
|
|
8568
|
-
/* @__PURE__ */
|
|
8857
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8569
8858
|
"Status: ",
|
|
8570
8859
|
session.status
|
|
8571
8860
|
] }),
|
|
8572
|
-
/* @__PURE__ */
|
|
8861
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8573
8862
|
"Prompt: ",
|
|
8574
8863
|
session.prompt
|
|
8575
8864
|
] }),
|
|
8576
|
-
session.prUrl && /* @__PURE__ */
|
|
8865
|
+
session.prUrl && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8577
8866
|
"PR: ",
|
|
8578
8867
|
session.prUrl
|
|
8579
8868
|
] }),
|
|
8580
|
-
session.errorMessage && /* @__PURE__ */
|
|
8869
|
+
session.errorMessage && /* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
|
|
8581
8870
|
"Error: ",
|
|
8582
8871
|
session.errorMessage
|
|
8583
8872
|
] }),
|
|
8584
|
-
session.tokensUsed !== void 0 && /* @__PURE__ */
|
|
8873
|
+
session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8585
8874
|
"Tokens: ",
|
|
8586
|
-
|
|
8587
|
-
session.tokensBudget ? ` / ${
|
|
8875
|
+
formatTokens3(session.tokensUsed),
|
|
8876
|
+
session.tokensBudget ? ` / ${formatTokens3(session.tokensBudget)}` : ""
|
|
8588
8877
|
] }),
|
|
8589
|
-
/* @__PURE__ */
|
|
8878
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8590
8879
|
"Created: ",
|
|
8591
8880
|
new Date(session.createdAt).toLocaleString()
|
|
8592
8881
|
] }),
|
|
8593
|
-
session.finishedAt && /* @__PURE__ */
|
|
8882
|
+
session.finishedAt && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8594
8883
|
"Finished: ",
|
|
8595
8884
|
new Date(session.finishedAt).toLocaleString()
|
|
8596
8885
|
] })
|
|
8597
8886
|
] }),
|
|
8598
|
-
/* @__PURE__ */
|
|
8599
|
-
isRunning && onCancel && /* @__PURE__ */
|
|
8600
|
-
/* @__PURE__ */
|
|
8887
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", gap: 2, children: [
|
|
8888
|
+
isRunning && onCancel && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
|
|
8889
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Esc back" })
|
|
8601
8890
|
] })
|
|
8602
8891
|
] });
|
|
8603
8892
|
}
|
|
@@ -9502,8 +9791,8 @@ function computeExactScore(memory, queryText, cwd) {
|
|
|
9502
9791
|
let score = 0;
|
|
9503
9792
|
const lowerQuery = queryText.toLowerCase();
|
|
9504
9793
|
for (const file of memory.relatedFiles) {
|
|
9505
|
-
const
|
|
9506
|
-
if (lowerQuery.includes(
|
|
9794
|
+
const basename5 = file.split("/").pop() ?? file;
|
|
9795
|
+
if (lowerQuery.includes(basename5.toLowerCase()) || basename5.toLowerCase().includes(lowerQuery)) {
|
|
9507
9796
|
score += 0.3;
|
|
9508
9797
|
}
|
|
9509
9798
|
if (cwd && file.startsWith(cwd)) {
|
|
@@ -10281,10 +10570,10 @@ var init_loader = __esm({
|
|
|
10281
10570
|
});
|
|
10282
10571
|
|
|
10283
10572
|
// src/commands/renderer.ts
|
|
10284
|
-
import { exec } from "child_process";
|
|
10573
|
+
import { exec as exec2 } from "child_process";
|
|
10285
10574
|
import { open as open2, realpath as realpath2 } from "fs/promises";
|
|
10286
10575
|
import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolvePathJoin, basename as pathBasename } from "path";
|
|
10287
|
-
import { promisify as
|
|
10576
|
+
import { promisify as promisify3 } from "util";
|
|
10288
10577
|
function tokenizeArgs(s) {
|
|
10289
10578
|
return [...s.matchAll(ARG_TOKEN_RE)].map((match) => {
|
|
10290
10579
|
const token = match[0];
|
|
@@ -10351,7 +10640,7 @@ async function replaceShell(prompt, warnings, cmd, shellTimeoutMs) {
|
|
|
10351
10640
|
matches.map(async (match) => {
|
|
10352
10641
|
const command = match[1] ?? "";
|
|
10353
10642
|
try {
|
|
10354
|
-
const { stdout } = await
|
|
10643
|
+
const { stdout } = await execAsync2(command, {
|
|
10355
10644
|
timeout: shellTimeoutMs,
|
|
10356
10645
|
maxBuffer: 1024 * 1024
|
|
10357
10646
|
});
|
|
@@ -10432,12 +10721,12 @@ async function replaceFiles(prompt, warnings, cmd, cwd, maxFileBytes) {
|
|
|
10432
10721
|
function message(error) {
|
|
10433
10722
|
return error instanceof Error ? error.message : String(error);
|
|
10434
10723
|
}
|
|
10435
|
-
var
|
|
10724
|
+
var execAsync2, ARG_TOKEN_RE, POSITIONAL_RE, HAS_POSITIONAL, SHELL_RE, FILE_RE, DEFAULT_MAX_FILE_BYTES, DEFAULT_SHELL_TIMEOUT_MS, SECRET_PATTERNS2;
|
|
10436
10725
|
var init_renderer2 = __esm({
|
|
10437
10726
|
"src/commands/renderer.ts"() {
|
|
10438
10727
|
"use strict";
|
|
10439
10728
|
init_paths();
|
|
10440
|
-
|
|
10729
|
+
execAsync2 = promisify3(exec2);
|
|
10441
10730
|
ARG_TOKEN_RE = /(?:"[^"]*"|'[^']*'|[^\s"']+)/g;
|
|
10442
10731
|
POSITIONAL_RE = /\$(\d+)/g;
|
|
10443
10732
|
HAS_POSITIONAL = /\$\d+/;
|
|
@@ -10535,9 +10824,9 @@ var init_save = __esm({
|
|
|
10535
10824
|
|
|
10536
10825
|
// src/ui/command-wizard.tsx
|
|
10537
10826
|
import { useState as useState8 } from "react";
|
|
10538
|
-
import { Box as
|
|
10539
|
-
import
|
|
10540
|
-
import { Fragment as Fragment2, jsx as
|
|
10827
|
+
import { Box as Box14, Text as Text15, useInput as useInput5, useWindowSize as useWindowSize2 } from "ink";
|
|
10828
|
+
import SelectInput7 from "ink-select-input";
|
|
10829
|
+
import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
10541
10830
|
function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
|
|
10542
10831
|
const theme = useTheme();
|
|
10543
10832
|
const [step, setStep] = useState8("name");
|
|
@@ -10561,7 +10850,7 @@ function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onS
|
|
|
10561
10850
|
if (existingNames.includes(trimmed) && !isEditingSelf(trimmed)) return `/${trimmed} already exists`;
|
|
10562
10851
|
return null;
|
|
10563
10852
|
};
|
|
10564
|
-
|
|
10853
|
+
useInput5((_input, key) => {
|
|
10565
10854
|
if (key.escape) {
|
|
10566
10855
|
onDone();
|
|
10567
10856
|
}
|
|
@@ -10661,8 +10950,8 @@ ${template}`;
|
|
|
10661
10950
|
const renderStep = () => {
|
|
10662
10951
|
switch (step) {
|
|
10663
10952
|
case "name":
|
|
10664
|
-
return /* @__PURE__ */
|
|
10665
|
-
/* @__PURE__ */
|
|
10953
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
10954
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10666
10955
|
mode === "create" ? "Create" : "Edit",
|
|
10667
10956
|
" custom command \u2014 Name (",
|
|
10668
10957
|
stepIndex,
|
|
@@ -10670,8 +10959,8 @@ ${template}`;
|
|
|
10670
10959
|
totalSteps,
|
|
10671
10960
|
")"
|
|
10672
10961
|
] }),
|
|
10673
|
-
error && /* @__PURE__ */
|
|
10674
|
-
/* @__PURE__ */
|
|
10962
|
+
error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
|
|
10963
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10675
10964
|
CustomTextInput,
|
|
10676
10965
|
{
|
|
10677
10966
|
value: name,
|
|
@@ -10680,11 +10969,11 @@ ${template}`;
|
|
|
10680
10969
|
focus: true
|
|
10681
10970
|
}
|
|
10682
10971
|
) }),
|
|
10683
|
-
/* @__PURE__ */
|
|
10972
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
|
|
10684
10973
|
] });
|
|
10685
10974
|
case "description":
|
|
10686
|
-
return /* @__PURE__ */
|
|
10687
|
-
/* @__PURE__ */
|
|
10975
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
10976
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10688
10977
|
mode === "create" ? "Create" : "Edit",
|
|
10689
10978
|
" custom command \u2014 Description (",
|
|
10690
10979
|
stepIndex,
|
|
@@ -10692,7 +10981,7 @@ ${template}`;
|
|
|
10692
10981
|
totalSteps,
|
|
10693
10982
|
")"
|
|
10694
10983
|
] }),
|
|
10695
|
-
/* @__PURE__ */
|
|
10984
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10696
10985
|
CustomTextInput,
|
|
10697
10986
|
{
|
|
10698
10987
|
value: description,
|
|
@@ -10701,49 +10990,49 @@ ${template}`;
|
|
|
10701
10990
|
focus: true
|
|
10702
10991
|
}
|
|
10703
10992
|
) }),
|
|
10704
|
-
/* @__PURE__ */
|
|
10993
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
|
|
10705
10994
|
] });
|
|
10706
10995
|
case "template": {
|
|
10707
|
-
const guide = /* @__PURE__ */
|
|
10708
|
-
/* @__PURE__ */
|
|
10709
|
-
/* @__PURE__ */
|
|
10710
|
-
/* @__PURE__ */
|
|
10996
|
+
const guide = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingLeft: 1, children: [
|
|
10997
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "What is this?" }),
|
|
10998
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
|
|
10999
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10711
11000
|
"When you type /",
|
|
10712
11001
|
name || "yourcommand",
|
|
10713
11002
|
" later, this gets sent to the model."
|
|
10714
11003
|
] }),
|
|
10715
|
-
/* @__PURE__ */
|
|
10716
|
-
/* @__PURE__ */
|
|
10717
|
-
/* @__PURE__ */
|
|
11004
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
11005
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Variables" }),
|
|
11006
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10718
11007
|
" ",
|
|
10719
11008
|
"$1, $2 ... \u2192 arguments you type"
|
|
10720
11009
|
] }),
|
|
10721
|
-
/* @__PURE__ */
|
|
11010
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10722
11011
|
" ",
|
|
10723
11012
|
"$ARGUMENTS \u2192 everything after the command"
|
|
10724
11013
|
] })
|
|
10725
11014
|
] }),
|
|
10726
|
-
/* @__PURE__ */
|
|
10727
|
-
/* @__PURE__ */
|
|
10728
|
-
/* @__PURE__ */
|
|
11015
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
11016
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
|
|
11017
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10729
11018
|
" ",
|
|
10730
11019
|
"!`git diff` \u2192 shell output inlined"
|
|
10731
11020
|
] }),
|
|
10732
|
-
/* @__PURE__ */
|
|
11021
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10733
11022
|
" ",
|
|
10734
11023
|
"@README.md \u2192 file contents inlined"
|
|
10735
11024
|
] })
|
|
10736
11025
|
] }),
|
|
10737
|
-
/* @__PURE__ */
|
|
10738
|
-
/* @__PURE__ */
|
|
10739
|
-
/* @__PURE__ */
|
|
10740
|
-
/* @__PURE__ */
|
|
10741
|
-
/* @__PURE__ */
|
|
11026
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
11027
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Example" }),
|
|
11028
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Review this PR diff:" }),
|
|
11029
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
|
|
11030
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Focus on: $1" })
|
|
10742
11031
|
] })
|
|
10743
11032
|
] });
|
|
10744
|
-
const inputArea = /* @__PURE__ */
|
|
10745
|
-
error && /* @__PURE__ */
|
|
10746
|
-
/* @__PURE__ */
|
|
11033
|
+
const inputArea = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexGrow: 1, children: [
|
|
11034
|
+
error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
|
|
11035
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10747
11036
|
CustomTextInput,
|
|
10748
11037
|
{
|
|
10749
11038
|
value: template,
|
|
@@ -10753,13 +11042,13 @@ ${template}`;
|
|
|
10753
11042
|
enablePaste: true
|
|
10754
11043
|
}
|
|
10755
11044
|
) }),
|
|
10756
|
-
columns < 100 && /* @__PURE__ */
|
|
10757
|
-
/* @__PURE__ */
|
|
10758
|
-
/* @__PURE__ */
|
|
11045
|
+
columns < 100 && /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11046
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
|
|
11047
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
|
|
10759
11048
|
] })
|
|
10760
11049
|
] });
|
|
10761
|
-
return /* @__PURE__ */
|
|
10762
|
-
/* @__PURE__ */
|
|
11050
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11051
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10763
11052
|
mode === "create" ? "Create" : "Edit",
|
|
10764
11053
|
" custom command \u2014 Template (",
|
|
10765
11054
|
stepIndex,
|
|
@@ -10767,10 +11056,10 @@ ${template}`;
|
|
|
10767
11056
|
totalSteps,
|
|
10768
11057
|
")"
|
|
10769
11058
|
] }),
|
|
10770
|
-
columns >= 100 ? /* @__PURE__ */
|
|
10771
|
-
/* @__PURE__ */
|
|
10772
|
-
/* @__PURE__ */
|
|
10773
|
-
] }) : /* @__PURE__ */
|
|
11059
|
+
columns >= 100 ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "row", marginTop: 1, children: [
|
|
11060
|
+
/* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: inputArea }),
|
|
11061
|
+
/* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: guide })
|
|
11062
|
+
] }) : /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", marginTop: 1, children: inputArea })
|
|
10774
11063
|
] });
|
|
10775
11064
|
}
|
|
10776
11065
|
case "advanced": {
|
|
@@ -10779,8 +11068,8 @@ ${template}`;
|
|
|
10779
11068
|
{ label: "Skip", value: "skip", key: "skip" },
|
|
10780
11069
|
{ label: "\u2190 Cancel", value: "cancel", key: "cancel" }
|
|
10781
11070
|
];
|
|
10782
|
-
return /* @__PURE__ */
|
|
10783
|
-
/* @__PURE__ */
|
|
11071
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11072
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10784
11073
|
mode === "create" ? "Create" : "Edit",
|
|
10785
11074
|
" custom command \u2014 Options (",
|
|
10786
11075
|
stepIndex,
|
|
@@ -10788,8 +11077,8 @@ ${template}`;
|
|
|
10788
11077
|
totalSteps,
|
|
10789
11078
|
")"
|
|
10790
11079
|
] }),
|
|
10791
|
-
/* @__PURE__ */
|
|
10792
|
-
|
|
11080
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11081
|
+
SelectInput7,
|
|
10793
11082
|
{
|
|
10794
11083
|
items,
|
|
10795
11084
|
onSelect: (item) => {
|
|
@@ -10808,17 +11097,17 @@ ${template}`;
|
|
|
10808
11097
|
{ label: cmdMode === "auto" ? "auto \xB7 current" : "auto", value: "auto", key: "auto" },
|
|
10809
11098
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10810
11099
|
];
|
|
10811
|
-
return /* @__PURE__ */
|
|
10812
|
-
/* @__PURE__ */
|
|
11100
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11101
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10813
11102
|
"Mode override (",
|
|
10814
11103
|
stepIndex,
|
|
10815
11104
|
"/",
|
|
10816
11105
|
totalSteps,
|
|
10817
11106
|
")"
|
|
10818
11107
|
] }),
|
|
10819
|
-
/* @__PURE__ */
|
|
10820
|
-
/* @__PURE__ */
|
|
10821
|
-
|
|
11108
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
|
|
11109
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11110
|
+
SelectInput7,
|
|
10822
11111
|
{
|
|
10823
11112
|
items,
|
|
10824
11113
|
onSelect: (item) => {
|
|
@@ -10837,16 +11126,16 @@ ${template}`;
|
|
|
10837
11126
|
{ label: cmdEffort === "high" ? "high \xB7 current" : "high", value: "high", key: "high" },
|
|
10838
11127
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10839
11128
|
];
|
|
10840
|
-
return /* @__PURE__ */
|
|
10841
|
-
/* @__PURE__ */
|
|
11129
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11130
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10842
11131
|
"Reasoning effort (",
|
|
10843
11132
|
stepIndex,
|
|
10844
11133
|
"/",
|
|
10845
11134
|
totalSteps,
|
|
10846
11135
|
")"
|
|
10847
11136
|
] }),
|
|
10848
|
-
/* @__PURE__ */
|
|
10849
|
-
|
|
11137
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11138
|
+
SelectInput7,
|
|
10850
11139
|
{
|
|
10851
11140
|
items,
|
|
10852
11141
|
onSelect: (item) => {
|
|
@@ -10858,15 +11147,15 @@ ${template}`;
|
|
|
10858
11147
|
] });
|
|
10859
11148
|
}
|
|
10860
11149
|
case "model":
|
|
10861
|
-
return /* @__PURE__ */
|
|
10862
|
-
/* @__PURE__ */
|
|
11150
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11151
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10863
11152
|
"Model override (",
|
|
10864
11153
|
stepIndex,
|
|
10865
11154
|
"/",
|
|
10866
11155
|
totalSteps,
|
|
10867
11156
|
")"
|
|
10868
11157
|
] }),
|
|
10869
|
-
/* @__PURE__ */
|
|
11158
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10870
11159
|
CustomTextInput,
|
|
10871
11160
|
{
|
|
10872
11161
|
value: cmdModel ?? "",
|
|
@@ -10875,7 +11164,7 @@ ${template}`;
|
|
|
10875
11164
|
focus: true
|
|
10876
11165
|
}
|
|
10877
11166
|
) }),
|
|
10878
|
-
/* @__PURE__ */
|
|
11167
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
|
|
10879
11168
|
] });
|
|
10880
11169
|
case "location": {
|
|
10881
11170
|
const items = [
|
|
@@ -10883,16 +11172,16 @@ ${template}`;
|
|
|
10883
11172
|
{ label: source === "global" ? "Global \xB7 current" : "Global", value: "global", key: "global" },
|
|
10884
11173
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10885
11174
|
];
|
|
10886
|
-
return /* @__PURE__ */
|
|
10887
|
-
/* @__PURE__ */
|
|
11175
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11176
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10888
11177
|
"Save location (",
|
|
10889
11178
|
stepIndex,
|
|
10890
11179
|
"/",
|
|
10891
11180
|
totalSteps,
|
|
10892
11181
|
")"
|
|
10893
11182
|
] }),
|
|
10894
|
-
/* @__PURE__ */
|
|
10895
|
-
|
|
11183
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11184
|
+
SelectInput7,
|
|
10896
11185
|
{
|
|
10897
11186
|
items,
|
|
10898
11187
|
onSelect: (item) => {
|
|
@@ -10901,7 +11190,7 @@ ${template}`;
|
|
|
10901
11190
|
}
|
|
10902
11191
|
}
|
|
10903
11192
|
) }),
|
|
10904
|
-
/* @__PURE__ */
|
|
11193
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
|
|
10905
11194
|
] });
|
|
10906
11195
|
}
|
|
10907
11196
|
case "confirm": {
|
|
@@ -10909,8 +11198,8 @@ ${template}`;
|
|
|
10909
11198
|
{ label: "Save", value: "save", key: "save" },
|
|
10910
11199
|
{ label: "Cancel", value: "cancel", key: "cancel" }
|
|
10911
11200
|
];
|
|
10912
|
-
return /* @__PURE__ */
|
|
10913
|
-
/* @__PURE__ */
|
|
11201
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11202
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10914
11203
|
mode === "create" ? "Create" : "Edit",
|
|
10915
11204
|
" custom command \u2014 Confirm (",
|
|
10916
11205
|
stepIndex,
|
|
@@ -10918,14 +11207,14 @@ ${template}`;
|
|
|
10918
11207
|
totalSteps,
|
|
10919
11208
|
")"
|
|
10920
11209
|
] }),
|
|
10921
|
-
/* @__PURE__ */
|
|
11210
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10922
11211
|
source === "project" ? ".kimiflare/commands/" : "~/.config/kimiflare/commands/",
|
|
10923
11212
|
name,
|
|
10924
11213
|
".md"
|
|
10925
11214
|
] }),
|
|
10926
|
-
/* @__PURE__ */
|
|
10927
|
-
/* @__PURE__ */
|
|
10928
|
-
|
|
11215
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: line || " " }, i)) }),
|
|
11216
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11217
|
+
SelectInput7,
|
|
10929
11218
|
{
|
|
10930
11219
|
items,
|
|
10931
11220
|
onSelect: (item) => handleConfirm(item.value)
|
|
@@ -10935,7 +11224,7 @@ ${template}`;
|
|
|
10935
11224
|
}
|
|
10936
11225
|
}
|
|
10937
11226
|
};
|
|
10938
|
-
return /* @__PURE__ */
|
|
11227
|
+
return /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
|
|
10939
11228
|
}
|
|
10940
11229
|
var NAME_RE;
|
|
10941
11230
|
var init_command_wizard = __esm({
|
|
@@ -10947,10 +11236,442 @@ var init_command_wizard = __esm({
|
|
|
10947
11236
|
}
|
|
10948
11237
|
});
|
|
10949
11238
|
|
|
11239
|
+
// src/init/context-generator.ts
|
|
11240
|
+
import { existsSync as existsSync2, statSync as statSync3 } from "fs";
|
|
11241
|
+
import { join as join20 } from "path";
|
|
11242
|
+
function detectFlavor(cwd) {
|
|
11243
|
+
for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
|
|
11244
|
+
if (flavor === "generic") continue;
|
|
11245
|
+
for (const sig of signatures) {
|
|
11246
|
+
const path = join20(cwd, sig);
|
|
11247
|
+
if (sig.includes("*")) {
|
|
11248
|
+
try {
|
|
11249
|
+
const parts = sig.split("*");
|
|
11250
|
+
const prefix = parts[0] ?? "";
|
|
11251
|
+
const suffix = parts[1] ?? "";
|
|
11252
|
+
const entries = __require("fs").readdirSync(cwd);
|
|
11253
|
+
if (entries.some((e) => e.startsWith(prefix) && e.endsWith(suffix))) {
|
|
11254
|
+
return flavor;
|
|
11255
|
+
}
|
|
11256
|
+
} catch {
|
|
11257
|
+
}
|
|
11258
|
+
} else if (existsSync2(path)) {
|
|
11259
|
+
return flavor;
|
|
11260
|
+
}
|
|
11261
|
+
}
|
|
11262
|
+
}
|
|
11263
|
+
return "generic";
|
|
11264
|
+
}
|
|
11265
|
+
function findFile(cwd, candidates) {
|
|
11266
|
+
for (const c of candidates) {
|
|
11267
|
+
if (existsSync2(join20(cwd, c))) return c;
|
|
11268
|
+
}
|
|
11269
|
+
return null;
|
|
11270
|
+
}
|
|
11271
|
+
function findSourceRoots(cwd) {
|
|
11272
|
+
const roots = [];
|
|
11273
|
+
for (const r of SOURCE_ROOT_CANDIDATES) {
|
|
11274
|
+
const p = join20(cwd, r);
|
|
11275
|
+
try {
|
|
11276
|
+
const s = statSync3(p);
|
|
11277
|
+
if (s.isDirectory()) roots.push(r);
|
|
11278
|
+
} catch {
|
|
11279
|
+
}
|
|
11280
|
+
}
|
|
11281
|
+
return roots;
|
|
11282
|
+
}
|
|
11283
|
+
function findCiConfig(cwd) {
|
|
11284
|
+
for (const c of CI_PATHS) {
|
|
11285
|
+
if (existsSync2(join20(cwd, c))) {
|
|
11286
|
+
try {
|
|
11287
|
+
const s = statSync3(join20(cwd, c));
|
|
11288
|
+
return s.isDirectory() ? c : c;
|
|
11289
|
+
} catch {
|
|
11290
|
+
}
|
|
11291
|
+
}
|
|
11292
|
+
}
|
|
11293
|
+
return null;
|
|
11294
|
+
}
|
|
11295
|
+
function languageForFlavor(f) {
|
|
11296
|
+
const map = {
|
|
11297
|
+
node: "JavaScript / TypeScript",
|
|
11298
|
+
python: "Python",
|
|
11299
|
+
go: "Go",
|
|
11300
|
+
rust: "Rust",
|
|
11301
|
+
ruby: "Ruby",
|
|
11302
|
+
java: "Java / Kotlin",
|
|
11303
|
+
dotnet: "C# / F#",
|
|
11304
|
+
php: "PHP",
|
|
11305
|
+
elixir: "Elixir",
|
|
11306
|
+
haskell: "Haskell",
|
|
11307
|
+
c: "C",
|
|
11308
|
+
cpp: "C++",
|
|
11309
|
+
zig: "Zig",
|
|
11310
|
+
generic: "Unknown"
|
|
11311
|
+
};
|
|
11312
|
+
return map[f];
|
|
11313
|
+
}
|
|
11314
|
+
function analyzeProject(cwd) {
|
|
11315
|
+
const flavor = detectFlavor(cwd);
|
|
11316
|
+
const packageFiles = {
|
|
11317
|
+
node: ["package.json"],
|
|
11318
|
+
python: ["pyproject.toml", "setup.py", "setup.cfg"],
|
|
11319
|
+
go: ["go.mod"],
|
|
11320
|
+
rust: ["Cargo.toml"],
|
|
11321
|
+
ruby: ["Gemfile"],
|
|
11322
|
+
java: ["pom.xml", "build.gradle", "build.gradle.kts"],
|
|
11323
|
+
dotnet: ["*.csproj"],
|
|
11324
|
+
php: ["composer.json"],
|
|
11325
|
+
elixir: ["mix.exs"],
|
|
11326
|
+
haskell: ["package.yaml", "*.cabal"],
|
|
11327
|
+
c: ["Makefile", "CMakeLists.txt"],
|
|
11328
|
+
cpp: ["Makefile", "CMakeLists.txt"],
|
|
11329
|
+
zig: ["build.zig"],
|
|
11330
|
+
generic: []
|
|
11331
|
+
};
|
|
11332
|
+
const lockFiles = {
|
|
11333
|
+
node: ["package-lock.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb"],
|
|
11334
|
+
python: ["poetry.lock", "uv.lock", "Pipfile.lock"],
|
|
11335
|
+
go: ["go.sum"],
|
|
11336
|
+
rust: ["Cargo.lock"],
|
|
11337
|
+
ruby: ["Gemfile.lock"],
|
|
11338
|
+
java: [],
|
|
11339
|
+
dotnet: [],
|
|
11340
|
+
php: ["composer.lock"],
|
|
11341
|
+
elixir: ["mix.lock"],
|
|
11342
|
+
haskell: [],
|
|
11343
|
+
c: [],
|
|
11344
|
+
cpp: [],
|
|
11345
|
+
zig: [],
|
|
11346
|
+
generic: []
|
|
11347
|
+
};
|
|
11348
|
+
const buildFiles = {
|
|
11349
|
+
node: ["tsup.config.ts", "vite.config.ts", "webpack.config.js", "rollup.config.js", "esbuild.js", "next.config.js", "nuxt.config.ts", "astro.config.mjs", "svelte.config.js"],
|
|
11350
|
+
python: ["setup.py", "setup.cfg", "pyproject.toml"],
|
|
11351
|
+
go: ["Makefile"],
|
|
11352
|
+
rust: ["Cargo.toml"],
|
|
11353
|
+
ruby: ["Rakefile"],
|
|
11354
|
+
java: ["pom.xml", "build.gradle"],
|
|
11355
|
+
dotnet: ["*.sln"],
|
|
11356
|
+
php: [],
|
|
11357
|
+
elixir: ["mix.exs"],
|
|
11358
|
+
haskell: ["package.yaml", "*.cabal"],
|
|
11359
|
+
c: ["Makefile", "CMakeLists.txt"],
|
|
11360
|
+
cpp: ["Makefile", "CMakeLists.txt"],
|
|
11361
|
+
zig: ["build.zig"],
|
|
11362
|
+
generic: []
|
|
11363
|
+
};
|
|
11364
|
+
const testConfigs = {
|
|
11365
|
+
node: ["vitest.config.ts", "jest.config.js", "playwright.config.ts", "cypress.config.ts", "ava.config.js"],
|
|
11366
|
+
python: ["pytest.ini", "tox.ini", "setup.cfg"],
|
|
11367
|
+
go: [],
|
|
11368
|
+
rust: [],
|
|
11369
|
+
ruby: ["Rakefile", "spec_helper.rb"],
|
|
11370
|
+
java: [],
|
|
11371
|
+
dotnet: [],
|
|
11372
|
+
php: ["phpunit.xml"],
|
|
11373
|
+
elixir: ["test/test_helper.exs"],
|
|
11374
|
+
haskell: [],
|
|
11375
|
+
c: ["Makefile"],
|
|
11376
|
+
cpp: ["Makefile"],
|
|
11377
|
+
zig: [],
|
|
11378
|
+
generic: []
|
|
11379
|
+
};
|
|
11380
|
+
const lintConfigs = {
|
|
11381
|
+
node: [".eslintrc", ".eslintrc.js", ".eslintrc.json", ".prettierrc", "biome.json", "deno.json"],
|
|
11382
|
+
python: [".flake8", "pyproject.toml", "setup.cfg", ".pylintrc", "ruff.toml"],
|
|
11383
|
+
go: [],
|
|
11384
|
+
rust: ["rustfmt.toml", "clippy.toml"],
|
|
11385
|
+
ruby: [".rubocop.yml"],
|
|
11386
|
+
java: [],
|
|
11387
|
+
dotnet: [],
|
|
11388
|
+
php: [],
|
|
11389
|
+
elixir: [".formatter.exs"],
|
|
11390
|
+
haskell: [],
|
|
11391
|
+
c: [".clang-format", ".clang-tidy"],
|
|
11392
|
+
cpp: [".clang-format", ".clang-tidy"],
|
|
11393
|
+
zig: [],
|
|
11394
|
+
generic: []
|
|
11395
|
+
};
|
|
11396
|
+
const typeConfigs = {
|
|
11397
|
+
node: ["tsconfig.json", "jsconfig.json"],
|
|
11398
|
+
python: ["pyproject.toml", "setup.cfg", "mypy.ini"],
|
|
11399
|
+
go: [],
|
|
11400
|
+
rust: [],
|
|
11401
|
+
ruby: [],
|
|
11402
|
+
java: [],
|
|
11403
|
+
dotnet: [],
|
|
11404
|
+
php: [],
|
|
11405
|
+
elixir: [],
|
|
11406
|
+
haskell: [],
|
|
11407
|
+
c: [],
|
|
11408
|
+
cpp: [],
|
|
11409
|
+
zig: [],
|
|
11410
|
+
generic: []
|
|
11411
|
+
};
|
|
11412
|
+
return {
|
|
11413
|
+
flavor,
|
|
11414
|
+
primaryLanguage: languageForFlavor(flavor),
|
|
11415
|
+
packageFile: findFile(cwd, packageFiles[flavor]),
|
|
11416
|
+
lockFile: findFile(cwd, lockFiles[flavor]),
|
|
11417
|
+
buildFile: findFile(cwd, buildFiles[flavor]),
|
|
11418
|
+
testConfig: findFile(cwd, testConfigs[flavor]),
|
|
11419
|
+
lintConfig: findFile(cwd, lintConfigs[flavor]),
|
|
11420
|
+
typeConfig: findFile(cwd, typeConfigs[flavor]),
|
|
11421
|
+
ciConfig: findCiConfig(cwd),
|
|
11422
|
+
readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
|
|
11423
|
+
sourceRoots: findSourceRoots(cwd),
|
|
11424
|
+
hasGit: existsSync2(join20(cwd, ".git"))
|
|
11425
|
+
};
|
|
11426
|
+
}
|
|
11427
|
+
function bashDiscoveryCommands(profile) {
|
|
11428
|
+
const cmds = [];
|
|
11429
|
+
if (profile.hasGit) {
|
|
11430
|
+
cmds.push(
|
|
11431
|
+
"git log --oneline -20",
|
|
11432
|
+
"git branch -a | head -20"
|
|
11433
|
+
);
|
|
11434
|
+
}
|
|
11435
|
+
switch (profile.flavor) {
|
|
11436
|
+
case "node":
|
|
11437
|
+
cmds.push(
|
|
11438
|
+
`cat package.json | jq -r '.scripts | to_entries[] | "\\(.key): \\(.value)"' 2>/dev/null || node -e "const p=require('./package.json'); Object.entries(p.scripts||{}).forEach(([k,v])=>console.log(k+': '+v))"`,
|
|
11439
|
+
"ls -la node_modules/.bin 2>/dev/null | head -30 || true"
|
|
11440
|
+
);
|
|
11441
|
+
break;
|
|
11442
|
+
case "python":
|
|
11443
|
+
cmds.push(
|
|
11444
|
+
`python -c "import tomllib; f=open('pyproject.toml','rb'); d=tomllib.load(f); [print(f'{k}: {v}') for k,v in d.get('project',{}).get('scripts',{}).items()]" 2>/dev/null || true`,
|
|
11445
|
+
"make -p 2>/dev/null | grep -E '^[a-zA-Z_-]+:.*$' | head -20 || true"
|
|
11446
|
+
);
|
|
11447
|
+
break;
|
|
11448
|
+
case "go":
|
|
11449
|
+
cmds.push("go help 2>/dev/null | head -10 || true");
|
|
11450
|
+
break;
|
|
11451
|
+
case "rust":
|
|
11452
|
+
cmds.push("cargo --list 2>/dev/null | head -20 || true");
|
|
11453
|
+
break;
|
|
11454
|
+
case "ruby":
|
|
11455
|
+
cmds.push("bundle exec rake -T 2>/dev/null | head -20 || true");
|
|
11456
|
+
break;
|
|
11457
|
+
case "java":
|
|
11458
|
+
cmds.push("./mvnw help:describe -Dplugin=help 2>/dev/null | head -10 || true");
|
|
11459
|
+
break;
|
|
11460
|
+
}
|
|
11461
|
+
cmds.push("ls -la");
|
|
11462
|
+
return cmds;
|
|
11463
|
+
}
|
|
11464
|
+
function discoveryChecklist(profile) {
|
|
11465
|
+
const lines = [];
|
|
11466
|
+
lines.push("## PHASE 1: Project Identity & Configuration");
|
|
11467
|
+
lines.push("");
|
|
11468
|
+
if (profile.readme) {
|
|
11469
|
+
lines.push(`- [ ] Read \`${profile.readme}\` \u2014 extract project name, description, purpose.`);
|
|
11470
|
+
}
|
|
11471
|
+
if (profile.packageFile) {
|
|
11472
|
+
lines.push(`- [ ] Read \`${profile.packageFile}\` \u2014 extract dependencies, scripts, metadata.`);
|
|
11473
|
+
}
|
|
11474
|
+
if (profile.buildFile) {
|
|
11475
|
+
lines.push(`- [ ] Read \`${profile.buildFile}\` \u2014 understand build system and entry points.`);
|
|
11476
|
+
}
|
|
11477
|
+
if (profile.typeConfig) {
|
|
11478
|
+
lines.push(`- [ ] Read \`${profile.typeConfig}\` \u2014 note strictness, target, module system.`);
|
|
11479
|
+
}
|
|
11480
|
+
if (profile.testConfig) {
|
|
11481
|
+
lines.push(`- [ ] Read \`${profile.testConfig}\` \u2014 understand test runner and conventions.`);
|
|
11482
|
+
}
|
|
11483
|
+
if (profile.lintConfig) {
|
|
11484
|
+
lines.push(`- [ ] Read \`${profile.lintConfig}\` \u2014 note style rules and formatter.`);
|
|
11485
|
+
}
|
|
11486
|
+
if (profile.ciConfig) {
|
|
11487
|
+
lines.push(`- [ ] Inspect CI config in \`${profile.ciConfig}\` \u2014 note checks, matrix, deployment.`);
|
|
11488
|
+
}
|
|
11489
|
+
lines.push("");
|
|
11490
|
+
lines.push("## PHASE 2: Source Structure Discovery");
|
|
11491
|
+
lines.push("");
|
|
11492
|
+
for (const root of profile.sourceRoots) {
|
|
11493
|
+
lines.push(`- [ ] Use \`glob\` to list files in \`${root}/**/*\` (limit to ~50 files).`);
|
|
11494
|
+
lines.push(`- [ ] Read 3-5 representative files from \`${root}\` to understand code patterns.`);
|
|
11495
|
+
}
|
|
11496
|
+
if (profile.sourceRoots.length === 0) {
|
|
11497
|
+
lines.push("- [ ] Use `glob` to find source files (`**/*.{js,ts,py,go,rs,rb,java,cs,php,ex,hs,c,cpp,zig}`) \u2014 list top 50.");
|
|
11498
|
+
lines.push("- [ ] Read 3-5 representative source files to understand code patterns.");
|
|
11499
|
+
}
|
|
11500
|
+
lines.push("- [ ] Use `glob` to find test files and note their location/naming pattern.");
|
|
11501
|
+
lines.push("- [ ] Use `glob` to find config files at root level.");
|
|
11502
|
+
lines.push("");
|
|
11503
|
+
lines.push("## PHASE 3: Convention Extraction");
|
|
11504
|
+
lines.push("");
|
|
11505
|
+
lines.push("- [ ] Use `grep` to find import patterns (e.g., `import .* from` or `require(`).");
|
|
11506
|
+
lines.push("- [ ] Use `grep` to find export patterns (e.g., `export ` or `module.exports`).");
|
|
11507
|
+
lines.push("- [ ] Check for any `.editorconfig`, `.gitignore`, or `CONTRIBUTING.md`.");
|
|
11508
|
+
if (profile.hasGit) {
|
|
11509
|
+
lines.push("- [ ] Run `git log --oneline -20` to understand commit style and recent activity.");
|
|
11510
|
+
lines.push("- [ ] Run `git branch -a | head -20` to understand branching strategy.");
|
|
11511
|
+
}
|
|
11512
|
+
lines.push("");
|
|
11513
|
+
lines.push("## PHASE 4: Build & Development Workflow");
|
|
11514
|
+
lines.push("");
|
|
11515
|
+
const bashCmds = bashDiscoveryCommands(profile);
|
|
11516
|
+
for (const cmd of bashCmds) {
|
|
11517
|
+
lines.push(`- [ ] Run \`bash\` with: \`${cmd}\``);
|
|
11518
|
+
}
|
|
11519
|
+
lines.push("");
|
|
11520
|
+
lines.push("## PHASE 5: Architecture & Patterns (Deep Dive)");
|
|
11521
|
+
lines.push("");
|
|
11522
|
+
lines.push("- [ ] Identify the main entry point(s) of the application.");
|
|
11523
|
+
lines.push("- [ ] Identify the testing framework and how tests are organized.");
|
|
11524
|
+
lines.push("- [ ] Look for any architectural patterns: MVC, hexagonal, actor model, etc.");
|
|
11525
|
+
lines.push("- [ ] Note any code-generation, build-time transforms, or code-mod tools.");
|
|
11526
|
+
lines.push("- [ ] Check for Docker, docker-compose, or deployment configs.");
|
|
11527
|
+
lines.push("- [ ] Note any monorepo patterns (workspaces, turborepo, nx, etc.).");
|
|
11528
|
+
return lines.join("\n");
|
|
11529
|
+
}
|
|
11530
|
+
function sectionTemplate() {
|
|
11531
|
+
return `
|
|
11532
|
+
Generate the context document with these sections. Be concise but comprehensive.
|
|
11533
|
+
Aim for 100\u2013200 lines total. Use markdown tables where they save space.
|
|
11534
|
+
|
|
11535
|
+
### Required Sections
|
|
11536
|
+
|
|
11537
|
+
1. **Project** \u2014 One-line description + primary language/runtime + key frameworks.
|
|
11538
|
+
|
|
11539
|
+
2. **Build / test / run** \u2014 Exact shell commands. Include:
|
|
11540
|
+
- Development server / watch mode
|
|
11541
|
+
- Production build
|
|
11542
|
+
- Test commands (unit, integration, e2e if separate)
|
|
11543
|
+
- Lint / format commands
|
|
11544
|
+
- Type-checking commands
|
|
11545
|
+
- Any setup / install commands
|
|
11546
|
+
Note which commands are slow or require special setup.
|
|
11547
|
+
|
|
11548
|
+
3. **Layout** \u2014 Table of key directories AND a one-sentence rationale for each.
|
|
11549
|
+
Explain *why* things live where they do, not just *what* is there.
|
|
11550
|
+
|
|
11551
|
+
4. **Conventions** \u2014 Cover:
|
|
11552
|
+
- Naming conventions (files, variables, types, tests)
|
|
11553
|
+
- Import style and path resolution quirks
|
|
11554
|
+
- File organization patterns
|
|
11555
|
+
- Commit message style (if discernible from git history)
|
|
11556
|
+
- Branching strategy
|
|
11557
|
+
- TypeScript / type system strictness rules
|
|
11558
|
+
- Testing conventions (naming, location, mocks)
|
|
11559
|
+
- Anything surprising or non-obvious
|
|
11560
|
+
|
|
11561
|
+
5. **Dependencies** \u2014 Rules for adding dependencies:
|
|
11562
|
+
- Package manager commands
|
|
11563
|
+
- Dev vs runtime dependency conventions
|
|
11564
|
+
- Native deps that must stay external (if bundling)
|
|
11565
|
+
- Version pinning policy
|
|
11566
|
+
|
|
11567
|
+
6. **Do / Don't** \u2014 Numbered list of hard rules:
|
|
11568
|
+
- Security rules (never commit secrets, etc.)
|
|
11569
|
+
- Performance rules (don't bundle X, etc.)
|
|
11570
|
+
- Style rules that aren't caught by linters
|
|
11571
|
+
- Common mistakes to avoid
|
|
11572
|
+
- Anything that would make a maintainer sad
|
|
11573
|
+
|
|
11574
|
+
7. **Debugging & Troubleshooting** \u2014 Common issues:
|
|
11575
|
+
- How to run in debug mode
|
|
11576
|
+
- Common build failures and fixes
|
|
11577
|
+
- How to reset / clean the project
|
|
11578
|
+
- Where logs live
|
|
11579
|
+
|
|
11580
|
+
8. **Architecture Notes** (if applicable) \u2014 Brief notes on:
|
|
11581
|
+
- Key abstractions and their responsibilities
|
|
11582
|
+
- Data flow
|
|
11583
|
+
- External integrations
|
|
11584
|
+
- State management approach
|
|
11585
|
+
`.trim();
|
|
11586
|
+
}
|
|
11587
|
+
function buildInitPrompt(cwd) {
|
|
11588
|
+
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
|
|
11589
|
+
(n) => existsSync2(join20(cwd, n))
|
|
11590
|
+
);
|
|
11591
|
+
const isRefresh = existingName !== void 0;
|
|
11592
|
+
const targetFilename = existingName ?? "KIMI.md";
|
|
11593
|
+
const profile = analyzeProject(cwd);
|
|
11594
|
+
const checklist = discoveryChecklist(profile);
|
|
11595
|
+
const sections = sectionTemplate();
|
|
11596
|
+
const promptParts = [
|
|
11597
|
+
isRefresh ? `Regenerate \`${targetFilename}\` at the repository root to refresh project context. The file already exists \u2014 read it first and preserve anything still accurate, updating only what has changed or is missing.` : `Generate a \`${targetFilename}\` at the repository root so future agents have comprehensive project context.`,
|
|
11598
|
+
"",
|
|
11599
|
+
"This is a **structured investigation**. Follow the checklist below systematically. Use the `glob`, `read`, `grep`, and `bash` tools to gather information. Do not skip steps.",
|
|
11600
|
+
"",
|
|
11601
|
+
`**Detected project profile:** ${profile.primaryLanguage} (${profile.flavor})`,
|
|
11602
|
+
profile.packageFile ? `- Package file: ${profile.packageFile}` : null,
|
|
11603
|
+
profile.buildFile ? `- Build file: ${profile.buildFile}` : null,
|
|
11604
|
+
profile.testConfig ? `- Test config: ${profile.testConfig}` : null,
|
|
11605
|
+
profile.typeConfig ? `- Type config: ${profile.typeConfig}` : null,
|
|
11606
|
+
profile.lintConfig ? `- Lint config: ${profile.lintConfig}` : null,
|
|
11607
|
+
profile.ciConfig ? `- CI config: ${profile.ciConfig}` : null,
|
|
11608
|
+
profile.sourceRoots.length > 0 ? `- Source roots: ${profile.sourceRoots.join(", ")}` : null,
|
|
11609
|
+
profile.hasGit ? `- Git repository: yes` : null,
|
|
11610
|
+
"",
|
|
11611
|
+
"---",
|
|
11612
|
+
"",
|
|
11613
|
+
checklist,
|
|
11614
|
+
"",
|
|
11615
|
+
"---",
|
|
11616
|
+
"",
|
|
11617
|
+
sections,
|
|
11618
|
+
"",
|
|
11619
|
+
isRefresh ? `After writing the file, re-read \`${targetFilename}\` and verify it is complete and accurate.` : "After writing the file, re-read it and verify all sections are present and accurate.",
|
|
11620
|
+
"",
|
|
11621
|
+
"Do not call `tasks_set` for this. Just follow the checklist, gather information, then write the file."
|
|
11622
|
+
];
|
|
11623
|
+
const prompt = promptParts.filter((p) => p !== null).join("\n");
|
|
11624
|
+
return { prompt, targetFilename, isRefresh };
|
|
11625
|
+
}
|
|
11626
|
+
var FLAVOR_SIGNATURES, SOURCE_ROOT_CANDIDATES, CI_PATHS;
|
|
11627
|
+
var init_context_generator = __esm({
|
|
11628
|
+
"src/init/context-generator.ts"() {
|
|
11629
|
+
"use strict";
|
|
11630
|
+
FLAVOR_SIGNATURES = {
|
|
11631
|
+
node: ["package.json", "package-lock.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb", "node_modules"],
|
|
11632
|
+
python: ["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", "poetry.lock", "uv.lock", "tox.ini"],
|
|
11633
|
+
go: ["go.mod", "go.sum"],
|
|
11634
|
+
rust: ["Cargo.toml", "Cargo.lock"],
|
|
11635
|
+
ruby: ["Gemfile", "Gemfile.lock", "*.gemspec"],
|
|
11636
|
+
java: ["pom.xml", "build.gradle", "build.gradle.kts"],
|
|
11637
|
+
dotnet: ["*.csproj", "*.fsproj", "*.sln"],
|
|
11638
|
+
php: ["composer.json", "composer.lock"],
|
|
11639
|
+
elixir: ["mix.exs", "mix.lock"],
|
|
11640
|
+
haskell: ["package.yaml", "*.cabal", "stack.yaml"],
|
|
11641
|
+
c: ["Makefile", "CMakeLists.txt", "configure.ac"],
|
|
11642
|
+
cpp: ["Makefile", "CMakeLists.txt", "configure.ac"],
|
|
11643
|
+
zig: ["build.zig", "build.zig.zon"],
|
|
11644
|
+
generic: []
|
|
11645
|
+
};
|
|
11646
|
+
SOURCE_ROOT_CANDIDATES = [
|
|
11647
|
+
"src",
|
|
11648
|
+
"lib",
|
|
11649
|
+
"app",
|
|
11650
|
+
"source",
|
|
11651
|
+
"Sources",
|
|
11652
|
+
"pkg",
|
|
11653
|
+
"internal",
|
|
11654
|
+
"cmd",
|
|
11655
|
+
"bin",
|
|
11656
|
+
"packages",
|
|
11657
|
+
"projects"
|
|
11658
|
+
];
|
|
11659
|
+
CI_PATHS = [
|
|
11660
|
+
".github/workflows",
|
|
11661
|
+
".gitlab-ci.yml",
|
|
11662
|
+
".circleci",
|
|
11663
|
+
"azure-pipelines.yml",
|
|
11664
|
+
"Jenkinsfile",
|
|
11665
|
+
".buildkite",
|
|
11666
|
+
"cloudbuild.yaml"
|
|
11667
|
+
];
|
|
11668
|
+
}
|
|
11669
|
+
});
|
|
11670
|
+
|
|
10950
11671
|
// src/ui/command-picker.tsx
|
|
10951
|
-
import { Box as
|
|
10952
|
-
import
|
|
10953
|
-
import { jsx as
|
|
11672
|
+
import { Box as Box15, Text as Text16 } from "ink";
|
|
11673
|
+
import SelectInput8 from "ink-select-input";
|
|
11674
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
10954
11675
|
function CommandPicker({ commands, title, onPick }) {
|
|
10955
11676
|
const theme = useTheme();
|
|
10956
11677
|
const items = commands.map((cmd) => ({
|
|
@@ -10959,11 +11680,11 @@ function CommandPicker({ commands, title, onPick }) {
|
|
|
10959
11680
|
key: cmd.name
|
|
10960
11681
|
}));
|
|
10961
11682
|
items.push({ label: "\u2190 Cancel", value: null, key: "__cancel__" });
|
|
10962
|
-
return /* @__PURE__ */
|
|
10963
|
-
/* @__PURE__ */
|
|
10964
|
-
/* @__PURE__ */
|
|
10965
|
-
/* @__PURE__ */
|
|
10966
|
-
|
|
11683
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11684
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.accent, bold: true, children: title }),
|
|
11685
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
11686
|
+
/* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
|
|
11687
|
+
SelectInput8,
|
|
10967
11688
|
{
|
|
10968
11689
|
items,
|
|
10969
11690
|
onSelect: (item) => {
|
|
@@ -10985,64 +11706,64 @@ var init_command_picker = __esm({
|
|
|
10985
11706
|
});
|
|
10986
11707
|
|
|
10987
11708
|
// src/ui/command-list.tsx
|
|
10988
|
-
import { Box as
|
|
10989
|
-
import { jsx as
|
|
11709
|
+
import { Box as Box16, Text as Text17, useInput as useInput6 } from "ink";
|
|
11710
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
10990
11711
|
function CommandList({ commands, onDone }) {
|
|
10991
11712
|
const theme = useTheme();
|
|
10992
|
-
|
|
11713
|
+
useInput6((_input, key) => {
|
|
10993
11714
|
if (key.escape) {
|
|
10994
11715
|
onDone();
|
|
10995
11716
|
}
|
|
10996
11717
|
});
|
|
10997
|
-
return /* @__PURE__ */
|
|
10998
|
-
/* @__PURE__ */
|
|
10999
|
-
/* @__PURE__ */
|
|
11000
|
-
/* @__PURE__ */
|
|
11001
|
-
commands.length === 0 && /* @__PURE__ */
|
|
11002
|
-
commands.map((cmd) => /* @__PURE__ */
|
|
11003
|
-
/* @__PURE__ */
|
|
11718
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11719
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
11720
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
|
|
11721
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
|
|
11722
|
+
commands.length === 0 && /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No custom commands found." }),
|
|
11723
|
+
commands.map((cmd) => /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginBottom: 1, children: [
|
|
11724
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
|
|
11004
11725
|
"/",
|
|
11005
11726
|
cmd.name
|
|
11006
11727
|
] }),
|
|
11007
|
-
/* @__PURE__ */
|
|
11728
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11008
11729
|
" ",
|
|
11009
11730
|
"source: ",
|
|
11010
11731
|
cmd.source
|
|
11011
11732
|
] }),
|
|
11012
|
-
/* @__PURE__ */
|
|
11733
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11013
11734
|
" ",
|
|
11014
11735
|
"path: ",
|
|
11015
11736
|
cmd.filepath
|
|
11016
11737
|
] }),
|
|
11017
|
-
cmd.description && /* @__PURE__ */
|
|
11738
|
+
cmd.description && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11018
11739
|
" ",
|
|
11019
11740
|
"desc: ",
|
|
11020
11741
|
cmd.description
|
|
11021
11742
|
] }),
|
|
11022
|
-
cmd.mode && /* @__PURE__ */
|
|
11743
|
+
cmd.mode && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11023
11744
|
" ",
|
|
11024
11745
|
"mode: ",
|
|
11025
11746
|
cmd.mode
|
|
11026
11747
|
] }),
|
|
11027
|
-
cmd.effort && /* @__PURE__ */
|
|
11748
|
+
cmd.effort && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11028
11749
|
" ",
|
|
11029
11750
|
"effort: ",
|
|
11030
11751
|
cmd.effort
|
|
11031
11752
|
] }),
|
|
11032
|
-
cmd.model && /* @__PURE__ */
|
|
11753
|
+
cmd.model && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11033
11754
|
" ",
|
|
11034
11755
|
"model: ",
|
|
11035
11756
|
cmd.model
|
|
11036
11757
|
] }),
|
|
11037
|
-
/* @__PURE__ */
|
|
11758
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11038
11759
|
" ",
|
|
11039
11760
|
"template:"
|
|
11040
11761
|
] }),
|
|
11041
|
-
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */
|
|
11762
|
+
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11042
11763
|
" ",
|
|
11043
11764
|
line || " "
|
|
11044
11765
|
] }, i)),
|
|
11045
|
-
cmd.template.split("\n").length > 5 && /* @__PURE__ */
|
|
11766
|
+
cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11046
11767
|
" ",
|
|
11047
11768
|
"..."
|
|
11048
11769
|
] })
|
|
@@ -11059,10 +11780,10 @@ var init_command_list = __esm({
|
|
|
11059
11780
|
|
|
11060
11781
|
// src/ui/lsp-wizard.tsx
|
|
11061
11782
|
import { useState as useState9 } from "react";
|
|
11062
|
-
import { Box as
|
|
11063
|
-
import
|
|
11783
|
+
import { Box as Box17, Text as Text18 } from "ink";
|
|
11784
|
+
import SelectInput9 from "ink-select-input";
|
|
11064
11785
|
import { spawn as spawn3 } from "child_process";
|
|
11065
|
-
import { jsx as
|
|
11786
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11066
11787
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
11067
11788
|
const theme = useTheme();
|
|
11068
11789
|
const [page, setPage] = useState9("main");
|
|
@@ -11173,11 +11894,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11173
11894
|
{ label: "(close)", value: "__close__", key: "__close__" }
|
|
11174
11895
|
];
|
|
11175
11896
|
if (page === "main") {
|
|
11176
|
-
return /* @__PURE__ */
|
|
11177
|
-
/* @__PURE__ */
|
|
11178
|
-
/* @__PURE__ */
|
|
11179
|
-
/* @__PURE__ */
|
|
11180
|
-
|
|
11897
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11898
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "LSP Servers" }),
|
|
11899
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
11900
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11901
|
+
SelectInput9,
|
|
11181
11902
|
{
|
|
11182
11903
|
items: mainItems,
|
|
11183
11904
|
onSelect: (item) => {
|
|
@@ -11204,11 +11925,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11204
11925
|
}),
|
|
11205
11926
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11206
11927
|
];
|
|
11207
|
-
return /* @__PURE__ */
|
|
11208
|
-
/* @__PURE__ */
|
|
11209
|
-
/* @__PURE__ */
|
|
11210
|
-
/* @__PURE__ */
|
|
11211
|
-
|
|
11928
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11929
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Add LSP Server" }),
|
|
11930
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
|
|
11931
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11932
|
+
SelectInput9,
|
|
11212
11933
|
{
|
|
11213
11934
|
items,
|
|
11214
11935
|
onSelect: (item) => {
|
|
@@ -11235,19 +11956,19 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11235
11956
|
{ label: isSuccess ? "Save to config \u2713" : "Save anyway", value: "save", key: "save" },
|
|
11236
11957
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11237
11958
|
];
|
|
11238
|
-
return /* @__PURE__ */
|
|
11239
|
-
/* @__PURE__ */
|
|
11959
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11960
|
+
/* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
|
|
11240
11961
|
"Install ",
|
|
11241
11962
|
selectedPreset.name
|
|
11242
11963
|
] }),
|
|
11243
|
-
/* @__PURE__ */
|
|
11244
|
-
/* @__PURE__ */
|
|
11245
|
-
/* @__PURE__ */
|
|
11246
|
-
/* @__PURE__ */
|
|
11964
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
|
|
11965
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
|
|
11966
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Command:" }),
|
|
11967
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
|
|
11247
11968
|
] }),
|
|
11248
|
-
installState.output && /* @__PURE__ */
|
|
11249
|
-
/* @__PURE__ */
|
|
11250
|
-
|
|
11969
|
+
installState.output && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx19(Text18, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
|
|
11970
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11971
|
+
SelectInput9,
|
|
11251
11972
|
{
|
|
11252
11973
|
items,
|
|
11253
11974
|
onSelect: (item) => {
|
|
@@ -11264,16 +11985,16 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11264
11985
|
}
|
|
11265
11986
|
}
|
|
11266
11987
|
) }),
|
|
11267
|
-
isSuccess && /* @__PURE__ */
|
|
11988
|
+
isSuccess && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
|
|
11268
11989
|
] });
|
|
11269
11990
|
}
|
|
11270
11991
|
if (page === "custom-name") {
|
|
11271
|
-
return /* @__PURE__ */
|
|
11272
|
-
/* @__PURE__ */
|
|
11273
|
-
/* @__PURE__ */
|
|
11274
|
-
/* @__PURE__ */
|
|
11275
|
-
/* @__PURE__ */
|
|
11276
|
-
/* @__PURE__ */
|
|
11992
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11993
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
|
|
11994
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
|
|
11995
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
|
|
11996
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
|
|
11997
|
+
/* @__PURE__ */ jsx19(
|
|
11277
11998
|
CustomTextInput,
|
|
11278
11999
|
{
|
|
11279
12000
|
value: customName,
|
|
@@ -11287,8 +12008,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11287
12008
|
}
|
|
11288
12009
|
)
|
|
11289
12010
|
] }),
|
|
11290
|
-
/* @__PURE__ */
|
|
11291
|
-
|
|
12011
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12012
|
+
SelectInput9,
|
|
11292
12013
|
{
|
|
11293
12014
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11294
12015
|
onSelect: () => setPage("add")
|
|
@@ -11297,12 +12018,12 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11297
12018
|
] });
|
|
11298
12019
|
}
|
|
11299
12020
|
if (page === "custom-command") {
|
|
11300
|
-
return /* @__PURE__ */
|
|
11301
|
-
/* @__PURE__ */
|
|
11302
|
-
/* @__PURE__ */
|
|
11303
|
-
/* @__PURE__ */
|
|
11304
|
-
/* @__PURE__ */
|
|
11305
|
-
/* @__PURE__ */
|
|
12021
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12022
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
|
|
12023
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
|
|
12024
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
|
|
12025
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
|
|
12026
|
+
/* @__PURE__ */ jsx19(
|
|
11306
12027
|
CustomTextInput,
|
|
11307
12028
|
{
|
|
11308
12029
|
value: customCommand,
|
|
@@ -11316,8 +12037,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11316
12037
|
}
|
|
11317
12038
|
)
|
|
11318
12039
|
] }),
|
|
11319
|
-
/* @__PURE__ */
|
|
11320
|
-
|
|
12040
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12041
|
+
SelectInput9,
|
|
11321
12042
|
{
|
|
11322
12043
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11323
12044
|
onSelect: () => setPage("custom-name")
|
|
@@ -11340,11 +12061,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11340
12061
|
},
|
|
11341
12062
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11342
12063
|
];
|
|
11343
|
-
return /* @__PURE__ */
|
|
11344
|
-
/* @__PURE__ */
|
|
11345
|
-
/* @__PURE__ */
|
|
11346
|
-
/* @__PURE__ */
|
|
11347
|
-
|
|
12064
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12065
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Save LSP Config" }),
|
|
12066
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
|
|
12067
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12068
|
+
SelectInput9,
|
|
11348
12069
|
{
|
|
11349
12070
|
items,
|
|
11350
12071
|
onSelect: (item) => {
|
|
@@ -11362,11 +12083,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11362
12083
|
if (page === "edit") {
|
|
11363
12084
|
const keys = Object.keys(servers);
|
|
11364
12085
|
if (keys.length === 0) {
|
|
11365
|
-
return /* @__PURE__ */
|
|
11366
|
-
/* @__PURE__ */
|
|
11367
|
-
/* @__PURE__ */
|
|
11368
|
-
/* @__PURE__ */
|
|
11369
|
-
|
|
12086
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12087
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
12088
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
|
|
12089
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12090
|
+
SelectInput9,
|
|
11370
12091
|
{
|
|
11371
12092
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11372
12093
|
onSelect: () => setPage("main")
|
|
@@ -11386,11 +12107,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11386
12107
|
}),
|
|
11387
12108
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11388
12109
|
];
|
|
11389
|
-
return /* @__PURE__ */
|
|
11390
|
-
/* @__PURE__ */
|
|
11391
|
-
/* @__PURE__ */
|
|
11392
|
-
/* @__PURE__ */
|
|
11393
|
-
|
|
12110
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12111
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
12112
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
|
|
12113
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12114
|
+
SelectInput9,
|
|
11394
12115
|
{
|
|
11395
12116
|
items,
|
|
11396
12117
|
onSelect: (item) => {
|
|
@@ -11407,11 +12128,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11407
12128
|
if (page === "delete") {
|
|
11408
12129
|
const keys = Object.keys(servers);
|
|
11409
12130
|
if (keys.length === 0) {
|
|
11410
|
-
return /* @__PURE__ */
|
|
11411
|
-
/* @__PURE__ */
|
|
11412
|
-
/* @__PURE__ */
|
|
11413
|
-
/* @__PURE__ */
|
|
11414
|
-
|
|
12131
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12132
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
12133
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
|
|
12134
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12135
|
+
SelectInput9,
|
|
11415
12136
|
{
|
|
11416
12137
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11417
12138
|
onSelect: () => setPage("main")
|
|
@@ -11427,11 +12148,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11427
12148
|
})),
|
|
11428
12149
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11429
12150
|
];
|
|
11430
|
-
return /* @__PURE__ */
|
|
11431
|
-
/* @__PURE__ */
|
|
11432
|
-
/* @__PURE__ */
|
|
11433
|
-
/* @__PURE__ */
|
|
11434
|
-
|
|
12151
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12152
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
12153
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
|
|
12154
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12155
|
+
SelectInput9,
|
|
11435
12156
|
{
|
|
11436
12157
|
items,
|
|
11437
12158
|
onSelect: (item) => {
|
|
@@ -11447,15 +12168,15 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11447
12168
|
}
|
|
11448
12169
|
if (page === "list") {
|
|
11449
12170
|
const keys = Object.keys(servers);
|
|
11450
|
-
return /* @__PURE__ */
|
|
11451
|
-
/* @__PURE__ */
|
|
11452
|
-
keys.length === 0 ? /* @__PURE__ */
|
|
12171
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12172
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
|
|
12173
|
+
keys.length === 0 ? /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
|
|
11453
12174
|
const s = servers[k];
|
|
11454
12175
|
const status = s.enabled !== false ? "enabled" : "disabled";
|
|
11455
|
-
return /* @__PURE__ */
|
|
12176
|
+
return /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
|
|
11456
12177
|
}) }),
|
|
11457
|
-
/* @__PURE__ */
|
|
11458
|
-
|
|
12178
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12179
|
+
SelectInput9,
|
|
11459
12180
|
{
|
|
11460
12181
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11461
12182
|
onSelect: () => setPage("main")
|
|
@@ -11581,9 +12302,9 @@ var init_lsp_wizard = __esm({
|
|
|
11581
12302
|
});
|
|
11582
12303
|
|
|
11583
12304
|
// src/ui/theme-picker.tsx
|
|
11584
|
-
import { Box as
|
|
11585
|
-
import
|
|
11586
|
-
import { jsx as
|
|
12305
|
+
import { Box as Box18, Text as Text19 } from "ink";
|
|
12306
|
+
import SelectInput10 from "ink-select-input";
|
|
12307
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11587
12308
|
function PaletteSwatches({ palette }) {
|
|
11588
12309
|
const colors = [
|
|
11589
12310
|
palette.primary,
|
|
@@ -11591,7 +12312,7 @@ function PaletteSwatches({ palette }) {
|
|
|
11591
12312
|
palette.success,
|
|
11592
12313
|
palette.error
|
|
11593
12314
|
];
|
|
11594
|
-
return /* @__PURE__ */
|
|
12315
|
+
return /* @__PURE__ */ jsx20(Box18, { children: colors.map((c, i) => /* @__PURE__ */ jsx20(Text19, { color: c, children: "\u2588" }, i)) });
|
|
11595
12316
|
}
|
|
11596
12317
|
function ThemePicker({ themes, onPick, onPreview }) {
|
|
11597
12318
|
const current = useTheme();
|
|
@@ -11599,10 +12320,10 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
11599
12320
|
...themes.map((t) => ({ label: t.label, value: t.name })),
|
|
11600
12321
|
{ label: "< Back", value: "__back__" }
|
|
11601
12322
|
];
|
|
11602
|
-
return /* @__PURE__ */
|
|
11603
|
-
/* @__PURE__ */
|
|
11604
|
-
/* @__PURE__ */
|
|
11605
|
-
|
|
12323
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
|
|
12324
|
+
/* @__PURE__ */ jsx20(Text19, { color: current.accent, bold: true, children: "Pick a theme" }),
|
|
12325
|
+
/* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
|
|
12326
|
+
SelectInput10,
|
|
11606
12327
|
{
|
|
11607
12328
|
items,
|
|
11608
12329
|
onHighlight: (item) => {
|
|
@@ -11621,9 +12342,9 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
11621
12342
|
itemComponent: ({ label, isSelected }) => {
|
|
11622
12343
|
const t = themes.find((x) => x.label === label);
|
|
11623
12344
|
const color = t?.accent ?? current.accent;
|
|
11624
|
-
return /* @__PURE__ */
|
|
11625
|
-
/* @__PURE__ */
|
|
11626
|
-
t && /* @__PURE__ */
|
|
12345
|
+
return /* @__PURE__ */ jsxs18(Box18, { children: [
|
|
12346
|
+
/* @__PURE__ */ jsx20(Text19, { color, bold: isSelected, dimColor: !isSelected, children: label }),
|
|
12347
|
+
t && /* @__PURE__ */ jsx20(Box18, { marginLeft: 1, children: /* @__PURE__ */ jsx20(PaletteSwatches, { palette: t.palette }) })
|
|
11627
12348
|
] });
|
|
11628
12349
|
}
|
|
11629
12350
|
}
|
|
@@ -11767,8 +12488,8 @@ var init_lsp_nudge = __esm({
|
|
|
11767
12488
|
});
|
|
11768
12489
|
|
|
11769
12490
|
// src/ui/file-picker.tsx
|
|
11770
|
-
import { Box as
|
|
11771
|
-
import { jsx as
|
|
12491
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
12492
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
11772
12493
|
function FilePicker({ items, selectedIndex, query }) {
|
|
11773
12494
|
const theme = useTheme();
|
|
11774
12495
|
let startIndex = 0;
|
|
@@ -11778,12 +12499,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
11778
12499
|
const visible = items.slice(startIndex, startIndex + VISIBLE_LIMIT);
|
|
11779
12500
|
const hasMoreAbove = startIndex > 0;
|
|
11780
12501
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT;
|
|
11781
|
-
return /* @__PURE__ */
|
|
11782
|
-
/* @__PURE__ */
|
|
11783
|
-
/* @__PURE__ */
|
|
11784
|
-
/* @__PURE__ */
|
|
11785
|
-
visible.length === 0 && /* @__PURE__ */
|
|
11786
|
-
hasMoreAbove && /* @__PURE__ */
|
|
12502
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12503
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
|
|
12504
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
12505
|
+
/* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
12506
|
+
visible.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No matches" }),
|
|
12507
|
+
hasMoreAbove && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
11787
12508
|
"\u2026 ",
|
|
11788
12509
|
startIndex,
|
|
11789
12510
|
" more above"
|
|
@@ -11792,12 +12513,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
11792
12513
|
const actualIndex = startIndex + i;
|
|
11793
12514
|
const isSelected = actualIndex === selectedIndex;
|
|
11794
12515
|
const label = item.isDirectory ? `${item.name}/` : item.name;
|
|
11795
|
-
return /* @__PURE__ */
|
|
12516
|
+
return /* @__PURE__ */ jsxs19(Text20, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
11796
12517
|
isSelected ? "\u203A " : " ",
|
|
11797
12518
|
label
|
|
11798
12519
|
] }, item.name);
|
|
11799
12520
|
}),
|
|
11800
|
-
hasMoreBelow && /* @__PURE__ */
|
|
12521
|
+
hasMoreBelow && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
11801
12522
|
"\u2026 ",
|
|
11802
12523
|
items.length - (startIndex + VISIBLE_LIMIT),
|
|
11803
12524
|
" more below"
|
|
@@ -11815,8 +12536,8 @@ var init_file_picker = __esm({
|
|
|
11815
12536
|
});
|
|
11816
12537
|
|
|
11817
12538
|
// src/ui/slash-picker.tsx
|
|
11818
|
-
import { Box as
|
|
11819
|
-
import { jsx as
|
|
12539
|
+
import { Box as Box20, Text as Text21 } from "ink";
|
|
12540
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
11820
12541
|
function sourceBadge(source) {
|
|
11821
12542
|
if (source === "builtin") return "";
|
|
11822
12543
|
if (source === "project") return "project";
|
|
@@ -11836,12 +12557,12 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
11836
12557
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT2;
|
|
11837
12558
|
const longestLabel = visible.reduce((m, it) => Math.max(m, commandLabel(it).length), 0);
|
|
11838
12559
|
const nameColWidth = Math.max(NAME_COL_MIN_WIDTH, longestLabel + NAME_DESC_GAP);
|
|
11839
|
-
return /* @__PURE__ */
|
|
11840
|
-
/* @__PURE__ */
|
|
11841
|
-
/* @__PURE__ */
|
|
11842
|
-
/* @__PURE__ */
|
|
11843
|
-
visible.length === 0 && /* @__PURE__ */
|
|
11844
|
-
hasMoreAbove && /* @__PURE__ */
|
|
12560
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12561
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
|
|
12562
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
12563
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
|
|
12564
|
+
visible.length === 0 && /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No matches" }),
|
|
12565
|
+
hasMoreAbove && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
11845
12566
|
"\u2026 ",
|
|
11846
12567
|
startIndex,
|
|
11847
12568
|
" more above"
|
|
@@ -11851,16 +12572,16 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
11851
12572
|
const isSelected = actualIndex === selectedIndex;
|
|
11852
12573
|
const nameCol = commandLabel(item).padEnd(nameColWidth);
|
|
11853
12574
|
const badge = sourceBadge(item.source);
|
|
11854
|
-
return /* @__PURE__ */
|
|
12575
|
+
return /* @__PURE__ */ jsxs20(Text21, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
11855
12576
|
isSelected ? "\u203A " : " ",
|
|
11856
12577
|
nameCol,
|
|
11857
|
-
/* @__PURE__ */
|
|
12578
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
11858
12579
|
item.description,
|
|
11859
12580
|
badge && ` [${badge}]`
|
|
11860
12581
|
] })
|
|
11861
12582
|
] }, item.name);
|
|
11862
12583
|
}),
|
|
11863
|
-
hasMoreBelow && /* @__PURE__ */
|
|
12584
|
+
hasMoreBelow && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
11864
12585
|
"\u2026 ",
|
|
11865
12586
|
items.length - (startIndex + VISIBLE_LIMIT2),
|
|
11866
12587
|
" more below"
|
|
@@ -11941,14 +12662,14 @@ __export(tui_report_exports, {
|
|
|
11941
12662
|
getCategoryReportText: () => getCategoryReportText
|
|
11942
12663
|
});
|
|
11943
12664
|
import { readFile as readFile16 } from "fs/promises";
|
|
11944
|
-
import { join as
|
|
12665
|
+
import { join as join21 } from "path";
|
|
11945
12666
|
import { homedir as homedir14 } from "os";
|
|
11946
12667
|
function usageDir3() {
|
|
11947
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
11948
|
-
return
|
|
12668
|
+
const xdg = process.env.XDG_DATA_HOME || join21(homedir14(), ".local", "share");
|
|
12669
|
+
return join21(xdg, "kimiflare");
|
|
11949
12670
|
}
|
|
11950
12671
|
function usagePath3() {
|
|
11951
|
-
return
|
|
12672
|
+
return join21(usageDir3(), "usage.json");
|
|
11952
12673
|
}
|
|
11953
12674
|
function today3() {
|
|
11954
12675
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -12026,18 +12747,18 @@ __export(app_exports, {
|
|
|
12026
12747
|
shouldOpenMentionPicker: () => shouldOpenMentionPicker,
|
|
12027
12748
|
shouldOpenSlashPicker: () => shouldOpenSlashPicker
|
|
12028
12749
|
});
|
|
12029
|
-
import React14, { useState as useState10, useRef as useRef3, useEffect as
|
|
12030
|
-
import { Box as
|
|
12031
|
-
import
|
|
12032
|
-
import { existsSync as
|
|
12033
|
-
import { join as
|
|
12750
|
+
import React14, { useState as useState10, useRef as useRef3, useEffect as useEffect6, useCallback as useCallback2 } from "react";
|
|
12751
|
+
import { Box as Box21, Text as Text22, useApp, useInput as useInput7, render } from "ink";
|
|
12752
|
+
import SelectInput11 from "ink-select-input";
|
|
12753
|
+
import { existsSync as existsSync3, statSync as statSync4 } from "fs";
|
|
12754
|
+
import { join as join22 } from "path";
|
|
12034
12755
|
import { unlink as unlink3 } from "fs/promises";
|
|
12035
12756
|
import { execSync as execSync2 } from "child_process";
|
|
12036
12757
|
import { spawn as spawn4 } from "child_process";
|
|
12037
12758
|
import { platform as platform2 } from "os";
|
|
12038
12759
|
import fg4 from "fast-glob";
|
|
12039
12760
|
import { readFileSync as readFileSync3 } from "fs";
|
|
12040
|
-
import { jsx as
|
|
12761
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
12041
12762
|
function buildFilePickerIgnoreList(cwd) {
|
|
12042
12763
|
const hardcoded = [
|
|
12043
12764
|
// Dependencies
|
|
@@ -12108,8 +12829,8 @@ function buildFilePickerIgnoreList(cwd) {
|
|
|
12108
12829
|
];
|
|
12109
12830
|
const gitignorePatterns = [];
|
|
12110
12831
|
try {
|
|
12111
|
-
const gitignorePath =
|
|
12112
|
-
const stats =
|
|
12832
|
+
const gitignorePath = join22(cwd, ".gitignore");
|
|
12833
|
+
const stats = statSync4(gitignorePath);
|
|
12113
12834
|
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
12114
12835
|
return hardcoded;
|
|
12115
12836
|
}
|
|
@@ -12177,7 +12898,7 @@ function gatewayUsageLookupFromConfig(cfg, meta) {
|
|
|
12177
12898
|
meta
|
|
12178
12899
|
};
|
|
12179
12900
|
}
|
|
12180
|
-
function
|
|
12901
|
+
function openBrowser2(url) {
|
|
12181
12902
|
const cmd = platform2() === "darwin" ? "open" : platform2() === "win32" ? "start" : "xdg-open";
|
|
12182
12903
|
const child = spawn4(cmd, [url], { detached: true, stdio: "ignore" });
|
|
12183
12904
|
child.unref();
|
|
@@ -12197,7 +12918,7 @@ function detectGitHubRepo(cachedRepo) {
|
|
|
12197
12918
|
}
|
|
12198
12919
|
return null;
|
|
12199
12920
|
}
|
|
12200
|
-
function
|
|
12921
|
+
function formatTokens4(n) {
|
|
12201
12922
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
12202
12923
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
12203
12924
|
return String(n);
|
|
@@ -12242,7 +12963,7 @@ function findImagePaths(text) {
|
|
|
12242
12963
|
let match;
|
|
12243
12964
|
while ((match = quotedRegex.exec(text)) !== null) {
|
|
12244
12965
|
const path = match[1] ?? match[2];
|
|
12245
|
-
if (path && isImagePath(path) &&
|
|
12966
|
+
if (path && isImagePath(path) && existsSync3(path)) {
|
|
12246
12967
|
paths.push(path);
|
|
12247
12968
|
}
|
|
12248
12969
|
}
|
|
@@ -12251,7 +12972,7 @@ function findImagePaths(text) {
|
|
|
12251
12972
|
const processed = remaining.replace(/\\ /g, ESCAPED_SPACE);
|
|
12252
12973
|
for (const token of processed.split(/\s+/)) {
|
|
12253
12974
|
const clean = token.replace(new RegExp(ESCAPED_SPACE, "g"), " ").replace(/^["']|["',;:!?]$/g, "").replace(/[.,;:!?]$/, "");
|
|
12254
|
-
if (clean && isImagePath(clean) &&
|
|
12975
|
+
if (clean && isImagePath(clean) && existsSync3(clean) && !paths.includes(clean)) {
|
|
12255
12976
|
paths.push(clean);
|
|
12256
12977
|
}
|
|
12257
12978
|
}
|
|
@@ -12268,8 +12989,9 @@ function App({
|
|
|
12268
12989
|
const [cfg, setCfg] = useState10(initialCfg);
|
|
12269
12990
|
const [lspScope, setLspScope] = useState10(initialLspScope);
|
|
12270
12991
|
const [lspProjectPath, setLspProjectPath] = useState10(initialLspProjectPath);
|
|
12992
|
+
const [cloudToken, setCloudToken] = useState10(initialCloudToken);
|
|
12271
12993
|
const [events, setRawEvents] = useState10([]);
|
|
12272
|
-
const setEvents =
|
|
12994
|
+
const setEvents = useCallback2(
|
|
12273
12995
|
(updater) => {
|
|
12274
12996
|
setRawEvents((prev) => {
|
|
12275
12997
|
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
@@ -12283,8 +13005,10 @@ function App({
|
|
|
12283
13005
|
const [usage, setUsage] = useState10(null);
|
|
12284
13006
|
const [sessionUsage, setSessionUsage] = useState10(null);
|
|
12285
13007
|
const [gatewayMeta, setGatewayMeta] = useState10(null);
|
|
13008
|
+
const [cloudBudget, setCloudBudget] = useState10(null);
|
|
12286
13009
|
const [showReasoning, setShowReasoning] = useState10(false);
|
|
12287
13010
|
const [perm, setPerm] = useState10(null);
|
|
13011
|
+
const [limitModal, setLimitModal] = useState10(null);
|
|
12288
13012
|
const [queue, setQueue] = useState10([]);
|
|
12289
13013
|
const [history, setHistory] = useState10([]);
|
|
12290
13014
|
const [historyIndex, setHistoryIndex] = useState10(-1);
|
|
@@ -12314,6 +13038,21 @@ function App({
|
|
|
12314
13038
|
const [theme, setTheme] = useState10(resolveTheme(initialCfg?.theme));
|
|
12315
13039
|
const [showThemePicker, setShowThemePicker] = useState10(false);
|
|
12316
13040
|
const [originalTheme, setOriginalTheme] = useState10(null);
|
|
13041
|
+
useEffect6(() => {
|
|
13042
|
+
if (!cfg?.cloudMode || !initialCloudToken) return;
|
|
13043
|
+
let cancelled = false;
|
|
13044
|
+
const fetchBudget = async () => {
|
|
13045
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
13046
|
+
const usage2 = await fetchCloudUsage2(initialCloudToken);
|
|
13047
|
+
if (usage2 && !cancelled) {
|
|
13048
|
+
setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
|
|
13049
|
+
}
|
|
13050
|
+
};
|
|
13051
|
+
fetchBudget();
|
|
13052
|
+
return () => {
|
|
13053
|
+
cancelled = true;
|
|
13054
|
+
};
|
|
13055
|
+
}, [cfg?.cloudMode, initialCloudToken]);
|
|
12317
13056
|
const [cursorOffset, setCursorOffset] = useState10(0);
|
|
12318
13057
|
const [activePicker, setActivePicker] = useState10(null);
|
|
12319
13058
|
const [filePickerItems, setFilePickerItems] = useState10([]);
|
|
@@ -12327,6 +13066,7 @@ function App({
|
|
|
12327
13066
|
const activeAsstIdRef = useRef3(null);
|
|
12328
13067
|
const activeControllerRef = useRef3(null);
|
|
12329
13068
|
const permResolveRef = useRef3(null);
|
|
13069
|
+
const limitResolveRef = useRef3(null);
|
|
12330
13070
|
const pendingToolCallsRef = useRef3(/* @__PURE__ */ new Map());
|
|
12331
13071
|
const sessionIdRef = useRef3(null);
|
|
12332
13072
|
const modeRef = useRef3(mode);
|
|
@@ -12348,12 +13088,16 @@ function App({
|
|
|
12348
13088
|
const lspManagerRef = useRef3(new LspManager());
|
|
12349
13089
|
const lspToolsRef = useRef3([]);
|
|
12350
13090
|
const lspInitRef = useRef3(false);
|
|
13091
|
+
const busyRef = useRef3(busy);
|
|
12351
13092
|
const memoryManagerRef = useRef3(null);
|
|
12352
13093
|
const sessionStartRecallRef = useRef3(null);
|
|
12353
13094
|
const pendingTextRef = useRef3(/* @__PURE__ */ new Map());
|
|
12354
13095
|
const flushTimeoutRef = useRef3(null);
|
|
12355
13096
|
const customCommandsRef = useRef3([]);
|
|
12356
13097
|
const pickerCancelRef = useRef3(null);
|
|
13098
|
+
useEffect6(() => {
|
|
13099
|
+
busyRef.current = busy;
|
|
13100
|
+
}, [busy]);
|
|
12357
13101
|
const pickerAnchor = activePicker?.anchor ?? null;
|
|
12358
13102
|
const pickerKind = activePicker?.kind ?? null;
|
|
12359
13103
|
const pickerQuery = React14.useMemo(() => {
|
|
@@ -12376,7 +13120,7 @@ function App({
|
|
|
12376
13120
|
if (pickerKind !== "slash" || pickerQuery === null) return [];
|
|
12377
13121
|
return fuzzyFilter(allSlashCommands, pickerQuery, (c) => c.name).slice(0, 50);
|
|
12378
13122
|
}, [pickerKind, allSlashCommands, pickerQuery]);
|
|
12379
|
-
|
|
13123
|
+
useEffect6(() => {
|
|
12380
13124
|
if (activePicker !== null) {
|
|
12381
13125
|
const trigger = activePicker.kind === "file" ? "@" : "/";
|
|
12382
13126
|
if (cursorOffset < activePicker.anchor) {
|
|
@@ -12433,28 +13177,28 @@ function App({
|
|
|
12433
13177
|
return;
|
|
12434
13178
|
}
|
|
12435
13179
|
}, [input, cursorOffset, activePicker, filePickerEnabled]);
|
|
12436
|
-
|
|
13180
|
+
useEffect6(() => {
|
|
12437
13181
|
if (activePicker?.kind !== "file") return;
|
|
12438
13182
|
const max = Math.max(0, filteredFileItems.length - 1);
|
|
12439
13183
|
if (activePicker.selected > max) {
|
|
12440
13184
|
setActivePicker({ ...activePicker, selected: max });
|
|
12441
13185
|
}
|
|
12442
13186
|
}, [filteredFileItems.length, activePicker]);
|
|
12443
|
-
|
|
13187
|
+
useEffect6(() => {
|
|
12444
13188
|
if (activePicker?.kind !== "slash") return;
|
|
12445
13189
|
const max = Math.max(0, filteredSlashItems.length - 1);
|
|
12446
13190
|
if (activePicker.selected > max) {
|
|
12447
13191
|
setActivePicker({ ...activePicker, selected: max });
|
|
12448
13192
|
}
|
|
12449
13193
|
}, [filteredSlashItems.length, activePicker]);
|
|
12450
|
-
const handlePickerUp =
|
|
13194
|
+
const handlePickerUp = useCallback2(() => {
|
|
12451
13195
|
setActivePicker((p) => {
|
|
12452
13196
|
if (!p) return null;
|
|
12453
13197
|
const next = Math.max(0, p.selected - 1);
|
|
12454
13198
|
return next === p.selected ? p : { ...p, selected: next };
|
|
12455
13199
|
});
|
|
12456
13200
|
}, []);
|
|
12457
|
-
const handlePickerDown =
|
|
13201
|
+
const handlePickerDown = useCallback2(() => {
|
|
12458
13202
|
setActivePicker((p) => {
|
|
12459
13203
|
if (!p) return null;
|
|
12460
13204
|
const max = p.kind === "file" ? Math.max(0, filteredFileItems.length - 1) : Math.max(0, filteredSlashItems.length - 1);
|
|
@@ -12462,7 +13206,7 @@ function App({
|
|
|
12462
13206
|
return next === p.selected ? p : { ...p, selected: next };
|
|
12463
13207
|
});
|
|
12464
13208
|
}, [filteredFileItems.length, filteredSlashItems.length]);
|
|
12465
|
-
const handlePickerSelect =
|
|
13209
|
+
const handlePickerSelect = useCallback2(() => {
|
|
12466
13210
|
if (!activePicker) return;
|
|
12467
13211
|
if (activePicker.kind === "file") {
|
|
12468
13212
|
const item2 = filteredFileItems[activePicker.selected];
|
|
@@ -12480,12 +13224,12 @@ function App({
|
|
|
12480
13224
|
setActivePicker(null);
|
|
12481
13225
|
submitRef.current(value);
|
|
12482
13226
|
}, [activePicker, filteredFileItems, filteredSlashItems, input, cursorOffset]);
|
|
12483
|
-
const handlePickerCancel =
|
|
13227
|
+
const handlePickerCancel = useCallback2(() => {
|
|
12484
13228
|
pickerCancelRef.current = cursorOffset;
|
|
12485
13229
|
setActivePicker(null);
|
|
12486
13230
|
}, [cursorOffset]);
|
|
12487
|
-
|
|
12488
|
-
const modalActive = showHelpMenu || commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null;
|
|
13231
|
+
useEffect6(() => {
|
|
13232
|
+
const modalActive = showHelpMenu || commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null || limitModal !== null;
|
|
12489
13233
|
if (modalActive && activePicker !== null) {
|
|
12490
13234
|
setActivePicker(null);
|
|
12491
13235
|
}
|
|
@@ -12498,9 +13242,10 @@ function App({
|
|
|
12498
13242
|
showLspWizard,
|
|
12499
13243
|
resumeSessions,
|
|
12500
13244
|
perm,
|
|
13245
|
+
limitModal,
|
|
12501
13246
|
activePicker
|
|
12502
13247
|
]);
|
|
12503
|
-
|
|
13248
|
+
useEffect6(() => {
|
|
12504
13249
|
if (!cfg) return;
|
|
12505
13250
|
void Promise.resolve().then(() => (init_sessions(), sessions_exports)).then(
|
|
12506
13251
|
({ pruneSessions: pruneSessions2 }) => pruneSessions2().then((removed) => {
|
|
@@ -12526,7 +13271,7 @@ function App({
|
|
|
12526
13271
|
}
|
|
12527
13272
|
});
|
|
12528
13273
|
if (cfg.memoryEnabled) {
|
|
12529
|
-
const dbPath = cfg.memoryDbPath ??
|
|
13274
|
+
const dbPath = cfg.memoryDbPath ?? join22(process.cwd(), ".kimiflare", "memory.db");
|
|
12530
13275
|
const manager = new MemoryManager({
|
|
12531
13276
|
dbPath,
|
|
12532
13277
|
accountId: cfg.accountId,
|
|
@@ -12594,7 +13339,7 @@ function App({
|
|
|
12594
13339
|
}
|
|
12595
13340
|
});
|
|
12596
13341
|
}, [cfg, setEvents]);
|
|
12597
|
-
|
|
13342
|
+
useEffect6(() => {
|
|
12598
13343
|
const id = setInterval(() => {
|
|
12599
13344
|
try {
|
|
12600
13345
|
performance.clearMarks();
|
|
@@ -12604,7 +13349,7 @@ function App({
|
|
|
12604
13349
|
}, 3e5);
|
|
12605
13350
|
return () => clearInterval(id);
|
|
12606
13351
|
}, []);
|
|
12607
|
-
const reloadCustomCommands =
|
|
13352
|
+
const reloadCustomCommands = useCallback2(async () => {
|
|
12608
13353
|
const { commands, warnings } = await loadCustomCommands(process.cwd());
|
|
12609
13354
|
customCommandsRef.current = commands;
|
|
12610
13355
|
setCustomCommandsVersion((v) => v + 1);
|
|
@@ -12619,7 +13364,7 @@ function App({
|
|
|
12619
13364
|
]);
|
|
12620
13365
|
}
|
|
12621
13366
|
}, [setEvents]);
|
|
12622
|
-
|
|
13367
|
+
useEffect6(() => {
|
|
12623
13368
|
if (!cfg || updateCheckedRef.current) return;
|
|
12624
13369
|
updateCheckedRef.current = true;
|
|
12625
13370
|
if (initialUpdateResult) {
|
|
@@ -12670,7 +13415,7 @@ function App({
|
|
|
12670
13415
|
}
|
|
12671
13416
|
});
|
|
12672
13417
|
}, [cfg, initialUpdateResult]);
|
|
12673
|
-
|
|
13418
|
+
useEffect6(() => {
|
|
12674
13419
|
modeRef.current = mode;
|
|
12675
13420
|
if (cacheStableRef.current) {
|
|
12676
13421
|
messagesRef.current[1] = {
|
|
@@ -12697,10 +13442,10 @@ function App({
|
|
|
12697
13442
|
executorRef.current.clearSessionPermissions();
|
|
12698
13443
|
}
|
|
12699
13444
|
}, [mode, cfg?.model]);
|
|
12700
|
-
|
|
13445
|
+
useEffect6(() => {
|
|
12701
13446
|
effortRef.current = effort;
|
|
12702
13447
|
}, [effort]);
|
|
12703
|
-
|
|
13448
|
+
useEffect6(() => {
|
|
12704
13449
|
if (!cfg) return;
|
|
12705
13450
|
const id = setInterval(() => {
|
|
12706
13451
|
void checkForUpdate().then((result) => {
|
|
@@ -12731,7 +13476,7 @@ function App({
|
|
|
12731
13476
|
}, 30 * 60 * 1e3);
|
|
12732
13477
|
return () => clearInterval(id);
|
|
12733
13478
|
}, [cfg]);
|
|
12734
|
-
const initMcp =
|
|
13479
|
+
const initMcp = useCallback2(async () => {
|
|
12735
13480
|
if (!cfg?.mcpServers || mcpInitRef.current) return;
|
|
12736
13481
|
mcpInitRef.current = true;
|
|
12737
13482
|
const manager = mcpManagerRef.current;
|
|
@@ -12792,7 +13537,7 @@ function App({
|
|
|
12792
13537
|
]);
|
|
12793
13538
|
}
|
|
12794
13539
|
}, [cfg]);
|
|
12795
|
-
const initLsp =
|
|
13540
|
+
const initLsp = useCallback2(async () => {
|
|
12796
13541
|
if (!cfg?.lspEnabled || !cfg?.lspServers || lspInitRef.current) {
|
|
12797
13542
|
if (lspInitRef.current) return;
|
|
12798
13543
|
if (!cfg?.lspEnabled) {
|
|
@@ -12855,7 +13600,7 @@ function App({
|
|
|
12855
13600
|
]);
|
|
12856
13601
|
}
|
|
12857
13602
|
}, [cfg]);
|
|
12858
|
-
|
|
13603
|
+
useEffect6(() => {
|
|
12859
13604
|
if (cfg && !mcpInitRef.current) {
|
|
12860
13605
|
void initMcp();
|
|
12861
13606
|
}
|
|
@@ -12863,7 +13608,7 @@ function App({
|
|
|
12863
13608
|
void initLsp();
|
|
12864
13609
|
}
|
|
12865
13610
|
}, [cfg, initMcp, initLsp]);
|
|
12866
|
-
const ensureSessionId =
|
|
13611
|
+
const ensureSessionId = useCallback2(() => {
|
|
12867
13612
|
if (sessionIdRef.current) return sessionIdRef.current;
|
|
12868
13613
|
const firstUser = messagesRef.current.find((m) => m.role === "user");
|
|
12869
13614
|
let firstText = "session";
|
|
@@ -12876,7 +13621,7 @@ function App({
|
|
|
12876
13621
|
sessionIdRef.current = makeSessionId(firstText);
|
|
12877
13622
|
return sessionIdRef.current;
|
|
12878
13623
|
}, []);
|
|
12879
|
-
const saveSessionSafe =
|
|
13624
|
+
const saveSessionSafe = useCallback2(async () => {
|
|
12880
13625
|
if (!cfg) return;
|
|
12881
13626
|
ensureSessionId();
|
|
12882
13627
|
try {
|
|
@@ -12893,7 +13638,7 @@ function App({
|
|
|
12893
13638
|
} catch {
|
|
12894
13639
|
}
|
|
12895
13640
|
}, [cfg, ensureSessionId]);
|
|
12896
|
-
const onIterationEnd =
|
|
13641
|
+
const onIterationEnd = useCallback2(
|
|
12897
13642
|
async (messages, signal) => {
|
|
12898
13643
|
if (signal.aborted) return messages;
|
|
12899
13644
|
if (!shouldCompact({ messages })) return messages;
|
|
@@ -12971,31 +13716,42 @@ function App({
|
|
|
12971
13716
|
},
|
|
12972
13717
|
[cfg]
|
|
12973
13718
|
);
|
|
12974
|
-
|
|
13719
|
+
useInput7((inputChar, key) => {
|
|
12975
13720
|
if (key.ctrl && inputChar === "c") {
|
|
12976
13721
|
const hadPerm = permResolveRef.current !== null;
|
|
13722
|
+
const hadLimit = limitResolveRef.current !== null;
|
|
12977
13723
|
if (hadPerm) {
|
|
12978
13724
|
permResolveRef.current("deny");
|
|
12979
13725
|
permResolveRef.current = null;
|
|
12980
13726
|
setPerm(null);
|
|
12981
13727
|
}
|
|
12982
|
-
if (
|
|
13728
|
+
if (hadLimit) {
|
|
13729
|
+
limitResolveRef.current("stop");
|
|
13730
|
+
limitResolveRef.current = null;
|
|
13731
|
+
setLimitModal(null);
|
|
13732
|
+
}
|
|
13733
|
+
if (busyRef.current && activeControllerRef.current) {
|
|
12983
13734
|
activeControllerRef.current.abort();
|
|
12984
13735
|
setQueue([]);
|
|
12985
13736
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
12986
|
-
} else if (!hadPerm) {
|
|
13737
|
+
} else if (!hadPerm && !hadLimit) {
|
|
12987
13738
|
void lspManagerRef.current.stopAll().finally(() => exit());
|
|
12988
13739
|
}
|
|
12989
13740
|
return;
|
|
12990
13741
|
}
|
|
12991
13742
|
if (key.escape) {
|
|
12992
|
-
const modalOpen = perm !== null || showHelpMenu || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null;
|
|
12993
|
-
if (!modalOpen &&
|
|
13743
|
+
const modalOpen = perm !== null || limitModal !== null || showHelpMenu || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null;
|
|
13744
|
+
if (!modalOpen && busyRef.current && activeControllerRef.current) {
|
|
12994
13745
|
if (permResolveRef.current) {
|
|
12995
13746
|
permResolveRef.current("deny");
|
|
12996
13747
|
permResolveRef.current = null;
|
|
12997
13748
|
setPerm(null);
|
|
12998
13749
|
}
|
|
13750
|
+
if (limitResolveRef.current) {
|
|
13751
|
+
limitResolveRef.current("stop");
|
|
13752
|
+
limitResolveRef.current = null;
|
|
13753
|
+
setLimitModal(null);
|
|
13754
|
+
}
|
|
12999
13755
|
activeControllerRef.current.abort();
|
|
13000
13756
|
setQueue([]);
|
|
13001
13757
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
@@ -13015,7 +13771,7 @@ function App({
|
|
|
13015
13771
|
return;
|
|
13016
13772
|
}
|
|
13017
13773
|
});
|
|
13018
|
-
const flushAssistantUpdates =
|
|
13774
|
+
const flushAssistantUpdates = useCallback2(() => {
|
|
13019
13775
|
flushTimeoutRef.current = null;
|
|
13020
13776
|
const pending = pendingTextRef.current;
|
|
13021
13777
|
if (pending.size === 0) return;
|
|
@@ -13033,7 +13789,7 @@ function App({
|
|
|
13033
13789
|
})
|
|
13034
13790
|
);
|
|
13035
13791
|
}, []);
|
|
13036
|
-
const updateAssistant =
|
|
13792
|
+
const updateAssistant = useCallback2(
|
|
13037
13793
|
(id, patch) => {
|
|
13038
13794
|
const result = patch({ text: "", reasoning: "" });
|
|
13039
13795
|
const assistantResult = result;
|
|
@@ -13062,7 +13818,7 @@ function App({
|
|
|
13062
13818
|
},
|
|
13063
13819
|
[flushAssistantUpdates]
|
|
13064
13820
|
);
|
|
13065
|
-
const updateTool =
|
|
13821
|
+
const updateTool = useCallback2(
|
|
13066
13822
|
(id, patch) => {
|
|
13067
13823
|
setEvents(
|
|
13068
13824
|
(evts) => evts.map(
|
|
@@ -13072,11 +13828,11 @@ function App({
|
|
|
13072
13828
|
},
|
|
13073
13829
|
[]
|
|
13074
13830
|
);
|
|
13075
|
-
const updateGatewayMeta =
|
|
13831
|
+
const updateGatewayMeta = useCallback2((meta) => {
|
|
13076
13832
|
gatewayMetaRef.current = meta;
|
|
13077
13833
|
setGatewayMeta(meta);
|
|
13078
13834
|
}, []);
|
|
13079
|
-
const runCompact =
|
|
13835
|
+
const runCompact = useCallback2(async () => {
|
|
13080
13836
|
if (!cfg) return;
|
|
13081
13837
|
if (busy) {
|
|
13082
13838
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't compact while model is running" }]);
|
|
@@ -13161,40 +13917,23 @@ function App({
|
|
|
13161
13917
|
setTurnStartedAt(null);
|
|
13162
13918
|
activeControllerRef.current = null;
|
|
13163
13919
|
permResolveRef.current = null;
|
|
13920
|
+
limitResolveRef.current = null;
|
|
13164
13921
|
pendingToolCallsRef.current.clear();
|
|
13165
13922
|
}
|
|
13166
13923
|
}, [cfg, busy, saveSessionSafe]);
|
|
13167
|
-
const openResumePicker =
|
|
13924
|
+
const openResumePicker = useCallback2(async () => {
|
|
13168
13925
|
const sessions = await listSessions(200, process.cwd());
|
|
13169
13926
|
setResumeSessions(sessions);
|
|
13170
13927
|
}, []);
|
|
13171
|
-
const runInit =
|
|
13928
|
+
const runInit = useCallback2(async () => {
|
|
13172
13929
|
if (!cfg) return;
|
|
13173
13930
|
if (busy) {
|
|
13174
13931
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't /init while model is running" }]);
|
|
13175
13932
|
return;
|
|
13176
13933
|
}
|
|
13177
13934
|
const cwd = process.cwd();
|
|
13178
|
-
const
|
|
13179
|
-
|
|
13180
|
-
const promptParts = [
|
|
13181
|
-
isRefresh ? `Regenerate ${existingName} at the repository root to refresh project context. If the file already exists, read it first and preserve anything still accurate, updating only what has changed.` : "Generate a KIMI.md at the repository root so future agents have project context.",
|
|
13182
|
-
"",
|
|
13183
|
-
"First, use the `glob`, `read`, and `grep` tools to understand the project: read `package.json`, the top-level `README.md` if present, the tsconfig / build config, and skim the top-level source directory structure.",
|
|
13184
|
-
isRefresh ? `Also read the existing ${existingName} so you know what to keep vs. update.` : null,
|
|
13185
|
-
"",
|
|
13186
|
-
"Then call the `write` tool to create `KIMI.md` at the repo root with these sections, terse (aim \u2264 100 lines total):",
|
|
13187
|
-
"",
|
|
13188
|
-
"- **Project** \u2014 one-line description + primary language/runtime.",
|
|
13189
|
-
"- **Build / test / run** \u2014 exact shell commands an agent should use.",
|
|
13190
|
-
"- **Layout** \u2014 key directories and what lives in each.",
|
|
13191
|
-
"- **Conventions** \u2014 naming, import style, file structure, commit style, anything surprising.",
|
|
13192
|
-
"- **Do / Don't** \u2014 quirks or rules future agents should know.",
|
|
13193
|
-
"",
|
|
13194
|
-
"Do not call `tasks_set` for this. Just read what you need, then write the file."
|
|
13195
|
-
];
|
|
13196
|
-
const prompt = promptParts.filter((p) => p !== null).join("\n");
|
|
13197
|
-
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: isRefresh ? `/init (refreshing ${existingName})` : "/init" }]);
|
|
13935
|
+
const { prompt, targetFilename, isRefresh } = buildInitPrompt(cwd);
|
|
13936
|
+
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: isRefresh ? `/init (refreshing ${targetFilename})` : "/init" }]);
|
|
13198
13937
|
messagesRef.current.push({ role: "user", content: sanitizeString(prompt) });
|
|
13199
13938
|
setBusy(true);
|
|
13200
13939
|
setTurnStartedAt(Date.now());
|
|
@@ -13227,7 +13966,7 @@ function App({
|
|
|
13227
13966
|
memoryManager: memoryManagerRef.current,
|
|
13228
13967
|
codeMode: effectiveCodeMode,
|
|
13229
13968
|
cloudMode: cfg.cloudMode,
|
|
13230
|
-
cloudToken: initialCloudToken,
|
|
13969
|
+
cloudToken: cloudToken ?? initialCloudToken,
|
|
13231
13970
|
onIterationEnd,
|
|
13232
13971
|
onFileChange: (path, content) => {
|
|
13233
13972
|
if (content) {
|
|
@@ -13328,7 +14067,7 @@ function App({
|
|
|
13328
14067
|
})
|
|
13329
14068
|
}
|
|
13330
14069
|
});
|
|
13331
|
-
if (
|
|
14070
|
+
if (existsSync3(join22(cwd, "KIMI.md"))) {
|
|
13332
14071
|
if (cacheStableRef.current) {
|
|
13333
14072
|
messagesRef.current[1] = {
|
|
13334
14073
|
role: "system",
|
|
@@ -13383,10 +14122,11 @@ function App({
|
|
|
13383
14122
|
activeAsstIdRef.current = null;
|
|
13384
14123
|
activeControllerRef.current = null;
|
|
13385
14124
|
permResolveRef.current = null;
|
|
14125
|
+
limitResolveRef.current = null;
|
|
13386
14126
|
pendingToolCallsRef.current.clear();
|
|
13387
14127
|
}
|
|
13388
14128
|
}, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
|
|
13389
|
-
const handleThemePick =
|
|
14129
|
+
const handleThemePick = useCallback2(
|
|
13390
14130
|
(picked) => {
|
|
13391
14131
|
setShowThemePicker(false);
|
|
13392
14132
|
setOriginalTheme(null);
|
|
@@ -13405,7 +14145,7 @@ function App({
|
|
|
13405
14145
|
},
|
|
13406
14146
|
[cfg, originalTheme]
|
|
13407
14147
|
);
|
|
13408
|
-
const handleResumePick =
|
|
14148
|
+
const handleResumePick = useCallback2(
|
|
13409
14149
|
async (picked) => {
|
|
13410
14150
|
setResumeSessions(null);
|
|
13411
14151
|
if (!picked) return;
|
|
@@ -13463,7 +14203,7 @@ function App({
|
|
|
13463
14203
|
},
|
|
13464
14204
|
[]
|
|
13465
14205
|
);
|
|
13466
|
-
const handleSlash =
|
|
14206
|
+
const handleSlash = useCallback2(
|
|
13467
14207
|
(cmd) => {
|
|
13468
14208
|
const raw = cmd.trim();
|
|
13469
14209
|
const [head, ...rest] = raw.split(/\s+/);
|
|
@@ -13949,7 +14689,7 @@ ${lines.join("\n")}` }]);
|
|
|
13949
14689
|
if (c === "/hello") {
|
|
13950
14690
|
const session = crypto.randomUUID();
|
|
13951
14691
|
const url = `${FEEDBACK_WORKER_URL}/?s=${session}&v=${getAppVersion()}`;
|
|
13952
|
-
|
|
14692
|
+
openBrowser2(url);
|
|
13953
14693
|
setEvents((e) => [
|
|
13954
14694
|
...e,
|
|
13955
14695
|
{ kind: "info", key: mkKey(), text: "Opened voice note page in your browser. Record your message there and hit Send when you're done." }
|
|
@@ -14074,7 +14814,7 @@ ${lines.join("\n")}` }]);
|
|
|
14074
14814
|
setEvents((e) => [
|
|
14075
14815
|
...e,
|
|
14076
14816
|
{ kind: "info", key: mkKey(), text: `Starting remote session for ${repo.owner}/${repo.name}...` },
|
|
14077
|
-
{ kind: "info", key: mkKey(), text: `Budget: ${
|
|
14817
|
+
{ kind: "info", key: mkKey(), text: `Budget: ${formatTokens4(budget)} tokens. TTL: ${ttl} min.` }
|
|
14078
14818
|
]);
|
|
14079
14819
|
try {
|
|
14080
14820
|
const data = await startRemoteSession({
|
|
@@ -14162,7 +14902,7 @@ ${lines.join("\n")}` }]);
|
|
|
14162
14902
|
},
|
|
14163
14903
|
[cfg, exit, usage, effort, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
|
|
14164
14904
|
);
|
|
14165
|
-
const handleHelpCommand =
|
|
14905
|
+
const handleHelpCommand = useCallback2(
|
|
14166
14906
|
(command) => {
|
|
14167
14907
|
setShowHelpMenu(false);
|
|
14168
14908
|
const executed = handleSlash(command);
|
|
@@ -14172,7 +14912,7 @@ ${lines.join("\n")}` }]);
|
|
|
14172
14912
|
},
|
|
14173
14913
|
[handleSlash]
|
|
14174
14914
|
);
|
|
14175
|
-
const handleCommandSave =
|
|
14915
|
+
const handleCommandSave = useCallback2(
|
|
14176
14916
|
async (opts2) => {
|
|
14177
14917
|
setCommandWizard(null);
|
|
14178
14918
|
try {
|
|
@@ -14194,7 +14934,7 @@ ${lines.join("\n")}` }]);
|
|
|
14194
14934
|
},
|
|
14195
14935
|
[commandWizard, reloadCustomCommands, setEvents]
|
|
14196
14936
|
);
|
|
14197
|
-
const handleCommandDelete =
|
|
14937
|
+
const handleCommandDelete = useCallback2(
|
|
14198
14938
|
async (cmd) => {
|
|
14199
14939
|
setCommandToDelete(null);
|
|
14200
14940
|
try {
|
|
@@ -14213,7 +14953,7 @@ ${lines.join("\n")}` }]);
|
|
|
14213
14953
|
},
|
|
14214
14954
|
[reloadCustomCommands, setEvents]
|
|
14215
14955
|
);
|
|
14216
|
-
const processMessage =
|
|
14956
|
+
const processMessage = useCallback2(
|
|
14217
14957
|
async (text, displayText) => {
|
|
14218
14958
|
if (!cfg) return;
|
|
14219
14959
|
let trimmed = text.trim();
|
|
@@ -14412,6 +15152,10 @@ ${lines.join("\n")}` }]);
|
|
|
14412
15152
|
}
|
|
14413
15153
|
permResolveRef.current = resolve2;
|
|
14414
15154
|
setPerm({ tool: req.tool, args: req.args, resolve: resolve2 });
|
|
15155
|
+
}),
|
|
15156
|
+
onToolLimitReached: () => new Promise((resolve2) => {
|
|
15157
|
+
limitResolveRef.current = resolve2;
|
|
15158
|
+
setLimitModal({ limit: 50, resolve: resolve2 });
|
|
14415
15159
|
})
|
|
14416
15160
|
};
|
|
14417
15161
|
try {
|
|
@@ -14432,7 +15176,7 @@ ${lines.join("\n")}` }]);
|
|
|
14432
15176
|
keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
|
|
14433
15177
|
codeMode: effectiveCodeMode,
|
|
14434
15178
|
cloudMode: cfg.cloudMode,
|
|
14435
|
-
cloudToken: initialCloudToken,
|
|
15179
|
+
cloudToken: cloudToken ?? initialCloudToken,
|
|
14436
15180
|
onIterationEnd,
|
|
14437
15181
|
intentClassification: classification,
|
|
14438
15182
|
onFileChange: (path, content2) => {
|
|
@@ -14501,6 +15245,8 @@ ${lines.join("\n")}` }]);
|
|
|
14501
15245
|
text: `auto-compact failed: ${compactErr.message ?? String(compactErr)}`
|
|
14502
15246
|
}
|
|
14503
15247
|
]);
|
|
15248
|
+
} else {
|
|
15249
|
+
throw compactErr;
|
|
14504
15250
|
}
|
|
14505
15251
|
}
|
|
14506
15252
|
}
|
|
@@ -14570,19 +15316,20 @@ ${lines.join("\n")}` }]);
|
|
|
14570
15316
|
activeAsstIdRef.current = null;
|
|
14571
15317
|
activeControllerRef.current = null;
|
|
14572
15318
|
permResolveRef.current = null;
|
|
15319
|
+
limitResolveRef.current = null;
|
|
14573
15320
|
pendingToolCallsRef.current.clear();
|
|
14574
15321
|
}
|
|
14575
15322
|
},
|
|
14576
15323
|
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta]
|
|
14577
15324
|
);
|
|
14578
|
-
|
|
15325
|
+
useEffect6(() => {
|
|
14579
15326
|
if (!busy && queue.length > 0) {
|
|
14580
15327
|
const next = queue[0];
|
|
14581
15328
|
setQueue((q) => q.slice(1));
|
|
14582
15329
|
processMessage(next.full, next.display);
|
|
14583
15330
|
}
|
|
14584
15331
|
}, [busy, queue, processMessage]);
|
|
14585
|
-
const submit =
|
|
15332
|
+
const submit = useCallback2(
|
|
14586
15333
|
(full, display) => {
|
|
14587
15334
|
const trimmedFull = full.trim();
|
|
14588
15335
|
if (!trimmedFull) return;
|
|
@@ -14603,7 +15350,7 @@ ${lines.join("\n")}` }]);
|
|
|
14603
15350
|
[busy, processMessage]
|
|
14604
15351
|
);
|
|
14605
15352
|
submitRef.current = submit;
|
|
14606
|
-
|
|
15353
|
+
useEffect6(() => {
|
|
14607
15354
|
if (compactSuggestedRef.current) return;
|
|
14608
15355
|
if (usage && usage.prompt_tokens / CONTEXT_LIMIT >= AUTO_COMPACT_SUGGEST_PCT) {
|
|
14609
15356
|
compactSuggestedRef.current = true;
|
|
@@ -14618,15 +15365,17 @@ ${lines.join("\n")}` }]);
|
|
|
14618
15365
|
}
|
|
14619
15366
|
}, [usage]);
|
|
14620
15367
|
if (!cfg) {
|
|
14621
|
-
return /* @__PURE__ */
|
|
15368
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(
|
|
14622
15369
|
Onboarding,
|
|
14623
15370
|
{
|
|
15371
|
+
onCancel: () => exit(),
|
|
14624
15372
|
onDone: async (newCfg) => {
|
|
14625
15373
|
setCfg(newCfg);
|
|
14626
15374
|
if (newCfg.cloudMode) {
|
|
14627
15375
|
const { loadCloudCredentials: loadCloudCredentials2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
14628
15376
|
const creds = await loadCloudCredentials2();
|
|
14629
15377
|
if (creds) {
|
|
15378
|
+
setCloudToken(creds.accessToken);
|
|
14630
15379
|
setEvents((e) => [
|
|
14631
15380
|
...e,
|
|
14632
15381
|
{ kind: "info", key: mkKey(), text: "configuration saved \u2014 welcome to kimiflare! (cloud mode)" }
|
|
@@ -14648,10 +15397,10 @@ ${lines.join("\n")}` }]);
|
|
|
14648
15397
|
) });
|
|
14649
15398
|
}
|
|
14650
15399
|
if (resumeSessions !== null) {
|
|
14651
|
-
return /* @__PURE__ */
|
|
15400
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
|
|
14652
15401
|
}
|
|
14653
15402
|
if (showRemoteDashboard) {
|
|
14654
|
-
return /* @__PURE__ */
|
|
15403
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx23(
|
|
14655
15404
|
RemoteSessionDetail,
|
|
14656
15405
|
{
|
|
14657
15406
|
session: selectedRemoteSession,
|
|
@@ -14674,7 +15423,7 @@ ${lines.join("\n")}` }]);
|
|
|
14674
15423
|
setShowRemoteDashboard(false);
|
|
14675
15424
|
}
|
|
14676
15425
|
}
|
|
14677
|
-
) : /* @__PURE__ */
|
|
15426
|
+
) : /* @__PURE__ */ jsx23(
|
|
14678
15427
|
RemoteDashboard,
|
|
14679
15428
|
{
|
|
14680
15429
|
onSelect: (session) => setSelectedRemoteSession(session),
|
|
@@ -14683,7 +15432,7 @@ ${lines.join("\n")}` }]);
|
|
|
14683
15432
|
) }) });
|
|
14684
15433
|
}
|
|
14685
15434
|
if (showHelpMenu) {
|
|
14686
|
-
return /* @__PURE__ */
|
|
15435
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14687
15436
|
HelpMenu,
|
|
14688
15437
|
{
|
|
14689
15438
|
customCommands: customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({ name: c.name, description: c.description })),
|
|
@@ -14695,12 +15444,12 @@ ${lines.join("\n")}` }]);
|
|
|
14695
15444
|
) }) });
|
|
14696
15445
|
}
|
|
14697
15446
|
if (showLspWizard) {
|
|
14698
|
-
return /* @__PURE__ */
|
|
15447
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14699
15448
|
LspWizard,
|
|
14700
15449
|
{
|
|
14701
15450
|
servers: cfg?.lspServers ?? {},
|
|
14702
15451
|
currentScope: lspScope,
|
|
14703
|
-
hasProjectDir:
|
|
15452
|
+
hasProjectDir: existsSync3(join22(process.cwd(), ".kimiflare")),
|
|
14704
15453
|
onDone: () => setShowLspWizard(false),
|
|
14705
15454
|
onSave: (servers, enabled, scope) => {
|
|
14706
15455
|
setCfg((c) => c ? { ...c, lspEnabled: enabled, lspServers: servers } : c);
|
|
@@ -14732,7 +15481,7 @@ ${lines.join("\n")}` }]);
|
|
|
14732
15481
|
) }) });
|
|
14733
15482
|
}
|
|
14734
15483
|
if (commandWizard) {
|
|
14735
|
-
return /* @__PURE__ */
|
|
15484
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14736
15485
|
CommandWizard,
|
|
14737
15486
|
{
|
|
14738
15487
|
mode: commandWizard.mode,
|
|
@@ -14745,7 +15494,7 @@ ${lines.join("\n")}` }]);
|
|
|
14745
15494
|
) }) });
|
|
14746
15495
|
}
|
|
14747
15496
|
if (commandPicker) {
|
|
14748
|
-
return /* @__PURE__ */
|
|
15497
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14749
15498
|
CommandPicker,
|
|
14750
15499
|
{
|
|
14751
15500
|
commands: customCommandsRef.current,
|
|
@@ -14763,15 +15512,15 @@ ${lines.join("\n")}` }]);
|
|
|
14763
15512
|
) }) });
|
|
14764
15513
|
}
|
|
14765
15514
|
if (commandToDelete) {
|
|
14766
|
-
return /* @__PURE__ */
|
|
14767
|
-
/* @__PURE__ */
|
|
15515
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
15516
|
+
/* @__PURE__ */ jsxs21(Text22, { color: theme.accent, bold: true, children: [
|
|
14768
15517
|
"Delete /",
|
|
14769
15518
|
commandToDelete.name,
|
|
14770
15519
|
"?"
|
|
14771
15520
|
] }),
|
|
14772
|
-
/* @__PURE__ */
|
|
14773
|
-
/* @__PURE__ */
|
|
14774
|
-
|
|
15521
|
+
/* @__PURE__ */ jsx23(Text22, { color: theme.info.color, children: commandToDelete.filepath }),
|
|
15522
|
+
/* @__PURE__ */ jsx23(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx23(
|
|
15523
|
+
SelectInput11,
|
|
14775
15524
|
{
|
|
14776
15525
|
items: [
|
|
14777
15526
|
{ label: "Yes, delete", value: "yes", key: "yes" },
|
|
@@ -14789,7 +15538,7 @@ ${lines.join("\n")}` }]);
|
|
|
14789
15538
|
] }) });
|
|
14790
15539
|
}
|
|
14791
15540
|
if (showCommandList) {
|
|
14792
|
-
return /* @__PURE__ */
|
|
15541
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14793
15542
|
CommandList,
|
|
14794
15543
|
{
|
|
14795
15544
|
commands: customCommandsRef.current,
|
|
@@ -14798,12 +15547,12 @@ ${lines.join("\n")}` }]);
|
|
|
14798
15547
|
) }) });
|
|
14799
15548
|
}
|
|
14800
15549
|
if (showThemePicker) {
|
|
14801
|
-
return /* @__PURE__ */
|
|
15550
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ThemePicker, { themes: themeList(), onPick: handleThemePick, onPreview: (t) => setTheme(t) }) }) });
|
|
14802
15551
|
}
|
|
14803
15552
|
const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
|
|
14804
|
-
return /* @__PURE__ */
|
|
14805
|
-
!hasConversation && events.length === 0 ? /* @__PURE__ */
|
|
14806
|
-
perm ? /* @__PURE__ */
|
|
15553
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
15554
|
+
!hasConversation && events.length === 0 ? /* @__PURE__ */ jsx23(Welcome, { accountId: cfg.accountId }) : /* @__PURE__ */ jsx23(ChatView, { events, showReasoning, verbose }),
|
|
15555
|
+
perm ? /* @__PURE__ */ jsx23(
|
|
14807
15556
|
PermissionModal,
|
|
14808
15557
|
{
|
|
14809
15558
|
tool: perm.tool,
|
|
@@ -14814,8 +15563,18 @@ ${lines.join("\n")}` }]);
|
|
|
14814
15563
|
setPerm(null);
|
|
14815
15564
|
}
|
|
14816
15565
|
}
|
|
14817
|
-
) : /* @__PURE__ */
|
|
14818
|
-
|
|
15566
|
+
) : limitModal ? /* @__PURE__ */ jsx23(
|
|
15567
|
+
LimitModal,
|
|
15568
|
+
{
|
|
15569
|
+
limit: limitModal.limit,
|
|
15570
|
+
onDecide: (d) => {
|
|
15571
|
+
limitModal.resolve(d);
|
|
15572
|
+
limitResolveRef.current = null;
|
|
15573
|
+
setLimitModal(null);
|
|
15574
|
+
}
|
|
15575
|
+
}
|
|
15576
|
+
) : /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
15577
|
+
tasks.length > 0 && /* @__PURE__ */ jsx23(
|
|
14819
15578
|
TaskList,
|
|
14820
15579
|
{
|
|
14821
15580
|
tasks,
|
|
@@ -14823,11 +15582,11 @@ ${lines.join("\n")}` }]);
|
|
|
14823
15582
|
tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
|
|
14824
15583
|
}
|
|
14825
15584
|
),
|
|
14826
|
-
queue.length > 0 && /* @__PURE__ */
|
|
15585
|
+
queue.length > 0 && /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, children: [
|
|
14827
15586
|
"\u23F3 ",
|
|
14828
15587
|
q.display
|
|
14829
15588
|
] }, `queue_${i}`)) }),
|
|
14830
|
-
/* @__PURE__ */
|
|
15589
|
+
/* @__PURE__ */ jsx23(
|
|
14831
15590
|
StatusBar,
|
|
14832
15591
|
{
|
|
14833
15592
|
model: cfg.model,
|
|
@@ -14842,10 +15601,11 @@ ${lines.join("\n")}` }]);
|
|
|
14842
15601
|
latestVersion,
|
|
14843
15602
|
gatewayMeta,
|
|
14844
15603
|
codeMode,
|
|
14845
|
-
cloudMode: cfg.cloudMode
|
|
15604
|
+
cloudMode: cfg.cloudMode,
|
|
15605
|
+
cloudBudget
|
|
14846
15606
|
}
|
|
14847
15607
|
),
|
|
14848
|
-
activePicker?.kind === "file" && /* @__PURE__ */
|
|
15608
|
+
activePicker?.kind === "file" && /* @__PURE__ */ jsx23(
|
|
14849
15609
|
FilePicker,
|
|
14850
15610
|
{
|
|
14851
15611
|
items: filteredFileItems,
|
|
@@ -14853,7 +15613,7 @@ ${lines.join("\n")}` }]);
|
|
|
14853
15613
|
query: pickerQuery ?? ""
|
|
14854
15614
|
}
|
|
14855
15615
|
),
|
|
14856
|
-
activePicker?.kind === "slash" && /* @__PURE__ */
|
|
15616
|
+
activePicker?.kind === "slash" && /* @__PURE__ */ jsx23(
|
|
14857
15617
|
SlashPicker,
|
|
14858
15618
|
{
|
|
14859
15619
|
items: filteredSlashItems,
|
|
@@ -14861,9 +15621,9 @@ ${lines.join("\n")}` }]);
|
|
|
14861
15621
|
query: pickerQuery ?? ""
|
|
14862
15622
|
}
|
|
14863
15623
|
),
|
|
14864
|
-
/* @__PURE__ */
|
|
14865
|
-
/* @__PURE__ */
|
|
14866
|
-
/* @__PURE__ */
|
|
15624
|
+
/* @__PURE__ */ jsxs21(Box21, { marginTop: 1, children: [
|
|
15625
|
+
/* @__PURE__ */ jsx23(Text22, { color: "#d699b6", children: "\u203A " }),
|
|
15626
|
+
/* @__PURE__ */ jsx23(
|
|
14867
15627
|
CustomTextInput,
|
|
14868
15628
|
{
|
|
14869
15629
|
value: input,
|
|
@@ -14920,7 +15680,7 @@ ${lines.join("\n")}` }]);
|
|
|
14920
15680
|
}
|
|
14921
15681
|
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken) {
|
|
14922
15682
|
const instance = render(
|
|
14923
|
-
/* @__PURE__ */
|
|
15683
|
+
/* @__PURE__ */ jsx23(
|
|
14924
15684
|
App,
|
|
14925
15685
|
{
|
|
14926
15686
|
initialCfg: cfg,
|
|
@@ -14954,6 +15714,7 @@ var init_app = __esm({
|
|
|
14954
15714
|
init_chat();
|
|
14955
15715
|
init_status();
|
|
14956
15716
|
init_permission();
|
|
15717
|
+
init_limit_modal();
|
|
14957
15718
|
init_resume_picker();
|
|
14958
15719
|
init_task_list();
|
|
14959
15720
|
init_text_input();
|
|
@@ -14981,6 +15742,7 @@ var init_app = __esm({
|
|
|
14981
15742
|
init_builtins();
|
|
14982
15743
|
init_save();
|
|
14983
15744
|
init_command_wizard();
|
|
15745
|
+
init_context_generator();
|
|
14984
15746
|
init_command_picker();
|
|
14985
15747
|
init_command_list();
|
|
14986
15748
|
init_lsp_wizard();
|
|
@@ -15138,14 +15900,12 @@ program.command("usage").description("Show Kimiflare Cloud token usage (requires
|
|
|
15138
15900
|
console.error("Not authenticated with Kimiflare Cloud. Run: kimiflare auth cloud");
|
|
15139
15901
|
process.exit(1);
|
|
15140
15902
|
}
|
|
15141
|
-
const
|
|
15142
|
-
|
|
15143
|
-
|
|
15144
|
-
|
|
15145
|
-
console.error(`Failed to fetch usage: ${res.status} ${res.statusText}`);
|
|
15903
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15904
|
+
const usage = await fetchCloudUsage2(creds.accessToken);
|
|
15905
|
+
if (!usage) {
|
|
15906
|
+
console.error("Failed to fetch usage: invalid response from server");
|
|
15146
15907
|
process.exit(1);
|
|
15147
15908
|
}
|
|
15148
|
-
const usage = await res.json();
|
|
15149
15909
|
console.log(`Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
|
|
15150
15910
|
console.log(`Used: ${usage.input_tokens_used.toLocaleString()}`);
|
|
15151
15911
|
console.log(`Grant expires: ${usage.expires_at}`);
|
|
@@ -15183,11 +15943,9 @@ Kimiflare Cloud Authentication`);
|
|
|
15183
15943
|
}
|
|
15184
15944
|
});
|
|
15185
15945
|
console.log(`Authenticated! Token expires at ${new Date(creds.expiresAt * 1e3).toISOString()}`);
|
|
15186
|
-
const
|
|
15187
|
-
|
|
15188
|
-
|
|
15189
|
-
if (usageRes.ok) {
|
|
15190
|
-
const usage = await usageRes.json();
|
|
15946
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15947
|
+
const usage = await fetchCloudUsage2(creds.accessToken);
|
|
15948
|
+
if (usage) {
|
|
15191
15949
|
console.log(`
|
|
15192
15950
|
Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
|
|
15193
15951
|
console.log(`Grant expires: ${usage.expires_at}`);
|