kimiflare 0.35.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1289 -541
- 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 {
|
|
@@ -1402,6 +1406,11 @@ function stripTypescript(code) {
|
|
|
1402
1406
|
return js.trim();
|
|
1403
1407
|
}
|
|
1404
1408
|
async function loadTypescript(cwd) {
|
|
1409
|
+
try {
|
|
1410
|
+
const tsPath = await import.meta.resolve("typescript");
|
|
1411
|
+
return await import(tsPath);
|
|
1412
|
+
} catch {
|
|
1413
|
+
}
|
|
1405
1414
|
let dir = cwd;
|
|
1406
1415
|
while (dir !== dirname3(dir)) {
|
|
1407
1416
|
try {
|
|
@@ -1669,7 +1678,18 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1669
1678
|
});
|
|
1670
1679
|
}
|
|
1671
1680
|
if (iter >= max) {
|
|
1672
|
-
if (opts2.
|
|
1681
|
+
if (opts2.callbacks.onToolLimitReached) {
|
|
1682
|
+
const decision = await opts2.callbacks.onToolLimitReached();
|
|
1683
|
+
if (decision === "continue") {
|
|
1684
|
+
opts2.messages.push({
|
|
1685
|
+
role: "system",
|
|
1686
|
+
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."
|
|
1687
|
+
});
|
|
1688
|
+
iter = 0;
|
|
1689
|
+
} else {
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
} else if (opts2.continueOnLimit) {
|
|
1673
1693
|
opts2.messages.push({
|
|
1674
1694
|
role: "system",
|
|
1675
1695
|
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 +4634,16 @@ var init_cli = __esm({
|
|
|
4614
4634
|
// src/cloud/auth.ts
|
|
4615
4635
|
var auth_exports = {};
|
|
4616
4636
|
__export(auth_exports, {
|
|
4637
|
+
CLOUD_API_URL: () => CLOUD_API_URL,
|
|
4638
|
+
POLL_INTERVAL_MS: () => POLL_INTERVAL_MS,
|
|
4639
|
+
POLL_TIMEOUT_MS: () => POLL_TIMEOUT_MS,
|
|
4617
4640
|
authenticateDevice: () => authenticateDevice,
|
|
4618
4641
|
clearCloudCredentials: () => clearCloudCredentials,
|
|
4642
|
+
fetchCloudUsage: () => fetchCloudUsage,
|
|
4643
|
+
generateDeviceCodes: () => generateDeviceCodes,
|
|
4619
4644
|
loadCloudCredentials: () => loadCloudCredentials,
|
|
4645
|
+
pollForToken: () => pollForToken,
|
|
4646
|
+
registerDevice: () => registerDevice,
|
|
4620
4647
|
saveCloudCredentials: () => saveCloudCredentials
|
|
4621
4648
|
});
|
|
4622
4649
|
import { readFile as readFile11, writeFile as writeFile7 } from "fs/promises";
|
|
@@ -4634,6 +4661,49 @@ function generateCode() {
|
|
|
4634
4661
|
}
|
|
4635
4662
|
return out;
|
|
4636
4663
|
}
|
|
4664
|
+
function generateDeviceCodes() {
|
|
4665
|
+
const deviceCode = `device-${generateCode()}-${Date.now()}`;
|
|
4666
|
+
const userCode = `${generateCode()}-${generateCode()}`;
|
|
4667
|
+
const authUrl = `${CLOUD_API_URL}/auth/github?code=${encodeURIComponent(userCode)}`;
|
|
4668
|
+
return { deviceCode, userCode, authUrl };
|
|
4669
|
+
}
|
|
4670
|
+
async function registerDevice(codes) {
|
|
4671
|
+
const registerRes = await fetch(`${CLOUD_API_URL}/auth/device`, {
|
|
4672
|
+
method: "POST",
|
|
4673
|
+
headers: { "Content-Type": "application/json" },
|
|
4674
|
+
body: JSON.stringify({ device_code: codes.deviceCode, user_code: codes.userCode })
|
|
4675
|
+
});
|
|
4676
|
+
if (!registerRes.ok) {
|
|
4677
|
+
const err = await registerRes.json().catch(() => ({}));
|
|
4678
|
+
throw new Error(`Failed to register device: ${err.error || registerRes.statusText}`);
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4681
|
+
async function pollForToken(deviceCode) {
|
|
4682
|
+
const pollRes = await fetch(`${CLOUD_API_URL}/auth/poll`, {
|
|
4683
|
+
method: "POST",
|
|
4684
|
+
headers: { "Content-Type": "application/json" },
|
|
4685
|
+
body: JSON.stringify({ device_code: deviceCode })
|
|
4686
|
+
});
|
|
4687
|
+
if (!pollRes.ok) return null;
|
|
4688
|
+
const pollData = await pollRes.json();
|
|
4689
|
+
if (pollData.status === "approved" && pollData.access_token) {
|
|
4690
|
+
const creds = {
|
|
4691
|
+
accessToken: pollData.access_token,
|
|
4692
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 7 * 24 * 60 * 60
|
|
4693
|
+
// 7 days
|
|
4694
|
+
};
|
|
4695
|
+
await saveCloudCredentials(creds);
|
|
4696
|
+
return creds;
|
|
4697
|
+
}
|
|
4698
|
+
return null;
|
|
4699
|
+
}
|
|
4700
|
+
async function fetchCloudUsage(token) {
|
|
4701
|
+
const res = await fetch(`${CLOUD_API_URL}/v1/usage`, {
|
|
4702
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
4703
|
+
});
|
|
4704
|
+
if (!res.ok) return null;
|
|
4705
|
+
return await res.json();
|
|
4706
|
+
}
|
|
4637
4707
|
async function loadCloudCredentials() {
|
|
4638
4708
|
try {
|
|
4639
4709
|
const raw = await readFile11(cloudCredPath(), "utf8");
|
|
@@ -4657,39 +4727,15 @@ async function clearCloudCredentials() {
|
|
|
4657
4727
|
}
|
|
4658
4728
|
}
|
|
4659
4729
|
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 });
|
|
4730
|
+
const codes = generateDeviceCodes();
|
|
4731
|
+
await registerDevice(codes);
|
|
4732
|
+
onStatus({ url: codes.authUrl, userCode: codes.userCode, polling: false });
|
|
4673
4733
|
const startTime = Date.now();
|
|
4674
4734
|
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
4675
4735
|
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
|
-
}
|
|
4736
|
+
onStatus({ url: codes.authUrl, userCode: codes.userCode, polling: true });
|
|
4737
|
+
const creds = await pollForToken(codes.deviceCode);
|
|
4738
|
+
if (creds) return creds;
|
|
4693
4739
|
}
|
|
4694
4740
|
throw new Error("Authentication timed out. Please try again.");
|
|
4695
4741
|
}
|
|
@@ -4699,7 +4745,7 @@ var init_auth = __esm({
|
|
|
4699
4745
|
"use strict";
|
|
4700
4746
|
CLOUD_API_URL = "https://api.kimiflare.com";
|
|
4701
4747
|
POLL_INTERVAL_MS = 5e3;
|
|
4702
|
-
POLL_TIMEOUT_MS =
|
|
4748
|
+
POLL_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
4703
4749
|
}
|
|
4704
4750
|
});
|
|
4705
4751
|
|
|
@@ -6754,7 +6800,7 @@ import { useEffect, useState } from "react";
|
|
|
6754
6800
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
6755
6801
|
import Spinner3 from "ink-spinner";
|
|
6756
6802
|
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 }) {
|
|
6803
|
+
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget }) {
|
|
6758
6804
|
const theme = useTheme();
|
|
6759
6805
|
const [now2, setNow] = useState(Date.now());
|
|
6760
6806
|
const modeColor = mode === "plan" ? theme.modeBadge.plan : mode === "auto" ? theme.modeBadge.auto : theme.modeBadge.edit;
|
|
@@ -6787,7 +6833,7 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
6787
6833
|
] })
|
|
6788
6834
|
] }),
|
|
6789
6835
|
usage && /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
6790
|
-
/* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta).join(" \xB7 ") }),
|
|
6836
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
|
|
6791
6837
|
warn ? /* @__PURE__ */ jsxs5(Text5, { color: theme.warn, bold: true, children: [
|
|
6792
6838
|
" \xB7 ",
|
|
6793
6839
|
"/compact recommended"
|
|
@@ -6801,7 +6847,7 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
6801
6847
|
] })
|
|
6802
6848
|
] });
|
|
6803
6849
|
}
|
|
6804
|
-
function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta) {
|
|
6850
|
+
function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget) {
|
|
6805
6851
|
const pct = Math.round(usage.prompt_tokens / contextLimit * 100);
|
|
6806
6852
|
const parts = [];
|
|
6807
6853
|
if (sessionUsage) {
|
|
@@ -6809,19 +6855,35 @@ function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta) {
|
|
|
6809
6855
|
parts.push(`in ${sessionUsage.promptTokens}${cached ? ` (${cached} cached)` : ""}`);
|
|
6810
6856
|
parts.push(`out ${sessionUsage.completionTokens}`);
|
|
6811
6857
|
parts.push(`ctx ${pct}%`);
|
|
6812
|
-
|
|
6858
|
+
if (cloudMode) {
|
|
6859
|
+
parts.push(`\x1B[9m${sessionUsage.cost.toFixed(5)}\x1B[29m`);
|
|
6860
|
+
} else {
|
|
6861
|
+
parts.push(`${sessionUsage.cost.toFixed(5)}`);
|
|
6862
|
+
}
|
|
6813
6863
|
} else {
|
|
6814
6864
|
const cached = usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
6815
6865
|
const cost = calculateCost(usage.prompt_tokens, usage.completion_tokens, cached);
|
|
6816
6866
|
parts.push(`in ${usage.prompt_tokens}${cached ? ` (${cached} cached)` : ""}`);
|
|
6817
6867
|
parts.push(`out ${usage.completion_tokens}`);
|
|
6818
6868
|
parts.push(`ctx ${pct}%`);
|
|
6819
|
-
|
|
6869
|
+
if (cloudMode) {
|
|
6870
|
+
parts.push(`\x1B[9m${cost.total.toFixed(5)}\x1B[29m`);
|
|
6871
|
+
} else {
|
|
6872
|
+
parts.push(`${cost.total.toFixed(5)}`);
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6875
|
+
if (cloudMode && cloudBudget) {
|
|
6876
|
+
parts.push(`${formatTokens(cloudBudget.remaining)}/${formatTokens(cloudBudget.limit)} tokens`);
|
|
6820
6877
|
}
|
|
6821
6878
|
const gatewayCache = formatGatewayCacheStatus(gatewayMeta);
|
|
6822
6879
|
if (gatewayCache) parts.push(gatewayCache);
|
|
6823
6880
|
return parts;
|
|
6824
6881
|
}
|
|
6882
|
+
function formatTokens(n) {
|
|
6883
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
6884
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
6885
|
+
return String(n);
|
|
6886
|
+
}
|
|
6825
6887
|
function formatGatewayCacheStatus(gatewayMeta) {
|
|
6826
6888
|
const status = gatewayMeta?.cacheStatus?.trim();
|
|
6827
6889
|
return status ? `AI Gateway \xB7 cache ${status.toLowerCase()}` : null;
|
|
@@ -6882,11 +6944,48 @@ var init_permission = __esm({
|
|
|
6882
6944
|
}
|
|
6883
6945
|
});
|
|
6884
6946
|
|
|
6885
|
-
// src/ui/
|
|
6886
|
-
import {
|
|
6887
|
-
import { Box as Box7, Text as Text7, useWindowSize } from "ink";
|
|
6947
|
+
// src/ui/limit-modal.tsx
|
|
6948
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
6888
6949
|
import SelectInput2 from "ink-select-input";
|
|
6889
6950
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
6951
|
+
function LimitModal({ limit, onDecide }) {
|
|
6952
|
+
const theme = useTheme();
|
|
6953
|
+
const items = [
|
|
6954
|
+
{ label: "Continue", value: "continue" },
|
|
6955
|
+
{ label: "Stop", value: "stop" }
|
|
6956
|
+
];
|
|
6957
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
|
|
6958
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.error, bold: true, children: [
|
|
6959
|
+
"Tool-call limit reached (",
|
|
6960
|
+
limit,
|
|
6961
|
+
")"
|
|
6962
|
+
] }),
|
|
6963
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
6964
|
+
"This session has made ",
|
|
6965
|
+
limit,
|
|
6966
|
+
" tool calls. What would you like to do?"
|
|
6967
|
+
] }),
|
|
6968
|
+
/* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
6969
|
+
SelectInput2,
|
|
6970
|
+
{
|
|
6971
|
+
items,
|
|
6972
|
+
onSelect: (item) => onDecide(item.value)
|
|
6973
|
+
}
|
|
6974
|
+
) })
|
|
6975
|
+
] });
|
|
6976
|
+
}
|
|
6977
|
+
var init_limit_modal = __esm({
|
|
6978
|
+
"src/ui/limit-modal.tsx"() {
|
|
6979
|
+
"use strict";
|
|
6980
|
+
init_theme_context();
|
|
6981
|
+
}
|
|
6982
|
+
});
|
|
6983
|
+
|
|
6984
|
+
// src/ui/resume-picker.tsx
|
|
6985
|
+
import { useState as useState2 } from "react";
|
|
6986
|
+
import { Box as Box8, Text as Text8, useWindowSize } from "ink";
|
|
6987
|
+
import SelectInput3 from "ink-select-input";
|
|
6988
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6890
6989
|
function ResumePicker({ sessions, onPick }) {
|
|
6891
6990
|
const theme = useTheme();
|
|
6892
6991
|
const { rows } = useWindowSize();
|
|
@@ -6895,11 +6994,11 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
6895
6994
|
const totalPages = Math.max(1, Math.ceil(sessions.length / pageSize));
|
|
6896
6995
|
const safePage = Math.min(page, totalPages - 1);
|
|
6897
6996
|
if (sessions.length === 0) {
|
|
6898
|
-
return /* @__PURE__ */
|
|
6899
|
-
/* @__PURE__ */
|
|
6900
|
-
/* @__PURE__ */
|
|
6901
|
-
/* @__PURE__ */
|
|
6902
|
-
|
|
6997
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
6998
|
+
/* @__PURE__ */ jsx9(Text8, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
6999
|
+
/* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
|
|
7000
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(
|
|
7001
|
+
SelectInput3,
|
|
6903
7002
|
{
|
|
6904
7003
|
items: [{ label: "(back)", value: "__cancel__" }],
|
|
6905
7004
|
onSelect: () => onPick(null)
|
|
@@ -6921,9 +7020,9 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
6921
7020
|
items.push({ label: "\u2192 next page", value: "__next__" });
|
|
6922
7021
|
}
|
|
6923
7022
|
items.push({ label: "(cancel)", value: "__cancel__" });
|
|
6924
|
-
return /* @__PURE__ */
|
|
6925
|
-
/* @__PURE__ */
|
|
6926
|
-
/* @__PURE__ */
|
|
7023
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
7024
|
+
/* @__PURE__ */ jsx9(Text8, { color: theme.accent, bold: true, children: "Resume a session" }),
|
|
7025
|
+
/* @__PURE__ */ jsxs8(Text8, { color: theme.info.color, children: [
|
|
6927
7026
|
"Arrow keys to select, Enter to confirm. Page ",
|
|
6928
7027
|
safePage + 1,
|
|
6929
7028
|
" of ",
|
|
@@ -6932,8 +7031,8 @@ function ResumePicker({ sessions, onPick }) {
|
|
|
6932
7031
|
sessions.length,
|
|
6933
7032
|
" total)"
|
|
6934
7033
|
] }),
|
|
6935
|
-
/* @__PURE__ */
|
|
6936
|
-
|
|
7034
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(
|
|
7035
|
+
SelectInput3,
|
|
6937
7036
|
{
|
|
6938
7037
|
items,
|
|
6939
7038
|
onSelect: (item) => {
|
|
@@ -6973,9 +7072,9 @@ var init_resume_picker = __esm({
|
|
|
6973
7072
|
|
|
6974
7073
|
// src/ui/task-list.tsx
|
|
6975
7074
|
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
6976
|
-
import { Box as
|
|
7075
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
6977
7076
|
import Spinner4 from "ink-spinner";
|
|
6978
|
-
import { jsx as
|
|
7077
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
6979
7078
|
function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
6980
7079
|
const theme = useTheme();
|
|
6981
7080
|
const [now2, setNow] = useState3(Date.now());
|
|
@@ -6999,21 +7098,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
6999
7098
|
const allDone = done === total;
|
|
7000
7099
|
const header = active ? active.title : allDone ? `${total} tasks done` : `${done}/${total}`;
|
|
7001
7100
|
const elapsed = startedAt ? formatElapsed2(now2 - startedAt) : null;
|
|
7002
|
-
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${
|
|
7101
|
+
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens2(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
|
|
7003
7102
|
const visibleTasks = tasks.slice(0, MAX_VISIBLE);
|
|
7004
7103
|
const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
|
|
7005
|
-
return /* @__PURE__ */
|
|
7006
|
-
/* @__PURE__ */
|
|
7007
|
-
/* @__PURE__ */
|
|
7008
|
-
headerStats && /* @__PURE__ */
|
|
7104
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginBottom: 1, children: [
|
|
7105
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
7106
|
+
/* @__PURE__ */ jsx10(Text9, { color: allDone ? "green" : theme.accent, bold: true, children: header }),
|
|
7107
|
+
headerStats && /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7009
7108
|
" ",
|
|
7010
7109
|
"(",
|
|
7011
7110
|
headerStats,
|
|
7012
7111
|
")"
|
|
7013
7112
|
] })
|
|
7014
7113
|
] }),
|
|
7015
|
-
visibleTasks.map((t) => /* @__PURE__ */
|
|
7016
|
-
hiddenPending > 0 && /* @__PURE__ */
|
|
7114
|
+
visibleTasks.map((t) => /* @__PURE__ */ jsx10(TaskRow, { task: t }, t.id)),
|
|
7115
|
+
hiddenPending > 0 && /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7017
7116
|
" ",
|
|
7018
7117
|
"\u2026 +",
|
|
7019
7118
|
hiddenPending,
|
|
@@ -7024,21 +7123,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
7024
7123
|
function TaskRow({ task }) {
|
|
7025
7124
|
const theme = useTheme();
|
|
7026
7125
|
if (task.status === "completed") {
|
|
7027
|
-
return /* @__PURE__ */
|
|
7126
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7028
7127
|
" ",
|
|
7029
7128
|
"\u2713 ",
|
|
7030
|
-
/* @__PURE__ */
|
|
7129
|
+
/* @__PURE__ */ jsx10(Text9, { strikethrough: true, children: task.title })
|
|
7031
7130
|
] });
|
|
7032
7131
|
}
|
|
7033
7132
|
if (task.status === "in_progress") {
|
|
7034
|
-
return /* @__PURE__ */
|
|
7133
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.accent, bold: true, children: [
|
|
7035
7134
|
" ",
|
|
7036
|
-
/* @__PURE__ */
|
|
7135
|
+
/* @__PURE__ */ jsx10(Spinner4, { type: "dots" }),
|
|
7037
7136
|
" ",
|
|
7038
7137
|
task.title
|
|
7039
7138
|
] });
|
|
7040
7139
|
}
|
|
7041
|
-
return /* @__PURE__ */
|
|
7140
|
+
return /* @__PURE__ */ jsxs9(Text9, { color: theme.info.color, children: [
|
|
7042
7141
|
" ",
|
|
7043
7142
|
"\u2610 ",
|
|
7044
7143
|
task.title
|
|
@@ -7051,7 +7150,7 @@ function formatElapsed2(ms) {
|
|
|
7051
7150
|
if (m === 0) return `${s}s`;
|
|
7052
7151
|
return `${m}m ${s}s`;
|
|
7053
7152
|
}
|
|
7054
|
-
function
|
|
7153
|
+
function formatTokens2(n) {
|
|
7055
7154
|
if (n < 1e3) return String(n);
|
|
7056
7155
|
return `${(n / 1e3).toFixed(1)}k`;
|
|
7057
7156
|
}
|
|
@@ -7586,8 +7685,8 @@ var init_source = __esm({
|
|
|
7586
7685
|
|
|
7587
7686
|
// src/ui/text-input.tsx
|
|
7588
7687
|
import { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
7589
|
-
import { Text as
|
|
7590
|
-
import { jsx as
|
|
7688
|
+
import { Text as Text10, useInput } from "ink";
|
|
7689
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
7591
7690
|
function shouldTreatAsPaste(input) {
|
|
7592
7691
|
if (input.length >= PASTE_CHAR_THRESHOLD) return true;
|
|
7593
7692
|
const newlines = (input.match(/\n/g) ?? []).length;
|
|
@@ -7797,7 +7896,7 @@ function CustomTextInput({
|
|
|
7797
7896
|
} else if (cursorOffset === displayValue.length) {
|
|
7798
7897
|
renderedValue += source_default.inverse(" ");
|
|
7799
7898
|
}
|
|
7800
|
-
return /* @__PURE__ */
|
|
7899
|
+
return /* @__PURE__ */ jsx11(Text10, { children: renderedValue });
|
|
7801
7900
|
}
|
|
7802
7901
|
function findPasteTokenEndingAt(value, pos, pastes) {
|
|
7803
7902
|
if (pos <= 0 || value[pos - 1] !== "]") return -1;
|
|
@@ -7819,11 +7918,28 @@ var init_text_input = __esm({
|
|
|
7819
7918
|
});
|
|
7820
7919
|
|
|
7821
7920
|
// src/ui/onboarding.tsx
|
|
7822
|
-
import { useState as useState5 } from "react";
|
|
7823
|
-
import { Box as
|
|
7824
|
-
import
|
|
7825
|
-
import
|
|
7826
|
-
|
|
7921
|
+
import { useState as useState5, useEffect as useEffect4, useCallback } from "react";
|
|
7922
|
+
import { Box as Box10, Text as Text11, useInput as useInput2 } from "ink";
|
|
7923
|
+
import SelectInput4 from "ink-select-input";
|
|
7924
|
+
import Spinner5 from "ink-spinner";
|
|
7925
|
+
import { exec } from "child_process";
|
|
7926
|
+
import { promisify as promisify2 } from "util";
|
|
7927
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
7928
|
+
function openBrowser(url) {
|
|
7929
|
+
const platform3 = process.platform;
|
|
7930
|
+
const cmd = platform3 === "darwin" ? `open "${url}"` : platform3 === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
|
|
7931
|
+
exec(cmd, (err) => {
|
|
7932
|
+
if (err) {
|
|
7933
|
+
}
|
|
7934
|
+
});
|
|
7935
|
+
}
|
|
7936
|
+
function formatRemaining(ms) {
|
|
7937
|
+
const totalSeconds = Math.ceil(ms / 1e3);
|
|
7938
|
+
const mins = Math.floor(totalSeconds / 60);
|
|
7939
|
+
const secs = totalSeconds % 60;
|
|
7940
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
7941
|
+
}
|
|
7942
|
+
function Onboarding({ onDone, onCancel }) {
|
|
7827
7943
|
const theme = useTheme();
|
|
7828
7944
|
const [step, setStep] = useState5("mode");
|
|
7829
7945
|
const [mode, setMode] = useState5("byok");
|
|
@@ -7831,15 +7947,109 @@ function Onboarding({ onDone }) {
|
|
|
7831
7947
|
const [apiToken, setApiToken] = useState5("");
|
|
7832
7948
|
const [model, setModel] = useState5(DEFAULT_MODEL);
|
|
7833
7949
|
const [savedPath, setSavedPath] = useState5(null);
|
|
7950
|
+
const [cloudAuth, setCloudAuth] = useState5(null);
|
|
7951
|
+
const [pollTick, setPollTick] = useState5(0);
|
|
7952
|
+
useEffect4(() => {
|
|
7953
|
+
if (step !== "cloudAuth" || !cloudAuth) return;
|
|
7954
|
+
if (cloudAuth.phase !== "polling") return;
|
|
7955
|
+
let cancelled = false;
|
|
7956
|
+
const tick = setInterval(() => {
|
|
7957
|
+
setPollTick((t) => t + 1);
|
|
7958
|
+
}, 1e3);
|
|
7959
|
+
const poll = async () => {
|
|
7960
|
+
while (!cancelled) {
|
|
7961
|
+
const elapsed = Date.now() - cloudAuth.startTime;
|
|
7962
|
+
if (elapsed >= POLL_TIMEOUT_MS) {
|
|
7963
|
+
if (!cancelled) {
|
|
7964
|
+
setCloudAuth({ phase: "error", message: "Authentication timed out. Please try again." });
|
|
7965
|
+
}
|
|
7966
|
+
return;
|
|
7967
|
+
}
|
|
7968
|
+
try {
|
|
7969
|
+
const creds = await pollForToken(cloudAuth.codes.deviceCode);
|
|
7970
|
+
if (creds && !cancelled) {
|
|
7971
|
+
const usage = await fetchCloudUsage(creds.accessToken);
|
|
7972
|
+
if (usage && !cancelled) {
|
|
7973
|
+
setCloudAuth({
|
|
7974
|
+
phase: "success",
|
|
7975
|
+
creds,
|
|
7976
|
+
usage
|
|
7977
|
+
});
|
|
7978
|
+
} else if (!cancelled) {
|
|
7979
|
+
setCloudAuth({ phase: "error", message: "Authenticated but failed to fetch usage." });
|
|
7980
|
+
}
|
|
7981
|
+
return;
|
|
7982
|
+
}
|
|
7983
|
+
} catch {
|
|
7984
|
+
}
|
|
7985
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
7986
|
+
}
|
|
7987
|
+
};
|
|
7988
|
+
poll();
|
|
7989
|
+
return () => {
|
|
7990
|
+
cancelled = true;
|
|
7991
|
+
clearInterval(tick);
|
|
7992
|
+
};
|
|
7993
|
+
}, [step, cloudAuth]);
|
|
7994
|
+
useInput2(
|
|
7995
|
+
useCallback(
|
|
7996
|
+
(_input, key) => {
|
|
7997
|
+
if (key.escape && onCancel) {
|
|
7998
|
+
onCancel();
|
|
7999
|
+
}
|
|
8000
|
+
},
|
|
8001
|
+
[onCancel]
|
|
8002
|
+
)
|
|
8003
|
+
);
|
|
8004
|
+
const startCloudAuth = useCallback(async () => {
|
|
8005
|
+
try {
|
|
8006
|
+
const codes = generateDeviceCodes();
|
|
8007
|
+
await registerDevice(codes);
|
|
8008
|
+
setCloudAuth({ phase: "ready", codes });
|
|
8009
|
+
setStep("cloudAuth");
|
|
8010
|
+
} catch (err) {
|
|
8011
|
+
setCloudAuth({
|
|
8012
|
+
phase: "error",
|
|
8013
|
+
message: err instanceof Error ? err.message : "Failed to start authentication"
|
|
8014
|
+
});
|
|
8015
|
+
setStep("cloudAuth");
|
|
8016
|
+
}
|
|
8017
|
+
}, []);
|
|
7834
8018
|
const handleModeSelect = (item) => {
|
|
7835
8019
|
if (item.value === "cloud") {
|
|
7836
8020
|
setMode("cloud");
|
|
7837
|
-
|
|
8021
|
+
void startCloudAuth();
|
|
7838
8022
|
} else {
|
|
7839
8023
|
setMode("byok");
|
|
7840
8024
|
setStep("accountId");
|
|
7841
8025
|
}
|
|
7842
8026
|
};
|
|
8027
|
+
const handleOpenBrowser = () => {
|
|
8028
|
+
if (cloudAuth?.phase === "ready") {
|
|
8029
|
+
openBrowser(cloudAuth.codes.authUrl);
|
|
8030
|
+
setCloudAuth({ phase: "polling", codes: cloudAuth.codes, startTime: Date.now() });
|
|
8031
|
+
}
|
|
8032
|
+
};
|
|
8033
|
+
const handleCloudSuccess = async () => {
|
|
8034
|
+
if (cloudAuth?.phase !== "success") return;
|
|
8035
|
+
const cfg = { accountId: "", apiToken: "", model: DEFAULT_MODEL, cloudMode: true };
|
|
8036
|
+
try {
|
|
8037
|
+
const path = await saveConfig(cfg);
|
|
8038
|
+
setSavedPath(path);
|
|
8039
|
+
onDone(cfg);
|
|
8040
|
+
} catch (e) {
|
|
8041
|
+
setSavedPath(`error: ${e.message}`);
|
|
8042
|
+
}
|
|
8043
|
+
};
|
|
8044
|
+
const handleCloudRetry = () => {
|
|
8045
|
+
setCloudAuth(null);
|
|
8046
|
+
void startCloudAuth();
|
|
8047
|
+
};
|
|
8048
|
+
const handleCloudSwitchToByok = () => {
|
|
8049
|
+
setCloudAuth(null);
|
|
8050
|
+
setMode("byok");
|
|
8051
|
+
setStep("accountId");
|
|
8052
|
+
};
|
|
7843
8053
|
const handleAccountIdSubmit = (value) => {
|
|
7844
8054
|
const trimmed = value.trim();
|
|
7845
8055
|
if (!trimmed) return;
|
|
@@ -7858,17 +8068,7 @@ function Onboarding({ onDone }) {
|
|
|
7858
8068
|
setStep("confirm");
|
|
7859
8069
|
};
|
|
7860
8070
|
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 };
|
|
8071
|
+
const cfg = { accountId, apiToken, model };
|
|
7872
8072
|
try {
|
|
7873
8073
|
const path = await saveConfig(cfg);
|
|
7874
8074
|
setSavedPath(path);
|
|
@@ -7878,27 +8078,27 @@ function Onboarding({ onDone }) {
|
|
|
7878
8078
|
}
|
|
7879
8079
|
};
|
|
7880
8080
|
const byokSteps = ["accountId", "apiToken", "model", "confirm"];
|
|
7881
|
-
const stepIndex = step === "mode" ? 1 : step === "
|
|
8081
|
+
const stepIndex = step === "mode" ? 1 : step === "cloudAuth" ? 2 : byokSteps.indexOf(step) + 2;
|
|
7882
8082
|
const totalSteps = mode === "cloud" ? 2 : byokSteps.length + 1;
|
|
7883
|
-
return /* @__PURE__ */
|
|
7884
|
-
/* @__PURE__ */
|
|
7885
|
-
/* @__PURE__ */
|
|
7886
|
-
/* @__PURE__ */
|
|
8083
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingY: 1, children: [
|
|
8084
|
+
/* @__PURE__ */ jsxs10(Box10, { marginBottom: 1, children: [
|
|
8085
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: theme.palette.primary, children: "kimiflare" }),
|
|
8086
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7887
8087
|
" ",
|
|
7888
8088
|
"Terminal coding agent"
|
|
7889
8089
|
] })
|
|
7890
8090
|
] }),
|
|
7891
|
-
/* @__PURE__ */
|
|
8091
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7892
8092
|
"Step ",
|
|
7893
8093
|
stepIndex,
|
|
7894
8094
|
" of ",
|
|
7895
8095
|
totalSteps
|
|
7896
8096
|
] }),
|
|
7897
|
-
/* @__PURE__ */
|
|
7898
|
-
step === "mode" && /* @__PURE__ */
|
|
7899
|
-
/* @__PURE__ */
|
|
7900
|
-
/* @__PURE__ */
|
|
7901
|
-
|
|
8097
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
8098
|
+
step === "mode" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8099
|
+
/* @__PURE__ */ jsx12(Text11, { children: "How do you want to connect?" }),
|
|
8100
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
|
|
8101
|
+
SelectInput4,
|
|
7902
8102
|
{
|
|
7903
8103
|
items: [
|
|
7904
8104
|
{ label: "Cloud (managed) \u2014 no API key needed", value: "cloud" },
|
|
@@ -7908,11 +8108,102 @@ function Onboarding({ onDone }) {
|
|
|
7908
8108
|
}
|
|
7909
8109
|
) })
|
|
7910
8110
|
] }),
|
|
7911
|
-
step === "
|
|
7912
|
-
/* @__PURE__ */
|
|
7913
|
-
/* @__PURE__ */
|
|
7914
|
-
/* @__PURE__ */
|
|
7915
|
-
/* @__PURE__ */
|
|
8111
|
+
step === "cloudAuth" && cloudAuth?.phase === "ready" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8112
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Authenticating with Kimiflare Cloud..." }),
|
|
8113
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
8114
|
+
/* @__PURE__ */ jsx12(Text11, { children: "1. Open this URL in your browser:" }),
|
|
8115
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: cloudAuth.codes.authUrl })
|
|
8116
|
+
] }),
|
|
8117
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8118
|
+
/* @__PURE__ */ jsx12(Text11, { children: "2. " }),
|
|
8119
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "[Press Enter to open browser]" })
|
|
8120
|
+
] }),
|
|
8121
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8122
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8123
|
+
/* @__PURE__ */ jsx12(
|
|
8124
|
+
CustomTextInput,
|
|
8125
|
+
{
|
|
8126
|
+
value: "",
|
|
8127
|
+
onChange: () => {
|
|
8128
|
+
},
|
|
8129
|
+
onSubmit: handleOpenBrowser
|
|
8130
|
+
}
|
|
8131
|
+
)
|
|
8132
|
+
] })
|
|
8133
|
+
] }),
|
|
8134
|
+
step === "cloudAuth" && cloudAuth?.phase === "polling" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8135
|
+
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
8136
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.spinner, children: /* @__PURE__ */ jsx12(Spinner5, { type: "dots" }) }),
|
|
8137
|
+
" ",
|
|
8138
|
+
"Waiting for authentication..."
|
|
8139
|
+
] }),
|
|
8140
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
8141
|
+
"Expires in ",
|
|
8142
|
+
formatRemaining(POLL_TIMEOUT_MS - (Date.now() - cloudAuth.startTime))
|
|
8143
|
+
] }),
|
|
8144
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
8145
|
+
"URL: ",
|
|
8146
|
+
cloudAuth.codes.authUrl
|
|
8147
|
+
] })
|
|
8148
|
+
] }),
|
|
8149
|
+
step === "cloudAuth" && cloudAuth?.phase === "success" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8150
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.success, children: "Authenticated!" }),
|
|
8151
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
8152
|
+
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
8153
|
+
"Token budget:",
|
|
8154
|
+
" ",
|
|
8155
|
+
/* @__PURE__ */ jsxs10(Text11, { bold: true, children: [
|
|
8156
|
+
cloudAuth.usage.remaining.toLocaleString(),
|
|
8157
|
+
" /",
|
|
8158
|
+
" ",
|
|
8159
|
+
cloudAuth.usage.input_token_limit.toLocaleString()
|
|
8160
|
+
] }),
|
|
8161
|
+
" ",
|
|
8162
|
+
"remaining"
|
|
8163
|
+
] }),
|
|
8164
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
8165
|
+
"Grant expires: ",
|
|
8166
|
+
cloudAuth.usage.expires_at
|
|
8167
|
+
] })
|
|
8168
|
+
] }),
|
|
8169
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text11, { children: "[Press Enter to continue]" }) }),
|
|
8170
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8171
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8172
|
+
/* @__PURE__ */ jsx12(
|
|
8173
|
+
CustomTextInput,
|
|
8174
|
+
{
|
|
8175
|
+
value: "",
|
|
8176
|
+
onChange: () => {
|
|
8177
|
+
},
|
|
8178
|
+
onSubmit: handleCloudSuccess
|
|
8179
|
+
}
|
|
8180
|
+
)
|
|
8181
|
+
] })
|
|
8182
|
+
] }),
|
|
8183
|
+
step === "cloudAuth" && cloudAuth?.phase === "error" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8184
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.error, children: "Authentication failed" }),
|
|
8185
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.info.color, children: cloudAuth.message }),
|
|
8186
|
+
/* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
|
|
8187
|
+
SelectInput4,
|
|
8188
|
+
{
|
|
8189
|
+
items: [
|
|
8190
|
+
{ label: "Retry", value: "retry" },
|
|
8191
|
+
{ label: "Switch to BYOK", value: "byok" },
|
|
8192
|
+
{ label: "Cancel", value: "cancel" }
|
|
8193
|
+
],
|
|
8194
|
+
onSelect: (item) => {
|
|
8195
|
+
if (item.value === "retry") handleCloudRetry();
|
|
8196
|
+
else if (item.value === "byok") handleCloudSwitchToByok();
|
|
8197
|
+
else if (onCancel) onCancel();
|
|
8198
|
+
}
|
|
8199
|
+
}
|
|
8200
|
+
) })
|
|
8201
|
+
] }),
|
|
8202
|
+
step === "accountId" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8203
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Enter your Cloudflare Account ID" }),
|
|
8204
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8205
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8206
|
+
/* @__PURE__ */ jsx12(
|
|
7916
8207
|
CustomTextInput,
|
|
7917
8208
|
{
|
|
7918
8209
|
value: accountId,
|
|
@@ -7922,12 +8213,12 @@ function Onboarding({ onDone }) {
|
|
|
7922
8213
|
)
|
|
7923
8214
|
] })
|
|
7924
8215
|
] }),
|
|
7925
|
-
step === "apiToken" && /* @__PURE__ */
|
|
7926
|
-
/* @__PURE__ */
|
|
7927
|
-
/* @__PURE__ */
|
|
7928
|
-
/* @__PURE__ */
|
|
7929
|
-
/* @__PURE__ */
|
|
7930
|
-
/* @__PURE__ */
|
|
8216
|
+
step === "apiToken" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8217
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Enter your Cloudflare API Token" }),
|
|
8218
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.info.color, children: "Create one at https://dash.cloudflare.com/profile/api-tokens" }),
|
|
8219
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8220
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8221
|
+
/* @__PURE__ */ jsx12(
|
|
7931
8222
|
CustomTextInput,
|
|
7932
8223
|
{
|
|
7933
8224
|
value: apiToken,
|
|
@@ -7938,15 +8229,15 @@ function Onboarding({ onDone }) {
|
|
|
7938
8229
|
)
|
|
7939
8230
|
] })
|
|
7940
8231
|
] }),
|
|
7941
|
-
step === "model" && /* @__PURE__ */
|
|
7942
|
-
/* @__PURE__ */
|
|
7943
|
-
/* @__PURE__ */
|
|
8232
|
+
step === "model" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8233
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Model ID (press Enter for default)" }),
|
|
8234
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7944
8235
|
"default: ",
|
|
7945
8236
|
DEFAULT_MODEL
|
|
7946
8237
|
] }),
|
|
7947
|
-
/* @__PURE__ */
|
|
7948
|
-
/* @__PURE__ */
|
|
7949
|
-
/* @__PURE__ */
|
|
8238
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8239
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8240
|
+
/* @__PURE__ */ jsx12(
|
|
7950
8241
|
CustomTextInput,
|
|
7951
8242
|
{
|
|
7952
8243
|
value: model,
|
|
@@ -7956,10 +8247,10 @@ function Onboarding({ onDone }) {
|
|
|
7956
8247
|
)
|
|
7957
8248
|
] })
|
|
7958
8249
|
] }),
|
|
7959
|
-
step === "confirm" && /* @__PURE__ */
|
|
7960
|
-
/* @__PURE__ */
|
|
7961
|
-
/* @__PURE__ */
|
|
7962
|
-
|
|
8250
|
+
step === "confirm" && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
8251
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Ready to save configuration" }),
|
|
8252
|
+
/* @__PURE__ */ jsxs10(
|
|
8253
|
+
Box10,
|
|
7963
8254
|
{
|
|
7964
8255
|
flexDirection: "column",
|
|
7965
8256
|
marginTop: 1,
|
|
@@ -7968,25 +8259,25 @@ function Onboarding({ onDone }) {
|
|
|
7968
8259
|
borderColor: theme.info.color,
|
|
7969
8260
|
paddingX: 1,
|
|
7970
8261
|
children: [
|
|
7971
|
-
/* @__PURE__ */
|
|
8262
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7972
8263
|
"Account ID: ",
|
|
7973
8264
|
accountId
|
|
7974
8265
|
] }),
|
|
7975
|
-
/* @__PURE__ */
|
|
8266
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7976
8267
|
"API Token: ",
|
|
7977
8268
|
"\u2022".repeat(apiToken.length)
|
|
7978
8269
|
] }),
|
|
7979
|
-
/* @__PURE__ */
|
|
8270
|
+
/* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
|
|
7980
8271
|
"Model: ",
|
|
7981
8272
|
model
|
|
7982
8273
|
] })
|
|
7983
8274
|
]
|
|
7984
8275
|
}
|
|
7985
8276
|
),
|
|
7986
|
-
/* @__PURE__ */
|
|
7987
|
-
/* @__PURE__ */
|
|
7988
|
-
/* @__PURE__ */
|
|
7989
|
-
/* @__PURE__ */
|
|
8277
|
+
/* @__PURE__ */ jsx12(Text11, { children: "Press Enter to confirm, or Ctrl+C to cancel" }),
|
|
8278
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
8279
|
+
/* @__PURE__ */ jsx12(Text11, { color: theme.palette.primary, children: "\u203A " }),
|
|
8280
|
+
/* @__PURE__ */ jsx12(
|
|
7990
8281
|
CustomTextInput,
|
|
7991
8282
|
{
|
|
7992
8283
|
value: "",
|
|
@@ -7997,68 +8288,54 @@ function Onboarding({ onDone }) {
|
|
|
7997
8288
|
)
|
|
7998
8289
|
] })
|
|
7999
8290
|
] }),
|
|
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: [
|
|
8291
|
+
savedPath && /* @__PURE__ */ jsxs10(Text11, { color: theme.palette.success, children: [
|
|
8018
8292
|
"Config saved to ",
|
|
8019
8293
|
savedPath
|
|
8020
8294
|
] })
|
|
8021
8295
|
] })
|
|
8022
8296
|
] });
|
|
8023
8297
|
}
|
|
8298
|
+
var execAsync;
|
|
8024
8299
|
var init_onboarding = __esm({
|
|
8025
8300
|
"src/ui/onboarding.tsx"() {
|
|
8026
8301
|
"use strict";
|
|
8027
8302
|
init_text_input();
|
|
8028
8303
|
init_config();
|
|
8029
8304
|
init_theme_context();
|
|
8305
|
+
init_auth();
|
|
8306
|
+
execAsync = promisify2(exec);
|
|
8030
8307
|
}
|
|
8031
8308
|
});
|
|
8032
8309
|
|
|
8033
8310
|
// src/ui/welcome.tsx
|
|
8034
|
-
import { Box as
|
|
8035
|
-
import { jsx as
|
|
8311
|
+
import { Box as Box11, Text as Text12 } from "ink";
|
|
8312
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
8036
8313
|
function Welcome({ accountId }) {
|
|
8037
8314
|
const theme = useTheme();
|
|
8038
|
-
return /* @__PURE__ */
|
|
8039
|
-
/* @__PURE__ */
|
|
8040
|
-
/* @__PURE__ */
|
|
8041
|
-
/* @__PURE__ */
|
|
8315
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
|
|
8316
|
+
/* @__PURE__ */ jsxs11(Box11, { marginBottom: 1, children: [
|
|
8317
|
+
/* @__PURE__ */ jsx13(Text12, { bold: true, color: theme.accent, children: "kimiflare" }),
|
|
8318
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
8042
8319
|
" ",
|
|
8043
8320
|
"Ready when you are."
|
|
8044
8321
|
] })
|
|
8045
8322
|
] }),
|
|
8046
|
-
accountId && /* @__PURE__ */
|
|
8323
|
+
accountId && /* @__PURE__ */ jsx13(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
8047
8324
|
" ",
|
|
8048
8325
|
"Check your Cloudflare billing: https://dash.cloudflare.com/",
|
|
8049
8326
|
accountId,
|
|
8050
8327
|
"/billing/billable-usage"
|
|
8051
8328
|
] }) }),
|
|
8052
|
-
/* @__PURE__ */
|
|
8053
|
-
/* @__PURE__ */
|
|
8329
|
+
/* @__PURE__ */ jsx13(Box11, { flexDirection: "column", children: SUGGESTIONS.map((s, i) => /* @__PURE__ */ jsxs11(Box11, { children: [
|
|
8330
|
+
/* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
|
|
8054
8331
|
" ",
|
|
8055
8332
|
"\u203A",
|
|
8056
8333
|
" "
|
|
8057
8334
|
] }),
|
|
8058
|
-
/* @__PURE__ */
|
|
8335
|
+
/* @__PURE__ */ jsx13(Text12, { color: theme.user, children: s })
|
|
8059
8336
|
] }, i)) }),
|
|
8060
|
-
/* @__PURE__ */
|
|
8061
|
-
/* @__PURE__ */
|
|
8337
|
+
/* @__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" }) }),
|
|
8338
|
+
/* @__PURE__ */ jsx13(Box11, { children: /* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: "Tip: type /hello to send feedback to the creator" }) })
|
|
8062
8339
|
] });
|
|
8063
8340
|
}
|
|
8064
8341
|
var SUGGESTIONS;
|
|
@@ -8076,14 +8353,14 @@ var init_welcome = __esm({
|
|
|
8076
8353
|
|
|
8077
8354
|
// src/ui/help-menu.tsx
|
|
8078
8355
|
import { useState as useState6 } from "react";
|
|
8079
|
-
import { Box as
|
|
8080
|
-
import
|
|
8081
|
-
import { jsx as
|
|
8356
|
+
import { Box as Box12, Text as Text13, useInput as useInput3 } from "ink";
|
|
8357
|
+
import SelectInput5 from "ink-select-input";
|
|
8358
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
8082
8359
|
function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, onCommand }) {
|
|
8083
8360
|
const theme = useTheme();
|
|
8084
8361
|
const [page, setPage] = useState6("main");
|
|
8085
8362
|
const customs = customCommands ?? [];
|
|
8086
|
-
|
|
8363
|
+
useInput3((_input, key) => {
|
|
8087
8364
|
if (key.escape) {
|
|
8088
8365
|
if (page !== "main") {
|
|
8089
8366
|
setPage("main");
|
|
@@ -8107,11 +8384,11 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8107
8384
|
items2.push({ label: "Run custom commands", value: "custom", key: "custom" });
|
|
8108
8385
|
}
|
|
8109
8386
|
items2.push({ label: "(close)", value: "__close__", key: "__close__" });
|
|
8110
|
-
return /* @__PURE__ */
|
|
8111
|
-
/* @__PURE__ */
|
|
8112
|
-
/* @__PURE__ */
|
|
8113
|
-
/* @__PURE__ */
|
|
8114
|
-
|
|
8387
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8388
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: "Help" }),
|
|
8389
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to close." }),
|
|
8390
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8391
|
+
SelectInput5,
|
|
8115
8392
|
{
|
|
8116
8393
|
items: items2,
|
|
8117
8394
|
onSelect: (item) => {
|
|
@@ -8123,8 +8400,8 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8123
8400
|
}
|
|
8124
8401
|
}
|
|
8125
8402
|
) }),
|
|
8126
|
-
/* @__PURE__ */
|
|
8127
|
-
/* @__PURE__ */
|
|
8403
|
+
/* @__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)) }),
|
|
8404
|
+
/* @__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
8405
|
] });
|
|
8129
8406
|
}
|
|
8130
8407
|
if (page === "custom") {
|
|
@@ -8134,11 +8411,11 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8134
8411
|
key: c.name
|
|
8135
8412
|
}));
|
|
8136
8413
|
items2.push({ label: "\u2190 Back", value: "__back__", key: "__back__" });
|
|
8137
|
-
return /* @__PURE__ */
|
|
8138
|
-
/* @__PURE__ */
|
|
8139
|
-
/* @__PURE__ */
|
|
8140
|
-
/* @__PURE__ */
|
|
8141
|
-
|
|
8414
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8415
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
8416
|
+
/* @__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." }),
|
|
8417
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8418
|
+
SelectInput5,
|
|
8142
8419
|
{
|
|
8143
8420
|
items: items2,
|
|
8144
8421
|
onSelect: (item) => {
|
|
@@ -8161,11 +8438,11 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8161
8438
|
key: cmd.command
|
|
8162
8439
|
}));
|
|
8163
8440
|
items.push({ label: "\u2190 Back", value: "__back__", key: "__back__" });
|
|
8164
|
-
return /* @__PURE__ */
|
|
8165
|
-
/* @__PURE__ */
|
|
8166
|
-
/* @__PURE__ */
|
|
8167
|
-
/* @__PURE__ */
|
|
8168
|
-
|
|
8441
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
8442
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: category.label }),
|
|
8443
|
+
/* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to execute, Esc to go back." }),
|
|
8444
|
+
/* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
|
|
8445
|
+
SelectInput5,
|
|
8169
8446
|
{
|
|
8170
8447
|
items,
|
|
8171
8448
|
onSelect: (item) => {
|
|
@@ -8177,7 +8454,7 @@ function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, o
|
|
|
8177
8454
|
}
|
|
8178
8455
|
}
|
|
8179
8456
|
) }),
|
|
8180
|
-
staticCmds.length > 0 && /* @__PURE__ */
|
|
8457
|
+
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
8458
|
] });
|
|
8182
8459
|
}
|
|
8183
8460
|
var CATEGORIES, SINGLE_COMMANDS;
|
|
@@ -8409,17 +8686,17 @@ var init_tui_deploy = __esm({
|
|
|
8409
8686
|
});
|
|
8410
8687
|
|
|
8411
8688
|
// src/ui/remote-dashboard.tsx
|
|
8412
|
-
import { useEffect as
|
|
8413
|
-
import { Box as
|
|
8414
|
-
import
|
|
8415
|
-
import { jsx as
|
|
8689
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
8690
|
+
import { Box as Box13, Text as Text14, useInput as useInput4 } from "ink";
|
|
8691
|
+
import SelectInput6 from "ink-select-input";
|
|
8692
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
8416
8693
|
function RemoteDashboard({ onSelect, onCancel }) {
|
|
8417
8694
|
const theme = useTheme();
|
|
8418
8695
|
const [sessions, setSessions] = useState7([]);
|
|
8419
8696
|
const [loading, setLoading] = useState7(true);
|
|
8420
8697
|
const [error, setError] = useState7(null);
|
|
8421
8698
|
const [refreshing, setRefreshing] = useState7(false);
|
|
8422
|
-
|
|
8699
|
+
useEffect5(() => {
|
|
8423
8700
|
loadSessions();
|
|
8424
8701
|
}, []);
|
|
8425
8702
|
async function loadSessions() {
|
|
@@ -8455,7 +8732,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8455
8732
|
setRefreshing(false);
|
|
8456
8733
|
}
|
|
8457
8734
|
}
|
|
8458
|
-
|
|
8735
|
+
useInput4((input, key) => {
|
|
8459
8736
|
if (input === "r" || input === "R") {
|
|
8460
8737
|
void loadSessions();
|
|
8461
8738
|
}
|
|
@@ -8468,31 +8745,31 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8468
8745
|
value: s.sessionId
|
|
8469
8746
|
}));
|
|
8470
8747
|
if (loading) {
|
|
8471
|
-
return /* @__PURE__ */
|
|
8748
|
+
return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "Loading remote sessions..." }) });
|
|
8472
8749
|
}
|
|
8473
8750
|
if (error) {
|
|
8474
|
-
return /* @__PURE__ */
|
|
8475
|
-
/* @__PURE__ */
|
|
8751
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8752
|
+
/* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
|
|
8476
8753
|
"Error: ",
|
|
8477
8754
|
error
|
|
8478
8755
|
] }),
|
|
8479
|
-
/* @__PURE__ */
|
|
8756
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press R to retry, Esc to close" })
|
|
8480
8757
|
] });
|
|
8481
8758
|
}
|
|
8482
8759
|
if (sessions.length === 0) {
|
|
8483
|
-
return /* @__PURE__ */
|
|
8484
|
-
/* @__PURE__ */
|
|
8485
|
-
/* @__PURE__ */
|
|
8486
|
-
/* @__PURE__ */
|
|
8760
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8761
|
+
/* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "No remote sessions yet." }),
|
|
8762
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Type /remote <prompt> to start one." }),
|
|
8763
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press Esc to close" })
|
|
8487
8764
|
] });
|
|
8488
8765
|
}
|
|
8489
|
-
return /* @__PURE__ */
|
|
8490
|
-
/* @__PURE__ */
|
|
8766
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8767
|
+
/* @__PURE__ */ jsxs13(Text14, { bold: true, color: theme.accent, children: [
|
|
8491
8768
|
"Recent remote tasks ",
|
|
8492
8769
|
refreshing ? "(refreshing...)" : ""
|
|
8493
8770
|
] }),
|
|
8494
|
-
/* @__PURE__ */
|
|
8495
|
-
|
|
8771
|
+
/* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
|
|
8772
|
+
SelectInput6,
|
|
8496
8773
|
{
|
|
8497
8774
|
items,
|
|
8498
8775
|
onSelect: (item) => {
|
|
@@ -8501,7 +8778,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
|
|
|
8501
8778
|
}
|
|
8502
8779
|
}
|
|
8503
8780
|
) }),
|
|
8504
|
-
/* @__PURE__ */
|
|
8781
|
+
/* @__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
8782
|
] });
|
|
8506
8783
|
}
|
|
8507
8784
|
function formatSessionLine(s) {
|
|
@@ -8509,7 +8786,7 @@ function formatSessionLine(s) {
|
|
|
8509
8786
|
const ago = formatAgo(new Date(s.updatedAt));
|
|
8510
8787
|
const prompt = s.prompt.slice(0, 30) + (s.prompt.length > 30 ? "\u2026" : "");
|
|
8511
8788
|
const outcome = s.prUrl ? `PR ${s.prUrl.split("/").pop()}` : s.status;
|
|
8512
|
-
const cost = s.tokensUsed && s.tokensBudget ? ` (${
|
|
8789
|
+
const cost = s.tokensUsed && s.tokensBudget ? ` (${formatTokens3(s.tokensUsed)}/${formatTokens3(s.tokensBudget)})` : s.tokensUsed ? ` (${formatTokens3(s.tokensUsed)})` : "";
|
|
8513
8790
|
return `${icon} ${prompt} \u2192 ${outcome} ${ago}${cost}`;
|
|
8514
8791
|
}
|
|
8515
8792
|
function formatAgo(date) {
|
|
@@ -8522,7 +8799,7 @@ function formatAgo(date) {
|
|
|
8522
8799
|
if (minutes > 0) return `${minutes}m ago`;
|
|
8523
8800
|
return "just now";
|
|
8524
8801
|
}
|
|
8525
|
-
function
|
|
8802
|
+
function formatTokens3(n) {
|
|
8526
8803
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
8527
8804
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
8528
8805
|
return String(n);
|
|
@@ -8534,7 +8811,7 @@ function RemoteSessionDetail({
|
|
|
8534
8811
|
}) {
|
|
8535
8812
|
const theme = useTheme();
|
|
8536
8813
|
const [cancelling, setCancelling] = useState7(false);
|
|
8537
|
-
|
|
8814
|
+
useInput4((input, key) => {
|
|
8538
8815
|
if (key.escape) {
|
|
8539
8816
|
onBack();
|
|
8540
8817
|
}
|
|
@@ -8554,50 +8831,50 @@ function RemoteSessionDetail({
|
|
|
8554
8831
|
}
|
|
8555
8832
|
}
|
|
8556
8833
|
const isRunning = session.status === "running" || session.status === "pending";
|
|
8557
|
-
return /* @__PURE__ */
|
|
8558
|
-
/* @__PURE__ */
|
|
8559
|
-
/* @__PURE__ */
|
|
8560
|
-
/* @__PURE__ */
|
|
8834
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
|
|
8835
|
+
/* @__PURE__ */ jsx15(Text14, { bold: true, color: theme.accent, children: "Remote Session" }),
|
|
8836
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
8837
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8561
8838
|
"ID: ",
|
|
8562
8839
|
session.sessionId
|
|
8563
8840
|
] }),
|
|
8564
|
-
/* @__PURE__ */
|
|
8841
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8565
8842
|
"Repo: ",
|
|
8566
8843
|
session.repo
|
|
8567
8844
|
] }),
|
|
8568
|
-
/* @__PURE__ */
|
|
8845
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8569
8846
|
"Status: ",
|
|
8570
8847
|
session.status
|
|
8571
8848
|
] }),
|
|
8572
|
-
/* @__PURE__ */
|
|
8849
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8573
8850
|
"Prompt: ",
|
|
8574
8851
|
session.prompt
|
|
8575
8852
|
] }),
|
|
8576
|
-
session.prUrl && /* @__PURE__ */
|
|
8853
|
+
session.prUrl && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8577
8854
|
"PR: ",
|
|
8578
8855
|
session.prUrl
|
|
8579
8856
|
] }),
|
|
8580
|
-
session.errorMessage && /* @__PURE__ */
|
|
8857
|
+
session.errorMessage && /* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
|
|
8581
8858
|
"Error: ",
|
|
8582
8859
|
session.errorMessage
|
|
8583
8860
|
] }),
|
|
8584
|
-
session.tokensUsed !== void 0 && /* @__PURE__ */
|
|
8861
|
+
session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8585
8862
|
"Tokens: ",
|
|
8586
|
-
|
|
8587
|
-
session.tokensBudget ? ` / ${
|
|
8863
|
+
formatTokens3(session.tokensUsed),
|
|
8864
|
+
session.tokensBudget ? ` / ${formatTokens3(session.tokensBudget)}` : ""
|
|
8588
8865
|
] }),
|
|
8589
|
-
/* @__PURE__ */
|
|
8866
|
+
/* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8590
8867
|
"Created: ",
|
|
8591
8868
|
new Date(session.createdAt).toLocaleString()
|
|
8592
8869
|
] }),
|
|
8593
|
-
session.finishedAt && /* @__PURE__ */
|
|
8870
|
+
session.finishedAt && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
8594
8871
|
"Finished: ",
|
|
8595
8872
|
new Date(session.finishedAt).toLocaleString()
|
|
8596
8873
|
] })
|
|
8597
8874
|
] }),
|
|
8598
|
-
/* @__PURE__ */
|
|
8599
|
-
isRunning && onCancel && /* @__PURE__ */
|
|
8600
|
-
/* @__PURE__ */
|
|
8875
|
+
/* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", gap: 2, children: [
|
|
8876
|
+
isRunning && onCancel && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
|
|
8877
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Esc back" })
|
|
8601
8878
|
] })
|
|
8602
8879
|
] });
|
|
8603
8880
|
}
|
|
@@ -9502,8 +9779,8 @@ function computeExactScore(memory, queryText, cwd) {
|
|
|
9502
9779
|
let score = 0;
|
|
9503
9780
|
const lowerQuery = queryText.toLowerCase();
|
|
9504
9781
|
for (const file of memory.relatedFiles) {
|
|
9505
|
-
const
|
|
9506
|
-
if (lowerQuery.includes(
|
|
9782
|
+
const basename5 = file.split("/").pop() ?? file;
|
|
9783
|
+
if (lowerQuery.includes(basename5.toLowerCase()) || basename5.toLowerCase().includes(lowerQuery)) {
|
|
9507
9784
|
score += 0.3;
|
|
9508
9785
|
}
|
|
9509
9786
|
if (cwd && file.startsWith(cwd)) {
|
|
@@ -10281,10 +10558,10 @@ var init_loader = __esm({
|
|
|
10281
10558
|
});
|
|
10282
10559
|
|
|
10283
10560
|
// src/commands/renderer.ts
|
|
10284
|
-
import { exec } from "child_process";
|
|
10561
|
+
import { exec as exec2 } from "child_process";
|
|
10285
10562
|
import { open as open2, realpath as realpath2 } from "fs/promises";
|
|
10286
10563
|
import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolvePathJoin, basename as pathBasename } from "path";
|
|
10287
|
-
import { promisify as
|
|
10564
|
+
import { promisify as promisify3 } from "util";
|
|
10288
10565
|
function tokenizeArgs(s) {
|
|
10289
10566
|
return [...s.matchAll(ARG_TOKEN_RE)].map((match) => {
|
|
10290
10567
|
const token = match[0];
|
|
@@ -10351,7 +10628,7 @@ async function replaceShell(prompt, warnings, cmd, shellTimeoutMs) {
|
|
|
10351
10628
|
matches.map(async (match) => {
|
|
10352
10629
|
const command = match[1] ?? "";
|
|
10353
10630
|
try {
|
|
10354
|
-
const { stdout } = await
|
|
10631
|
+
const { stdout } = await execAsync2(command, {
|
|
10355
10632
|
timeout: shellTimeoutMs,
|
|
10356
10633
|
maxBuffer: 1024 * 1024
|
|
10357
10634
|
});
|
|
@@ -10432,12 +10709,12 @@ async function replaceFiles(prompt, warnings, cmd, cwd, maxFileBytes) {
|
|
|
10432
10709
|
function message(error) {
|
|
10433
10710
|
return error instanceof Error ? error.message : String(error);
|
|
10434
10711
|
}
|
|
10435
|
-
var
|
|
10712
|
+
var execAsync2, ARG_TOKEN_RE, POSITIONAL_RE, HAS_POSITIONAL, SHELL_RE, FILE_RE, DEFAULT_MAX_FILE_BYTES, DEFAULT_SHELL_TIMEOUT_MS, SECRET_PATTERNS2;
|
|
10436
10713
|
var init_renderer2 = __esm({
|
|
10437
10714
|
"src/commands/renderer.ts"() {
|
|
10438
10715
|
"use strict";
|
|
10439
10716
|
init_paths();
|
|
10440
|
-
|
|
10717
|
+
execAsync2 = promisify3(exec2);
|
|
10441
10718
|
ARG_TOKEN_RE = /(?:"[^"]*"|'[^']*'|[^\s"']+)/g;
|
|
10442
10719
|
POSITIONAL_RE = /\$(\d+)/g;
|
|
10443
10720
|
HAS_POSITIONAL = /\$\d+/;
|
|
@@ -10535,9 +10812,9 @@ var init_save = __esm({
|
|
|
10535
10812
|
|
|
10536
10813
|
// src/ui/command-wizard.tsx
|
|
10537
10814
|
import { useState as useState8 } from "react";
|
|
10538
|
-
import { Box as
|
|
10539
|
-
import
|
|
10540
|
-
import { Fragment as Fragment2, jsx as
|
|
10815
|
+
import { Box as Box14, Text as Text15, useInput as useInput5, useWindowSize as useWindowSize2 } from "ink";
|
|
10816
|
+
import SelectInput7 from "ink-select-input";
|
|
10817
|
+
import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
10541
10818
|
function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
|
|
10542
10819
|
const theme = useTheme();
|
|
10543
10820
|
const [step, setStep] = useState8("name");
|
|
@@ -10561,7 +10838,7 @@ function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onS
|
|
|
10561
10838
|
if (existingNames.includes(trimmed) && !isEditingSelf(trimmed)) return `/${trimmed} already exists`;
|
|
10562
10839
|
return null;
|
|
10563
10840
|
};
|
|
10564
|
-
|
|
10841
|
+
useInput5((_input, key) => {
|
|
10565
10842
|
if (key.escape) {
|
|
10566
10843
|
onDone();
|
|
10567
10844
|
}
|
|
@@ -10661,8 +10938,8 @@ ${template}`;
|
|
|
10661
10938
|
const renderStep = () => {
|
|
10662
10939
|
switch (step) {
|
|
10663
10940
|
case "name":
|
|
10664
|
-
return /* @__PURE__ */
|
|
10665
|
-
/* @__PURE__ */
|
|
10941
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
10942
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10666
10943
|
mode === "create" ? "Create" : "Edit",
|
|
10667
10944
|
" custom command \u2014 Name (",
|
|
10668
10945
|
stepIndex,
|
|
@@ -10670,8 +10947,8 @@ ${template}`;
|
|
|
10670
10947
|
totalSteps,
|
|
10671
10948
|
")"
|
|
10672
10949
|
] }),
|
|
10673
|
-
error && /* @__PURE__ */
|
|
10674
|
-
/* @__PURE__ */
|
|
10950
|
+
error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
|
|
10951
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10675
10952
|
CustomTextInput,
|
|
10676
10953
|
{
|
|
10677
10954
|
value: name,
|
|
@@ -10680,11 +10957,11 @@ ${template}`;
|
|
|
10680
10957
|
focus: true
|
|
10681
10958
|
}
|
|
10682
10959
|
) }),
|
|
10683
|
-
/* @__PURE__ */
|
|
10960
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
|
|
10684
10961
|
] });
|
|
10685
10962
|
case "description":
|
|
10686
|
-
return /* @__PURE__ */
|
|
10687
|
-
/* @__PURE__ */
|
|
10963
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
10964
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10688
10965
|
mode === "create" ? "Create" : "Edit",
|
|
10689
10966
|
" custom command \u2014 Description (",
|
|
10690
10967
|
stepIndex,
|
|
@@ -10692,7 +10969,7 @@ ${template}`;
|
|
|
10692
10969
|
totalSteps,
|
|
10693
10970
|
")"
|
|
10694
10971
|
] }),
|
|
10695
|
-
/* @__PURE__ */
|
|
10972
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10696
10973
|
CustomTextInput,
|
|
10697
10974
|
{
|
|
10698
10975
|
value: description,
|
|
@@ -10701,49 +10978,49 @@ ${template}`;
|
|
|
10701
10978
|
focus: true
|
|
10702
10979
|
}
|
|
10703
10980
|
) }),
|
|
10704
|
-
/* @__PURE__ */
|
|
10981
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
|
|
10705
10982
|
] });
|
|
10706
10983
|
case "template": {
|
|
10707
|
-
const guide = /* @__PURE__ */
|
|
10708
|
-
/* @__PURE__ */
|
|
10709
|
-
/* @__PURE__ */
|
|
10710
|
-
/* @__PURE__ */
|
|
10984
|
+
const guide = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingLeft: 1, children: [
|
|
10985
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "What is this?" }),
|
|
10986
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
|
|
10987
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10711
10988
|
"When you type /",
|
|
10712
10989
|
name || "yourcommand",
|
|
10713
10990
|
" later, this gets sent to the model."
|
|
10714
10991
|
] }),
|
|
10715
|
-
/* @__PURE__ */
|
|
10716
|
-
/* @__PURE__ */
|
|
10717
|
-
/* @__PURE__ */
|
|
10992
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
10993
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Variables" }),
|
|
10994
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10718
10995
|
" ",
|
|
10719
10996
|
"$1, $2 ... \u2192 arguments you type"
|
|
10720
10997
|
] }),
|
|
10721
|
-
/* @__PURE__ */
|
|
10998
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10722
10999
|
" ",
|
|
10723
11000
|
"$ARGUMENTS \u2192 everything after the command"
|
|
10724
11001
|
] })
|
|
10725
11002
|
] }),
|
|
10726
|
-
/* @__PURE__ */
|
|
10727
|
-
/* @__PURE__ */
|
|
10728
|
-
/* @__PURE__ */
|
|
11003
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
11004
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
|
|
11005
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10729
11006
|
" ",
|
|
10730
11007
|
"!`git diff` \u2192 shell output inlined"
|
|
10731
11008
|
] }),
|
|
10732
|
-
/* @__PURE__ */
|
|
11009
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10733
11010
|
" ",
|
|
10734
11011
|
"@README.md \u2192 file contents inlined"
|
|
10735
11012
|
] })
|
|
10736
11013
|
] }),
|
|
10737
|
-
/* @__PURE__ */
|
|
10738
|
-
/* @__PURE__ */
|
|
10739
|
-
/* @__PURE__ */
|
|
10740
|
-
/* @__PURE__ */
|
|
10741
|
-
/* @__PURE__ */
|
|
11014
|
+
/* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
11015
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Example" }),
|
|
11016
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Review this PR diff:" }),
|
|
11017
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
|
|
11018
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Focus on: $1" })
|
|
10742
11019
|
] })
|
|
10743
11020
|
] });
|
|
10744
|
-
const inputArea = /* @__PURE__ */
|
|
10745
|
-
error && /* @__PURE__ */
|
|
10746
|
-
/* @__PURE__ */
|
|
11021
|
+
const inputArea = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexGrow: 1, children: [
|
|
11022
|
+
error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
|
|
11023
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10747
11024
|
CustomTextInput,
|
|
10748
11025
|
{
|
|
10749
11026
|
value: template,
|
|
@@ -10753,13 +11030,13 @@ ${template}`;
|
|
|
10753
11030
|
enablePaste: true
|
|
10754
11031
|
}
|
|
10755
11032
|
) }),
|
|
10756
|
-
columns < 100 && /* @__PURE__ */
|
|
10757
|
-
/* @__PURE__ */
|
|
10758
|
-
/* @__PURE__ */
|
|
11033
|
+
columns < 100 && /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11034
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
|
|
11035
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
|
|
10759
11036
|
] })
|
|
10760
11037
|
] });
|
|
10761
|
-
return /* @__PURE__ */
|
|
10762
|
-
/* @__PURE__ */
|
|
11038
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11039
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10763
11040
|
mode === "create" ? "Create" : "Edit",
|
|
10764
11041
|
" custom command \u2014 Template (",
|
|
10765
11042
|
stepIndex,
|
|
@@ -10767,10 +11044,10 @@ ${template}`;
|
|
|
10767
11044
|
totalSteps,
|
|
10768
11045
|
")"
|
|
10769
11046
|
] }),
|
|
10770
|
-
columns >= 100 ? /* @__PURE__ */
|
|
10771
|
-
/* @__PURE__ */
|
|
10772
|
-
/* @__PURE__ */
|
|
10773
|
-
] }) : /* @__PURE__ */
|
|
11047
|
+
columns >= 100 ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "row", marginTop: 1, children: [
|
|
11048
|
+
/* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: inputArea }),
|
|
11049
|
+
/* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: guide })
|
|
11050
|
+
] }) : /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", marginTop: 1, children: inputArea })
|
|
10774
11051
|
] });
|
|
10775
11052
|
}
|
|
10776
11053
|
case "advanced": {
|
|
@@ -10779,8 +11056,8 @@ ${template}`;
|
|
|
10779
11056
|
{ label: "Skip", value: "skip", key: "skip" },
|
|
10780
11057
|
{ label: "\u2190 Cancel", value: "cancel", key: "cancel" }
|
|
10781
11058
|
];
|
|
10782
|
-
return /* @__PURE__ */
|
|
10783
|
-
/* @__PURE__ */
|
|
11059
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11060
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10784
11061
|
mode === "create" ? "Create" : "Edit",
|
|
10785
11062
|
" custom command \u2014 Options (",
|
|
10786
11063
|
stepIndex,
|
|
@@ -10788,8 +11065,8 @@ ${template}`;
|
|
|
10788
11065
|
totalSteps,
|
|
10789
11066
|
")"
|
|
10790
11067
|
] }),
|
|
10791
|
-
/* @__PURE__ */
|
|
10792
|
-
|
|
11068
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11069
|
+
SelectInput7,
|
|
10793
11070
|
{
|
|
10794
11071
|
items,
|
|
10795
11072
|
onSelect: (item) => {
|
|
@@ -10808,17 +11085,17 @@ ${template}`;
|
|
|
10808
11085
|
{ label: cmdMode === "auto" ? "auto \xB7 current" : "auto", value: "auto", key: "auto" },
|
|
10809
11086
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10810
11087
|
];
|
|
10811
|
-
return /* @__PURE__ */
|
|
10812
|
-
/* @__PURE__ */
|
|
11088
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11089
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10813
11090
|
"Mode override (",
|
|
10814
11091
|
stepIndex,
|
|
10815
11092
|
"/",
|
|
10816
11093
|
totalSteps,
|
|
10817
11094
|
")"
|
|
10818
11095
|
] }),
|
|
10819
|
-
/* @__PURE__ */
|
|
10820
|
-
/* @__PURE__ */
|
|
10821
|
-
|
|
11096
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
|
|
11097
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11098
|
+
SelectInput7,
|
|
10822
11099
|
{
|
|
10823
11100
|
items,
|
|
10824
11101
|
onSelect: (item) => {
|
|
@@ -10837,16 +11114,16 @@ ${template}`;
|
|
|
10837
11114
|
{ label: cmdEffort === "high" ? "high \xB7 current" : "high", value: "high", key: "high" },
|
|
10838
11115
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10839
11116
|
];
|
|
10840
|
-
return /* @__PURE__ */
|
|
10841
|
-
/* @__PURE__ */
|
|
11117
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11118
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10842
11119
|
"Reasoning effort (",
|
|
10843
11120
|
stepIndex,
|
|
10844
11121
|
"/",
|
|
10845
11122
|
totalSteps,
|
|
10846
11123
|
")"
|
|
10847
11124
|
] }),
|
|
10848
|
-
/* @__PURE__ */
|
|
10849
|
-
|
|
11125
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11126
|
+
SelectInput7,
|
|
10850
11127
|
{
|
|
10851
11128
|
items,
|
|
10852
11129
|
onSelect: (item) => {
|
|
@@ -10858,15 +11135,15 @@ ${template}`;
|
|
|
10858
11135
|
] });
|
|
10859
11136
|
}
|
|
10860
11137
|
case "model":
|
|
10861
|
-
return /* @__PURE__ */
|
|
10862
|
-
/* @__PURE__ */
|
|
11138
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11139
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10863
11140
|
"Model override (",
|
|
10864
11141
|
stepIndex,
|
|
10865
11142
|
"/",
|
|
10866
11143
|
totalSteps,
|
|
10867
11144
|
")"
|
|
10868
11145
|
] }),
|
|
10869
|
-
/* @__PURE__ */
|
|
11146
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
10870
11147
|
CustomTextInput,
|
|
10871
11148
|
{
|
|
10872
11149
|
value: cmdModel ?? "",
|
|
@@ -10875,7 +11152,7 @@ ${template}`;
|
|
|
10875
11152
|
focus: true
|
|
10876
11153
|
}
|
|
10877
11154
|
) }),
|
|
10878
|
-
/* @__PURE__ */
|
|
11155
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
|
|
10879
11156
|
] });
|
|
10880
11157
|
case "location": {
|
|
10881
11158
|
const items = [
|
|
@@ -10883,16 +11160,16 @@ ${template}`;
|
|
|
10883
11160
|
{ label: source === "global" ? "Global \xB7 current" : "Global", value: "global", key: "global" },
|
|
10884
11161
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
10885
11162
|
];
|
|
10886
|
-
return /* @__PURE__ */
|
|
10887
|
-
/* @__PURE__ */
|
|
11163
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11164
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10888
11165
|
"Save location (",
|
|
10889
11166
|
stepIndex,
|
|
10890
11167
|
"/",
|
|
10891
11168
|
totalSteps,
|
|
10892
11169
|
")"
|
|
10893
11170
|
] }),
|
|
10894
|
-
/* @__PURE__ */
|
|
10895
|
-
|
|
11171
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11172
|
+
SelectInput7,
|
|
10896
11173
|
{
|
|
10897
11174
|
items,
|
|
10898
11175
|
onSelect: (item) => {
|
|
@@ -10901,7 +11178,7 @@ ${template}`;
|
|
|
10901
11178
|
}
|
|
10902
11179
|
}
|
|
10903
11180
|
) }),
|
|
10904
|
-
/* @__PURE__ */
|
|
11181
|
+
/* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
|
|
10905
11182
|
] });
|
|
10906
11183
|
}
|
|
10907
11184
|
case "confirm": {
|
|
@@ -10909,8 +11186,8 @@ ${template}`;
|
|
|
10909
11186
|
{ label: "Save", value: "save", key: "save" },
|
|
10910
11187
|
{ label: "Cancel", value: "cancel", key: "cancel" }
|
|
10911
11188
|
];
|
|
10912
|
-
return /* @__PURE__ */
|
|
10913
|
-
/* @__PURE__ */
|
|
11189
|
+
return /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
11190
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
|
|
10914
11191
|
mode === "create" ? "Create" : "Edit",
|
|
10915
11192
|
" custom command \u2014 Confirm (",
|
|
10916
11193
|
stepIndex,
|
|
@@ -10918,14 +11195,14 @@ ${template}`;
|
|
|
10918
11195
|
totalSteps,
|
|
10919
11196
|
")"
|
|
10920
11197
|
] }),
|
|
10921
|
-
/* @__PURE__ */
|
|
11198
|
+
/* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
|
|
10922
11199
|
source === "project" ? ".kimiflare/commands/" : "~/.config/kimiflare/commands/",
|
|
10923
11200
|
name,
|
|
10924
11201
|
".md"
|
|
10925
11202
|
] }),
|
|
10926
|
-
/* @__PURE__ */
|
|
10927
|
-
/* @__PURE__ */
|
|
10928
|
-
|
|
11203
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: line || " " }, i)) }),
|
|
11204
|
+
/* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
11205
|
+
SelectInput7,
|
|
10929
11206
|
{
|
|
10930
11207
|
items,
|
|
10931
11208
|
onSelect: (item) => handleConfirm(item.value)
|
|
@@ -10935,7 +11212,7 @@ ${template}`;
|
|
|
10935
11212
|
}
|
|
10936
11213
|
}
|
|
10937
11214
|
};
|
|
10938
|
-
return /* @__PURE__ */
|
|
11215
|
+
return /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
|
|
10939
11216
|
}
|
|
10940
11217
|
var NAME_RE;
|
|
10941
11218
|
var init_command_wizard = __esm({
|
|
@@ -10947,10 +11224,442 @@ var init_command_wizard = __esm({
|
|
|
10947
11224
|
}
|
|
10948
11225
|
});
|
|
10949
11226
|
|
|
11227
|
+
// src/init/context-generator.ts
|
|
11228
|
+
import { existsSync as existsSync2, statSync as statSync3 } from "fs";
|
|
11229
|
+
import { join as join20 } from "path";
|
|
11230
|
+
function detectFlavor(cwd) {
|
|
11231
|
+
for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
|
|
11232
|
+
if (flavor === "generic") continue;
|
|
11233
|
+
for (const sig of signatures) {
|
|
11234
|
+
const path = join20(cwd, sig);
|
|
11235
|
+
if (sig.includes("*")) {
|
|
11236
|
+
try {
|
|
11237
|
+
const parts = sig.split("*");
|
|
11238
|
+
const prefix = parts[0] ?? "";
|
|
11239
|
+
const suffix = parts[1] ?? "";
|
|
11240
|
+
const entries = __require("fs").readdirSync(cwd);
|
|
11241
|
+
if (entries.some((e) => e.startsWith(prefix) && e.endsWith(suffix))) {
|
|
11242
|
+
return flavor;
|
|
11243
|
+
}
|
|
11244
|
+
} catch {
|
|
11245
|
+
}
|
|
11246
|
+
} else if (existsSync2(path)) {
|
|
11247
|
+
return flavor;
|
|
11248
|
+
}
|
|
11249
|
+
}
|
|
11250
|
+
}
|
|
11251
|
+
return "generic";
|
|
11252
|
+
}
|
|
11253
|
+
function findFile(cwd, candidates) {
|
|
11254
|
+
for (const c of candidates) {
|
|
11255
|
+
if (existsSync2(join20(cwd, c))) return c;
|
|
11256
|
+
}
|
|
11257
|
+
return null;
|
|
11258
|
+
}
|
|
11259
|
+
function findSourceRoots(cwd) {
|
|
11260
|
+
const roots = [];
|
|
11261
|
+
for (const r of SOURCE_ROOT_CANDIDATES) {
|
|
11262
|
+
const p = join20(cwd, r);
|
|
11263
|
+
try {
|
|
11264
|
+
const s = statSync3(p);
|
|
11265
|
+
if (s.isDirectory()) roots.push(r);
|
|
11266
|
+
} catch {
|
|
11267
|
+
}
|
|
11268
|
+
}
|
|
11269
|
+
return roots;
|
|
11270
|
+
}
|
|
11271
|
+
function findCiConfig(cwd) {
|
|
11272
|
+
for (const c of CI_PATHS) {
|
|
11273
|
+
if (existsSync2(join20(cwd, c))) {
|
|
11274
|
+
try {
|
|
11275
|
+
const s = statSync3(join20(cwd, c));
|
|
11276
|
+
return s.isDirectory() ? c : c;
|
|
11277
|
+
} catch {
|
|
11278
|
+
}
|
|
11279
|
+
}
|
|
11280
|
+
}
|
|
11281
|
+
return null;
|
|
11282
|
+
}
|
|
11283
|
+
function languageForFlavor(f) {
|
|
11284
|
+
const map = {
|
|
11285
|
+
node: "JavaScript / TypeScript",
|
|
11286
|
+
python: "Python",
|
|
11287
|
+
go: "Go",
|
|
11288
|
+
rust: "Rust",
|
|
11289
|
+
ruby: "Ruby",
|
|
11290
|
+
java: "Java / Kotlin",
|
|
11291
|
+
dotnet: "C# / F#",
|
|
11292
|
+
php: "PHP",
|
|
11293
|
+
elixir: "Elixir",
|
|
11294
|
+
haskell: "Haskell",
|
|
11295
|
+
c: "C",
|
|
11296
|
+
cpp: "C++",
|
|
11297
|
+
zig: "Zig",
|
|
11298
|
+
generic: "Unknown"
|
|
11299
|
+
};
|
|
11300
|
+
return map[f];
|
|
11301
|
+
}
|
|
11302
|
+
function analyzeProject(cwd) {
|
|
11303
|
+
const flavor = detectFlavor(cwd);
|
|
11304
|
+
const packageFiles = {
|
|
11305
|
+
node: ["package.json"],
|
|
11306
|
+
python: ["pyproject.toml", "setup.py", "setup.cfg"],
|
|
11307
|
+
go: ["go.mod"],
|
|
11308
|
+
rust: ["Cargo.toml"],
|
|
11309
|
+
ruby: ["Gemfile"],
|
|
11310
|
+
java: ["pom.xml", "build.gradle", "build.gradle.kts"],
|
|
11311
|
+
dotnet: ["*.csproj"],
|
|
11312
|
+
php: ["composer.json"],
|
|
11313
|
+
elixir: ["mix.exs"],
|
|
11314
|
+
haskell: ["package.yaml", "*.cabal"],
|
|
11315
|
+
c: ["Makefile", "CMakeLists.txt"],
|
|
11316
|
+
cpp: ["Makefile", "CMakeLists.txt"],
|
|
11317
|
+
zig: ["build.zig"],
|
|
11318
|
+
generic: []
|
|
11319
|
+
};
|
|
11320
|
+
const lockFiles = {
|
|
11321
|
+
node: ["package-lock.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb"],
|
|
11322
|
+
python: ["poetry.lock", "uv.lock", "Pipfile.lock"],
|
|
11323
|
+
go: ["go.sum"],
|
|
11324
|
+
rust: ["Cargo.lock"],
|
|
11325
|
+
ruby: ["Gemfile.lock"],
|
|
11326
|
+
java: [],
|
|
11327
|
+
dotnet: [],
|
|
11328
|
+
php: ["composer.lock"],
|
|
11329
|
+
elixir: ["mix.lock"],
|
|
11330
|
+
haskell: [],
|
|
11331
|
+
c: [],
|
|
11332
|
+
cpp: [],
|
|
11333
|
+
zig: [],
|
|
11334
|
+
generic: []
|
|
11335
|
+
};
|
|
11336
|
+
const buildFiles = {
|
|
11337
|
+
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"],
|
|
11338
|
+
python: ["setup.py", "setup.cfg", "pyproject.toml"],
|
|
11339
|
+
go: ["Makefile"],
|
|
11340
|
+
rust: ["Cargo.toml"],
|
|
11341
|
+
ruby: ["Rakefile"],
|
|
11342
|
+
java: ["pom.xml", "build.gradle"],
|
|
11343
|
+
dotnet: ["*.sln"],
|
|
11344
|
+
php: [],
|
|
11345
|
+
elixir: ["mix.exs"],
|
|
11346
|
+
haskell: ["package.yaml", "*.cabal"],
|
|
11347
|
+
c: ["Makefile", "CMakeLists.txt"],
|
|
11348
|
+
cpp: ["Makefile", "CMakeLists.txt"],
|
|
11349
|
+
zig: ["build.zig"],
|
|
11350
|
+
generic: []
|
|
11351
|
+
};
|
|
11352
|
+
const testConfigs = {
|
|
11353
|
+
node: ["vitest.config.ts", "jest.config.js", "playwright.config.ts", "cypress.config.ts", "ava.config.js"],
|
|
11354
|
+
python: ["pytest.ini", "tox.ini", "setup.cfg"],
|
|
11355
|
+
go: [],
|
|
11356
|
+
rust: [],
|
|
11357
|
+
ruby: ["Rakefile", "spec_helper.rb"],
|
|
11358
|
+
java: [],
|
|
11359
|
+
dotnet: [],
|
|
11360
|
+
php: ["phpunit.xml"],
|
|
11361
|
+
elixir: ["test/test_helper.exs"],
|
|
11362
|
+
haskell: [],
|
|
11363
|
+
c: ["Makefile"],
|
|
11364
|
+
cpp: ["Makefile"],
|
|
11365
|
+
zig: [],
|
|
11366
|
+
generic: []
|
|
11367
|
+
};
|
|
11368
|
+
const lintConfigs = {
|
|
11369
|
+
node: [".eslintrc", ".eslintrc.js", ".eslintrc.json", ".prettierrc", "biome.json", "deno.json"],
|
|
11370
|
+
python: [".flake8", "pyproject.toml", "setup.cfg", ".pylintrc", "ruff.toml"],
|
|
11371
|
+
go: [],
|
|
11372
|
+
rust: ["rustfmt.toml", "clippy.toml"],
|
|
11373
|
+
ruby: [".rubocop.yml"],
|
|
11374
|
+
java: [],
|
|
11375
|
+
dotnet: [],
|
|
11376
|
+
php: [],
|
|
11377
|
+
elixir: [".formatter.exs"],
|
|
11378
|
+
haskell: [],
|
|
11379
|
+
c: [".clang-format", ".clang-tidy"],
|
|
11380
|
+
cpp: [".clang-format", ".clang-tidy"],
|
|
11381
|
+
zig: [],
|
|
11382
|
+
generic: []
|
|
11383
|
+
};
|
|
11384
|
+
const typeConfigs = {
|
|
11385
|
+
node: ["tsconfig.json", "jsconfig.json"],
|
|
11386
|
+
python: ["pyproject.toml", "setup.cfg", "mypy.ini"],
|
|
11387
|
+
go: [],
|
|
11388
|
+
rust: [],
|
|
11389
|
+
ruby: [],
|
|
11390
|
+
java: [],
|
|
11391
|
+
dotnet: [],
|
|
11392
|
+
php: [],
|
|
11393
|
+
elixir: [],
|
|
11394
|
+
haskell: [],
|
|
11395
|
+
c: [],
|
|
11396
|
+
cpp: [],
|
|
11397
|
+
zig: [],
|
|
11398
|
+
generic: []
|
|
11399
|
+
};
|
|
11400
|
+
return {
|
|
11401
|
+
flavor,
|
|
11402
|
+
primaryLanguage: languageForFlavor(flavor),
|
|
11403
|
+
packageFile: findFile(cwd, packageFiles[flavor]),
|
|
11404
|
+
lockFile: findFile(cwd, lockFiles[flavor]),
|
|
11405
|
+
buildFile: findFile(cwd, buildFiles[flavor]),
|
|
11406
|
+
testConfig: findFile(cwd, testConfigs[flavor]),
|
|
11407
|
+
lintConfig: findFile(cwd, lintConfigs[flavor]),
|
|
11408
|
+
typeConfig: findFile(cwd, typeConfigs[flavor]),
|
|
11409
|
+
ciConfig: findCiConfig(cwd),
|
|
11410
|
+
readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
|
|
11411
|
+
sourceRoots: findSourceRoots(cwd),
|
|
11412
|
+
hasGit: existsSync2(join20(cwd, ".git"))
|
|
11413
|
+
};
|
|
11414
|
+
}
|
|
11415
|
+
function bashDiscoveryCommands(profile) {
|
|
11416
|
+
const cmds = [];
|
|
11417
|
+
if (profile.hasGit) {
|
|
11418
|
+
cmds.push(
|
|
11419
|
+
"git log --oneline -20",
|
|
11420
|
+
"git branch -a | head -20"
|
|
11421
|
+
);
|
|
11422
|
+
}
|
|
11423
|
+
switch (profile.flavor) {
|
|
11424
|
+
case "node":
|
|
11425
|
+
cmds.push(
|
|
11426
|
+
`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))"`,
|
|
11427
|
+
"ls -la node_modules/.bin 2>/dev/null | head -30 || true"
|
|
11428
|
+
);
|
|
11429
|
+
break;
|
|
11430
|
+
case "python":
|
|
11431
|
+
cmds.push(
|
|
11432
|
+
`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`,
|
|
11433
|
+
"make -p 2>/dev/null | grep -E '^[a-zA-Z_-]+:.*$' | head -20 || true"
|
|
11434
|
+
);
|
|
11435
|
+
break;
|
|
11436
|
+
case "go":
|
|
11437
|
+
cmds.push("go help 2>/dev/null | head -10 || true");
|
|
11438
|
+
break;
|
|
11439
|
+
case "rust":
|
|
11440
|
+
cmds.push("cargo --list 2>/dev/null | head -20 || true");
|
|
11441
|
+
break;
|
|
11442
|
+
case "ruby":
|
|
11443
|
+
cmds.push("bundle exec rake -T 2>/dev/null | head -20 || true");
|
|
11444
|
+
break;
|
|
11445
|
+
case "java":
|
|
11446
|
+
cmds.push("./mvnw help:describe -Dplugin=help 2>/dev/null | head -10 || true");
|
|
11447
|
+
break;
|
|
11448
|
+
}
|
|
11449
|
+
cmds.push("ls -la");
|
|
11450
|
+
return cmds;
|
|
11451
|
+
}
|
|
11452
|
+
function discoveryChecklist(profile) {
|
|
11453
|
+
const lines = [];
|
|
11454
|
+
lines.push("## PHASE 1: Project Identity & Configuration");
|
|
11455
|
+
lines.push("");
|
|
11456
|
+
if (profile.readme) {
|
|
11457
|
+
lines.push(`- [ ] Read \`${profile.readme}\` \u2014 extract project name, description, purpose.`);
|
|
11458
|
+
}
|
|
11459
|
+
if (profile.packageFile) {
|
|
11460
|
+
lines.push(`- [ ] Read \`${profile.packageFile}\` \u2014 extract dependencies, scripts, metadata.`);
|
|
11461
|
+
}
|
|
11462
|
+
if (profile.buildFile) {
|
|
11463
|
+
lines.push(`- [ ] Read \`${profile.buildFile}\` \u2014 understand build system and entry points.`);
|
|
11464
|
+
}
|
|
11465
|
+
if (profile.typeConfig) {
|
|
11466
|
+
lines.push(`- [ ] Read \`${profile.typeConfig}\` \u2014 note strictness, target, module system.`);
|
|
11467
|
+
}
|
|
11468
|
+
if (profile.testConfig) {
|
|
11469
|
+
lines.push(`- [ ] Read \`${profile.testConfig}\` \u2014 understand test runner and conventions.`);
|
|
11470
|
+
}
|
|
11471
|
+
if (profile.lintConfig) {
|
|
11472
|
+
lines.push(`- [ ] Read \`${profile.lintConfig}\` \u2014 note style rules and formatter.`);
|
|
11473
|
+
}
|
|
11474
|
+
if (profile.ciConfig) {
|
|
11475
|
+
lines.push(`- [ ] Inspect CI config in \`${profile.ciConfig}\` \u2014 note checks, matrix, deployment.`);
|
|
11476
|
+
}
|
|
11477
|
+
lines.push("");
|
|
11478
|
+
lines.push("## PHASE 2: Source Structure Discovery");
|
|
11479
|
+
lines.push("");
|
|
11480
|
+
for (const root of profile.sourceRoots) {
|
|
11481
|
+
lines.push(`- [ ] Use \`glob\` to list files in \`${root}/**/*\` (limit to ~50 files).`);
|
|
11482
|
+
lines.push(`- [ ] Read 3-5 representative files from \`${root}\` to understand code patterns.`);
|
|
11483
|
+
}
|
|
11484
|
+
if (profile.sourceRoots.length === 0) {
|
|
11485
|
+
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.");
|
|
11486
|
+
lines.push("- [ ] Read 3-5 representative source files to understand code patterns.");
|
|
11487
|
+
}
|
|
11488
|
+
lines.push("- [ ] Use `glob` to find test files and note their location/naming pattern.");
|
|
11489
|
+
lines.push("- [ ] Use `glob` to find config files at root level.");
|
|
11490
|
+
lines.push("");
|
|
11491
|
+
lines.push("## PHASE 3: Convention Extraction");
|
|
11492
|
+
lines.push("");
|
|
11493
|
+
lines.push("- [ ] Use `grep` to find import patterns (e.g., `import .* from` or `require(`).");
|
|
11494
|
+
lines.push("- [ ] Use `grep` to find export patterns (e.g., `export ` or `module.exports`).");
|
|
11495
|
+
lines.push("- [ ] Check for any `.editorconfig`, `.gitignore`, or `CONTRIBUTING.md`.");
|
|
11496
|
+
if (profile.hasGit) {
|
|
11497
|
+
lines.push("- [ ] Run `git log --oneline -20` to understand commit style and recent activity.");
|
|
11498
|
+
lines.push("- [ ] Run `git branch -a | head -20` to understand branching strategy.");
|
|
11499
|
+
}
|
|
11500
|
+
lines.push("");
|
|
11501
|
+
lines.push("## PHASE 4: Build & Development Workflow");
|
|
11502
|
+
lines.push("");
|
|
11503
|
+
const bashCmds = bashDiscoveryCommands(profile);
|
|
11504
|
+
for (const cmd of bashCmds) {
|
|
11505
|
+
lines.push(`- [ ] Run \`bash\` with: \`${cmd}\``);
|
|
11506
|
+
}
|
|
11507
|
+
lines.push("");
|
|
11508
|
+
lines.push("## PHASE 5: Architecture & Patterns (Deep Dive)");
|
|
11509
|
+
lines.push("");
|
|
11510
|
+
lines.push("- [ ] Identify the main entry point(s) of the application.");
|
|
11511
|
+
lines.push("- [ ] Identify the testing framework and how tests are organized.");
|
|
11512
|
+
lines.push("- [ ] Look for any architectural patterns: MVC, hexagonal, actor model, etc.");
|
|
11513
|
+
lines.push("- [ ] Note any code-generation, build-time transforms, or code-mod tools.");
|
|
11514
|
+
lines.push("- [ ] Check for Docker, docker-compose, or deployment configs.");
|
|
11515
|
+
lines.push("- [ ] Note any monorepo patterns (workspaces, turborepo, nx, etc.).");
|
|
11516
|
+
return lines.join("\n");
|
|
11517
|
+
}
|
|
11518
|
+
function sectionTemplate() {
|
|
11519
|
+
return `
|
|
11520
|
+
Generate the context document with these sections. Be concise but comprehensive.
|
|
11521
|
+
Aim for 100\u2013200 lines total. Use markdown tables where they save space.
|
|
11522
|
+
|
|
11523
|
+
### Required Sections
|
|
11524
|
+
|
|
11525
|
+
1. **Project** \u2014 One-line description + primary language/runtime + key frameworks.
|
|
11526
|
+
|
|
11527
|
+
2. **Build / test / run** \u2014 Exact shell commands. Include:
|
|
11528
|
+
- Development server / watch mode
|
|
11529
|
+
- Production build
|
|
11530
|
+
- Test commands (unit, integration, e2e if separate)
|
|
11531
|
+
- Lint / format commands
|
|
11532
|
+
- Type-checking commands
|
|
11533
|
+
- Any setup / install commands
|
|
11534
|
+
Note which commands are slow or require special setup.
|
|
11535
|
+
|
|
11536
|
+
3. **Layout** \u2014 Table of key directories AND a one-sentence rationale for each.
|
|
11537
|
+
Explain *why* things live where they do, not just *what* is there.
|
|
11538
|
+
|
|
11539
|
+
4. **Conventions** \u2014 Cover:
|
|
11540
|
+
- Naming conventions (files, variables, types, tests)
|
|
11541
|
+
- Import style and path resolution quirks
|
|
11542
|
+
- File organization patterns
|
|
11543
|
+
- Commit message style (if discernible from git history)
|
|
11544
|
+
- Branching strategy
|
|
11545
|
+
- TypeScript / type system strictness rules
|
|
11546
|
+
- Testing conventions (naming, location, mocks)
|
|
11547
|
+
- Anything surprising or non-obvious
|
|
11548
|
+
|
|
11549
|
+
5. **Dependencies** \u2014 Rules for adding dependencies:
|
|
11550
|
+
- Package manager commands
|
|
11551
|
+
- Dev vs runtime dependency conventions
|
|
11552
|
+
- Native deps that must stay external (if bundling)
|
|
11553
|
+
- Version pinning policy
|
|
11554
|
+
|
|
11555
|
+
6. **Do / Don't** \u2014 Numbered list of hard rules:
|
|
11556
|
+
- Security rules (never commit secrets, etc.)
|
|
11557
|
+
- Performance rules (don't bundle X, etc.)
|
|
11558
|
+
- Style rules that aren't caught by linters
|
|
11559
|
+
- Common mistakes to avoid
|
|
11560
|
+
- Anything that would make a maintainer sad
|
|
11561
|
+
|
|
11562
|
+
7. **Debugging & Troubleshooting** \u2014 Common issues:
|
|
11563
|
+
- How to run in debug mode
|
|
11564
|
+
- Common build failures and fixes
|
|
11565
|
+
- How to reset / clean the project
|
|
11566
|
+
- Where logs live
|
|
11567
|
+
|
|
11568
|
+
8. **Architecture Notes** (if applicable) \u2014 Brief notes on:
|
|
11569
|
+
- Key abstractions and their responsibilities
|
|
11570
|
+
- Data flow
|
|
11571
|
+
- External integrations
|
|
11572
|
+
- State management approach
|
|
11573
|
+
`.trim();
|
|
11574
|
+
}
|
|
11575
|
+
function buildInitPrompt(cwd) {
|
|
11576
|
+
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
|
|
11577
|
+
(n) => existsSync2(join20(cwd, n))
|
|
11578
|
+
);
|
|
11579
|
+
const isRefresh = existingName !== void 0;
|
|
11580
|
+
const targetFilename = existingName ?? "KIMI.md";
|
|
11581
|
+
const profile = analyzeProject(cwd);
|
|
11582
|
+
const checklist = discoveryChecklist(profile);
|
|
11583
|
+
const sections = sectionTemplate();
|
|
11584
|
+
const promptParts = [
|
|
11585
|
+
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.`,
|
|
11586
|
+
"",
|
|
11587
|
+
"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.",
|
|
11588
|
+
"",
|
|
11589
|
+
`**Detected project profile:** ${profile.primaryLanguage} (${profile.flavor})`,
|
|
11590
|
+
profile.packageFile ? `- Package file: ${profile.packageFile}` : null,
|
|
11591
|
+
profile.buildFile ? `- Build file: ${profile.buildFile}` : null,
|
|
11592
|
+
profile.testConfig ? `- Test config: ${profile.testConfig}` : null,
|
|
11593
|
+
profile.typeConfig ? `- Type config: ${profile.typeConfig}` : null,
|
|
11594
|
+
profile.lintConfig ? `- Lint config: ${profile.lintConfig}` : null,
|
|
11595
|
+
profile.ciConfig ? `- CI config: ${profile.ciConfig}` : null,
|
|
11596
|
+
profile.sourceRoots.length > 0 ? `- Source roots: ${profile.sourceRoots.join(", ")}` : null,
|
|
11597
|
+
profile.hasGit ? `- Git repository: yes` : null,
|
|
11598
|
+
"",
|
|
11599
|
+
"---",
|
|
11600
|
+
"",
|
|
11601
|
+
checklist,
|
|
11602
|
+
"",
|
|
11603
|
+
"---",
|
|
11604
|
+
"",
|
|
11605
|
+
sections,
|
|
11606
|
+
"",
|
|
11607
|
+
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.",
|
|
11608
|
+
"",
|
|
11609
|
+
"Do not call `tasks_set` for this. Just follow the checklist, gather information, then write the file."
|
|
11610
|
+
];
|
|
11611
|
+
const prompt = promptParts.filter((p) => p !== null).join("\n");
|
|
11612
|
+
return { prompt, targetFilename, isRefresh };
|
|
11613
|
+
}
|
|
11614
|
+
var FLAVOR_SIGNATURES, SOURCE_ROOT_CANDIDATES, CI_PATHS;
|
|
11615
|
+
var init_context_generator = __esm({
|
|
11616
|
+
"src/init/context-generator.ts"() {
|
|
11617
|
+
"use strict";
|
|
11618
|
+
FLAVOR_SIGNATURES = {
|
|
11619
|
+
node: ["package.json", "package-lock.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb", "node_modules"],
|
|
11620
|
+
python: ["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", "poetry.lock", "uv.lock", "tox.ini"],
|
|
11621
|
+
go: ["go.mod", "go.sum"],
|
|
11622
|
+
rust: ["Cargo.toml", "Cargo.lock"],
|
|
11623
|
+
ruby: ["Gemfile", "Gemfile.lock", "*.gemspec"],
|
|
11624
|
+
java: ["pom.xml", "build.gradle", "build.gradle.kts"],
|
|
11625
|
+
dotnet: ["*.csproj", "*.fsproj", "*.sln"],
|
|
11626
|
+
php: ["composer.json", "composer.lock"],
|
|
11627
|
+
elixir: ["mix.exs", "mix.lock"],
|
|
11628
|
+
haskell: ["package.yaml", "*.cabal", "stack.yaml"],
|
|
11629
|
+
c: ["Makefile", "CMakeLists.txt", "configure.ac"],
|
|
11630
|
+
cpp: ["Makefile", "CMakeLists.txt", "configure.ac"],
|
|
11631
|
+
zig: ["build.zig", "build.zig.zon"],
|
|
11632
|
+
generic: []
|
|
11633
|
+
};
|
|
11634
|
+
SOURCE_ROOT_CANDIDATES = [
|
|
11635
|
+
"src",
|
|
11636
|
+
"lib",
|
|
11637
|
+
"app",
|
|
11638
|
+
"source",
|
|
11639
|
+
"Sources",
|
|
11640
|
+
"pkg",
|
|
11641
|
+
"internal",
|
|
11642
|
+
"cmd",
|
|
11643
|
+
"bin",
|
|
11644
|
+
"packages",
|
|
11645
|
+
"projects"
|
|
11646
|
+
];
|
|
11647
|
+
CI_PATHS = [
|
|
11648
|
+
".github/workflows",
|
|
11649
|
+
".gitlab-ci.yml",
|
|
11650
|
+
".circleci",
|
|
11651
|
+
"azure-pipelines.yml",
|
|
11652
|
+
"Jenkinsfile",
|
|
11653
|
+
".buildkite",
|
|
11654
|
+
"cloudbuild.yaml"
|
|
11655
|
+
];
|
|
11656
|
+
}
|
|
11657
|
+
});
|
|
11658
|
+
|
|
10950
11659
|
// src/ui/command-picker.tsx
|
|
10951
|
-
import { Box as
|
|
10952
|
-
import
|
|
10953
|
-
import { jsx as
|
|
11660
|
+
import { Box as Box15, Text as Text16 } from "ink";
|
|
11661
|
+
import SelectInput8 from "ink-select-input";
|
|
11662
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
10954
11663
|
function CommandPicker({ commands, title, onPick }) {
|
|
10955
11664
|
const theme = useTheme();
|
|
10956
11665
|
const items = commands.map((cmd) => ({
|
|
@@ -10959,11 +11668,11 @@ function CommandPicker({ commands, title, onPick }) {
|
|
|
10959
11668
|
key: cmd.name
|
|
10960
11669
|
}));
|
|
10961
11670
|
items.push({ label: "\u2190 Cancel", value: null, key: "__cancel__" });
|
|
10962
|
-
return /* @__PURE__ */
|
|
10963
|
-
/* @__PURE__ */
|
|
10964
|
-
/* @__PURE__ */
|
|
10965
|
-
/* @__PURE__ */
|
|
10966
|
-
|
|
11671
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11672
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.accent, bold: true, children: title }),
|
|
11673
|
+
/* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
11674
|
+
/* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
|
|
11675
|
+
SelectInput8,
|
|
10967
11676
|
{
|
|
10968
11677
|
items,
|
|
10969
11678
|
onSelect: (item) => {
|
|
@@ -10985,64 +11694,64 @@ var init_command_picker = __esm({
|
|
|
10985
11694
|
});
|
|
10986
11695
|
|
|
10987
11696
|
// src/ui/command-list.tsx
|
|
10988
|
-
import { Box as
|
|
10989
|
-
import { jsx as
|
|
11697
|
+
import { Box as Box16, Text as Text17, useInput as useInput6 } from "ink";
|
|
11698
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
10990
11699
|
function CommandList({ commands, onDone }) {
|
|
10991
11700
|
const theme = useTheme();
|
|
10992
|
-
|
|
11701
|
+
useInput6((_input, key) => {
|
|
10993
11702
|
if (key.escape) {
|
|
10994
11703
|
onDone();
|
|
10995
11704
|
}
|
|
10996
11705
|
});
|
|
10997
|
-
return /* @__PURE__ */
|
|
10998
|
-
/* @__PURE__ */
|
|
10999
|
-
/* @__PURE__ */
|
|
11000
|
-
/* @__PURE__ */
|
|
11001
|
-
commands.length === 0 && /* @__PURE__ */
|
|
11002
|
-
commands.map((cmd) => /* @__PURE__ */
|
|
11003
|
-
/* @__PURE__ */
|
|
11706
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11707
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom commands" }),
|
|
11708
|
+
/* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
|
|
11709
|
+
/* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
|
|
11710
|
+
commands.length === 0 && /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No custom commands found." }),
|
|
11711
|
+
commands.map((cmd) => /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginBottom: 1, children: [
|
|
11712
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
|
|
11004
11713
|
"/",
|
|
11005
11714
|
cmd.name
|
|
11006
11715
|
] }),
|
|
11007
|
-
/* @__PURE__ */
|
|
11716
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11008
11717
|
" ",
|
|
11009
11718
|
"source: ",
|
|
11010
11719
|
cmd.source
|
|
11011
11720
|
] }),
|
|
11012
|
-
/* @__PURE__ */
|
|
11721
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11013
11722
|
" ",
|
|
11014
11723
|
"path: ",
|
|
11015
11724
|
cmd.filepath
|
|
11016
11725
|
] }),
|
|
11017
|
-
cmd.description && /* @__PURE__ */
|
|
11726
|
+
cmd.description && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11018
11727
|
" ",
|
|
11019
11728
|
"desc: ",
|
|
11020
11729
|
cmd.description
|
|
11021
11730
|
] }),
|
|
11022
|
-
cmd.mode && /* @__PURE__ */
|
|
11731
|
+
cmd.mode && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11023
11732
|
" ",
|
|
11024
11733
|
"mode: ",
|
|
11025
11734
|
cmd.mode
|
|
11026
11735
|
] }),
|
|
11027
|
-
cmd.effort && /* @__PURE__ */
|
|
11736
|
+
cmd.effort && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11028
11737
|
" ",
|
|
11029
11738
|
"effort: ",
|
|
11030
11739
|
cmd.effort
|
|
11031
11740
|
] }),
|
|
11032
|
-
cmd.model && /* @__PURE__ */
|
|
11741
|
+
cmd.model && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11033
11742
|
" ",
|
|
11034
11743
|
"model: ",
|
|
11035
11744
|
cmd.model
|
|
11036
11745
|
] }),
|
|
11037
|
-
/* @__PURE__ */
|
|
11746
|
+
/* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11038
11747
|
" ",
|
|
11039
11748
|
"template:"
|
|
11040
11749
|
] }),
|
|
11041
|
-
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */
|
|
11750
|
+
cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11042
11751
|
" ",
|
|
11043
11752
|
line || " "
|
|
11044
11753
|
] }, i)),
|
|
11045
|
-
cmd.template.split("\n").length > 5 && /* @__PURE__ */
|
|
11754
|
+
cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
|
|
11046
11755
|
" ",
|
|
11047
11756
|
"..."
|
|
11048
11757
|
] })
|
|
@@ -11059,10 +11768,10 @@ var init_command_list = __esm({
|
|
|
11059
11768
|
|
|
11060
11769
|
// src/ui/lsp-wizard.tsx
|
|
11061
11770
|
import { useState as useState9 } from "react";
|
|
11062
|
-
import { Box as
|
|
11063
|
-
import
|
|
11771
|
+
import { Box as Box17, Text as Text18 } from "ink";
|
|
11772
|
+
import SelectInput9 from "ink-select-input";
|
|
11064
11773
|
import { spawn as spawn3 } from "child_process";
|
|
11065
|
-
import { jsx as
|
|
11774
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11066
11775
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
11067
11776
|
const theme = useTheme();
|
|
11068
11777
|
const [page, setPage] = useState9("main");
|
|
@@ -11173,11 +11882,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11173
11882
|
{ label: "(close)", value: "__close__", key: "__close__" }
|
|
11174
11883
|
];
|
|
11175
11884
|
if (page === "main") {
|
|
11176
|
-
return /* @__PURE__ */
|
|
11177
|
-
/* @__PURE__ */
|
|
11178
|
-
/* @__PURE__ */
|
|
11179
|
-
/* @__PURE__ */
|
|
11180
|
-
|
|
11885
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11886
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "LSP Servers" }),
|
|
11887
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
|
|
11888
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11889
|
+
SelectInput9,
|
|
11181
11890
|
{
|
|
11182
11891
|
items: mainItems,
|
|
11183
11892
|
onSelect: (item) => {
|
|
@@ -11204,11 +11913,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11204
11913
|
}),
|
|
11205
11914
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11206
11915
|
];
|
|
11207
|
-
return /* @__PURE__ */
|
|
11208
|
-
/* @__PURE__ */
|
|
11209
|
-
/* @__PURE__ */
|
|
11210
|
-
/* @__PURE__ */
|
|
11211
|
-
|
|
11916
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11917
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Add LSP Server" }),
|
|
11918
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
|
|
11919
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11920
|
+
SelectInput9,
|
|
11212
11921
|
{
|
|
11213
11922
|
items,
|
|
11214
11923
|
onSelect: (item) => {
|
|
@@ -11235,19 +11944,19 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11235
11944
|
{ label: isSuccess ? "Save to config \u2713" : "Save anyway", value: "save", key: "save" },
|
|
11236
11945
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11237
11946
|
];
|
|
11238
|
-
return /* @__PURE__ */
|
|
11239
|
-
/* @__PURE__ */
|
|
11947
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11948
|
+
/* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
|
|
11240
11949
|
"Install ",
|
|
11241
11950
|
selectedPreset.name
|
|
11242
11951
|
] }),
|
|
11243
|
-
/* @__PURE__ */
|
|
11244
|
-
/* @__PURE__ */
|
|
11245
|
-
/* @__PURE__ */
|
|
11246
|
-
/* @__PURE__ */
|
|
11952
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
|
|
11953
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
|
|
11954
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Command:" }),
|
|
11955
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
|
|
11247
11956
|
] }),
|
|
11248
|
-
installState.output && /* @__PURE__ */
|
|
11249
|
-
/* @__PURE__ */
|
|
11250
|
-
|
|
11957
|
+
installState.output && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx19(Text18, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
|
|
11958
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
11959
|
+
SelectInput9,
|
|
11251
11960
|
{
|
|
11252
11961
|
items,
|
|
11253
11962
|
onSelect: (item) => {
|
|
@@ -11264,16 +11973,16 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11264
11973
|
}
|
|
11265
11974
|
}
|
|
11266
11975
|
) }),
|
|
11267
|
-
isSuccess && /* @__PURE__ */
|
|
11976
|
+
isSuccess && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
|
|
11268
11977
|
] });
|
|
11269
11978
|
}
|
|
11270
11979
|
if (page === "custom-name") {
|
|
11271
|
-
return /* @__PURE__ */
|
|
11272
|
-
/* @__PURE__ */
|
|
11273
|
-
/* @__PURE__ */
|
|
11274
|
-
/* @__PURE__ */
|
|
11275
|
-
/* @__PURE__ */
|
|
11276
|
-
/* @__PURE__ */
|
|
11980
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
11981
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
|
|
11982
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
|
|
11983
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
|
|
11984
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
|
|
11985
|
+
/* @__PURE__ */ jsx19(
|
|
11277
11986
|
CustomTextInput,
|
|
11278
11987
|
{
|
|
11279
11988
|
value: customName,
|
|
@@ -11287,8 +11996,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11287
11996
|
}
|
|
11288
11997
|
)
|
|
11289
11998
|
] }),
|
|
11290
|
-
/* @__PURE__ */
|
|
11291
|
-
|
|
11999
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12000
|
+
SelectInput9,
|
|
11292
12001
|
{
|
|
11293
12002
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11294
12003
|
onSelect: () => setPage("add")
|
|
@@ -11297,12 +12006,12 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11297
12006
|
] });
|
|
11298
12007
|
}
|
|
11299
12008
|
if (page === "custom-command") {
|
|
11300
|
-
return /* @__PURE__ */
|
|
11301
|
-
/* @__PURE__ */
|
|
11302
|
-
/* @__PURE__ */
|
|
11303
|
-
/* @__PURE__ */
|
|
11304
|
-
/* @__PURE__ */
|
|
11305
|
-
/* @__PURE__ */
|
|
12009
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12010
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
|
|
12011
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
|
|
12012
|
+
/* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
|
|
12013
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
|
|
12014
|
+
/* @__PURE__ */ jsx19(
|
|
11306
12015
|
CustomTextInput,
|
|
11307
12016
|
{
|
|
11308
12017
|
value: customCommand,
|
|
@@ -11316,8 +12025,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11316
12025
|
}
|
|
11317
12026
|
)
|
|
11318
12027
|
] }),
|
|
11319
|
-
/* @__PURE__ */
|
|
11320
|
-
|
|
12028
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12029
|
+
SelectInput9,
|
|
11321
12030
|
{
|
|
11322
12031
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11323
12032
|
onSelect: () => setPage("custom-name")
|
|
@@ -11340,11 +12049,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11340
12049
|
},
|
|
11341
12050
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11342
12051
|
];
|
|
11343
|
-
return /* @__PURE__ */
|
|
11344
|
-
/* @__PURE__ */
|
|
11345
|
-
/* @__PURE__ */
|
|
11346
|
-
/* @__PURE__ */
|
|
11347
|
-
|
|
12052
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12053
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Save LSP Config" }),
|
|
12054
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
|
|
12055
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12056
|
+
SelectInput9,
|
|
11348
12057
|
{
|
|
11349
12058
|
items,
|
|
11350
12059
|
onSelect: (item) => {
|
|
@@ -11362,11 +12071,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11362
12071
|
if (page === "edit") {
|
|
11363
12072
|
const keys = Object.keys(servers);
|
|
11364
12073
|
if (keys.length === 0) {
|
|
11365
|
-
return /* @__PURE__ */
|
|
11366
|
-
/* @__PURE__ */
|
|
11367
|
-
/* @__PURE__ */
|
|
11368
|
-
/* @__PURE__ */
|
|
11369
|
-
|
|
12074
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12075
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
12076
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
|
|
12077
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12078
|
+
SelectInput9,
|
|
11370
12079
|
{
|
|
11371
12080
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11372
12081
|
onSelect: () => setPage("main")
|
|
@@ -11386,11 +12095,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11386
12095
|
}),
|
|
11387
12096
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11388
12097
|
];
|
|
11389
|
-
return /* @__PURE__ */
|
|
11390
|
-
/* @__PURE__ */
|
|
11391
|
-
/* @__PURE__ */
|
|
11392
|
-
/* @__PURE__ */
|
|
11393
|
-
|
|
12098
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12099
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
|
|
12100
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
|
|
12101
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12102
|
+
SelectInput9,
|
|
11394
12103
|
{
|
|
11395
12104
|
items,
|
|
11396
12105
|
onSelect: (item) => {
|
|
@@ -11407,11 +12116,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11407
12116
|
if (page === "delete") {
|
|
11408
12117
|
const keys = Object.keys(servers);
|
|
11409
12118
|
if (keys.length === 0) {
|
|
11410
|
-
return /* @__PURE__ */
|
|
11411
|
-
/* @__PURE__ */
|
|
11412
|
-
/* @__PURE__ */
|
|
11413
|
-
/* @__PURE__ */
|
|
11414
|
-
|
|
12119
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12120
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
12121
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
|
|
12122
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12123
|
+
SelectInput9,
|
|
11415
12124
|
{
|
|
11416
12125
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11417
12126
|
onSelect: () => setPage("main")
|
|
@@ -11427,11 +12136,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11427
12136
|
})),
|
|
11428
12137
|
{ label: "\u2190 Back", value: "__back__", key: "__back__" }
|
|
11429
12138
|
];
|
|
11430
|
-
return /* @__PURE__ */
|
|
11431
|
-
/* @__PURE__ */
|
|
11432
|
-
/* @__PURE__ */
|
|
11433
|
-
/* @__PURE__ */
|
|
11434
|
-
|
|
12139
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12140
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
|
|
12141
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
|
|
12142
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12143
|
+
SelectInput9,
|
|
11435
12144
|
{
|
|
11436
12145
|
items,
|
|
11437
12146
|
onSelect: (item) => {
|
|
@@ -11447,15 +12156,15 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
11447
12156
|
}
|
|
11448
12157
|
if (page === "list") {
|
|
11449
12158
|
const keys = Object.keys(servers);
|
|
11450
|
-
return /* @__PURE__ */
|
|
11451
|
-
/* @__PURE__ */
|
|
11452
|
-
keys.length === 0 ? /* @__PURE__ */
|
|
12159
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12160
|
+
/* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
|
|
12161
|
+
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
12162
|
const s = servers[k];
|
|
11454
12163
|
const status = s.enabled !== false ? "enabled" : "disabled";
|
|
11455
|
-
return /* @__PURE__ */
|
|
12164
|
+
return /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
|
|
11456
12165
|
}) }),
|
|
11457
|
-
/* @__PURE__ */
|
|
11458
|
-
|
|
12166
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
|
|
12167
|
+
SelectInput9,
|
|
11459
12168
|
{
|
|
11460
12169
|
items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
|
|
11461
12170
|
onSelect: () => setPage("main")
|
|
@@ -11581,9 +12290,9 @@ var init_lsp_wizard = __esm({
|
|
|
11581
12290
|
});
|
|
11582
12291
|
|
|
11583
12292
|
// src/ui/theme-picker.tsx
|
|
11584
|
-
import { Box as
|
|
11585
|
-
import
|
|
11586
|
-
import { jsx as
|
|
12293
|
+
import { Box as Box18, Text as Text19 } from "ink";
|
|
12294
|
+
import SelectInput10 from "ink-select-input";
|
|
12295
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11587
12296
|
function PaletteSwatches({ palette }) {
|
|
11588
12297
|
const colors = [
|
|
11589
12298
|
palette.primary,
|
|
@@ -11591,7 +12300,7 @@ function PaletteSwatches({ palette }) {
|
|
|
11591
12300
|
palette.success,
|
|
11592
12301
|
palette.error
|
|
11593
12302
|
];
|
|
11594
|
-
return /* @__PURE__ */
|
|
12303
|
+
return /* @__PURE__ */ jsx20(Box18, { children: colors.map((c, i) => /* @__PURE__ */ jsx20(Text19, { color: c, children: "\u2588" }, i)) });
|
|
11595
12304
|
}
|
|
11596
12305
|
function ThemePicker({ themes, onPick, onPreview }) {
|
|
11597
12306
|
const current = useTheme();
|
|
@@ -11599,10 +12308,10 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
11599
12308
|
...themes.map((t) => ({ label: t.label, value: t.name })),
|
|
11600
12309
|
{ label: "< Back", value: "__back__" }
|
|
11601
12310
|
];
|
|
11602
|
-
return /* @__PURE__ */
|
|
11603
|
-
/* @__PURE__ */
|
|
11604
|
-
/* @__PURE__ */
|
|
11605
|
-
|
|
12311
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
|
|
12312
|
+
/* @__PURE__ */ jsx20(Text19, { color: current.accent, bold: true, children: "Pick a theme" }),
|
|
12313
|
+
/* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
|
|
12314
|
+
SelectInput10,
|
|
11606
12315
|
{
|
|
11607
12316
|
items,
|
|
11608
12317
|
onHighlight: (item) => {
|
|
@@ -11621,9 +12330,9 @@ function ThemePicker({ themes, onPick, onPreview }) {
|
|
|
11621
12330
|
itemComponent: ({ label, isSelected }) => {
|
|
11622
12331
|
const t = themes.find((x) => x.label === label);
|
|
11623
12332
|
const color = t?.accent ?? current.accent;
|
|
11624
|
-
return /* @__PURE__ */
|
|
11625
|
-
/* @__PURE__ */
|
|
11626
|
-
t && /* @__PURE__ */
|
|
12333
|
+
return /* @__PURE__ */ jsxs18(Box18, { children: [
|
|
12334
|
+
/* @__PURE__ */ jsx20(Text19, { color, bold: isSelected, dimColor: !isSelected, children: label }),
|
|
12335
|
+
t && /* @__PURE__ */ jsx20(Box18, { marginLeft: 1, children: /* @__PURE__ */ jsx20(PaletteSwatches, { palette: t.palette }) })
|
|
11627
12336
|
] });
|
|
11628
12337
|
}
|
|
11629
12338
|
}
|
|
@@ -11767,8 +12476,8 @@ var init_lsp_nudge = __esm({
|
|
|
11767
12476
|
});
|
|
11768
12477
|
|
|
11769
12478
|
// src/ui/file-picker.tsx
|
|
11770
|
-
import { Box as
|
|
11771
|
-
import { jsx as
|
|
12479
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
12480
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
11772
12481
|
function FilePicker({ items, selectedIndex, query }) {
|
|
11773
12482
|
const theme = useTheme();
|
|
11774
12483
|
let startIndex = 0;
|
|
@@ -11778,12 +12487,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
11778
12487
|
const visible = items.slice(startIndex, startIndex + VISIBLE_LIMIT);
|
|
11779
12488
|
const hasMoreAbove = startIndex > 0;
|
|
11780
12489
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT;
|
|
11781
|
-
return /* @__PURE__ */
|
|
11782
|
-
/* @__PURE__ */
|
|
11783
|
-
/* @__PURE__ */
|
|
11784
|
-
/* @__PURE__ */
|
|
11785
|
-
visible.length === 0 && /* @__PURE__ */
|
|
11786
|
-
hasMoreAbove && /* @__PURE__ */
|
|
12490
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12491
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
|
|
12492
|
+
/* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
12493
|
+
/* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
12494
|
+
visible.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No matches" }),
|
|
12495
|
+
hasMoreAbove && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
11787
12496
|
"\u2026 ",
|
|
11788
12497
|
startIndex,
|
|
11789
12498
|
" more above"
|
|
@@ -11792,12 +12501,12 @@ function FilePicker({ items, selectedIndex, query }) {
|
|
|
11792
12501
|
const actualIndex = startIndex + i;
|
|
11793
12502
|
const isSelected = actualIndex === selectedIndex;
|
|
11794
12503
|
const label = item.isDirectory ? `${item.name}/` : item.name;
|
|
11795
|
-
return /* @__PURE__ */
|
|
12504
|
+
return /* @__PURE__ */ jsxs19(Text20, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
11796
12505
|
isSelected ? "\u203A " : " ",
|
|
11797
12506
|
label
|
|
11798
12507
|
] }, item.name);
|
|
11799
12508
|
}),
|
|
11800
|
-
hasMoreBelow && /* @__PURE__ */
|
|
12509
|
+
hasMoreBelow && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
|
|
11801
12510
|
"\u2026 ",
|
|
11802
12511
|
items.length - (startIndex + VISIBLE_LIMIT),
|
|
11803
12512
|
" more below"
|
|
@@ -11815,8 +12524,8 @@ var init_file_picker = __esm({
|
|
|
11815
12524
|
});
|
|
11816
12525
|
|
|
11817
12526
|
// src/ui/slash-picker.tsx
|
|
11818
|
-
import { Box as
|
|
11819
|
-
import { jsx as
|
|
12527
|
+
import { Box as Box20, Text as Text21 } from "ink";
|
|
12528
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
11820
12529
|
function sourceBadge(source) {
|
|
11821
12530
|
if (source === "builtin") return "";
|
|
11822
12531
|
if (source === "project") return "project";
|
|
@@ -11836,12 +12545,12 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
11836
12545
|
const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT2;
|
|
11837
12546
|
const longestLabel = visible.reduce((m, it) => Math.max(m, commandLabel(it).length), 0);
|
|
11838
12547
|
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__ */
|
|
12548
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
12549
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
|
|
12550
|
+
/* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
12551
|
+
/* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
|
|
12552
|
+
visible.length === 0 && /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No matches" }),
|
|
12553
|
+
hasMoreAbove && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
11845
12554
|
"\u2026 ",
|
|
11846
12555
|
startIndex,
|
|
11847
12556
|
" more above"
|
|
@@ -11851,16 +12560,16 @@ function SlashPicker({ items, selectedIndex, query }) {
|
|
|
11851
12560
|
const isSelected = actualIndex === selectedIndex;
|
|
11852
12561
|
const nameCol = commandLabel(item).padEnd(nameColWidth);
|
|
11853
12562
|
const badge = sourceBadge(item.source);
|
|
11854
|
-
return /* @__PURE__ */
|
|
12563
|
+
return /* @__PURE__ */ jsxs20(Text21, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
|
|
11855
12564
|
isSelected ? "\u203A " : " ",
|
|
11856
12565
|
nameCol,
|
|
11857
|
-
/* @__PURE__ */
|
|
12566
|
+
/* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
11858
12567
|
item.description,
|
|
11859
12568
|
badge && ` [${badge}]`
|
|
11860
12569
|
] })
|
|
11861
12570
|
] }, item.name);
|
|
11862
12571
|
}),
|
|
11863
|
-
hasMoreBelow && /* @__PURE__ */
|
|
12572
|
+
hasMoreBelow && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
|
|
11864
12573
|
"\u2026 ",
|
|
11865
12574
|
items.length - (startIndex + VISIBLE_LIMIT2),
|
|
11866
12575
|
" more below"
|
|
@@ -11941,14 +12650,14 @@ __export(tui_report_exports, {
|
|
|
11941
12650
|
getCategoryReportText: () => getCategoryReportText
|
|
11942
12651
|
});
|
|
11943
12652
|
import { readFile as readFile16 } from "fs/promises";
|
|
11944
|
-
import { join as
|
|
12653
|
+
import { join as join21 } from "path";
|
|
11945
12654
|
import { homedir as homedir14 } from "os";
|
|
11946
12655
|
function usageDir3() {
|
|
11947
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
11948
|
-
return
|
|
12656
|
+
const xdg = process.env.XDG_DATA_HOME || join21(homedir14(), ".local", "share");
|
|
12657
|
+
return join21(xdg, "kimiflare");
|
|
11949
12658
|
}
|
|
11950
12659
|
function usagePath3() {
|
|
11951
|
-
return
|
|
12660
|
+
return join21(usageDir3(), "usage.json");
|
|
11952
12661
|
}
|
|
11953
12662
|
function today3() {
|
|
11954
12663
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -12026,18 +12735,18 @@ __export(app_exports, {
|
|
|
12026
12735
|
shouldOpenMentionPicker: () => shouldOpenMentionPicker,
|
|
12027
12736
|
shouldOpenSlashPicker: () => shouldOpenSlashPicker
|
|
12028
12737
|
});
|
|
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
|
|
12738
|
+
import React14, { useState as useState10, useRef as useRef3, useEffect as useEffect6, useCallback as useCallback2 } from "react";
|
|
12739
|
+
import { Box as Box21, Text as Text22, useApp, useInput as useInput7, render } from "ink";
|
|
12740
|
+
import SelectInput11 from "ink-select-input";
|
|
12741
|
+
import { existsSync as existsSync3, statSync as statSync4 } from "fs";
|
|
12742
|
+
import { join as join22 } from "path";
|
|
12034
12743
|
import { unlink as unlink3 } from "fs/promises";
|
|
12035
12744
|
import { execSync as execSync2 } from "child_process";
|
|
12036
12745
|
import { spawn as spawn4 } from "child_process";
|
|
12037
12746
|
import { platform as platform2 } from "os";
|
|
12038
12747
|
import fg4 from "fast-glob";
|
|
12039
12748
|
import { readFileSync as readFileSync3 } from "fs";
|
|
12040
|
-
import { jsx as
|
|
12749
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
12041
12750
|
function buildFilePickerIgnoreList(cwd) {
|
|
12042
12751
|
const hardcoded = [
|
|
12043
12752
|
// Dependencies
|
|
@@ -12108,8 +12817,8 @@ function buildFilePickerIgnoreList(cwd) {
|
|
|
12108
12817
|
];
|
|
12109
12818
|
const gitignorePatterns = [];
|
|
12110
12819
|
try {
|
|
12111
|
-
const gitignorePath =
|
|
12112
|
-
const stats =
|
|
12820
|
+
const gitignorePath = join22(cwd, ".gitignore");
|
|
12821
|
+
const stats = statSync4(gitignorePath);
|
|
12113
12822
|
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
12114
12823
|
return hardcoded;
|
|
12115
12824
|
}
|
|
@@ -12177,7 +12886,7 @@ function gatewayUsageLookupFromConfig(cfg, meta) {
|
|
|
12177
12886
|
meta
|
|
12178
12887
|
};
|
|
12179
12888
|
}
|
|
12180
|
-
function
|
|
12889
|
+
function openBrowser2(url) {
|
|
12181
12890
|
const cmd = platform2() === "darwin" ? "open" : platform2() === "win32" ? "start" : "xdg-open";
|
|
12182
12891
|
const child = spawn4(cmd, [url], { detached: true, stdio: "ignore" });
|
|
12183
12892
|
child.unref();
|
|
@@ -12197,7 +12906,7 @@ function detectGitHubRepo(cachedRepo) {
|
|
|
12197
12906
|
}
|
|
12198
12907
|
return null;
|
|
12199
12908
|
}
|
|
12200
|
-
function
|
|
12909
|
+
function formatTokens4(n) {
|
|
12201
12910
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
12202
12911
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
12203
12912
|
return String(n);
|
|
@@ -12242,7 +12951,7 @@ function findImagePaths(text) {
|
|
|
12242
12951
|
let match;
|
|
12243
12952
|
while ((match = quotedRegex.exec(text)) !== null) {
|
|
12244
12953
|
const path = match[1] ?? match[2];
|
|
12245
|
-
if (path && isImagePath(path) &&
|
|
12954
|
+
if (path && isImagePath(path) && existsSync3(path)) {
|
|
12246
12955
|
paths.push(path);
|
|
12247
12956
|
}
|
|
12248
12957
|
}
|
|
@@ -12251,7 +12960,7 @@ function findImagePaths(text) {
|
|
|
12251
12960
|
const processed = remaining.replace(/\\ /g, ESCAPED_SPACE);
|
|
12252
12961
|
for (const token of processed.split(/\s+/)) {
|
|
12253
12962
|
const clean = token.replace(new RegExp(ESCAPED_SPACE, "g"), " ").replace(/^["']|["',;:!?]$/g, "").replace(/[.,;:!?]$/, "");
|
|
12254
|
-
if (clean && isImagePath(clean) &&
|
|
12963
|
+
if (clean && isImagePath(clean) && existsSync3(clean) && !paths.includes(clean)) {
|
|
12255
12964
|
paths.push(clean);
|
|
12256
12965
|
}
|
|
12257
12966
|
}
|
|
@@ -12269,7 +12978,7 @@ function App({
|
|
|
12269
12978
|
const [lspScope, setLspScope] = useState10(initialLspScope);
|
|
12270
12979
|
const [lspProjectPath, setLspProjectPath] = useState10(initialLspProjectPath);
|
|
12271
12980
|
const [events, setRawEvents] = useState10([]);
|
|
12272
|
-
const setEvents =
|
|
12981
|
+
const setEvents = useCallback2(
|
|
12273
12982
|
(updater) => {
|
|
12274
12983
|
setRawEvents((prev) => {
|
|
12275
12984
|
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
@@ -12283,8 +12992,10 @@ function App({
|
|
|
12283
12992
|
const [usage, setUsage] = useState10(null);
|
|
12284
12993
|
const [sessionUsage, setSessionUsage] = useState10(null);
|
|
12285
12994
|
const [gatewayMeta, setGatewayMeta] = useState10(null);
|
|
12995
|
+
const [cloudBudget, setCloudBudget] = useState10(null);
|
|
12286
12996
|
const [showReasoning, setShowReasoning] = useState10(false);
|
|
12287
12997
|
const [perm, setPerm] = useState10(null);
|
|
12998
|
+
const [limitModal, setLimitModal] = useState10(null);
|
|
12288
12999
|
const [queue, setQueue] = useState10([]);
|
|
12289
13000
|
const [history, setHistory] = useState10([]);
|
|
12290
13001
|
const [historyIndex, setHistoryIndex] = useState10(-1);
|
|
@@ -12314,6 +13025,21 @@ function App({
|
|
|
12314
13025
|
const [theme, setTheme] = useState10(resolveTheme(initialCfg?.theme));
|
|
12315
13026
|
const [showThemePicker, setShowThemePicker] = useState10(false);
|
|
12316
13027
|
const [originalTheme, setOriginalTheme] = useState10(null);
|
|
13028
|
+
useEffect6(() => {
|
|
13029
|
+
if (!cfg?.cloudMode || !initialCloudToken) return;
|
|
13030
|
+
let cancelled = false;
|
|
13031
|
+
const fetchBudget = async () => {
|
|
13032
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
13033
|
+
const usage2 = await fetchCloudUsage2(initialCloudToken);
|
|
13034
|
+
if (usage2 && !cancelled) {
|
|
13035
|
+
setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
|
|
13036
|
+
}
|
|
13037
|
+
};
|
|
13038
|
+
fetchBudget();
|
|
13039
|
+
return () => {
|
|
13040
|
+
cancelled = true;
|
|
13041
|
+
};
|
|
13042
|
+
}, [cfg?.cloudMode, initialCloudToken]);
|
|
12317
13043
|
const [cursorOffset, setCursorOffset] = useState10(0);
|
|
12318
13044
|
const [activePicker, setActivePicker] = useState10(null);
|
|
12319
13045
|
const [filePickerItems, setFilePickerItems] = useState10([]);
|
|
@@ -12327,6 +13053,7 @@ function App({
|
|
|
12327
13053
|
const activeAsstIdRef = useRef3(null);
|
|
12328
13054
|
const activeControllerRef = useRef3(null);
|
|
12329
13055
|
const permResolveRef = useRef3(null);
|
|
13056
|
+
const limitResolveRef = useRef3(null);
|
|
12330
13057
|
const pendingToolCallsRef = useRef3(/* @__PURE__ */ new Map());
|
|
12331
13058
|
const sessionIdRef = useRef3(null);
|
|
12332
13059
|
const modeRef = useRef3(mode);
|
|
@@ -12348,12 +13075,16 @@ function App({
|
|
|
12348
13075
|
const lspManagerRef = useRef3(new LspManager());
|
|
12349
13076
|
const lspToolsRef = useRef3([]);
|
|
12350
13077
|
const lspInitRef = useRef3(false);
|
|
13078
|
+
const busyRef = useRef3(busy);
|
|
12351
13079
|
const memoryManagerRef = useRef3(null);
|
|
12352
13080
|
const sessionStartRecallRef = useRef3(null);
|
|
12353
13081
|
const pendingTextRef = useRef3(/* @__PURE__ */ new Map());
|
|
12354
13082
|
const flushTimeoutRef = useRef3(null);
|
|
12355
13083
|
const customCommandsRef = useRef3([]);
|
|
12356
13084
|
const pickerCancelRef = useRef3(null);
|
|
13085
|
+
useEffect6(() => {
|
|
13086
|
+
busyRef.current = busy;
|
|
13087
|
+
}, [busy]);
|
|
12357
13088
|
const pickerAnchor = activePicker?.anchor ?? null;
|
|
12358
13089
|
const pickerKind = activePicker?.kind ?? null;
|
|
12359
13090
|
const pickerQuery = React14.useMemo(() => {
|
|
@@ -12376,7 +13107,7 @@ function App({
|
|
|
12376
13107
|
if (pickerKind !== "slash" || pickerQuery === null) return [];
|
|
12377
13108
|
return fuzzyFilter(allSlashCommands, pickerQuery, (c) => c.name).slice(0, 50);
|
|
12378
13109
|
}, [pickerKind, allSlashCommands, pickerQuery]);
|
|
12379
|
-
|
|
13110
|
+
useEffect6(() => {
|
|
12380
13111
|
if (activePicker !== null) {
|
|
12381
13112
|
const trigger = activePicker.kind === "file" ? "@" : "/";
|
|
12382
13113
|
if (cursorOffset < activePicker.anchor) {
|
|
@@ -12433,28 +13164,28 @@ function App({
|
|
|
12433
13164
|
return;
|
|
12434
13165
|
}
|
|
12435
13166
|
}, [input, cursorOffset, activePicker, filePickerEnabled]);
|
|
12436
|
-
|
|
13167
|
+
useEffect6(() => {
|
|
12437
13168
|
if (activePicker?.kind !== "file") return;
|
|
12438
13169
|
const max = Math.max(0, filteredFileItems.length - 1);
|
|
12439
13170
|
if (activePicker.selected > max) {
|
|
12440
13171
|
setActivePicker({ ...activePicker, selected: max });
|
|
12441
13172
|
}
|
|
12442
13173
|
}, [filteredFileItems.length, activePicker]);
|
|
12443
|
-
|
|
13174
|
+
useEffect6(() => {
|
|
12444
13175
|
if (activePicker?.kind !== "slash") return;
|
|
12445
13176
|
const max = Math.max(0, filteredSlashItems.length - 1);
|
|
12446
13177
|
if (activePicker.selected > max) {
|
|
12447
13178
|
setActivePicker({ ...activePicker, selected: max });
|
|
12448
13179
|
}
|
|
12449
13180
|
}, [filteredSlashItems.length, activePicker]);
|
|
12450
|
-
const handlePickerUp =
|
|
13181
|
+
const handlePickerUp = useCallback2(() => {
|
|
12451
13182
|
setActivePicker((p) => {
|
|
12452
13183
|
if (!p) return null;
|
|
12453
13184
|
const next = Math.max(0, p.selected - 1);
|
|
12454
13185
|
return next === p.selected ? p : { ...p, selected: next };
|
|
12455
13186
|
});
|
|
12456
13187
|
}, []);
|
|
12457
|
-
const handlePickerDown =
|
|
13188
|
+
const handlePickerDown = useCallback2(() => {
|
|
12458
13189
|
setActivePicker((p) => {
|
|
12459
13190
|
if (!p) return null;
|
|
12460
13191
|
const max = p.kind === "file" ? Math.max(0, filteredFileItems.length - 1) : Math.max(0, filteredSlashItems.length - 1);
|
|
@@ -12462,7 +13193,7 @@ function App({
|
|
|
12462
13193
|
return next === p.selected ? p : { ...p, selected: next };
|
|
12463
13194
|
});
|
|
12464
13195
|
}, [filteredFileItems.length, filteredSlashItems.length]);
|
|
12465
|
-
const handlePickerSelect =
|
|
13196
|
+
const handlePickerSelect = useCallback2(() => {
|
|
12466
13197
|
if (!activePicker) return;
|
|
12467
13198
|
if (activePicker.kind === "file") {
|
|
12468
13199
|
const item2 = filteredFileItems[activePicker.selected];
|
|
@@ -12480,12 +13211,12 @@ function App({
|
|
|
12480
13211
|
setActivePicker(null);
|
|
12481
13212
|
submitRef.current(value);
|
|
12482
13213
|
}, [activePicker, filteredFileItems, filteredSlashItems, input, cursorOffset]);
|
|
12483
|
-
const handlePickerCancel =
|
|
13214
|
+
const handlePickerCancel = useCallback2(() => {
|
|
12484
13215
|
pickerCancelRef.current = cursorOffset;
|
|
12485
13216
|
setActivePicker(null);
|
|
12486
13217
|
}, [cursorOffset]);
|
|
12487
|
-
|
|
12488
|
-
const modalActive = showHelpMenu || commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null;
|
|
13218
|
+
useEffect6(() => {
|
|
13219
|
+
const modalActive = showHelpMenu || commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null || limitModal !== null;
|
|
12489
13220
|
if (modalActive && activePicker !== null) {
|
|
12490
13221
|
setActivePicker(null);
|
|
12491
13222
|
}
|
|
@@ -12498,9 +13229,10 @@ function App({
|
|
|
12498
13229
|
showLspWizard,
|
|
12499
13230
|
resumeSessions,
|
|
12500
13231
|
perm,
|
|
13232
|
+
limitModal,
|
|
12501
13233
|
activePicker
|
|
12502
13234
|
]);
|
|
12503
|
-
|
|
13235
|
+
useEffect6(() => {
|
|
12504
13236
|
if (!cfg) return;
|
|
12505
13237
|
void Promise.resolve().then(() => (init_sessions(), sessions_exports)).then(
|
|
12506
13238
|
({ pruneSessions: pruneSessions2 }) => pruneSessions2().then((removed) => {
|
|
@@ -12526,7 +13258,7 @@ function App({
|
|
|
12526
13258
|
}
|
|
12527
13259
|
});
|
|
12528
13260
|
if (cfg.memoryEnabled) {
|
|
12529
|
-
const dbPath = cfg.memoryDbPath ??
|
|
13261
|
+
const dbPath = cfg.memoryDbPath ?? join22(process.cwd(), ".kimiflare", "memory.db");
|
|
12530
13262
|
const manager = new MemoryManager({
|
|
12531
13263
|
dbPath,
|
|
12532
13264
|
accountId: cfg.accountId,
|
|
@@ -12594,7 +13326,7 @@ function App({
|
|
|
12594
13326
|
}
|
|
12595
13327
|
});
|
|
12596
13328
|
}, [cfg, setEvents]);
|
|
12597
|
-
|
|
13329
|
+
useEffect6(() => {
|
|
12598
13330
|
const id = setInterval(() => {
|
|
12599
13331
|
try {
|
|
12600
13332
|
performance.clearMarks();
|
|
@@ -12604,7 +13336,7 @@ function App({
|
|
|
12604
13336
|
}, 3e5);
|
|
12605
13337
|
return () => clearInterval(id);
|
|
12606
13338
|
}, []);
|
|
12607
|
-
const reloadCustomCommands =
|
|
13339
|
+
const reloadCustomCommands = useCallback2(async () => {
|
|
12608
13340
|
const { commands, warnings } = await loadCustomCommands(process.cwd());
|
|
12609
13341
|
customCommandsRef.current = commands;
|
|
12610
13342
|
setCustomCommandsVersion((v) => v + 1);
|
|
@@ -12619,7 +13351,7 @@ function App({
|
|
|
12619
13351
|
]);
|
|
12620
13352
|
}
|
|
12621
13353
|
}, [setEvents]);
|
|
12622
|
-
|
|
13354
|
+
useEffect6(() => {
|
|
12623
13355
|
if (!cfg || updateCheckedRef.current) return;
|
|
12624
13356
|
updateCheckedRef.current = true;
|
|
12625
13357
|
if (initialUpdateResult) {
|
|
@@ -12670,7 +13402,7 @@ function App({
|
|
|
12670
13402
|
}
|
|
12671
13403
|
});
|
|
12672
13404
|
}, [cfg, initialUpdateResult]);
|
|
12673
|
-
|
|
13405
|
+
useEffect6(() => {
|
|
12674
13406
|
modeRef.current = mode;
|
|
12675
13407
|
if (cacheStableRef.current) {
|
|
12676
13408
|
messagesRef.current[1] = {
|
|
@@ -12697,10 +13429,10 @@ function App({
|
|
|
12697
13429
|
executorRef.current.clearSessionPermissions();
|
|
12698
13430
|
}
|
|
12699
13431
|
}, [mode, cfg?.model]);
|
|
12700
|
-
|
|
13432
|
+
useEffect6(() => {
|
|
12701
13433
|
effortRef.current = effort;
|
|
12702
13434
|
}, [effort]);
|
|
12703
|
-
|
|
13435
|
+
useEffect6(() => {
|
|
12704
13436
|
if (!cfg) return;
|
|
12705
13437
|
const id = setInterval(() => {
|
|
12706
13438
|
void checkForUpdate().then((result) => {
|
|
@@ -12731,7 +13463,7 @@ function App({
|
|
|
12731
13463
|
}, 30 * 60 * 1e3);
|
|
12732
13464
|
return () => clearInterval(id);
|
|
12733
13465
|
}, [cfg]);
|
|
12734
|
-
const initMcp =
|
|
13466
|
+
const initMcp = useCallback2(async () => {
|
|
12735
13467
|
if (!cfg?.mcpServers || mcpInitRef.current) return;
|
|
12736
13468
|
mcpInitRef.current = true;
|
|
12737
13469
|
const manager = mcpManagerRef.current;
|
|
@@ -12792,7 +13524,7 @@ function App({
|
|
|
12792
13524
|
]);
|
|
12793
13525
|
}
|
|
12794
13526
|
}, [cfg]);
|
|
12795
|
-
const initLsp =
|
|
13527
|
+
const initLsp = useCallback2(async () => {
|
|
12796
13528
|
if (!cfg?.lspEnabled || !cfg?.lspServers || lspInitRef.current) {
|
|
12797
13529
|
if (lspInitRef.current) return;
|
|
12798
13530
|
if (!cfg?.lspEnabled) {
|
|
@@ -12855,7 +13587,7 @@ function App({
|
|
|
12855
13587
|
]);
|
|
12856
13588
|
}
|
|
12857
13589
|
}, [cfg]);
|
|
12858
|
-
|
|
13590
|
+
useEffect6(() => {
|
|
12859
13591
|
if (cfg && !mcpInitRef.current) {
|
|
12860
13592
|
void initMcp();
|
|
12861
13593
|
}
|
|
@@ -12863,7 +13595,7 @@ function App({
|
|
|
12863
13595
|
void initLsp();
|
|
12864
13596
|
}
|
|
12865
13597
|
}, [cfg, initMcp, initLsp]);
|
|
12866
|
-
const ensureSessionId =
|
|
13598
|
+
const ensureSessionId = useCallback2(() => {
|
|
12867
13599
|
if (sessionIdRef.current) return sessionIdRef.current;
|
|
12868
13600
|
const firstUser = messagesRef.current.find((m) => m.role === "user");
|
|
12869
13601
|
let firstText = "session";
|
|
@@ -12876,7 +13608,7 @@ function App({
|
|
|
12876
13608
|
sessionIdRef.current = makeSessionId(firstText);
|
|
12877
13609
|
return sessionIdRef.current;
|
|
12878
13610
|
}, []);
|
|
12879
|
-
const saveSessionSafe =
|
|
13611
|
+
const saveSessionSafe = useCallback2(async () => {
|
|
12880
13612
|
if (!cfg) return;
|
|
12881
13613
|
ensureSessionId();
|
|
12882
13614
|
try {
|
|
@@ -12893,7 +13625,7 @@ function App({
|
|
|
12893
13625
|
} catch {
|
|
12894
13626
|
}
|
|
12895
13627
|
}, [cfg, ensureSessionId]);
|
|
12896
|
-
const onIterationEnd =
|
|
13628
|
+
const onIterationEnd = useCallback2(
|
|
12897
13629
|
async (messages, signal) => {
|
|
12898
13630
|
if (signal.aborted) return messages;
|
|
12899
13631
|
if (!shouldCompact({ messages })) return messages;
|
|
@@ -12971,31 +13703,42 @@ function App({
|
|
|
12971
13703
|
},
|
|
12972
13704
|
[cfg]
|
|
12973
13705
|
);
|
|
12974
|
-
|
|
13706
|
+
useInput7((inputChar, key) => {
|
|
12975
13707
|
if (key.ctrl && inputChar === "c") {
|
|
12976
13708
|
const hadPerm = permResolveRef.current !== null;
|
|
13709
|
+
const hadLimit = limitResolveRef.current !== null;
|
|
12977
13710
|
if (hadPerm) {
|
|
12978
13711
|
permResolveRef.current("deny");
|
|
12979
13712
|
permResolveRef.current = null;
|
|
12980
13713
|
setPerm(null);
|
|
12981
13714
|
}
|
|
12982
|
-
if (
|
|
13715
|
+
if (hadLimit) {
|
|
13716
|
+
limitResolveRef.current("stop");
|
|
13717
|
+
limitResolveRef.current = null;
|
|
13718
|
+
setLimitModal(null);
|
|
13719
|
+
}
|
|
13720
|
+
if (busyRef.current && activeControllerRef.current) {
|
|
12983
13721
|
activeControllerRef.current.abort();
|
|
12984
13722
|
setQueue([]);
|
|
12985
13723
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
12986
|
-
} else if (!hadPerm) {
|
|
13724
|
+
} else if (!hadPerm && !hadLimit) {
|
|
12987
13725
|
void lspManagerRef.current.stopAll().finally(() => exit());
|
|
12988
13726
|
}
|
|
12989
13727
|
return;
|
|
12990
13728
|
}
|
|
12991
13729
|
if (key.escape) {
|
|
12992
|
-
const modalOpen = perm !== null || showHelpMenu || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null;
|
|
12993
|
-
if (!modalOpen &&
|
|
13730
|
+
const modalOpen = perm !== null || limitModal !== null || showHelpMenu || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null;
|
|
13731
|
+
if (!modalOpen && busyRef.current && activeControllerRef.current) {
|
|
12994
13732
|
if (permResolveRef.current) {
|
|
12995
13733
|
permResolveRef.current("deny");
|
|
12996
13734
|
permResolveRef.current = null;
|
|
12997
13735
|
setPerm(null);
|
|
12998
13736
|
}
|
|
13737
|
+
if (limitResolveRef.current) {
|
|
13738
|
+
limitResolveRef.current("stop");
|
|
13739
|
+
limitResolveRef.current = null;
|
|
13740
|
+
setLimitModal(null);
|
|
13741
|
+
}
|
|
12999
13742
|
activeControllerRef.current.abort();
|
|
13000
13743
|
setQueue([]);
|
|
13001
13744
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
@@ -13015,7 +13758,7 @@ function App({
|
|
|
13015
13758
|
return;
|
|
13016
13759
|
}
|
|
13017
13760
|
});
|
|
13018
|
-
const flushAssistantUpdates =
|
|
13761
|
+
const flushAssistantUpdates = useCallback2(() => {
|
|
13019
13762
|
flushTimeoutRef.current = null;
|
|
13020
13763
|
const pending = pendingTextRef.current;
|
|
13021
13764
|
if (pending.size === 0) return;
|
|
@@ -13033,7 +13776,7 @@ function App({
|
|
|
13033
13776
|
})
|
|
13034
13777
|
);
|
|
13035
13778
|
}, []);
|
|
13036
|
-
const updateAssistant =
|
|
13779
|
+
const updateAssistant = useCallback2(
|
|
13037
13780
|
(id, patch) => {
|
|
13038
13781
|
const result = patch({ text: "", reasoning: "" });
|
|
13039
13782
|
const assistantResult = result;
|
|
@@ -13062,7 +13805,7 @@ function App({
|
|
|
13062
13805
|
},
|
|
13063
13806
|
[flushAssistantUpdates]
|
|
13064
13807
|
);
|
|
13065
|
-
const updateTool =
|
|
13808
|
+
const updateTool = useCallback2(
|
|
13066
13809
|
(id, patch) => {
|
|
13067
13810
|
setEvents(
|
|
13068
13811
|
(evts) => evts.map(
|
|
@@ -13072,11 +13815,11 @@ function App({
|
|
|
13072
13815
|
},
|
|
13073
13816
|
[]
|
|
13074
13817
|
);
|
|
13075
|
-
const updateGatewayMeta =
|
|
13818
|
+
const updateGatewayMeta = useCallback2((meta) => {
|
|
13076
13819
|
gatewayMetaRef.current = meta;
|
|
13077
13820
|
setGatewayMeta(meta);
|
|
13078
13821
|
}, []);
|
|
13079
|
-
const runCompact =
|
|
13822
|
+
const runCompact = useCallback2(async () => {
|
|
13080
13823
|
if (!cfg) return;
|
|
13081
13824
|
if (busy) {
|
|
13082
13825
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't compact while model is running" }]);
|
|
@@ -13161,40 +13904,23 @@ function App({
|
|
|
13161
13904
|
setTurnStartedAt(null);
|
|
13162
13905
|
activeControllerRef.current = null;
|
|
13163
13906
|
permResolveRef.current = null;
|
|
13907
|
+
limitResolveRef.current = null;
|
|
13164
13908
|
pendingToolCallsRef.current.clear();
|
|
13165
13909
|
}
|
|
13166
13910
|
}, [cfg, busy, saveSessionSafe]);
|
|
13167
|
-
const openResumePicker =
|
|
13911
|
+
const openResumePicker = useCallback2(async () => {
|
|
13168
13912
|
const sessions = await listSessions(200, process.cwd());
|
|
13169
13913
|
setResumeSessions(sessions);
|
|
13170
13914
|
}, []);
|
|
13171
|
-
const runInit =
|
|
13915
|
+
const runInit = useCallback2(async () => {
|
|
13172
13916
|
if (!cfg) return;
|
|
13173
13917
|
if (busy) {
|
|
13174
13918
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't /init while model is running" }]);
|
|
13175
13919
|
return;
|
|
13176
13920
|
}
|
|
13177
13921
|
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" }]);
|
|
13922
|
+
const { prompt, targetFilename, isRefresh } = buildInitPrompt(cwd);
|
|
13923
|
+
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: isRefresh ? `/init (refreshing ${targetFilename})` : "/init" }]);
|
|
13198
13924
|
messagesRef.current.push({ role: "user", content: sanitizeString(prompt) });
|
|
13199
13925
|
setBusy(true);
|
|
13200
13926
|
setTurnStartedAt(Date.now());
|
|
@@ -13328,7 +14054,7 @@ function App({
|
|
|
13328
14054
|
})
|
|
13329
14055
|
}
|
|
13330
14056
|
});
|
|
13331
|
-
if (
|
|
14057
|
+
if (existsSync3(join22(cwd, "KIMI.md"))) {
|
|
13332
14058
|
if (cacheStableRef.current) {
|
|
13333
14059
|
messagesRef.current[1] = {
|
|
13334
14060
|
role: "system",
|
|
@@ -13383,10 +14109,11 @@ function App({
|
|
|
13383
14109
|
activeAsstIdRef.current = null;
|
|
13384
14110
|
activeControllerRef.current = null;
|
|
13385
14111
|
permResolveRef.current = null;
|
|
14112
|
+
limitResolveRef.current = null;
|
|
13386
14113
|
pendingToolCallsRef.current.clear();
|
|
13387
14114
|
}
|
|
13388
14115
|
}, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
|
|
13389
|
-
const handleThemePick =
|
|
14116
|
+
const handleThemePick = useCallback2(
|
|
13390
14117
|
(picked) => {
|
|
13391
14118
|
setShowThemePicker(false);
|
|
13392
14119
|
setOriginalTheme(null);
|
|
@@ -13405,7 +14132,7 @@ function App({
|
|
|
13405
14132
|
},
|
|
13406
14133
|
[cfg, originalTheme]
|
|
13407
14134
|
);
|
|
13408
|
-
const handleResumePick =
|
|
14135
|
+
const handleResumePick = useCallback2(
|
|
13409
14136
|
async (picked) => {
|
|
13410
14137
|
setResumeSessions(null);
|
|
13411
14138
|
if (!picked) return;
|
|
@@ -13463,7 +14190,7 @@ function App({
|
|
|
13463
14190
|
},
|
|
13464
14191
|
[]
|
|
13465
14192
|
);
|
|
13466
|
-
const handleSlash =
|
|
14193
|
+
const handleSlash = useCallback2(
|
|
13467
14194
|
(cmd) => {
|
|
13468
14195
|
const raw = cmd.trim();
|
|
13469
14196
|
const [head, ...rest] = raw.split(/\s+/);
|
|
@@ -13949,7 +14676,7 @@ ${lines.join("\n")}` }]);
|
|
|
13949
14676
|
if (c === "/hello") {
|
|
13950
14677
|
const session = crypto.randomUUID();
|
|
13951
14678
|
const url = `${FEEDBACK_WORKER_URL}/?s=${session}&v=${getAppVersion()}`;
|
|
13952
|
-
|
|
14679
|
+
openBrowser2(url);
|
|
13953
14680
|
setEvents((e) => [
|
|
13954
14681
|
...e,
|
|
13955
14682
|
{ 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 +14801,7 @@ ${lines.join("\n")}` }]);
|
|
|
14074
14801
|
setEvents((e) => [
|
|
14075
14802
|
...e,
|
|
14076
14803
|
{ kind: "info", key: mkKey(), text: `Starting remote session for ${repo.owner}/${repo.name}...` },
|
|
14077
|
-
{ kind: "info", key: mkKey(), text: `Budget: ${
|
|
14804
|
+
{ kind: "info", key: mkKey(), text: `Budget: ${formatTokens4(budget)} tokens. TTL: ${ttl} min.` }
|
|
14078
14805
|
]);
|
|
14079
14806
|
try {
|
|
14080
14807
|
const data = await startRemoteSession({
|
|
@@ -14162,7 +14889,7 @@ ${lines.join("\n")}` }]);
|
|
|
14162
14889
|
},
|
|
14163
14890
|
[cfg, exit, usage, effort, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
|
|
14164
14891
|
);
|
|
14165
|
-
const handleHelpCommand =
|
|
14892
|
+
const handleHelpCommand = useCallback2(
|
|
14166
14893
|
(command) => {
|
|
14167
14894
|
setShowHelpMenu(false);
|
|
14168
14895
|
const executed = handleSlash(command);
|
|
@@ -14172,7 +14899,7 @@ ${lines.join("\n")}` }]);
|
|
|
14172
14899
|
},
|
|
14173
14900
|
[handleSlash]
|
|
14174
14901
|
);
|
|
14175
|
-
const handleCommandSave =
|
|
14902
|
+
const handleCommandSave = useCallback2(
|
|
14176
14903
|
async (opts2) => {
|
|
14177
14904
|
setCommandWizard(null);
|
|
14178
14905
|
try {
|
|
@@ -14194,7 +14921,7 @@ ${lines.join("\n")}` }]);
|
|
|
14194
14921
|
},
|
|
14195
14922
|
[commandWizard, reloadCustomCommands, setEvents]
|
|
14196
14923
|
);
|
|
14197
|
-
const handleCommandDelete =
|
|
14924
|
+
const handleCommandDelete = useCallback2(
|
|
14198
14925
|
async (cmd) => {
|
|
14199
14926
|
setCommandToDelete(null);
|
|
14200
14927
|
try {
|
|
@@ -14213,7 +14940,7 @@ ${lines.join("\n")}` }]);
|
|
|
14213
14940
|
},
|
|
14214
14941
|
[reloadCustomCommands, setEvents]
|
|
14215
14942
|
);
|
|
14216
|
-
const processMessage =
|
|
14943
|
+
const processMessage = useCallback2(
|
|
14217
14944
|
async (text, displayText) => {
|
|
14218
14945
|
if (!cfg) return;
|
|
14219
14946
|
let trimmed = text.trim();
|
|
@@ -14412,6 +15139,10 @@ ${lines.join("\n")}` }]);
|
|
|
14412
15139
|
}
|
|
14413
15140
|
permResolveRef.current = resolve2;
|
|
14414
15141
|
setPerm({ tool: req.tool, args: req.args, resolve: resolve2 });
|
|
15142
|
+
}),
|
|
15143
|
+
onToolLimitReached: () => new Promise((resolve2) => {
|
|
15144
|
+
limitResolveRef.current = resolve2;
|
|
15145
|
+
setLimitModal({ limit: 50, resolve: resolve2 });
|
|
14415
15146
|
})
|
|
14416
15147
|
};
|
|
14417
15148
|
try {
|
|
@@ -14501,6 +15232,8 @@ ${lines.join("\n")}` }]);
|
|
|
14501
15232
|
text: `auto-compact failed: ${compactErr.message ?? String(compactErr)}`
|
|
14502
15233
|
}
|
|
14503
15234
|
]);
|
|
15235
|
+
} else {
|
|
15236
|
+
throw compactErr;
|
|
14504
15237
|
}
|
|
14505
15238
|
}
|
|
14506
15239
|
}
|
|
@@ -14570,19 +15303,20 @@ ${lines.join("\n")}` }]);
|
|
|
14570
15303
|
activeAsstIdRef.current = null;
|
|
14571
15304
|
activeControllerRef.current = null;
|
|
14572
15305
|
permResolveRef.current = null;
|
|
15306
|
+
limitResolveRef.current = null;
|
|
14573
15307
|
pendingToolCallsRef.current.clear();
|
|
14574
15308
|
}
|
|
14575
15309
|
},
|
|
14576
15310
|
[cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta]
|
|
14577
15311
|
);
|
|
14578
|
-
|
|
15312
|
+
useEffect6(() => {
|
|
14579
15313
|
if (!busy && queue.length > 0) {
|
|
14580
15314
|
const next = queue[0];
|
|
14581
15315
|
setQueue((q) => q.slice(1));
|
|
14582
15316
|
processMessage(next.full, next.display);
|
|
14583
15317
|
}
|
|
14584
15318
|
}, [busy, queue, processMessage]);
|
|
14585
|
-
const submit =
|
|
15319
|
+
const submit = useCallback2(
|
|
14586
15320
|
(full, display) => {
|
|
14587
15321
|
const trimmedFull = full.trim();
|
|
14588
15322
|
if (!trimmedFull) return;
|
|
@@ -14603,7 +15337,7 @@ ${lines.join("\n")}` }]);
|
|
|
14603
15337
|
[busy, processMessage]
|
|
14604
15338
|
);
|
|
14605
15339
|
submitRef.current = submit;
|
|
14606
|
-
|
|
15340
|
+
useEffect6(() => {
|
|
14607
15341
|
if (compactSuggestedRef.current) return;
|
|
14608
15342
|
if (usage && usage.prompt_tokens / CONTEXT_LIMIT >= AUTO_COMPACT_SUGGEST_PCT) {
|
|
14609
15343
|
compactSuggestedRef.current = true;
|
|
@@ -14618,9 +15352,10 @@ ${lines.join("\n")}` }]);
|
|
|
14618
15352
|
}
|
|
14619
15353
|
}, [usage]);
|
|
14620
15354
|
if (!cfg) {
|
|
14621
|
-
return /* @__PURE__ */
|
|
15355
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(
|
|
14622
15356
|
Onboarding,
|
|
14623
15357
|
{
|
|
15358
|
+
onCancel: () => exit(),
|
|
14624
15359
|
onDone: async (newCfg) => {
|
|
14625
15360
|
setCfg(newCfg);
|
|
14626
15361
|
if (newCfg.cloudMode) {
|
|
@@ -14648,10 +15383,10 @@ ${lines.join("\n")}` }]);
|
|
|
14648
15383
|
) });
|
|
14649
15384
|
}
|
|
14650
15385
|
if (resumeSessions !== null) {
|
|
14651
|
-
return /* @__PURE__ */
|
|
15386
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
|
|
14652
15387
|
}
|
|
14653
15388
|
if (showRemoteDashboard) {
|
|
14654
|
-
return /* @__PURE__ */
|
|
15389
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx23(
|
|
14655
15390
|
RemoteSessionDetail,
|
|
14656
15391
|
{
|
|
14657
15392
|
session: selectedRemoteSession,
|
|
@@ -14674,7 +15409,7 @@ ${lines.join("\n")}` }]);
|
|
|
14674
15409
|
setShowRemoteDashboard(false);
|
|
14675
15410
|
}
|
|
14676
15411
|
}
|
|
14677
|
-
) : /* @__PURE__ */
|
|
15412
|
+
) : /* @__PURE__ */ jsx23(
|
|
14678
15413
|
RemoteDashboard,
|
|
14679
15414
|
{
|
|
14680
15415
|
onSelect: (session) => setSelectedRemoteSession(session),
|
|
@@ -14683,7 +15418,7 @@ ${lines.join("\n")}` }]);
|
|
|
14683
15418
|
) }) });
|
|
14684
15419
|
}
|
|
14685
15420
|
if (showHelpMenu) {
|
|
14686
|
-
return /* @__PURE__ */
|
|
15421
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14687
15422
|
HelpMenu,
|
|
14688
15423
|
{
|
|
14689
15424
|
customCommands: customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({ name: c.name, description: c.description })),
|
|
@@ -14695,12 +15430,12 @@ ${lines.join("\n")}` }]);
|
|
|
14695
15430
|
) }) });
|
|
14696
15431
|
}
|
|
14697
15432
|
if (showLspWizard) {
|
|
14698
|
-
return /* @__PURE__ */
|
|
15433
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14699
15434
|
LspWizard,
|
|
14700
15435
|
{
|
|
14701
15436
|
servers: cfg?.lspServers ?? {},
|
|
14702
15437
|
currentScope: lspScope,
|
|
14703
|
-
hasProjectDir:
|
|
15438
|
+
hasProjectDir: existsSync3(join22(process.cwd(), ".kimiflare")),
|
|
14704
15439
|
onDone: () => setShowLspWizard(false),
|
|
14705
15440
|
onSave: (servers, enabled, scope) => {
|
|
14706
15441
|
setCfg((c) => c ? { ...c, lspEnabled: enabled, lspServers: servers } : c);
|
|
@@ -14732,7 +15467,7 @@ ${lines.join("\n")}` }]);
|
|
|
14732
15467
|
) }) });
|
|
14733
15468
|
}
|
|
14734
15469
|
if (commandWizard) {
|
|
14735
|
-
return /* @__PURE__ */
|
|
15470
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14736
15471
|
CommandWizard,
|
|
14737
15472
|
{
|
|
14738
15473
|
mode: commandWizard.mode,
|
|
@@ -14745,7 +15480,7 @@ ${lines.join("\n")}` }]);
|
|
|
14745
15480
|
) }) });
|
|
14746
15481
|
}
|
|
14747
15482
|
if (commandPicker) {
|
|
14748
|
-
return /* @__PURE__ */
|
|
15483
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14749
15484
|
CommandPicker,
|
|
14750
15485
|
{
|
|
14751
15486
|
commands: customCommandsRef.current,
|
|
@@ -14763,15 +15498,15 @@ ${lines.join("\n")}` }]);
|
|
|
14763
15498
|
) }) });
|
|
14764
15499
|
}
|
|
14765
15500
|
if (commandToDelete) {
|
|
14766
|
-
return /* @__PURE__ */
|
|
14767
|
-
/* @__PURE__ */
|
|
15501
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
15502
|
+
/* @__PURE__ */ jsxs21(Text22, { color: theme.accent, bold: true, children: [
|
|
14768
15503
|
"Delete /",
|
|
14769
15504
|
commandToDelete.name,
|
|
14770
15505
|
"?"
|
|
14771
15506
|
] }),
|
|
14772
|
-
/* @__PURE__ */
|
|
14773
|
-
/* @__PURE__ */
|
|
14774
|
-
|
|
15507
|
+
/* @__PURE__ */ jsx23(Text22, { color: theme.info.color, children: commandToDelete.filepath }),
|
|
15508
|
+
/* @__PURE__ */ jsx23(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx23(
|
|
15509
|
+
SelectInput11,
|
|
14775
15510
|
{
|
|
14776
15511
|
items: [
|
|
14777
15512
|
{ label: "Yes, delete", value: "yes", key: "yes" },
|
|
@@ -14789,7 +15524,7 @@ ${lines.join("\n")}` }]);
|
|
|
14789
15524
|
] }) });
|
|
14790
15525
|
}
|
|
14791
15526
|
if (showCommandList) {
|
|
14792
|
-
return /* @__PURE__ */
|
|
15527
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
|
|
14793
15528
|
CommandList,
|
|
14794
15529
|
{
|
|
14795
15530
|
commands: customCommandsRef.current,
|
|
@@ -14798,12 +15533,12 @@ ${lines.join("\n")}` }]);
|
|
|
14798
15533
|
) }) });
|
|
14799
15534
|
}
|
|
14800
15535
|
if (showThemePicker) {
|
|
14801
|
-
return /* @__PURE__ */
|
|
15536
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ThemePicker, { themes: themeList(), onPick: handleThemePick, onPreview: (t) => setTheme(t) }) }) });
|
|
14802
15537
|
}
|
|
14803
15538
|
const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
|
|
14804
|
-
return /* @__PURE__ */
|
|
14805
|
-
!hasConversation && events.length === 0 ? /* @__PURE__ */
|
|
14806
|
-
perm ? /* @__PURE__ */
|
|
15539
|
+
return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
15540
|
+
!hasConversation && events.length === 0 ? /* @__PURE__ */ jsx23(Welcome, { accountId: cfg.accountId }) : /* @__PURE__ */ jsx23(ChatView, { events, showReasoning, verbose }),
|
|
15541
|
+
perm ? /* @__PURE__ */ jsx23(
|
|
14807
15542
|
PermissionModal,
|
|
14808
15543
|
{
|
|
14809
15544
|
tool: perm.tool,
|
|
@@ -14814,8 +15549,18 @@ ${lines.join("\n")}` }]);
|
|
|
14814
15549
|
setPerm(null);
|
|
14815
15550
|
}
|
|
14816
15551
|
}
|
|
14817
|
-
) : /* @__PURE__ */
|
|
14818
|
-
|
|
15552
|
+
) : limitModal ? /* @__PURE__ */ jsx23(
|
|
15553
|
+
LimitModal,
|
|
15554
|
+
{
|
|
15555
|
+
limit: limitModal.limit,
|
|
15556
|
+
onDecide: (d) => {
|
|
15557
|
+
limitModal.resolve(d);
|
|
15558
|
+
limitResolveRef.current = null;
|
|
15559
|
+
setLimitModal(null);
|
|
15560
|
+
}
|
|
15561
|
+
}
|
|
15562
|
+
) : /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
15563
|
+
tasks.length > 0 && /* @__PURE__ */ jsx23(
|
|
14819
15564
|
TaskList,
|
|
14820
15565
|
{
|
|
14821
15566
|
tasks,
|
|
@@ -14823,11 +15568,11 @@ ${lines.join("\n")}` }]);
|
|
|
14823
15568
|
tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
|
|
14824
15569
|
}
|
|
14825
15570
|
),
|
|
14826
|
-
queue.length > 0 && /* @__PURE__ */
|
|
15571
|
+
queue.length > 0 && /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, children: [
|
|
14827
15572
|
"\u23F3 ",
|
|
14828
15573
|
q.display
|
|
14829
15574
|
] }, `queue_${i}`)) }),
|
|
14830
|
-
/* @__PURE__ */
|
|
15575
|
+
/* @__PURE__ */ jsx23(
|
|
14831
15576
|
StatusBar,
|
|
14832
15577
|
{
|
|
14833
15578
|
model: cfg.model,
|
|
@@ -14842,10 +15587,11 @@ ${lines.join("\n")}` }]);
|
|
|
14842
15587
|
latestVersion,
|
|
14843
15588
|
gatewayMeta,
|
|
14844
15589
|
codeMode,
|
|
14845
|
-
cloudMode: cfg.cloudMode
|
|
15590
|
+
cloudMode: cfg.cloudMode,
|
|
15591
|
+
cloudBudget
|
|
14846
15592
|
}
|
|
14847
15593
|
),
|
|
14848
|
-
activePicker?.kind === "file" && /* @__PURE__ */
|
|
15594
|
+
activePicker?.kind === "file" && /* @__PURE__ */ jsx23(
|
|
14849
15595
|
FilePicker,
|
|
14850
15596
|
{
|
|
14851
15597
|
items: filteredFileItems,
|
|
@@ -14853,7 +15599,7 @@ ${lines.join("\n")}` }]);
|
|
|
14853
15599
|
query: pickerQuery ?? ""
|
|
14854
15600
|
}
|
|
14855
15601
|
),
|
|
14856
|
-
activePicker?.kind === "slash" && /* @__PURE__ */
|
|
15602
|
+
activePicker?.kind === "slash" && /* @__PURE__ */ jsx23(
|
|
14857
15603
|
SlashPicker,
|
|
14858
15604
|
{
|
|
14859
15605
|
items: filteredSlashItems,
|
|
@@ -14861,9 +15607,9 @@ ${lines.join("\n")}` }]);
|
|
|
14861
15607
|
query: pickerQuery ?? ""
|
|
14862
15608
|
}
|
|
14863
15609
|
),
|
|
14864
|
-
/* @__PURE__ */
|
|
14865
|
-
/* @__PURE__ */
|
|
14866
|
-
/* @__PURE__ */
|
|
15610
|
+
/* @__PURE__ */ jsxs21(Box21, { marginTop: 1, children: [
|
|
15611
|
+
/* @__PURE__ */ jsx23(Text22, { color: "#d699b6", children: "\u203A " }),
|
|
15612
|
+
/* @__PURE__ */ jsx23(
|
|
14867
15613
|
CustomTextInput,
|
|
14868
15614
|
{
|
|
14869
15615
|
value: input,
|
|
@@ -14920,7 +15666,7 @@ ${lines.join("\n")}` }]);
|
|
|
14920
15666
|
}
|
|
14921
15667
|
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken) {
|
|
14922
15668
|
const instance = render(
|
|
14923
|
-
/* @__PURE__ */
|
|
15669
|
+
/* @__PURE__ */ jsx23(
|
|
14924
15670
|
App,
|
|
14925
15671
|
{
|
|
14926
15672
|
initialCfg: cfg,
|
|
@@ -14954,6 +15700,7 @@ var init_app = __esm({
|
|
|
14954
15700
|
init_chat();
|
|
14955
15701
|
init_status();
|
|
14956
15702
|
init_permission();
|
|
15703
|
+
init_limit_modal();
|
|
14957
15704
|
init_resume_picker();
|
|
14958
15705
|
init_task_list();
|
|
14959
15706
|
init_text_input();
|
|
@@ -14981,6 +15728,7 @@ var init_app = __esm({
|
|
|
14981
15728
|
init_builtins();
|
|
14982
15729
|
init_save();
|
|
14983
15730
|
init_command_wizard();
|
|
15731
|
+
init_context_generator();
|
|
14984
15732
|
init_command_picker();
|
|
14985
15733
|
init_command_list();
|
|
14986
15734
|
init_lsp_wizard();
|