kimiflare 0.57.0 → 0.58.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 CHANGED
@@ -140,7 +140,7 @@ async function loadConfig() {
140
140
  cacheStablePrompts,
141
141
  compiledContext,
142
142
  imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? void 0 : imageHistoryTurns,
143
- memoryEnabled: envMemoryEnabled ?? true,
143
+ memoryEnabled: envMemoryEnabled ?? false,
144
144
  memoryDbPath: envMemoryDbPath,
145
145
  memoryMaxAgeDays: envMemoryMaxAgeDays,
146
146
  memoryMaxEntries: envMemoryMaxEntries,
@@ -169,7 +169,7 @@ async function loadConfig() {
169
169
  cacheStablePrompts,
170
170
  compiledContext,
171
171
  imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? void 0 : imageHistoryTurns,
172
- memoryEnabled: envMemoryEnabled ?? true,
172
+ memoryEnabled: envMemoryEnabled ?? false,
173
173
  memoryDbPath: envMemoryDbPath,
174
174
  memoryMaxAgeDays: envMemoryMaxAgeDays,
175
175
  memoryMaxEntries: envMemoryMaxEntries,
@@ -199,7 +199,7 @@ async function loadConfig() {
199
199
  cacheStablePrompts: parsed.cacheStablePrompts ?? cacheStablePrompts,
200
200
  compiledContext: parsed.compiledContext ?? compiledContext,
201
201
  imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? parsed.imageHistoryTurns : imageHistoryTurns,
202
- memoryEnabled: envMemoryEnabled ?? parsed.memoryEnabled ?? true,
202
+ memoryEnabled: envMemoryEnabled ?? parsed.memoryEnabled ?? false,
203
203
  memoryDbPath: envMemoryDbPath ?? parsed.memoryDbPath,
204
204
  memoryMaxAgeDays: envMemoryMaxAgeDays ?? parsed.memoryMaxAgeDays,
205
205
  memoryMaxEntries: envMemoryMaxEntries ?? parsed.memoryMaxEntries,
@@ -230,7 +230,7 @@ async function loadConfig() {
230
230
  cacheStablePrompts: parsed.cacheStablePrompts ?? cacheStablePrompts,
231
231
  compiledContext: parsed.compiledContext ?? compiledContext,
232
232
  imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? parsed.imageHistoryTurns : imageHistoryTurns,
233
- memoryEnabled: envMemoryEnabled ?? parsed.memoryEnabled ?? true,
233
+ memoryEnabled: envMemoryEnabled ?? parsed.memoryEnabled ?? false,
234
234
  memoryDbPath: envMemoryDbPath ?? parsed.memoryDbPath,
235
235
  memoryMaxAgeDays: envMemoryMaxAgeDays ?? parsed.memoryMaxAgeDays,
236
236
  memoryMaxEntries: envMemoryMaxEntries ?? parsed.memoryMaxEntries,
@@ -462,6 +462,17 @@ var init_sse = __esm({
462
462
  });
463
463
 
464
464
  // src/util/errors.ts
465
+ function isKillSwitchError(err) {
466
+ return err instanceof KillSwitchError;
467
+ }
468
+ async function detectKillSwitch(res) {
469
+ if (res.status === 503) {
470
+ const data = await res.json().catch(() => ({}));
471
+ if (data.error === "SERVICE_ENDED") {
472
+ throw new KillSwitchError(typeof data.ended_at === "string" ? data.ended_at : void 0);
473
+ }
474
+ }
475
+ }
465
476
  function isCloudQuotaExhaustedError(err) {
466
477
  return err instanceof KimiApiError && err.httpStatus === 429 && /token quota exhausted/i.test(err.message);
467
478
  }
@@ -499,7 +510,7 @@ Get a new token: https://dash.cloudflare.com/profile/api-tokens`;
499
510
  }
500
511
  return message2.replace(/\{[\s\S]*?\}/g, "(see logs for details)");
501
512
  }
502
- var KimiApiError;
513
+ var KimiApiError, KillSwitchError;
503
514
  var init_errors = __esm({
504
515
  "src/util/errors.ts"() {
505
516
  "use strict";
@@ -513,6 +524,14 @@ var init_errors = __esm({
513
524
  code;
514
525
  httpStatus;
515
526
  };
527
+ KillSwitchError = class extends Error {
528
+ endedAt;
529
+ constructor(endedAt) {
530
+ super("SERVICE_ENDED");
531
+ this.name = "KillSwitchError";
532
+ this.endedAt = endedAt;
533
+ }
534
+ };
516
535
  }
517
536
  });
518
537
 
@@ -649,7 +668,9 @@ async function* runKimi(opts2) {
649
668
  body: stableStringify(body, jsonReplacer),
650
669
  signal: opts2.signal
651
670
  });
671
+ await detectKillSwitch(res);
652
672
  } catch (fetchErr) {
673
+ if (fetchErr instanceof KillSwitchError) throw fetchErr;
653
674
  const msg = fetchErr instanceof Error ? fetchErr.message : String(fetchErr);
654
675
  logger.warn("runKimi:fetch_error", { requestId, attempt, error: msg });
655
676
  if (attempt < MAX_ATTEMPTS - 1) {
@@ -2954,6 +2975,20 @@ ${sandboxResult.output}` : sandboxResult.output;
2954
2975
  throw new BudgetExhaustedError();
2955
2976
  }
2956
2977
  if (loopExhausted) {
2978
+ if (opts2.callbacks.onLoopDetected) {
2979
+ const decision = await opts2.callbacks.onLoopDetected();
2980
+ if (decision === "continue") {
2981
+ opts2.messages.push({
2982
+ role: "system",
2983
+ content: "You were stuck calling the same tools with identical arguments. The guardrail has been reset so you can continue. Try a different approach."
2984
+ });
2985
+ loopExhausted = false;
2986
+ recentToolCalls.length = 0;
2987
+ continue;
2988
+ } else {
2989
+ return;
2990
+ }
2991
+ }
2957
2992
  throw new AgentLoopError();
2958
2993
  }
2959
2994
  }
@@ -6222,6 +6257,7 @@ async function registerDevice(codes) {
6222
6257
  headers: { "Content-Type": "application/json" },
6223
6258
  body: JSON.stringify({ device_code: codes.deviceCode, user_code: codes.userCode, device_id: codes.deviceId })
6224
6259
  });
6260
+ await detectKillSwitch(registerRes);
6225
6261
  if (!registerRes.ok) {
6226
6262
  const err = await registerRes.json().catch(() => ({}));
6227
6263
  throw new Error(`Failed to register device: ${err.error || registerRes.statusText}`);
@@ -6233,6 +6269,7 @@ async function pollForToken(deviceCode, deviceId) {
6233
6269
  headers: { "Content-Type": "application/json" },
6234
6270
  body: JSON.stringify({ device_code: deviceCode })
6235
6271
  });
6272
+ await detectKillSwitch(pollRes);
6236
6273
  if (!pollRes.ok) return null;
6237
6274
  const pollData = await pollRes.json();
6238
6275
  if (pollData.status === "approved" && pollData.access_token) {
@@ -6256,6 +6293,7 @@ async function fetchCloudUsage(token, deviceId) {
6256
6293
  } catch {
6257
6294
  return null;
6258
6295
  }
6296
+ await detectKillSwitch(res);
6259
6297
  if (!res.ok) return null;
6260
6298
  const data = await res.json();
6261
6299
  if (typeof data.remaining !== "number" || typeof data.input_token_limit !== "number" || typeof data.input_tokens_used !== "number" || typeof data.expires_at !== "string") {
@@ -6320,6 +6358,7 @@ var CLOUD_API_URL, POLL_INTERVAL_MS, POLL_TIMEOUT_MS;
6320
6358
  var init_auth = __esm({
6321
6359
  "src/cloud/auth.ts"() {
6322
6360
  "use strict";
6361
+ init_errors();
6323
6362
  CLOUD_API_URL = "https://api.kimiflare.com";
6324
6363
  POLL_INTERVAL_MS = 5e3;
6325
6364
  POLL_TIMEOUT_MS = 15 * 60 * 1e3;
@@ -6850,6 +6889,7 @@ async function fetchWithRetry(url, init, retries = 3) {
6850
6889
  for (let i = 0; i < retries; i++) {
6851
6890
  try {
6852
6891
  const res = await fetch(url, init);
6892
+ await detectKillSwitch(res);
6853
6893
  if (res.ok) return res;
6854
6894
  if (res.status === 429 || res.status >= 500) {
6855
6895
  const delay = 1e3 * 2 ** i;
@@ -6948,6 +6988,7 @@ var init_embeddings = __esm({
6948
6988
  "src/memory/embeddings.ts"() {
6949
6989
  "use strict";
6950
6990
  init_version();
6991
+ init_errors();
6951
6992
  DEFAULT_MODEL2 = "@cf/baai/bge-base-en-v1.5";
6952
6993
  MAX_EMBED_CHARS = 2e3;
6953
6994
  }
@@ -8889,7 +8930,7 @@ async function createAgentSession(opts2) {
8889
8930
  const tools = opts2.tools ?? ALL_TOOLS;
8890
8931
  const executor = new ToolExecutor(tools);
8891
8932
  let memoryManager = null;
8892
- const memoryEnabled = opts2.memoryEnabled ?? config.memoryEnabled ?? true;
8933
+ const memoryEnabled = opts2.memoryEnabled ?? config.memoryEnabled ?? false;
8893
8934
  if (memoryEnabled) {
8894
8935
  const dbPath = config.memoryDbPath ?? join19(homedir12(), ".local", "share", "kimiflare", "memory.db");
8895
8936
  memoryManager = new MemoryManager({
@@ -9878,6 +9919,7 @@ async function sendReport(payload, token) {
9878
9919
  headers,
9879
9920
  body: JSON.stringify(payload)
9880
9921
  });
9922
+ await detectKillSwitch(res);
9881
9923
  if (res.ok) {
9882
9924
  return { ok: true, message: "Report sent. Thanks for helping improve KimiFlare!" };
9883
9925
  }
@@ -9893,6 +9935,7 @@ var init_report2 = __esm({
9893
9935
  "src/cloud/report.ts"() {
9894
9936
  "use strict";
9895
9937
  init_version();
9938
+ init_errors();
9896
9939
  REPORT_URL = "https://api.kimiflare.com/v1/report";
9897
9940
  }
9898
9941
  });
@@ -10716,11 +10759,45 @@ var init_api_error_message = __esm({
10716
10759
  }
10717
10760
  });
10718
10761
 
10762
+ // src/ui/service-ended-message.tsx
10763
+ import { Box as Box6, Text as Text6 } from "ink";
10764
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
10765
+ function ServiceEndedMessage({ endedAt }) {
10766
+ const theme = useTheme();
10767
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginY: 1, children: [
10768
+ /* @__PURE__ */ jsx7(Text6, { bold: true, color: theme.accent, children: "KimiFlare Cloud has reached its maximum budget across all users." }),
10769
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, children: [
10770
+ /* @__PURE__ */ jsxs6(Text6, { color: theme.info.color, children: [
10771
+ "The free credits period has ended",
10772
+ endedAt ? ` at ${new Date(endedAt).toLocaleString()}` : "",
10773
+ "."
10774
+ ] }),
10775
+ /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: "Thank you for using KimiFlare!" })
10776
+ ] }),
10777
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, children: [
10778
+ /* @__PURE__ */ jsx7(Text6, { bold: true, children: "To continue using KimiFlare, switch to Bring Your Own Key mode:" }),
10779
+ /* @__PURE__ */ jsxs6(Box6, { paddingLeft: 2, flexDirection: "column", children: [
10780
+ /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: "\u2192 Set API token: kimiflare config set-key <your-key>" }),
10781
+ /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: "\u2192 Set account ID: kimiflare config set-account <your-account-id>" }),
10782
+ /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: "\u2192 Get a token: https://dash.cloudflare.com/profile/api-tokens" }),
10783
+ /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: '\u2192 Or re-run kimiflare and select "BYOK \u2014 bring your own Cloudflare key"' })
10784
+ ] })
10785
+ ] }),
10786
+ /* @__PURE__ */ jsx7(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text6, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim ?? true, children: "You can no longer send messages or authenticate via KimiFlare Cloud." }) })
10787
+ ] });
10788
+ }
10789
+ var init_service_ended_message = __esm({
10790
+ "src/ui/service-ended-message.tsx"() {
10791
+ "use strict";
10792
+ init_theme_context();
10793
+ }
10794
+ });
10795
+
10719
10796
  // src/ui/chat.tsx
10720
10797
  import React4 from "react";
10721
- import { Box as Box6, Text as Text6 } from "ink";
10798
+ import { Box as Box7, Text as Text7 } from "ink";
10722
10799
  import Spinner2 from "ink-spinner";
10723
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
10800
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
10724
10801
  function toolSignature(name, args) {
10725
10802
  return `${name}:${args}`;
10726
10803
  }
@@ -10734,6 +10811,7 @@ var init_chat = __esm({
10734
10811
  init_narrator();
10735
10812
  init_cloud_quota_message();
10736
10813
  init_api_error_message();
10814
+ init_service_ended_message();
10737
10815
  ChatView = React4.memo(function ChatView2({ events, showReasoning, verbose, intentTier }) {
10738
10816
  const theme = useTheme();
10739
10817
  const toolCounts = /* @__PURE__ */ new Map();
@@ -10747,12 +10825,12 @@ var init_chat = __esm({
10747
10825
  for (const [sig, count] of toolCounts) {
10748
10826
  if (count >= 3) repeatedSigs.add(sig);
10749
10827
  }
10750
- return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: events.map((e, i) => {
10828
+ return /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", children: events.map((e, i) => {
10751
10829
  const prev = events[i - 1];
10752
10830
  const showSeparator = !!(e.kind === "user" && prev && (prev.kind === "assistant" || prev.kind === "tool"));
10753
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
10754
- showSeparator && /* @__PURE__ */ jsx7(Box6, { marginY: 1, children: /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, children: "\u2500".repeat(40) }) }),
10755
- /* @__PURE__ */ jsx7(EventView, { evt: e, showReasoning, verbose, repeatedSigs, intentTier })
10831
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
10832
+ showSeparator && /* @__PURE__ */ jsx8(Box7, { marginY: 1, children: /* @__PURE__ */ jsx8(Text7, { color: theme.info.color, children: "\u2500".repeat(40) }) }),
10833
+ /* @__PURE__ */ jsx8(EventView, { evt: e, showReasoning, verbose, repeatedSigs, intentTier })
10756
10834
  ] }, e.key);
10757
10835
  }) });
10758
10836
  });
@@ -10767,61 +10845,61 @@ var init_chat = __esm({
10767
10845
  if (evt.kind === "user") {
10768
10846
  if (evt.queued) {
10769
10847
  const mutedColor = theme.muted?.color ?? theme.info.color;
10770
- return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsxs6(Box6, { children: [
10771
- /* @__PURE__ */ jsxs6(Text6, { italic: true, color: mutedColor, children: [
10848
+ return /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", children: /* @__PURE__ */ jsxs7(Box7, { children: [
10849
+ /* @__PURE__ */ jsxs7(Text7, { italic: true, color: mutedColor, children: [
10772
10850
  "\xB7\xB7\xB7",
10773
10851
  " "
10774
10852
  ] }),
10775
- /* @__PURE__ */ jsx7(Text6, { italic: true, color: mutedColor, children: evt.text }),
10776
- /* @__PURE__ */ jsxs6(Text6, { italic: true, color: mutedColor, children: [
10853
+ /* @__PURE__ */ jsx8(Text7, { italic: true, color: mutedColor, children: evt.text }),
10854
+ /* @__PURE__ */ jsxs7(Text7, { italic: true, color: mutedColor, children: [
10777
10855
  " ",
10778
10856
  "(queued)"
10779
10857
  ] })
10780
10858
  ] }) });
10781
10859
  }
10782
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
10783
- /* @__PURE__ */ jsxs6(Box6, { children: [
10784
- /* @__PURE__ */ jsxs6(Text6, { bold: true, color: theme.user, children: [
10860
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
10861
+ /* @__PURE__ */ jsxs7(Box7, { children: [
10862
+ /* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.user, children: [
10785
10863
  "\u203A",
10786
10864
  " "
10787
10865
  ] }),
10788
- /* @__PURE__ */ jsx7(Text6, { bold: true, children: evt.text })
10866
+ /* @__PURE__ */ jsx8(Text7, { bold: true, children: evt.text })
10789
10867
  ] }),
10790
- evt.images && evt.images.length > 0 && /* @__PURE__ */ jsx7(Box6, { paddingLeft: 2, children: /* @__PURE__ */ jsxs6(Text6, { color: theme.info.color, children: [
10868
+ evt.images && evt.images.length > 0 && /* @__PURE__ */ jsx8(Box7, { paddingLeft: 2, children: /* @__PURE__ */ jsxs7(Text7, { color: theme.info.color, children: [
10791
10869
  "\u{1F5BC}\uFE0F ",
10792
10870
  evt.images.join(", ")
10793
10871
  ] }) })
10794
10872
  ] });
10795
10873
  }
10796
10874
  if (evt.kind === "assistant") {
10797
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingLeft: 2, children: [
10798
- showReasoning && evt.reasoning ? /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs6(Text6, { color: theme.reasoning.color, children: [
10875
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingLeft: 2, children: [
10876
+ showReasoning && evt.reasoning ? /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs7(Text7, { color: theme.reasoning.color, children: [
10799
10877
  "thinking\u2026",
10800
10878
  " ",
10801
10879
  evt.reasoning.length > 400 ? evt.reasoning.slice(0, 400) + "\u2026" : evt.reasoning
10802
10880
  ] }) }) : null,
10803
- evt.text ? /* @__PURE__ */ jsx7(MD, { text: evt.text }) : null,
10804
- evt.streaming && /* @__PURE__ */ jsx7(Text6, { color: theme.spinner, children: /* @__PURE__ */ jsx7(Spinner2, { type: "dots" }) })
10881
+ evt.text ? /* @__PURE__ */ jsx8(MD, { text: evt.text }) : null,
10882
+ evt.streaming && /* @__PURE__ */ jsx8(Text7, { color: theme.spinner, children: /* @__PURE__ */ jsx8(Spinner2, { type: "dots" }) })
10805
10883
  ] });
10806
10884
  }
10807
10885
  if (evt.kind === "tool") {
10808
10886
  const isRepeated = repeatedSigs?.has(toolSignature(evt.name, evt.args)) ?? false;
10809
- return /* @__PURE__ */ jsx7(ToolView, { evt, verbose, isRepeated, intentTier });
10887
+ return /* @__PURE__ */ jsx8(ToolView, { evt, verbose, isRepeated, intentTier });
10810
10888
  }
10811
10889
  if (evt.kind === "info") {
10812
- return /* @__PURE__ */ jsxs6(Text6, { color: theme.info.color, children: [
10890
+ return /* @__PURE__ */ jsxs7(Text7, { color: theme.info.color, children: [
10813
10891
  "\xB7 ",
10814
10892
  humanizeInfo(evt.text, intentTier)
10815
10893
  ] });
10816
10894
  }
10817
10895
  if (evt.kind === "memory") {
10818
- return /* @__PURE__ */ jsxs6(Text6, { color: theme.info.color, children: [
10896
+ return /* @__PURE__ */ jsxs7(Text7, { color: theme.info.color, children: [
10819
10897
  "\u25C8 ",
10820
10898
  humanizeMemory(evt.text, intentTier)
10821
10899
  ] });
10822
10900
  }
10823
10901
  if (evt.kind === "cloud_quota_exhausted") {
10824
- return /* @__PURE__ */ jsx7(
10902
+ return /* @__PURE__ */ jsx8(
10825
10903
  CloudQuotaMessage,
10826
10904
  {
10827
10905
  used: evt.used,
@@ -10840,10 +10918,10 @@ var init_chat = __esm({
10840
10918
  }
10841
10919
  const metaText = humanizeMeta(metaParts, intentTier ?? evt.intentTier);
10842
10920
  if (!metaText) return null;
10843
- return /* @__PURE__ */ jsx7(Text6, { color: theme.info.color, dimColor: true, children: metaText });
10921
+ return /* @__PURE__ */ jsx8(Text7, { color: theme.info.color, dimColor: true, children: metaText });
10844
10922
  }
10845
10923
  if (evt.kind === "api_error") {
10846
- return /* @__PURE__ */ jsx7(
10924
+ return /* @__PURE__ */ jsx8(
10847
10925
  ApiErrorMessage,
10848
10926
  {
10849
10927
  httpStatus: evt.httpStatus,
@@ -10852,7 +10930,10 @@ var init_chat = __esm({
10852
10930
  }
10853
10931
  );
10854
10932
  }
10855
- return /* @__PURE__ */ jsxs6(Text6, { color: theme.error, children: [
10933
+ if (evt.kind === "service_ended") {
10934
+ return /* @__PURE__ */ jsx8(ServiceEndedMessage, { endedAt: evt.endedAt });
10935
+ }
10936
+ return /* @__PURE__ */ jsxs7(Text7, { color: theme.error, children: [
10856
10937
  "! ",
10857
10938
  evt.text
10858
10939
  ] });
@@ -10862,9 +10943,9 @@ var init_chat = __esm({
10862
10943
 
10863
10944
  // src/ui/status.tsx
10864
10945
  import { useEffect as useEffect2, useState as useState2 } from "react";
10865
- import { Box as Box7, Text as Text7 } from "ink";
10946
+ import { Box as Box8, Text as Text8 } from "ink";
10866
10947
  import Spinner3 from "ink-spinner";
10867
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
10948
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
10868
10949
  function StatusBar({ usage, sessionUsage, thinking, turnStartedAt, mode, contextLimit, gatewayMeta, codeMode, cloudMode, cloudBudget, skillsActive, memoryRecalled, phase, currentTool, lastActivityAt, kimiMdStale, gitBranch, intentTier }) {
10869
10950
  const theme = useTheme();
10870
10951
  const [now2, setNow] = useState2(Date.now());
@@ -10892,32 +10973,32 @@ function StatusBar({ usage, sessionUsage, thinking, turnStartedAt, mode, context
10892
10973
  const idleLabel = idleMs > 3e4 ? ` (idle ${formatElapsed2(Math.floor(idleMs / 1e3))})` : "";
10893
10974
  const thinkingText = metaParts.length > 0 ? `${phaseLabel}${elapsed ? ` \xB7 ${elapsed}` : ""}${idleLabel} \xB7 ${metaParts.join(" \xB7 ")}` : `${phaseLabel}${elapsed ? ` \xB7 ${elapsed}` : ""}${idleLabel}`;
10894
10975
  const readyText = idleParts.length > 0 ? `${idleParts.join(" \xB7 ")} \xB7 ready` : "ready";
10895
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
10896
- /* @__PURE__ */ jsxs7(Box7, { children: [
10897
- /* @__PURE__ */ jsxs7(Text7, { color: modeColor, bold: true, children: [
10976
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
10977
+ /* @__PURE__ */ jsxs8(Box8, { children: [
10978
+ /* @__PURE__ */ jsxs8(Text8, { color: modeColor, bold: true, children: [
10898
10979
  "[",
10899
10980
  mode,
10900
10981
  "]"
10901
10982
  ] }),
10902
- /* @__PURE__ */ jsx8(Text7, { children: " " }),
10903
- thinking ? /* @__PURE__ */ jsxs7(Text7, { color: theme.spinner, children: [
10904
- /* @__PURE__ */ jsx8(Spinner3, { type: "dots2" }),
10983
+ /* @__PURE__ */ jsx9(Text8, { children: " " }),
10984
+ thinking ? /* @__PURE__ */ jsxs8(Text8, { color: theme.spinner, children: [
10985
+ /* @__PURE__ */ jsx9(Spinner3, { type: "dots2" }),
10905
10986
  " ",
10906
10987
  thinkingText
10907
- ] }) : /* @__PURE__ */ jsx8(Text7, { color: theme.info.color, children: readyText })
10988
+ ] }) : /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: readyText })
10908
10989
  ] }),
10909
- usage && /* @__PURE__ */ jsxs7(Box7, { children: [
10910
- /* @__PURE__ */ jsx8(Text7, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
10911
- warn ? /* @__PURE__ */ jsxs7(Text7, { color: theme.warn, bold: true, children: [
10990
+ usage && /* @__PURE__ */ jsxs8(Box8, { children: [
10991
+ /* @__PURE__ */ jsx9(Text8, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
10992
+ warn ? /* @__PURE__ */ jsxs8(Text8, { color: theme.warn, bold: true, children: [
10912
10993
  " \xB7 ",
10913
10994
  "/compact recommended"
10914
10995
  ] }) : null,
10915
- kimiMdStale ? /* @__PURE__ */ jsxs7(Text7, { color: theme.warn, bold: true, children: [
10996
+ kimiMdStale ? /* @__PURE__ */ jsxs8(Text8, { color: theme.warn, bold: true, children: [
10916
10997
  " \xB7 ",
10917
10998
  "\u26A0 KIMI.md stale \xB7 run /init"
10918
10999
  ] }) : null
10919
11000
  ] }),
10920
- !thinking && /* @__PURE__ */ jsx8(Box7, { children: /* @__PURE__ */ jsx8(Text7, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim, children: "tip: shift+tab cycles mode" }) })
11001
+ !thinking && /* @__PURE__ */ jsx9(Box8, { children: /* @__PURE__ */ jsx9(Text8, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim, children: "tip: shift+tab cycles mode" }) })
10921
11002
  ] });
10922
11003
  }
10923
11004
  function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget) {
@@ -11498,8 +11579,8 @@ var init_source = __esm({
11498
11579
 
11499
11580
  // src/ui/text-input.tsx
11500
11581
  import { useState as useState3, useEffect as useEffect3, useRef } from "react";
11501
- import { Text as Text8, useInput } from "ink";
11502
- import { jsx as jsx9 } from "react/jsx-runtime";
11582
+ import { Text as Text9, useInput } from "ink";
11583
+ import { jsx as jsx10 } from "react/jsx-runtime";
11503
11584
  function shouldTreatAsPaste(input) {
11504
11585
  if (input.length >= PASTE_CHAR_THRESHOLD) return true;
11505
11586
  const newlines = (input.match(/\n/g) ?? []).length;
@@ -11720,7 +11801,7 @@ function CustomTextInput({
11720
11801
  } else if (cursorOffset === displayValue.length) {
11721
11802
  renderedValue += source_default.inverse(" ");
11722
11803
  }
11723
- return /* @__PURE__ */ jsx9(Text8, { children: renderedValue });
11804
+ return /* @__PURE__ */ jsx10(Text9, { children: renderedValue });
11724
11805
  }
11725
11806
  function findPasteTokenEndingAt(value, pos, pastes) {
11726
11807
  if (pos <= 0 || value[pos - 1] !== "\u2998") return -1;
@@ -11743,9 +11824,9 @@ var init_text_input = __esm({
11743
11824
 
11744
11825
  // src/ui/permission.tsx
11745
11826
  import { useState as useState4, useCallback } from "react";
11746
- import { Box as Box8, Text as Text9, useInput as useInput2 } from "ink";
11827
+ import { Box as Box9, Text as Text10, useInput as useInput2 } from "ink";
11747
11828
  import { platform as platform3 } from "os";
11748
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
11829
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
11749
11830
  function formatSelection(label, shortcut) {
11750
11831
  return `${label} [${MOD_KEY}+${shortcut}]`;
11751
11832
  }
@@ -11833,10 +11914,10 @@ function PermissionModal({ tool, args, onDecide, onFeedback }) {
11833
11914
  { isActive: !feedbackActive }
11834
11915
  );
11835
11916
  if (showHelp) {
11836
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
11837
- /* @__PURE__ */ jsx10(Text9, { color: theme.permission, bold: true, children: "Permission modal \u2014 keyboard shortcuts" }),
11838
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "\u2191 / \u2193 or j / k \u2014 navigate options" }),
11839
- /* @__PURE__ */ jsxs8(Text9, { color: theme.info.color, children: [
11917
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
11918
+ /* @__PURE__ */ jsx11(Text10, { color: theme.permission, bold: true, children: "Permission modal \u2014 keyboard shortcuts" }),
11919
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "\u2191 / \u2193 or j / k \u2014 navigate options" }),
11920
+ /* @__PURE__ */ jsxs9(Text10, { color: theme.info.color, children: [
11840
11921
  MOD_KEY,
11841
11922
  "+1 / ",
11842
11923
  MOD_KEY,
@@ -11844,31 +11925,31 @@ function PermissionModal({ tool, args, onDecide, onFeedback }) {
11844
11925
  MOD_KEY,
11845
11926
  "+3 \u2014 select option directly"
11846
11927
  ] }),
11847
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "Enter \u2014 confirm selection" }),
11848
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "Esc \u2014 deny and close" }),
11849
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "? \u2014 toggle this help" }),
11850
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: "When feedback input is open:" }),
11851
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: " Enter \u2014 submit feedback and deny" }),
11852
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, children: " Esc \u2014 deny without feedback" }),
11853
- /* @__PURE__ */ jsx10(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text9, { color: theme.accent, children: "Press any key to close" }) })
11928
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "Enter \u2014 confirm selection" }),
11929
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "Esc \u2014 deny and close" }),
11930
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "? \u2014 toggle this help" }),
11931
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: "When feedback input is open:" }),
11932
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: " Enter \u2014 submit feedback and deny" }),
11933
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, children: " Esc \u2014 deny without feedback" }),
11934
+ /* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { color: theme.accent, children: "Press any key to close" }) })
11854
11935
  ] });
11855
11936
  }
11856
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
11857
- /* @__PURE__ */ jsx10(Text9, { color: theme.permission, bold: true, children: "Permission requested" }),
11858
- /* @__PURE__ */ jsxs8(Text9, { children: [
11937
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [
11938
+ /* @__PURE__ */ jsx11(Text10, { color: theme.permission, bold: true, children: "Permission requested" }),
11939
+ /* @__PURE__ */ jsxs9(Text10, { children: [
11859
11940
  "tool: ",
11860
- /* @__PURE__ */ jsx10(Text9, { color: theme.tool, children: tool.name })
11941
+ /* @__PURE__ */ jsx11(Text10, { color: theme.tool, children: tool.name })
11861
11942
  ] }),
11862
- render2?.title ? /* @__PURE__ */ jsxs8(Text9, { children: [
11943
+ render2?.title ? /* @__PURE__ */ jsxs9(Text10, { children: [
11863
11944
  "action: ",
11864
11945
  render2.title
11865
11946
  ] }) : null,
11866
- render2?.diff ? /* @__PURE__ */ jsx10(Box8, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx10(DiffView, { ...render2.diff }) }) : /* @__PURE__ */ jsxs8(Text9, { color: theme.info.color, children: [
11947
+ render2?.diff ? /* @__PURE__ */ jsx11(Box9, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx11(DiffView, { ...render2.diff }) }) : /* @__PURE__ */ jsxs9(Text10, { color: theme.info.color, children: [
11867
11948
  "args: ",
11868
11949
  JSON.stringify(args)
11869
11950
  ] }),
11870
- /* @__PURE__ */ jsx10(Box8, { marginTop: 1, flexDirection: "column", children: OPTIONS.map((opt, i) => /* @__PURE__ */ jsxs8(
11871
- Text9,
11951
+ /* @__PURE__ */ jsx11(Box9, { marginTop: 1, flexDirection: "column", children: OPTIONS.map((opt, i) => /* @__PURE__ */ jsxs9(
11952
+ Text10,
11872
11953
  {
11873
11954
  color: i === selectedIndex ? theme.accent : void 0,
11874
11955
  bold: i === selectedIndex,
@@ -11879,10 +11960,10 @@ function PermissionModal({ tool, args, onDecide, onFeedback }) {
11879
11960
  },
11880
11961
  opt.value
11881
11962
  )) }),
11882
- feedbackActive && /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
11883
- /* @__PURE__ */ jsx10(Text9, { color: theme.palette.error, children: "Tell me what to do instead" }),
11884
- /* @__PURE__ */ jsx10(Text9, { color: theme.info.color, dimColor: true, children: "Press Esc to deny without feedback" }),
11885
- /* @__PURE__ */ jsx10(
11963
+ feedbackActive && /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, flexDirection: "column", children: [
11964
+ /* @__PURE__ */ jsx11(Text10, { color: theme.palette.error, children: "Tell me what to do instead" }),
11965
+ /* @__PURE__ */ jsx11(Text10, { color: theme.info.color, dimColor: true, children: "Press Esc to deny without feedback" }),
11966
+ /* @__PURE__ */ jsx11(
11886
11967
  CustomTextInput,
11887
11968
  {
11888
11969
  value: feedbackValue,
@@ -11912,27 +11993,19 @@ var init_permission = __esm({
11912
11993
  });
11913
11994
 
11914
11995
  // src/ui/limit-modal.tsx
11915
- import { Box as Box9, Text as Text10 } from "ink";
11996
+ import { Box as Box10, Text as Text11 } from "ink";
11916
11997
  import SelectInput from "ink-select-input";
11917
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
11918
- function LimitModal({ limit, onDecide }) {
11998
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
11999
+ function LimitModal({ limit, onDecide, title, description }) {
11919
12000
  const theme = useTheme();
11920
12001
  const items = [
11921
12002
  { label: "Continue", value: "continue" },
11922
12003
  { label: "Stop", value: "stop" }
11923
12004
  ];
11924
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
11925
- /* @__PURE__ */ jsxs9(Text10, { color: theme.error, bold: true, children: [
11926
- "Tool-call limit reached (",
11927
- limit,
11928
- ")"
11929
- ] }),
11930
- /* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
11931
- "This session has made ",
11932
- limit,
11933
- " tool calls. What would you like to do?"
11934
- ] }),
11935
- /* @__PURE__ */ jsx11(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx11(
12005
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: theme.error, paddingX: 1, children: [
12006
+ /* @__PURE__ */ jsx12(Text11, { color: theme.error, bold: true, children: title ?? `Tool-call limit reached (${limit})` }),
12007
+ /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: description ?? `This session has made ${limit} tool calls. What would you like to do?` }),
12008
+ /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
11936
12009
  SelectInput,
11937
12010
  {
11938
12011
  items,
@@ -12019,9 +12092,9 @@ var init_fuzzy = __esm({
12019
12092
 
12020
12093
  // src/ui/resume-picker.tsx
12021
12094
  import { useState as useState5 } from "react";
12022
- import { Box as Box10, Text as Text11, useInput as useInput3 } from "ink";
12095
+ import { Box as Box11, Text as Text12, useInput as useInput3 } from "ink";
12023
12096
  import SelectInput2 from "ink-select-input";
12024
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
12097
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
12025
12098
  function ResumePicker({ sessions, onPick }) {
12026
12099
  const theme = useTheme();
12027
12100
  const [page, setPage] = useState5(0);
@@ -12062,10 +12135,10 @@ function ResumePicker({ sessions, onPick }) {
12062
12135
  }
12063
12136
  });
12064
12137
  if (sessions.length === 0) {
12065
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12066
- /* @__PURE__ */ jsx12(Text11, { color: theme.accent, bold: true, children: "Resume a session" }),
12067
- /* @__PURE__ */ jsx12(Text11, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
12068
- /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
12138
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12139
+ /* @__PURE__ */ jsx13(Text12, { color: theme.accent, bold: true, children: "Resume a session" }),
12140
+ /* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: "No saved sessions yet. Press Enter to dismiss." }),
12141
+ /* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
12069
12142
  SelectInput2,
12070
12143
  {
12071
12144
  items: [{ label: "(back)", value: "__cancel__" }],
@@ -12078,9 +12151,9 @@ function ResumePicker({ sessions, onPick }) {
12078
12151
  label: `${formatDate(s.updatedAt)} \xB7 ${s.messageCount} msgs \xB7 ${s.title ?? s.firstPrompt}`,
12079
12152
  value: s.id
12080
12153
  }));
12081
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12082
- /* @__PURE__ */ jsx12(Text11, { color: theme.accent, bold: true, children: "Resume a session" }),
12083
- /* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
12154
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12155
+ /* @__PURE__ */ jsx13(Text12, { color: theme.accent, bold: true, children: "Resume a session" }),
12156
+ /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12084
12157
  query ? `Search: ${query}\u258C` : "Type to search\u2026",
12085
12158
  " \xB7 Page ",
12086
12159
  safePage + 1,
@@ -12090,7 +12163,7 @@ function ResumePicker({ sessions, onPick }) {
12090
12163
  filtered.length,
12091
12164
  " total)"
12092
12165
  ] }),
12093
- /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx12(
12166
+ /* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
12094
12167
  SelectInput2,
12095
12168
  {
12096
12169
  items,
@@ -12105,7 +12178,7 @@ function ResumePicker({ sessions, onPick }) {
12105
12178
  }
12106
12179
  }
12107
12180
  ) }),
12108
- /* @__PURE__ */ jsx12(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text11, { color: theme.info.color, children: [
12181
+ /* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12109
12182
  safePage > 0 ? "\u2190 prev " : "",
12110
12183
  safePage < totalPages - 1 ? "\u2192 next " : "",
12111
12184
  "q: cancel"
@@ -12137,9 +12210,9 @@ var init_resume_picker = __esm({
12137
12210
 
12138
12211
  // src/ui/checkpoint-picker.tsx
12139
12212
  import { useState as useState6 } from "react";
12140
- import { Box as Box11, Text as Text12, useInput as useInput4 } from "ink";
12213
+ import { Box as Box12, Text as Text13, useInput as useInput4 } from "ink";
12141
12214
  import SelectInput3 from "ink-select-input";
12142
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
12215
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
12143
12216
  function CheckpointPicker({ session, checkpoints, onPick }) {
12144
12217
  const theme = useTheme();
12145
12218
  const [selectedIndex, setSelectedIndex] = useState6(0);
@@ -12159,16 +12232,16 @@ function CheckpointPicker({ session, checkpoints, onPick }) {
12159
12232
  value: cp.id
12160
12233
  }))
12161
12234
  ];
12162
- return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12163
- /* @__PURE__ */ jsx13(Text12, { color: theme.accent, bold: true, children: session.firstPrompt.slice(0, 50) }),
12164
- /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
12235
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12236
+ /* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: session.firstPrompt.slice(0, 50) }),
12237
+ /* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
12165
12238
  session.messageCount,
12166
12239
  " turns \xB7 ",
12167
12240
  checkpoints.length,
12168
12241
  " checkpoint",
12169
12242
  checkpoints.length === 1 ? "" : "s"
12170
12243
  ] }),
12171
- /* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(
12244
+ /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
12172
12245
  SelectInput3,
12173
12246
  {
12174
12247
  items,
@@ -12186,7 +12259,7 @@ function CheckpointPicker({ session, checkpoints, onPick }) {
12186
12259
  }
12187
12260
  }
12188
12261
  ) }),
12189
- /* @__PURE__ */ jsx13(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text12, { color: theme.info.color, children: "q: cancel / go back" }) })
12262
+ /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, children: "q: cancel / go back" }) })
12190
12263
  ] });
12191
12264
  }
12192
12265
  function formatDate2(iso) {
@@ -12211,9 +12284,9 @@ var init_checkpoint_picker = __esm({
12211
12284
 
12212
12285
  // src/ui/task-list.tsx
12213
12286
  import { useEffect as useEffect4, useRef as useRef2, useState as useState7 } from "react";
12214
- import { Box as Box12, Text as Text13 } from "ink";
12287
+ import { Box as Box13, Text as Text14 } from "ink";
12215
12288
  import Spinner4 from "ink-spinner";
12216
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
12289
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
12217
12290
  function TaskList({ tasks, startedAt, tokensDelta }) {
12218
12291
  const theme = useTheme();
12219
12292
  const [now2, setNow] = useState7(Date.now());
@@ -12251,18 +12324,18 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
12251
12324
  const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens3(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
12252
12325
  const visibleTasks = tasks.slice(0, MAX_VISIBLE);
12253
12326
  const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
12254
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginBottom: 1, children: [
12255
- /* @__PURE__ */ jsxs12(Box12, { children: [
12256
- /* @__PURE__ */ jsx14(Text13, { color: celebrating ? theme.palette.success : allDone ? "green" : theme.accent, bold: true, children: celebrating ? `\u2728 ${header}` : header }),
12257
- headerStats && /* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
12327
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", marginBottom: 1, children: [
12328
+ /* @__PURE__ */ jsxs13(Box13, { children: [
12329
+ /* @__PURE__ */ jsx15(Text14, { color: celebrating ? theme.palette.success : allDone ? "green" : theme.accent, bold: true, children: celebrating ? `\u2728 ${header}` : header }),
12330
+ headerStats && /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12258
12331
  " ",
12259
12332
  "(",
12260
12333
  headerStats,
12261
12334
  ")"
12262
12335
  ] })
12263
12336
  ] }),
12264
- visibleTasks.map((t) => /* @__PURE__ */ jsx14(TaskRow, { task: t }, t.id)),
12265
- hiddenPending > 0 && /* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
12337
+ visibleTasks.map((t) => /* @__PURE__ */ jsx15(TaskRow, { task: t }, t.id)),
12338
+ hiddenPending > 0 && /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12266
12339
  " ",
12267
12340
  "\u2026 +",
12268
12341
  hiddenPending,
@@ -12273,21 +12346,21 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
12273
12346
  function TaskRow({ task }) {
12274
12347
  const theme = useTheme();
12275
12348
  if (task.status === "completed") {
12276
- return /* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
12349
+ return /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12277
12350
  " ",
12278
12351
  "\u2713 ",
12279
- /* @__PURE__ */ jsx14(Text13, { strikethrough: true, children: task.title })
12352
+ /* @__PURE__ */ jsx15(Text14, { strikethrough: true, children: task.title })
12280
12353
  ] });
12281
12354
  }
12282
12355
  if (task.status === "in_progress") {
12283
- return /* @__PURE__ */ jsxs12(Text13, { color: theme.accent, bold: true, children: [
12356
+ return /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
12284
12357
  " ",
12285
- /* @__PURE__ */ jsx14(Spinner4, { type: "line" }),
12358
+ /* @__PURE__ */ jsx15(Spinner4, { type: "line" }),
12286
12359
  " ",
12287
12360
  task.title
12288
12361
  ] });
12289
12362
  }
12290
- return /* @__PURE__ */ jsxs12(Text13, { color: theme.info.color, children: [
12363
+ return /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12291
12364
  " ",
12292
12365
  "\u2610 ",
12293
12366
  task.title
@@ -12315,12 +12388,12 @@ var init_task_list = __esm({
12315
12388
 
12316
12389
  // src/ui/onboarding.tsx
12317
12390
  import { useState as useState8, useEffect as useEffect5, useCallback as useCallback2 } from "react";
12318
- import { Box as Box13, Text as Text14, useInput as useInput5 } from "ink";
12391
+ import { Box as Box14, Text as Text15, useInput as useInput5 } from "ink";
12319
12392
  import SelectInput4 from "ink-select-input";
12320
12393
  import Spinner5 from "ink-spinner";
12321
12394
  import { exec } from "child_process";
12322
12395
  import { promisify as promisify2 } from "util";
12323
- import { Fragment, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
12396
+ import { Fragment, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
12324
12397
  function openBrowser(url) {
12325
12398
  const platform5 = process.platform;
12326
12399
  const cmd = platform5 === "darwin" ? `open "${url}"` : platform5 === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
@@ -12376,7 +12449,16 @@ function Onboarding({ onDone, onCancel }) {
12376
12449
  }
12377
12450
  return;
12378
12451
  }
12379
- } catch {
12452
+ } catch (err) {
12453
+ if (isKillSwitchError(err)) {
12454
+ if (!cancelled) {
12455
+ setCloudAuth({
12456
+ phase: "error",
12457
+ message: "KimiFlare Cloud has reached its maximum budget across all users. The free credits period has ended. Switch to BYOK mode to continue using KimiFlare."
12458
+ });
12459
+ }
12460
+ return;
12461
+ }
12380
12462
  }
12381
12463
  await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
12382
12464
  }
@@ -12476,24 +12558,24 @@ function Onboarding({ onDone, onCancel }) {
12476
12558
  const byokSteps = ["accountId", "apiToken", "model", "confirm"];
12477
12559
  const stepIndex = step === "mode" ? 1 : step === "cloudAuth" ? 2 : byokSteps.indexOf(step) + 2;
12478
12560
  const totalSteps = mode === "cloud" ? 2 : byokSteps.length + 1;
12479
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingY: 1, children: [
12480
- /* @__PURE__ */ jsxs13(Box13, { marginBottom: 1, children: [
12481
- /* @__PURE__ */ jsx15(Text14, { bold: true, color: theme.palette.primary, children: "kimiflare" }),
12482
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12561
+ return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingY: 1, children: [
12562
+ /* @__PURE__ */ jsxs14(Box14, { marginBottom: 1, children: [
12563
+ /* @__PURE__ */ jsx16(Text15, { bold: true, color: theme.palette.primary, children: "kimiflare" }),
12564
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12483
12565
  " ",
12484
12566
  "Terminal coding agent"
12485
12567
  ] })
12486
12568
  ] }),
12487
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12569
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12488
12570
  "Step ",
12489
12571
  stepIndex,
12490
12572
  " of ",
12491
12573
  totalSteps
12492
12574
  ] }),
12493
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
12494
- step === "mode" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12495
- /* @__PURE__ */ jsx15(Text14, { children: "How do you want to connect?" }),
12496
- /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
12575
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
12576
+ step === "mode" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12577
+ /* @__PURE__ */ jsx16(Text15, { children: "How do you want to connect?" }),
12578
+ /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
12497
12579
  SelectInput4,
12498
12580
  {
12499
12581
  items: [
@@ -12504,19 +12586,19 @@ function Onboarding({ onDone, onCancel }) {
12504
12586
  }
12505
12587
  ) })
12506
12588
  ] }),
12507
- step === "cloudAuth" && cloudAuth?.phase === "ready" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12508
- /* @__PURE__ */ jsx15(Text14, { children: "Authenticating with Kimiflare Cloud..." }),
12509
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
12510
- /* @__PURE__ */ jsx15(Text14, { children: "1. Open this URL in your browser:" }),
12511
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: cloudAuth.codes.authUrl })
12589
+ step === "cloudAuth" && cloudAuth?.phase === "ready" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12590
+ /* @__PURE__ */ jsx16(Text15, { children: "Authenticating with Kimiflare Cloud..." }),
12591
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
12592
+ /* @__PURE__ */ jsx16(Text15, { children: "1. Open this URL in your browser:" }),
12593
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: cloudAuth.codes.authUrl })
12512
12594
  ] }),
12513
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12514
- /* @__PURE__ */ jsx15(Text14, { children: "2. " }),
12515
- /* @__PURE__ */ jsx15(Text14, { bold: true, children: "[Press Enter to open browser]" })
12595
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12596
+ /* @__PURE__ */ jsx16(Text15, { children: "2. " }),
12597
+ /* @__PURE__ */ jsx16(Text15, { bold: true, children: "[Press Enter to open browser]" })
12516
12598
  ] }),
12517
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12518
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: "\u203A " }),
12519
- /* @__PURE__ */ jsx15(
12599
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12600
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: "\u203A " }),
12601
+ /* @__PURE__ */ jsx16(
12520
12602
  CustomTextInput,
12521
12603
  {
12522
12604
  value: "",
@@ -12527,28 +12609,28 @@ function Onboarding({ onDone, onCancel }) {
12527
12609
  )
12528
12610
  ] })
12529
12611
  ] }),
12530
- step === "cloudAuth" && cloudAuth?.phase === "polling" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12531
- /* @__PURE__ */ jsxs13(Text14, { children: [
12532
- /* @__PURE__ */ jsx15(Text14, { color: theme.spinner, children: /* @__PURE__ */ jsx15(Spinner5, { type: "dots" }) }),
12612
+ step === "cloudAuth" && cloudAuth?.phase === "polling" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12613
+ /* @__PURE__ */ jsxs14(Text15, { children: [
12614
+ /* @__PURE__ */ jsx16(Text15, { color: theme.spinner, children: /* @__PURE__ */ jsx16(Spinner5, { type: "dots" }) }),
12533
12615
  " ",
12534
12616
  "Waiting for authentication..."
12535
12617
  ] }),
12536
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12618
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12537
12619
  "Expires in ",
12538
12620
  formatRemaining(POLL_TIMEOUT_MS - (Date.now() - cloudAuth.startTime))
12539
12621
  ] }),
12540
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12622
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12541
12623
  "URL: ",
12542
12624
  cloudAuth.codes.authUrl
12543
12625
  ] })
12544
12626
  ] }),
12545
- step === "cloudAuth" && cloudAuth?.phase === "success" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12546
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.success, children: "Authenticated!" }),
12547
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
12548
- /* @__PURE__ */ jsxs13(Text14, { children: [
12627
+ step === "cloudAuth" && cloudAuth?.phase === "success" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12628
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.success, children: "Authenticated!" }),
12629
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
12630
+ /* @__PURE__ */ jsxs14(Text15, { children: [
12549
12631
  "Token budget:",
12550
12632
  " ",
12551
- /* @__PURE__ */ jsxs13(Text14, { bold: true, children: [
12633
+ /* @__PURE__ */ jsxs14(Text15, { bold: true, children: [
12552
12634
  cloudAuth.usage.remaining.toLocaleString(),
12553
12635
  " /",
12554
12636
  " ",
@@ -12557,15 +12639,16 @@ function Onboarding({ onDone, onCancel }) {
12557
12639
  " ",
12558
12640
  "remaining"
12559
12641
  ] }),
12560
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12642
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12561
12643
  "Grant expires: ",
12562
12644
  cloudAuth.usage.expires_at
12563
- ] })
12645
+ ] }),
12646
+ /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Or when the global pool of free tokens runs out." })
12564
12647
  ] }),
12565
- /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text14, { children: "[Press Enter to continue]" }) }),
12566
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12567
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: "\u203A " }),
12568
- /* @__PURE__ */ jsx15(
12648
+ /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text15, { children: "[Press Enter to continue]" }) }),
12649
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12650
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: "\u203A " }),
12651
+ /* @__PURE__ */ jsx16(
12569
12652
  CustomTextInput,
12570
12653
  {
12571
12654
  value: "",
@@ -12576,10 +12659,10 @@ function Onboarding({ onDone, onCancel }) {
12576
12659
  )
12577
12660
  ] })
12578
12661
  ] }),
12579
- step === "cloudAuth" && cloudAuth?.phase === "error" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12580
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.error, children: "Authentication failed" }),
12581
- /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: cloudAuth.message }),
12582
- /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
12662
+ step === "cloudAuth" && cloudAuth?.phase === "error" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12663
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.error, children: "Authentication failed" }),
12664
+ /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: cloudAuth.message }),
12665
+ /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
12583
12666
  SelectInput4,
12584
12667
  {
12585
12668
  items: [
@@ -12595,11 +12678,11 @@ function Onboarding({ onDone, onCancel }) {
12595
12678
  }
12596
12679
  ) })
12597
12680
  ] }),
12598
- step === "accountId" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12599
- /* @__PURE__ */ jsx15(Text14, { children: "Enter your Cloudflare Account ID" }),
12600
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12601
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: "\u203A " }),
12602
- /* @__PURE__ */ jsx15(
12681
+ step === "accountId" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12682
+ /* @__PURE__ */ jsx16(Text15, { children: "Enter your Cloudflare Account ID" }),
12683
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12684
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: "\u203A " }),
12685
+ /* @__PURE__ */ jsx16(
12603
12686
  CustomTextInput,
12604
12687
  {
12605
12688
  value: accountId,
@@ -12609,12 +12692,12 @@ function Onboarding({ onDone, onCancel }) {
12609
12692
  )
12610
12693
  ] })
12611
12694
  ] }),
12612
- step === "apiToken" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12613
- /* @__PURE__ */ jsx15(Text14, { children: "Enter your Cloudflare API Token" }),
12614
- /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Create one at https://dash.cloudflare.com/profile/api-tokens" }),
12615
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12616
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: "\u203A " }),
12617
- /* @__PURE__ */ jsx15(
12695
+ step === "apiToken" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12696
+ /* @__PURE__ */ jsx16(Text15, { children: "Enter your Cloudflare API Token" }),
12697
+ /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Create one at https://dash.cloudflare.com/profile/api-tokens" }),
12698
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12699
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: "\u203A " }),
12700
+ /* @__PURE__ */ jsx16(
12618
12701
  CustomTextInput,
12619
12702
  {
12620
12703
  value: apiToken,
@@ -12625,15 +12708,15 @@ function Onboarding({ onDone, onCancel }) {
12625
12708
  )
12626
12709
  ] })
12627
12710
  ] }),
12628
- step === "model" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12629
- /* @__PURE__ */ jsx15(Text14, { children: "Model ID (press Enter for default)" }),
12630
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12711
+ step === "model" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12712
+ /* @__PURE__ */ jsx16(Text15, { children: "Model ID (press Enter for default)" }),
12713
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12631
12714
  "default: ",
12632
12715
  DEFAULT_MODEL
12633
12716
  ] }),
12634
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12635
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: "\u203A " }),
12636
- /* @__PURE__ */ jsx15(
12717
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12718
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: "\u203A " }),
12719
+ /* @__PURE__ */ jsx16(
12637
12720
  CustomTextInput,
12638
12721
  {
12639
12722
  value: model,
@@ -12643,10 +12726,10 @@ function Onboarding({ onDone, onCancel }) {
12643
12726
  )
12644
12727
  ] })
12645
12728
  ] }),
12646
- step === "confirm" && /* @__PURE__ */ jsxs13(Fragment, { children: [
12647
- /* @__PURE__ */ jsx15(Text14, { children: "Ready to save configuration" }),
12648
- /* @__PURE__ */ jsxs13(
12649
- Box13,
12729
+ step === "confirm" && /* @__PURE__ */ jsxs14(Fragment, { children: [
12730
+ /* @__PURE__ */ jsx16(Text15, { children: "Ready to save configuration" }),
12731
+ /* @__PURE__ */ jsxs14(
12732
+ Box14,
12650
12733
  {
12651
12734
  flexDirection: "column",
12652
12735
  marginTop: 1,
@@ -12655,25 +12738,25 @@ function Onboarding({ onDone, onCancel }) {
12655
12738
  borderColor: theme.info.color,
12656
12739
  paddingX: 1,
12657
12740
  children: [
12658
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12741
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12659
12742
  "Account ID: ",
12660
12743
  accountId
12661
12744
  ] }),
12662
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12745
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12663
12746
  "API Token: ",
12664
12747
  "\u2022".repeat(apiToken.length)
12665
12748
  ] }),
12666
- /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
12749
+ /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
12667
12750
  "Model: ",
12668
12751
  model
12669
12752
  ] })
12670
12753
  ]
12671
12754
  }
12672
12755
  ),
12673
- /* @__PURE__ */ jsx15(Text14, { children: "Press Enter to confirm, or Ctrl+C to cancel" }),
12674
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, children: [
12675
- /* @__PURE__ */ jsx15(Text14, { color: theme.palette.primary, children: "\u203A " }),
12676
- /* @__PURE__ */ jsx15(
12756
+ /* @__PURE__ */ jsx16(Text15, { children: "Press Enter to confirm, or Ctrl+C to cancel" }),
12757
+ /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
12758
+ /* @__PURE__ */ jsx16(Text15, { color: theme.palette.primary, children: "\u203A " }),
12759
+ /* @__PURE__ */ jsx16(
12677
12760
  CustomTextInput,
12678
12761
  {
12679
12762
  value: "",
@@ -12684,7 +12767,7 @@ function Onboarding({ onDone, onCancel }) {
12684
12767
  )
12685
12768
  ] })
12686
12769
  ] }),
12687
- savedPath && /* @__PURE__ */ jsxs13(Text14, { color: theme.palette.success, children: [
12770
+ savedPath && /* @__PURE__ */ jsxs14(Text15, { color: theme.palette.success, children: [
12688
12771
  "Config saved to ",
12689
12772
  savedPath
12690
12773
  ] })
@@ -12699,6 +12782,7 @@ var init_onboarding = __esm({
12699
12782
  init_config();
12700
12783
  init_theme_context();
12701
12784
  init_auth();
12785
+ init_errors();
12702
12786
  execAsync = promisify2(exec);
12703
12787
  }
12704
12788
  });
@@ -12742,8 +12826,8 @@ var init_greetings = __esm({
12742
12826
  });
12743
12827
 
12744
12828
  // src/ui/welcome.tsx
12745
- import { Box as Box14, Text as Text15 } from "ink";
12746
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
12829
+ import { Box as Box15, Text as Text16 } from "ink";
12830
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
12747
12831
  function Welcome() {
12748
12832
  const theme = useTheme();
12749
12833
  const now2 = /* @__PURE__ */ new Date();
@@ -12751,9 +12835,9 @@ function Welcome() {
12751
12835
  hour: now2.getHours(),
12752
12836
  day: now2.getDay()
12753
12837
  });
12754
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", marginBottom: 1, children: [
12755
- /* @__PURE__ */ jsx16(Box14, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text15, { bold: true, color: theme.accent, children: headline }) }),
12756
- /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", children: /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, dimColor: true, children: "Type / for commands" }) })
12838
+ return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginBottom: 1, children: [
12839
+ /* @__PURE__ */ jsx17(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx17(Text16, { bold: true, color: theme.accent, children: headline }) }),
12840
+ /* @__PURE__ */ jsx17(Box15, { flexDirection: "column", children: /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: true, children: "Type / for commands" }) })
12757
12841
  ] });
12758
12842
  }
12759
12843
  var init_welcome = __esm({
@@ -12861,9 +12945,9 @@ var init_worker_client = __esm({
12861
12945
 
12862
12946
  // src/ui/remote-dashboard.tsx
12863
12947
  import { useEffect as useEffect6, useState as useState9 } from "react";
12864
- import { Box as Box15, Text as Text16, useInput as useInput6 } from "ink";
12948
+ import { Box as Box16, Text as Text17, useInput as useInput6 } from "ink";
12865
12949
  import SelectInput5 from "ink-select-input";
12866
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
12950
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
12867
12951
  function RemoteDashboard({ onSelect, onCancel }) {
12868
12952
  const theme = useTheme();
12869
12953
  const [sessions, setSessions] = useState9([]);
@@ -12919,30 +13003,30 @@ function RemoteDashboard({ onSelect, onCancel }) {
12919
13003
  value: s.sessionId
12920
13004
  }));
12921
13005
  if (loading) {
12922
- return /* @__PURE__ */ jsx17(Box15, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx17(Text16, { color: theme.accent, children: "Loading remote sessions..." }) });
13006
+ return /* @__PURE__ */ jsx18(Box16, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "Loading remote sessions..." }) });
12923
13007
  }
12924
13008
  if (error) {
12925
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
12926
- /* @__PURE__ */ jsxs15(Text16, { color: theme.error, children: [
13009
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", padding: 1, children: [
13010
+ /* @__PURE__ */ jsxs16(Text17, { color: theme.error, children: [
12927
13011
  "Error: ",
12928
13012
  error
12929
13013
  ] }),
12930
- /* @__PURE__ */ jsx17(Text16, { dimColor: true, children: "Press R to retry, Esc to close" })
13014
+ /* @__PURE__ */ jsx18(Text17, { dimColor: true, children: "Press R to retry, Esc to close" })
12931
13015
  ] });
12932
13016
  }
12933
13017
  if (sessions.length === 0) {
12934
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
12935
- /* @__PURE__ */ jsx17(Text16, { color: theme.accent, children: "No remote sessions yet." }),
12936
- /* @__PURE__ */ jsx17(Text16, { dimColor: true, children: "Type /remote <prompt> to start one." }),
12937
- /* @__PURE__ */ jsx17(Text16, { dimColor: true, children: "Press Esc to close" })
13018
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", padding: 1, children: [
13019
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "No remote sessions yet." }),
13020
+ /* @__PURE__ */ jsx18(Text17, { dimColor: true, children: "Type /remote <prompt> to start one." }),
13021
+ /* @__PURE__ */ jsx18(Text17, { dimColor: true, children: "Press Esc to close" })
12938
13022
  ] });
12939
13023
  }
12940
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
12941
- /* @__PURE__ */ jsxs15(Text16, { bold: true, color: theme.accent, children: [
13024
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", padding: 1, children: [
13025
+ /* @__PURE__ */ jsxs16(Text17, { bold: true, color: theme.accent, children: [
12942
13026
  "Recent remote tasks ",
12943
13027
  refreshing ? "(refreshing...)" : ""
12944
13028
  ] }),
12945
- /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
13029
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12946
13030
  SelectInput5,
12947
13031
  {
12948
13032
  items,
@@ -12952,7 +13036,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
12952
13036
  }
12953
13037
  }
12954
13038
  ) }),
12955
- /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text16, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
13039
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text17, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
12956
13040
  ] });
12957
13041
  }
12958
13042
  function formatSessionLine(s) {
@@ -13005,50 +13089,50 @@ function RemoteSessionDetail({
13005
13089
  }
13006
13090
  }
13007
13091
  const isRunning = session.status === "running" || session.status === "pending";
13008
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", padding: 1, children: [
13009
- /* @__PURE__ */ jsx17(Text16, { bold: true, color: theme.accent, children: "Remote Session" }),
13010
- /* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "column", children: [
13011
- /* @__PURE__ */ jsxs15(Text16, { children: [
13092
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", padding: 1, children: [
13093
+ /* @__PURE__ */ jsx18(Text17, { bold: true, color: theme.accent, children: "Remote Session" }),
13094
+ /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
13095
+ /* @__PURE__ */ jsxs16(Text17, { children: [
13012
13096
  "ID: ",
13013
13097
  session.sessionId
13014
13098
  ] }),
13015
- /* @__PURE__ */ jsxs15(Text16, { children: [
13099
+ /* @__PURE__ */ jsxs16(Text17, { children: [
13016
13100
  "Repo: ",
13017
13101
  session.repo
13018
13102
  ] }),
13019
- /* @__PURE__ */ jsxs15(Text16, { children: [
13103
+ /* @__PURE__ */ jsxs16(Text17, { children: [
13020
13104
  "Status: ",
13021
13105
  session.status
13022
13106
  ] }),
13023
- /* @__PURE__ */ jsxs15(Text16, { children: [
13107
+ /* @__PURE__ */ jsxs16(Text17, { children: [
13024
13108
  "Prompt: ",
13025
13109
  session.prompt
13026
13110
  ] }),
13027
- session.prUrl && /* @__PURE__ */ jsxs15(Text16, { children: [
13111
+ session.prUrl && /* @__PURE__ */ jsxs16(Text17, { children: [
13028
13112
  "PR: ",
13029
13113
  session.prUrl
13030
13114
  ] }),
13031
- session.errorMessage && /* @__PURE__ */ jsxs15(Text16, { color: theme.error, children: [
13115
+ session.errorMessage && /* @__PURE__ */ jsxs16(Text17, { color: theme.error, children: [
13032
13116
  "Error: ",
13033
13117
  session.errorMessage
13034
13118
  ] }),
13035
- session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs15(Text16, { children: [
13119
+ session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs16(Text17, { children: [
13036
13120
  "Tokens: ",
13037
13121
  formatTokens4(session.tokensUsed),
13038
13122
  session.tokensBudget ? ` / ${formatTokens4(session.tokensBudget)}` : ""
13039
13123
  ] }),
13040
- /* @__PURE__ */ jsxs15(Text16, { children: [
13124
+ /* @__PURE__ */ jsxs16(Text17, { children: [
13041
13125
  "Created: ",
13042
13126
  new Date(session.createdAt).toLocaleString()
13043
13127
  ] }),
13044
- session.finishedAt && /* @__PURE__ */ jsxs15(Text16, { children: [
13128
+ session.finishedAt && /* @__PURE__ */ jsxs16(Text17, { children: [
13045
13129
  "Finished: ",
13046
13130
  new Date(session.finishedAt).toLocaleString()
13047
13131
  ] })
13048
13132
  ] }),
13049
- /* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "row", gap: 2, children: [
13050
- isRunning && onCancel && /* @__PURE__ */ jsx17(Text16, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
13051
- /* @__PURE__ */ jsx17(Text16, { dimColor: true, children: "Esc back" })
13133
+ /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "row", gap: 2, children: [
13134
+ isRunning && onCancel && /* @__PURE__ */ jsx18(Text17, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
13135
+ /* @__PURE__ */ jsx18(Text17, { dimColor: true, children: "Esc back" })
13052
13136
  ] })
13053
13137
  ] });
13054
13138
  }
@@ -14245,9 +14329,9 @@ var init_save = __esm({
14245
14329
 
14246
14330
  // src/ui/command-wizard.tsx
14247
14331
  import { useState as useState10 } from "react";
14248
- import { Box as Box16, Text as Text17, useInput as useInput7, useWindowSize } from "ink";
14332
+ import { Box as Box17, Text as Text18, useInput as useInput7, useWindowSize } from "ink";
14249
14333
  import SelectInput6 from "ink-select-input";
14250
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
14334
+ import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
14251
14335
  function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
14252
14336
  const theme = useTheme();
14253
14337
  const [step, setStep] = useState10("name");
@@ -14371,8 +14455,8 @@ ${template}`;
14371
14455
  const renderStep = () => {
14372
14456
  switch (step) {
14373
14457
  case "name":
14374
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14375
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14458
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14459
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14376
14460
  mode === "create" ? "Create" : "Edit",
14377
14461
  " custom command \u2014 Name (",
14378
14462
  stepIndex,
@@ -14380,8 +14464,8 @@ ${template}`;
14380
14464
  totalSteps,
14381
14465
  ")"
14382
14466
  ] }),
14383
- error && /* @__PURE__ */ jsx18(Text17, { color: theme.error, children: error }),
14384
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14467
+ error && /* @__PURE__ */ jsx19(Text18, { color: theme.error, children: error }),
14468
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14385
14469
  CustomTextInput,
14386
14470
  {
14387
14471
  value: name,
@@ -14390,11 +14474,11 @@ ${template}`;
14390
14474
  focus: true
14391
14475
  }
14392
14476
  ) }),
14393
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
14477
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
14394
14478
  ] });
14395
14479
  case "description":
14396
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14397
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14480
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14481
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14398
14482
  mode === "create" ? "Create" : "Edit",
14399
14483
  " custom command \u2014 Description (",
14400
14484
  stepIndex,
@@ -14402,7 +14486,7 @@ ${template}`;
14402
14486
  totalSteps,
14403
14487
  ")"
14404
14488
  ] }),
14405
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14489
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14406
14490
  CustomTextInput,
14407
14491
  {
14408
14492
  value: description,
@@ -14411,49 +14495,49 @@ ${template}`;
14411
14495
  focus: true
14412
14496
  }
14413
14497
  ) }),
14414
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Press Enter to skip" })
14498
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Press Enter to skip" })
14415
14499
  ] });
14416
14500
  case "template": {
14417
- const guide = /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingLeft: 1, children: [
14418
- /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "What is this?" }),
14419
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
14420
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
14501
+ const guide = /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", paddingLeft: 1, children: [
14502
+ /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "What is this?" }),
14503
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
14504
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.info.color, children: [
14421
14505
  "When you type /",
14422
14506
  name || "yourcommand",
14423
14507
  " later, this gets sent to the model."
14424
14508
  ] }),
14425
- /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
14426
- /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Variables" }),
14427
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
14509
+ /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
14510
+ /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Variables" }),
14511
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.info.color, children: [
14428
14512
  " ",
14429
14513
  "$1, $2 ... \u2192 arguments you type"
14430
14514
  ] }),
14431
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
14515
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.info.color, children: [
14432
14516
  " ",
14433
14517
  "$ARGUMENTS \u2192 everything after the command"
14434
14518
  ] })
14435
14519
  ] }),
14436
- /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
14437
- /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
14438
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
14520
+ /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
14521
+ /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
14522
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.info.color, children: [
14439
14523
  " ",
14440
14524
  "!`git diff` \u2192 shell output inlined"
14441
14525
  ] }),
14442
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
14526
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.info.color, children: [
14443
14527
  " ",
14444
14528
  "@README.md \u2192 file contents inlined"
14445
14529
  ] })
14446
14530
  ] }),
14447
- /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
14448
- /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Example" }),
14449
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Review this PR diff:" }),
14450
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
14451
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Focus on: $1" })
14531
+ /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
14532
+ /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Example" }),
14533
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Review this PR diff:" }),
14534
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
14535
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Focus on: $1" })
14452
14536
  ] })
14453
14537
  ] });
14454
- const inputArea = /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", flexGrow: 1, children: [
14455
- error && /* @__PURE__ */ jsx18(Text17, { color: theme.error, children: error }),
14456
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14538
+ const inputArea = /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", flexGrow: 1, children: [
14539
+ error && /* @__PURE__ */ jsx19(Text18, { color: theme.error, children: error }),
14540
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14457
14541
  CustomTextInput,
14458
14542
  {
14459
14543
  value: template,
@@ -14463,13 +14547,13 @@ ${template}`;
14463
14547
  enablePaste: true
14464
14548
  }
14465
14549
  ) }),
14466
- columns < 100 && /* @__PURE__ */ jsxs16(Fragment2, { children: [
14467
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
14468
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
14550
+ columns < 100 && /* @__PURE__ */ jsxs17(Fragment2, { children: [
14551
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
14552
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
14469
14553
  ] })
14470
14554
  ] });
14471
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14472
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14555
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14556
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14473
14557
  mode === "create" ? "Create" : "Edit",
14474
14558
  " custom command \u2014 Template (",
14475
14559
  stepIndex,
@@ -14477,10 +14561,10 @@ ${template}`;
14477
14561
  totalSteps,
14478
14562
  ")"
14479
14563
  ] }),
14480
- columns >= 100 ? /* @__PURE__ */ jsxs16(Box16, { flexDirection: "row", marginTop: 1, children: [
14481
- /* @__PURE__ */ jsx18(Box16, { flexDirection: "column", width: "50%", children: inputArea }),
14482
- /* @__PURE__ */ jsx18(Box16, { flexDirection: "column", width: "50%", children: guide })
14483
- ] }) : /* @__PURE__ */ jsx18(Box16, { flexDirection: "column", marginTop: 1, children: inputArea })
14564
+ columns >= 100 ? /* @__PURE__ */ jsxs17(Box17, { flexDirection: "row", marginTop: 1, children: [
14565
+ /* @__PURE__ */ jsx19(Box17, { flexDirection: "column", width: "50%", children: inputArea }),
14566
+ /* @__PURE__ */ jsx19(Box17, { flexDirection: "column", width: "50%", children: guide })
14567
+ ] }) : /* @__PURE__ */ jsx19(Box17, { flexDirection: "column", marginTop: 1, children: inputArea })
14484
14568
  ] });
14485
14569
  }
14486
14570
  case "advanced": {
@@ -14489,8 +14573,8 @@ ${template}`;
14489
14573
  { label: "Skip", value: "skip", key: "skip" },
14490
14574
  { label: "\u2190 Cancel", value: "cancel", key: "cancel" }
14491
14575
  ];
14492
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14493
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14576
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14577
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14494
14578
  mode === "create" ? "Create" : "Edit",
14495
14579
  " custom command \u2014 Options (",
14496
14580
  stepIndex,
@@ -14498,7 +14582,7 @@ ${template}`;
14498
14582
  totalSteps,
14499
14583
  ")"
14500
14584
  ] }),
14501
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14585
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14502
14586
  SelectInput6,
14503
14587
  {
14504
14588
  items,
@@ -14518,16 +14602,16 @@ ${template}`;
14518
14602
  { label: cmdMode === "auto" ? "auto \xB7 current" : "auto", value: "auto", key: "auto" },
14519
14603
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
14520
14604
  ];
14521
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14522
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14605
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14606
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14523
14607
  "Mode override (",
14524
14608
  stepIndex,
14525
14609
  "/",
14526
14610
  totalSteps,
14527
14611
  ")"
14528
14612
  ] }),
14529
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
14530
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14613
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
14614
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14531
14615
  SelectInput6,
14532
14616
  {
14533
14617
  items,
@@ -14547,15 +14631,15 @@ ${template}`;
14547
14631
  { label: cmdEffort === "high" ? "high \xB7 current" : "high", value: "high", key: "high" },
14548
14632
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
14549
14633
  ];
14550
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14551
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14634
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14635
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14552
14636
  "Reasoning effort (",
14553
14637
  stepIndex,
14554
14638
  "/",
14555
14639
  totalSteps,
14556
14640
  ")"
14557
14641
  ] }),
14558
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14642
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14559
14643
  SelectInput6,
14560
14644
  {
14561
14645
  items,
@@ -14568,15 +14652,15 @@ ${template}`;
14568
14652
  ] });
14569
14653
  }
14570
14654
  case "model":
14571
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14572
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14655
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14656
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14573
14657
  "Model override (",
14574
14658
  stepIndex,
14575
14659
  "/",
14576
14660
  totalSteps,
14577
14661
  ")"
14578
14662
  ] }),
14579
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14663
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14580
14664
  CustomTextInput,
14581
14665
  {
14582
14666
  value: cmdModel ?? "",
@@ -14585,7 +14669,7 @@ ${template}`;
14585
14669
  focus: true
14586
14670
  }
14587
14671
  ) }),
14588
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Press Enter to skip" })
14672
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Press Enter to skip" })
14589
14673
  ] });
14590
14674
  case "location": {
14591
14675
  const items = [
@@ -14593,15 +14677,15 @@ ${template}`;
14593
14677
  { label: source === "global" ? "Global \xB7 current" : "Global", value: "global", key: "global" },
14594
14678
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
14595
14679
  ];
14596
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14597
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14680
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14681
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14598
14682
  "Save location (",
14599
14683
  stepIndex,
14600
14684
  "/",
14601
14685
  totalSteps,
14602
14686
  ")"
14603
14687
  ] }),
14604
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14688
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14605
14689
  SelectInput6,
14606
14690
  {
14607
14691
  items,
@@ -14611,7 +14695,7 @@ ${template}`;
14611
14695
  }
14612
14696
  }
14613
14697
  ) }),
14614
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
14698
+ /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
14615
14699
  ] });
14616
14700
  }
14617
14701
  case "confirm": {
@@ -14619,8 +14703,8 @@ ${template}`;
14619
14703
  { label: "Save", value: "save", key: "save" },
14620
14704
  { label: "Cancel", value: "cancel", key: "cancel" }
14621
14705
  ];
14622
- return /* @__PURE__ */ jsxs16(Fragment2, { children: [
14623
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
14706
+ return /* @__PURE__ */ jsxs17(Fragment2, { children: [
14707
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
14624
14708
  mode === "create" ? "Create" : "Edit",
14625
14709
  " custom command \u2014 Confirm (",
14626
14710
  stepIndex,
@@ -14628,13 +14712,13 @@ ${template}`;
14628
14712
  totalSteps,
14629
14713
  ")"
14630
14714
  ] }),
14631
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
14715
+ /* @__PURE__ */ jsxs17(Text18, { color: theme.info.color, children: [
14632
14716
  source === "project" ? ".kimiflare/commands/" : "~/.config/kimiflare/commands/",
14633
14717
  name,
14634
14718
  ".md"
14635
14719
  ] }),
14636
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: line || " " }, i)) }),
14637
- /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
14720
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: line || " " }, i)) }),
14721
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
14638
14722
  SelectInput6,
14639
14723
  {
14640
14724
  items,
@@ -14645,7 +14729,7 @@ ${template}`;
14645
14729
  }
14646
14730
  }
14647
14731
  };
14648
- return /* @__PURE__ */ jsx18(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
14732
+ return /* @__PURE__ */ jsx19(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
14649
14733
  }
14650
14734
  var NAME_RE;
14651
14735
  var init_command_wizard = __esm({
@@ -15090,9 +15174,9 @@ var init_context_generator = __esm({
15090
15174
  });
15091
15175
 
15092
15176
  // src/ui/command-picker.tsx
15093
- import { Box as Box17, Text as Text18 } from "ink";
15177
+ import { Box as Box18, Text as Text19 } from "ink";
15094
15178
  import SelectInput7 from "ink-select-input";
15095
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
15179
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
15096
15180
  function CommandPicker({ commands, title, onPick }) {
15097
15181
  const theme = useTheme();
15098
15182
  const items = commands.map((cmd) => ({
@@ -15101,10 +15185,10 @@ function CommandPicker({ commands, title, onPick }) {
15101
15185
  key: cmd.name
15102
15186
  }));
15103
15187
  items.push({ label: "\u2190 Cancel", value: null, key: "__cancel__" });
15104
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15105
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: title }),
15106
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
15107
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
15188
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15189
+ /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: title }),
15190
+ /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
15191
+ /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
15108
15192
  SelectInput7,
15109
15193
  {
15110
15194
  items,
@@ -15127,8 +15211,8 @@ var init_command_picker = __esm({
15127
15211
  });
15128
15212
 
15129
15213
  // src/ui/command-list.tsx
15130
- import { Box as Box18, Text as Text19, useInput as useInput8 } from "ink";
15131
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
15214
+ import { Box as Box19, Text as Text20, useInput as useInput8 } from "ink";
15215
+ import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
15132
15216
  function CommandList({ commands, onDone }) {
15133
15217
  const theme = useTheme();
15134
15218
  useInput8((_input, key) => {
@@ -15136,55 +15220,55 @@ function CommandList({ commands, onDone }) {
15136
15220
  onDone();
15137
15221
  }
15138
15222
  });
15139
- return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15140
- /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: "Custom commands" }),
15141
- /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
15142
- /* @__PURE__ */ jsxs18(Box18, { marginTop: 1, flexDirection: "column", children: [
15143
- commands.length === 0 && /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, children: "No custom commands found." }),
15144
- commands.map((cmd) => /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginBottom: 1, children: [
15145
- /* @__PURE__ */ jsxs18(Text19, { color: theme.accent, bold: true, children: [
15223
+ return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15224
+ /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Custom commands" }),
15225
+ /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
15226
+ /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
15227
+ commands.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No custom commands found." }),
15228
+ commands.map((cmd) => /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginBottom: 1, children: [
15229
+ /* @__PURE__ */ jsxs19(Text20, { color: theme.accent, bold: true, children: [
15146
15230
  "/",
15147
15231
  cmd.name
15148
15232
  ] }),
15149
- /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15233
+ /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15150
15234
  " ",
15151
15235
  "source: ",
15152
15236
  cmd.source
15153
15237
  ] }),
15154
- /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15238
+ /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15155
15239
  " ",
15156
15240
  "path: ",
15157
15241
  cmd.filepath
15158
15242
  ] }),
15159
- cmd.description && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15243
+ cmd.description && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15160
15244
  " ",
15161
15245
  "desc: ",
15162
15246
  cmd.description
15163
15247
  ] }),
15164
- cmd.mode && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15248
+ cmd.mode && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15165
15249
  " ",
15166
15250
  "mode: ",
15167
15251
  cmd.mode
15168
15252
  ] }),
15169
- cmd.effort && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15253
+ cmd.effort && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15170
15254
  " ",
15171
15255
  "effort: ",
15172
15256
  cmd.effort
15173
15257
  ] }),
15174
- cmd.model && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15258
+ cmd.model && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15175
15259
  " ",
15176
15260
  "model: ",
15177
15261
  cmd.model
15178
15262
  ] }),
15179
- /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15263
+ /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15180
15264
  " ",
15181
15265
  "template:"
15182
15266
  ] }),
15183
- cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15267
+ cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15184
15268
  " ",
15185
15269
  line || " "
15186
15270
  ] }, i)),
15187
- cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
15271
+ cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
15188
15272
  " ",
15189
15273
  "..."
15190
15274
  ] })
@@ -15201,10 +15285,10 @@ var init_command_list = __esm({
15201
15285
 
15202
15286
  // src/ui/lsp-wizard.tsx
15203
15287
  import { useState as useState11 } from "react";
15204
- import { Box as Box19, Text as Text20 } from "ink";
15288
+ import { Box as Box20, Text as Text21 } from "ink";
15205
15289
  import SelectInput8 from "ink-select-input";
15206
15290
  import { spawn as spawn3 } from "child_process";
15207
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
15291
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
15208
15292
  function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15209
15293
  const theme = useTheme();
15210
15294
  const [page, setPage] = useState11("main");
@@ -15316,10 +15400,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15316
15400
  { label: "(close)", value: "__close__", key: "__close__" }
15317
15401
  ];
15318
15402
  if (page === "main") {
15319
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15320
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "LSP Servers" }),
15321
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
15322
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15403
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15404
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "LSP Servers" }),
15405
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
15406
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15323
15407
  SelectInput8,
15324
15408
  {
15325
15409
  items: mainItems,
@@ -15347,10 +15431,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15347
15431
  }),
15348
15432
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
15349
15433
  ];
15350
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15351
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Add LSP Server" }),
15352
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
15353
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15434
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15435
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Add LSP Server" }),
15436
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
15437
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15354
15438
  SelectInput8,
15355
15439
  {
15356
15440
  items,
@@ -15378,18 +15462,18 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15378
15462
  { label: isSuccess ? "Save to config \u2713" : "Save anyway", value: "save", key: "save" },
15379
15463
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
15380
15464
  ];
15381
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15382
- /* @__PURE__ */ jsxs19(Text20, { color: theme.accent, bold: true, children: [
15465
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15466
+ /* @__PURE__ */ jsxs20(Text21, { color: theme.accent, bold: true, children: [
15383
15467
  "Install ",
15384
15468
  selectedPreset.name
15385
15469
  ] }),
15386
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
15387
- /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
15388
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Command:" }),
15389
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
15470
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
15471
+ /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
15472
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Command:" }),
15473
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
15390
15474
  ] }),
15391
- installState.output && /* @__PURE__ */ jsx21(Box19, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx21(Text20, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
15392
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15475
+ installState.output && /* @__PURE__ */ jsx22(Box20, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx22(Text21, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
15476
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15393
15477
  SelectInput8,
15394
15478
  {
15395
15479
  items,
@@ -15407,16 +15491,16 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15407
15491
  }
15408
15492
  }
15409
15493
  ) }),
15410
- isSuccess && /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text20, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
15494
+ isSuccess && /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(Text21, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
15411
15495
  ] });
15412
15496
  }
15413
15497
  if (page === "custom-name") {
15414
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15415
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
15416
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
15417
- /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, children: [
15418
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, children: "\u203A " }),
15419
- /* @__PURE__ */ jsx21(
15498
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15499
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
15500
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
15501
+ /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, children: [
15502
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, children: "\u203A " }),
15503
+ /* @__PURE__ */ jsx22(
15420
15504
  CustomTextInput,
15421
15505
  {
15422
15506
  value: customName,
@@ -15430,7 +15514,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15430
15514
  }
15431
15515
  )
15432
15516
  ] }),
15433
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15517
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15434
15518
  SelectInput8,
15435
15519
  {
15436
15520
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
@@ -15440,12 +15524,12 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15440
15524
  ] });
15441
15525
  }
15442
15526
  if (page === "custom-command") {
15443
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15444
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
15445
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
15446
- /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, children: [
15447
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, children: "\u203A " }),
15448
- /* @__PURE__ */ jsx21(
15527
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15528
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
15529
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
15530
+ /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, children: [
15531
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, children: "\u203A " }),
15532
+ /* @__PURE__ */ jsx22(
15449
15533
  CustomTextInput,
15450
15534
  {
15451
15535
  value: customCommand,
@@ -15459,7 +15543,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15459
15543
  }
15460
15544
  )
15461
15545
  ] }),
15462
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15546
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15463
15547
  SelectInput8,
15464
15548
  {
15465
15549
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
@@ -15483,10 +15567,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15483
15567
  },
15484
15568
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
15485
15569
  ];
15486
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15487
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Save LSP Config" }),
15488
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
15489
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15570
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15571
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Save LSP Config" }),
15572
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
15573
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15490
15574
  SelectInput8,
15491
15575
  {
15492
15576
  items,
@@ -15505,10 +15589,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15505
15589
  if (page === "edit") {
15506
15590
  const keys = Object.keys(servers);
15507
15591
  if (keys.length === 0) {
15508
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15509
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
15510
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No servers configured." }),
15511
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15592
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15593
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
15594
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No servers configured." }),
15595
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15512
15596
  SelectInput8,
15513
15597
  {
15514
15598
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
@@ -15529,10 +15613,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15529
15613
  }),
15530
15614
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
15531
15615
  ];
15532
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15533
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
15534
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
15535
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15616
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15617
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
15618
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
15619
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15536
15620
  SelectInput8,
15537
15621
  {
15538
15622
  items,
@@ -15550,10 +15634,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15550
15634
  if (page === "delete") {
15551
15635
  const keys = Object.keys(servers);
15552
15636
  if (keys.length === 0) {
15553
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15554
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
15555
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No servers configured." }),
15556
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15637
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15638
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
15639
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No servers configured." }),
15640
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15557
15641
  SelectInput8,
15558
15642
  {
15559
15643
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
@@ -15570,10 +15654,10 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15570
15654
  })),
15571
15655
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
15572
15656
  ];
15573
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15574
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
15575
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
15576
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15657
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15658
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
15659
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
15660
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15577
15661
  SelectInput8,
15578
15662
  {
15579
15663
  items,
@@ -15590,14 +15674,14 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
15590
15674
  }
15591
15675
  if (page === "list") {
15592
15676
  const keys = Object.keys(servers);
15593
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15594
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
15595
- keys.length === 0 ? /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx21(Box19, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
15677
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
15678
+ /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
15679
+ keys.length === 0 ? /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx22(Box20, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
15596
15680
  const s = servers[k];
15597
15681
  const status = s.enabled !== false ? "enabled" : "disabled";
15598
- return /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
15682
+ return /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
15599
15683
  }) }),
15600
- /* @__PURE__ */ jsx21(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx21(
15684
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15601
15685
  SelectInput8,
15602
15686
  {
15603
15687
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
@@ -15725,9 +15809,9 @@ var init_lsp_wizard = __esm({
15725
15809
  });
15726
15810
 
15727
15811
  // src/ui/theme-picker.tsx
15728
- import { Box as Box20, Text as Text21 } from "ink";
15812
+ import { Box as Box21, Text as Text22 } from "ink";
15729
15813
  import SelectInput9 from "ink-select-input";
15730
- import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
15814
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
15731
15815
  function PaletteSwatches({ palette }) {
15732
15816
  const colors = [
15733
15817
  palette.primary,
@@ -15735,7 +15819,7 @@ function PaletteSwatches({ palette }) {
15735
15819
  palette.success,
15736
15820
  palette.error
15737
15821
  ];
15738
- return /* @__PURE__ */ jsx22(Box20, { children: colors.map((c, i) => /* @__PURE__ */ jsx22(Text21, { color: c, children: "\u2588" }, i)) });
15822
+ return /* @__PURE__ */ jsx23(Box21, { children: colors.map((c, i) => /* @__PURE__ */ jsx23(Text22, { color: c, children: "\u2588" }, i)) });
15739
15823
  }
15740
15824
  function ThemePicker({ themes, onPick }) {
15741
15825
  const current = useTheme();
@@ -15743,9 +15827,9 @@ function ThemePicker({ themes, onPick }) {
15743
15827
  ...themes.map((t) => ({ label: t.label, value: t.name })),
15744
15828
  { label: "< Back", value: "__back__" }
15745
15829
  ];
15746
- return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
15747
- /* @__PURE__ */ jsx22(Text21, { color: current.accent, bold: true, children: "Pick a theme (restart to apply)" }),
15748
- /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
15830
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
15831
+ /* @__PURE__ */ jsx23(Text22, { color: current.accent, bold: true, children: "Pick a theme (restart to apply)" }),
15832
+ /* @__PURE__ */ jsx23(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx23(
15749
15833
  SelectInput9,
15750
15834
  {
15751
15835
  items,
@@ -15760,9 +15844,9 @@ function ThemePicker({ themes, onPick }) {
15760
15844
  itemComponent: ({ label, isSelected }) => {
15761
15845
  const t = themes.find((x) => x.label === label);
15762
15846
  const color = t?.accent ?? current.accent;
15763
- return /* @__PURE__ */ jsxs20(Box20, { children: [
15764
- /* @__PURE__ */ jsx22(Text21, { color, bold: isSelected, dimColor: !isSelected, children: label }),
15765
- t && /* @__PURE__ */ jsx22(Box20, { marginLeft: 1, children: /* @__PURE__ */ jsx22(PaletteSwatches, { palette: t.palette }) })
15847
+ return /* @__PURE__ */ jsxs21(Box21, { children: [
15848
+ /* @__PURE__ */ jsx23(Text22, { color, bold: isSelected, dimColor: !isSelected, children: label }),
15849
+ t && /* @__PURE__ */ jsx23(Box21, { marginLeft: 1, children: /* @__PURE__ */ jsx23(PaletteSwatches, { palette: t.palette }) })
15766
15850
  ] });
15767
15851
  }
15768
15852
  }
@@ -16949,8 +17033,8 @@ var init_lsp_nudge = __esm({
16949
17033
  });
16950
17034
 
16951
17035
  // src/ui/file-picker.tsx
16952
- import { Box as Box21, Text as Text22 } from "ink";
16953
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
17036
+ import { Box as Box22, Text as Text23 } from "ink";
17037
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
16954
17038
  function FilePicker({ items, selectedIndex, query, recentFiles }) {
16955
17039
  const theme = useTheme();
16956
17040
  let startIndex = 0;
@@ -16962,12 +17046,12 @@ function FilePicker({ items, selectedIndex, query, recentFiles }) {
16962
17046
  const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT;
16963
17047
  const recentInVisible = visible.filter((item) => recentFiles?.has(item.name)).length;
16964
17048
  const hasRecentSection = recentInVisible > 0;
16965
- return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
16966
- /* @__PURE__ */ jsx23(Text22, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
16967
- /* @__PURE__ */ jsx23(Text22, { color: theme.info.color, dimColor: true, children: "\u2191\u2193 navigate \xB7 Enter pick \xB7 Esc cancel" }),
16968
- /* @__PURE__ */ jsxs21(Box21, { marginTop: 1, flexDirection: "column", children: [
16969
- visible.length === 0 && /* @__PURE__ */ jsx23(Text22, { color: theme.info.color, children: "No matches" }),
16970
- hasMoreAbove && /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, dimColor: true, children: [
17049
+ return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
17050
+ /* @__PURE__ */ jsx24(Text23, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
17051
+ /* @__PURE__ */ jsx24(Text23, { color: theme.info.color, dimColor: true, children: "\u2191\u2193 navigate \xB7 Enter pick \xB7 Esc cancel" }),
17052
+ /* @__PURE__ */ jsxs22(Box22, { marginTop: 1, flexDirection: "column", children: [
17053
+ visible.length === 0 && /* @__PURE__ */ jsx24(Text23, { color: theme.info.color, children: "No matches" }),
17054
+ hasMoreAbove && /* @__PURE__ */ jsxs22(Text23, { color: theme.info.color, dimColor: true, children: [
16971
17055
  "\u2026 ",
16972
17056
  startIndex,
16973
17057
  " more above"
@@ -16979,28 +17063,28 @@ function FilePicker({ items, selectedIndex, query, recentFiles }) {
16979
17063
  const label = item.isDirectory ? `${item.name}/` : item.name;
16980
17064
  const isFirstRecent = isRecent && (i === 0 || !recentFiles?.has(visible[i - 1]?.name ?? ""));
16981
17065
  const isFirstNonRecentAfterRecent = !isRecent && (i > 0 && recentFiles?.has(visible[i - 1]?.name ?? ""));
16982
- return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16983
- hasRecentSection && isFirstRecent && /* @__PURE__ */ jsxs21(Text22, { color: theme.palette.success, bold: true, children: [
17066
+ return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
17067
+ hasRecentSection && isFirstRecent && /* @__PURE__ */ jsxs22(Text23, { color: theme.palette.success, bold: true, children: [
16984
17068
  " ",
16985
17069
  "Recent"
16986
17070
  ] }),
16987
- hasRecentSection && isFirstNonRecentAfterRecent && /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, dimColor: true, children: [
17071
+ hasRecentSection && isFirstNonRecentAfterRecent && /* @__PURE__ */ jsxs22(Text23, { color: theme.info.color, dimColor: true, children: [
16988
17072
  " ",
16989
17073
  "All files"
16990
17074
  ] }),
16991
- /* @__PURE__ */ jsxs21(Text22, { color: isSelected ? theme.accent : isRecent ? theme.palette.success : void 0, bold: isSelected || isRecent, children: [
17075
+ /* @__PURE__ */ jsxs22(Text23, { color: isSelected ? theme.accent : isRecent ? theme.palette.success : void 0, bold: isSelected || isRecent, children: [
16992
17076
  isSelected ? "\u203A " : isRecent ? "\u2192 " : " ",
16993
17077
  isRecent ? "\u21BB " : "",
16994
17078
  label
16995
17079
  ] })
16996
17080
  ] }, item.name);
16997
17081
  }),
16998
- hasMoreBelow && /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, dimColor: true, children: [
17082
+ hasMoreBelow && /* @__PURE__ */ jsxs22(Text23, { color: theme.info.color, dimColor: true, children: [
16999
17083
  "\u2026 ",
17000
17084
  items.length - (startIndex + VISIBLE_LIMIT),
17001
17085
  " more below"
17002
17086
  ] }),
17003
- hasRecentSection && /* @__PURE__ */ jsx23(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx23(Text22, { color: theme.info.color, dimColor: true, children: "\u21BB = recently used" }) })
17087
+ hasRecentSection && /* @__PURE__ */ jsx24(Box22, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text23, { color: theme.info.color, dimColor: true, children: "\u21BB = recently used" }) })
17004
17088
  ] })
17005
17089
  ] });
17006
17090
  }
@@ -17014,8 +17098,8 @@ var init_file_picker = __esm({
17014
17098
  });
17015
17099
 
17016
17100
  // src/ui/slash-picker.tsx
17017
- import { Box as Box22, Text as Text23 } from "ink";
17018
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
17101
+ import { Box as Box23, Text as Text24 } from "ink";
17102
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
17019
17103
  function sourceBadge(source) {
17020
17104
  if (source === "builtin") return "";
17021
17105
  if (source === "project") return "project";
@@ -17035,12 +17119,12 @@ function SlashPicker({ items, selectedIndex, query }) {
17035
17119
  const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT2;
17036
17120
  const longestLabel = visible.reduce((m, it) => Math.max(m, commandLabel(it).length), 0);
17037
17121
  const nameColWidth = Math.max(NAME_COL_MIN_WIDTH, longestLabel + NAME_DESC_GAP);
17038
- return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
17039
- /* @__PURE__ */ jsx24(Text23, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
17040
- /* @__PURE__ */ jsx24(Text23, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
17041
- /* @__PURE__ */ jsxs22(Box22, { marginTop: 1, flexDirection: "column", children: [
17042
- visible.length === 0 && /* @__PURE__ */ jsx24(Text23, { color: theme.info.color, children: "No matches" }),
17043
- hasMoreAbove && /* @__PURE__ */ jsxs22(Text23, { color: theme.info.color, children: [
17122
+ return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
17123
+ /* @__PURE__ */ jsx25(Text24, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
17124
+ /* @__PURE__ */ jsx25(Text24, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
17125
+ /* @__PURE__ */ jsxs23(Box23, { marginTop: 1, flexDirection: "column", children: [
17126
+ visible.length === 0 && /* @__PURE__ */ jsx25(Text24, { color: theme.info.color, children: "No matches" }),
17127
+ hasMoreAbove && /* @__PURE__ */ jsxs23(Text24, { color: theme.info.color, children: [
17044
17128
  "\u2026 ",
17045
17129
  startIndex,
17046
17130
  " more above"
@@ -17050,16 +17134,16 @@ function SlashPicker({ items, selectedIndex, query }) {
17050
17134
  const isSelected = actualIndex === selectedIndex;
17051
17135
  const nameCol = commandLabel(item).padEnd(nameColWidth);
17052
17136
  const badge = sourceBadge(item.source);
17053
- return /* @__PURE__ */ jsxs22(Text23, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
17137
+ return /* @__PURE__ */ jsxs23(Text24, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
17054
17138
  isSelected ? "\u203A " : " ",
17055
17139
  nameCol,
17056
- /* @__PURE__ */ jsxs22(Text23, { color: theme.info.color, children: [
17140
+ /* @__PURE__ */ jsxs23(Text24, { color: theme.info.color, children: [
17057
17141
  item.description,
17058
17142
  badge && ` [${badge}]`
17059
17143
  ] })
17060
17144
  ] }, item.name);
17061
17145
  }),
17062
- hasMoreBelow && /* @__PURE__ */ jsxs22(Text23, { color: theme.info.color, children: [
17146
+ hasMoreBelow && /* @__PURE__ */ jsxs23(Text24, { color: theme.info.color, children: [
17063
17147
  "\u2026 ",
17064
17148
  items.length - (startIndex + VISIBLE_LIMIT2),
17065
17149
  " more below"
@@ -17170,7 +17254,7 @@ __export(app_exports, {
17170
17254
  shouldOpenSlashPicker: () => shouldOpenSlashPicker
17171
17255
  });
17172
17256
  import React15, { useState as useState12, useRef as useRef3, useEffect as useEffect7, useCallback as useCallback3 } from "react";
17173
- import { Box as Box23, Text as Text24, useApp, useInput as useInput9, render } from "ink";
17257
+ import { Box as Box24, Text as Text25, useApp, useInput as useInput9, render } from "ink";
17174
17258
  import SelectInput10 from "ink-select-input";
17175
17259
  import { existsSync as existsSync4, statSync as statSync4 } from "fs";
17176
17260
  import { join as join28 } from "path";
@@ -17180,7 +17264,7 @@ import { spawn as spawn4 } from "child_process";
17180
17264
  import { platform as platform4 } from "os";
17181
17265
  import fg4 from "fast-glob";
17182
17266
  import { readFileSync as readFileSync3 } from "fs";
17183
- import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
17267
+ import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
17184
17268
  function buildFilePickerIgnoreList(cwd) {
17185
17269
  const hardcoded = [
17186
17270
  // Dependencies
@@ -17453,6 +17537,7 @@ function App({
17453
17537
  const [showReasoning, setShowReasoning] = useState12(false);
17454
17538
  const [perm, setPerm] = useState12(null);
17455
17539
  const [limitModal, setLimitModal] = useState12(null);
17540
+ const [loopModal, setLoopModal] = useState12(null);
17456
17541
  const [queue, setQueue] = useState12([]);
17457
17542
  const [history, setHistory] = useState12([]);
17458
17543
  const [historyIndex, setHistoryIndex] = useState12(-1);
@@ -17545,10 +17630,21 @@ ${wcagWarnings.join("\n")}` }
17545
17630
  if (!cfg?.cloudMode || !initialCloudToken) return;
17546
17631
  let cancelled = false;
17547
17632
  const fetchBudget = async () => {
17548
- const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
17549
- const usage2 = await fetchCloudUsage2(initialCloudToken, cloudDeviceId ?? initialCloudDeviceId);
17550
- if (usage2 && !cancelled) {
17551
- setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
17633
+ try {
17634
+ const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
17635
+ const usage2 = await fetchCloudUsage2(initialCloudToken, cloudDeviceId ?? initialCloudDeviceId);
17636
+ if (usage2 && !cancelled) {
17637
+ setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
17638
+ }
17639
+ } catch (err) {
17640
+ if (isKillSwitchError(err) && !cancelled) {
17641
+ setCloudToken(void 0);
17642
+ setCloudDeviceId(void 0);
17643
+ setEvents((es) => [
17644
+ ...es,
17645
+ { kind: "service_ended", key: mkKey(), endedAt: err.endedAt }
17646
+ ]);
17647
+ }
17552
17648
  }
17553
17649
  };
17554
17650
  fetchBudget();
@@ -17575,6 +17671,7 @@ ${wcagWarnings.join("\n")}` }
17575
17671
  const sigintHandlerRef = useRef3(null);
17576
17672
  const permResolveRef = useRef3(null);
17577
17673
  const limitResolveRef = useRef3(null);
17674
+ const loopResolveRef = useRef3(null);
17578
17675
  const pendingToolCallsRef = useRef3(/* @__PURE__ */ new Map());
17579
17676
  const sessionIdRef = useRef3(null);
17580
17677
  const sessionCreatedAtRef = useRef3(null);
@@ -17753,7 +17850,7 @@ ${wcagWarnings.join("\n")}` }
17753
17850
  setActivePicker(null);
17754
17851
  }, [cursorOffset]);
17755
17852
  useEffect7(() => {
17756
- const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || checkpointSession !== null || perm !== null || limitModal !== null;
17853
+ const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || checkpointSession !== null || perm !== null || limitModal !== null || loopModal !== null;
17757
17854
  if (modalActive && activePicker !== null) {
17758
17855
  setActivePicker(null);
17759
17856
  }
@@ -17766,6 +17863,7 @@ ${wcagWarnings.join("\n")}` }
17766
17863
  resumeSessions,
17767
17864
  perm,
17768
17865
  limitModal,
17866
+ loopModal,
17769
17867
  activePicker
17770
17868
  ]);
17771
17869
  useEffect7(() => {
@@ -18292,6 +18390,7 @@ ${wcagWarnings.join("\n")}` }
18292
18390
  });
18293
18391
  const hadPerm = permResolveRef.current !== null;
18294
18392
  const hadLimit = limitResolveRef.current !== null;
18393
+ const hadLoop = loopResolveRef.current !== null;
18295
18394
  if (hadPerm) {
18296
18395
  permResolveRef.current("deny");
18297
18396
  permResolveRef.current = null;
@@ -18302,6 +18401,11 @@ ${wcagWarnings.join("\n")}` }
18302
18401
  limitResolveRef.current = null;
18303
18402
  setLimitModal(null);
18304
18403
  }
18404
+ if (hadLoop) {
18405
+ loopResolveRef.current("stop");
18406
+ loopResolveRef.current = null;
18407
+ setLoopModal(null);
18408
+ }
18305
18409
  if (busyRef.current && activeScopeRef.current && !isAbortingRef.current) {
18306
18410
  isAbortingRef.current = true;
18307
18411
  supervisorRef.current.killTurn();
@@ -18316,7 +18420,7 @@ ${wcagWarnings.join("\n")}` }
18316
18420
  setTasksStartedAt(null);
18317
18421
  setTasksStartTokens(0);
18318
18422
  tasksRef.current = [];
18319
- } else if (!hadPerm && !hadLimit) {
18423
+ } else if (!hadPerm && !hadLimit && !hadLoop) {
18320
18424
  logger.info("input:ctrl+c:exiting");
18321
18425
  void lspManagerRef.current.stopAll().finally(() => exit());
18322
18426
  }
@@ -18324,7 +18428,7 @@ ${wcagWarnings.join("\n")}` }
18324
18428
  }
18325
18429
  if (key.escape) {
18326
18430
  const now2 = Date.now();
18327
- const modalOpen = perm !== null || limitModal !== null || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null || checkpointSession !== null || showThemePicker;
18431
+ const modalOpen = perm !== null || limitModal !== null || loopModal !== null || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null || checkpointSession !== null || showThemePicker;
18328
18432
  if (!modalOpen && busyRef.current && activeScopeRef.current && !isAbortingRef.current && now2 - lastEscapeAtRef.current > 500) {
18329
18433
  lastEscapeAtRef.current = now2;
18330
18434
  isAbortingRef.current = true;
@@ -18339,6 +18443,11 @@ ${wcagWarnings.join("\n")}` }
18339
18443
  limitResolveRef.current = null;
18340
18444
  setLimitModal(null);
18341
18445
  }
18446
+ if (loopResolveRef.current) {
18447
+ loopResolveRef.current("stop");
18448
+ loopResolveRef.current = null;
18449
+ setLoopModal(null);
18450
+ }
18342
18451
  activeScopeRef.current.abort("user_stopped");
18343
18452
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
18344
18453
  for (const [toolId] of pendingToolCallsRef.current) {
@@ -18371,10 +18480,12 @@ ${wcagWarnings.join("\n")}` }
18371
18480
  hasActiveScope: activeScopeRef.current !== null,
18372
18481
  isAborting: isAbortingRef.current,
18373
18482
  hasPerm: permResolveRef.current !== null,
18374
- hasLimit: limitResolveRef.current !== null
18483
+ hasLimit: limitResolveRef.current !== null,
18484
+ hasLoop: loopResolveRef.current !== null
18375
18485
  });
18376
18486
  const hadPerm = permResolveRef.current !== null;
18377
18487
  const hadLimit = limitResolveRef.current !== null;
18488
+ const hadLoop = loopResolveRef.current !== null;
18378
18489
  if (hadPerm) {
18379
18490
  permResolveRef.current("deny");
18380
18491
  permResolveRef.current = null;
@@ -18385,6 +18496,11 @@ ${wcagWarnings.join("\n")}` }
18385
18496
  limitResolveRef.current = null;
18386
18497
  setLimitModal(null);
18387
18498
  }
18499
+ if (hadLoop) {
18500
+ loopResolveRef.current("stop");
18501
+ loopResolveRef.current = null;
18502
+ setLoopModal(null);
18503
+ }
18388
18504
  if (busyRef.current && activeScopeRef.current && !isAbortingRef.current) {
18389
18505
  isAbortingRef.current = true;
18390
18506
  supervisorRef.current.killTurn();
@@ -18704,10 +18820,21 @@ ${wcagWarnings.join("\n")}` }
18704
18820
  const token = cloudToken ?? initialCloudToken;
18705
18821
  const did = cloudDeviceId ?? initialCloudDeviceId;
18706
18822
  void (async () => {
18707
- const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
18708
- const usage2 = await fetchCloudUsage2(token, did);
18709
- if (usage2) {
18710
- setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
18823
+ try {
18824
+ const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
18825
+ const usage2 = await fetchCloudUsage2(token, did);
18826
+ if (usage2) {
18827
+ setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
18828
+ }
18829
+ } catch (err) {
18830
+ if (isKillSwitchError(err)) {
18831
+ setCloudToken(void 0);
18832
+ setCloudDeviceId(void 0);
18833
+ setEvents((es) => [
18834
+ ...es,
18835
+ { kind: "service_ended", key: mkKey(), endedAt: err.endedAt }
18836
+ ]);
18837
+ }
18711
18838
  }
18712
18839
  })();
18713
18840
  }
@@ -18797,6 +18924,13 @@ ${wcagWarnings.join("\n")}` }
18797
18924
  setEvents(
18798
18925
  (evts) => evts.map((e2) => e2.kind === "tool" && e2.status === "running" ? { ...e2, status: "error", result: "(stopped)" } : e2)
18799
18926
  );
18927
+ } else if (isKillSwitchError(e)) {
18928
+ setCloudToken(void 0);
18929
+ setCloudDeviceId(void 0);
18930
+ setEvents((es) => [
18931
+ ...es,
18932
+ { kind: "service_ended", key: mkKey(), endedAt: e.endedAt }
18933
+ ]);
18800
18934
  } else if (cfg?.cloudMode && isCloudQuotaExhaustedError(e)) {
18801
18935
  const token = cloudToken ?? initialCloudToken;
18802
18936
  const did = cloudDeviceId ?? initialCloudDeviceId;
@@ -18861,6 +18995,8 @@ ${wcagWarnings.join("\n")}` }
18861
18995
  isAbortingRef.current = false;
18862
18996
  permResolveRef.current = null;
18863
18997
  limitResolveRef.current = null;
18998
+ loopResolveRef.current = null;
18999
+ setLoopModal(null);
18864
19000
  pendingToolCallsRef.current.clear();
18865
19001
  }
18866
19002
  }, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
@@ -20231,10 +20367,21 @@ ${lines.join("\n")}` }]);
20231
20367
  const token = cloudToken ?? initialCloudToken;
20232
20368
  const did = cloudDeviceId ?? initialCloudDeviceId;
20233
20369
  void (async () => {
20234
- const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
20235
- const usage2 = await fetchCloudUsage2(token, did);
20236
- if (usage2) {
20237
- setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
20370
+ try {
20371
+ const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
20372
+ const usage2 = await fetchCloudUsage2(token, did);
20373
+ if (usage2) {
20374
+ setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
20375
+ }
20376
+ } catch (err) {
20377
+ if (isKillSwitchError(err)) {
20378
+ setCloudToken(void 0);
20379
+ setCloudDeviceId(void 0);
20380
+ setEvents((es) => [
20381
+ ...es,
20382
+ { kind: "service_ended", key: mkKey(), endedAt: err.endedAt }
20383
+ ]);
20384
+ }
20238
20385
  }
20239
20386
  })();
20240
20387
  }
@@ -20282,6 +20429,10 @@ ${lines.join("\n")}` }]);
20282
20429
  limitResolveRef.current = resolve3;
20283
20430
  setLimitModal({ limit: 50, resolve: resolve3 });
20284
20431
  }),
20432
+ onLoopDetected: () => new Promise((resolve3) => {
20433
+ loopResolveRef.current = resolve3;
20434
+ setLoopModal({ resolve: resolve3 });
20435
+ }),
20285
20436
  onKimiMdStale: () => {
20286
20437
  if (!kimiMdStaleNudgedRef.current) {
20287
20438
  kimiMdStaleNudgedRef.current = true;
@@ -20309,6 +20460,8 @@ ${lines.join("\n")}` }]);
20309
20460
  isAbortingRef.current = false;
20310
20461
  permResolveRef.current = null;
20311
20462
  limitResolveRef.current = null;
20463
+ loopResolveRef.current = null;
20464
+ setLoopModal(null);
20312
20465
  pendingToolCallsRef.current.clear();
20313
20466
  setTasks([]);
20314
20467
  setTasksStartedAt(null);
@@ -20456,6 +20609,13 @@ ${lines.join("\n")}` }]);
20456
20609
  setEvents(
20457
20610
  (evts) => evts.map((e2) => e2.kind === "tool" && e2.status === "running" ? { ...e2, status: "error", result: "(stopped)" } : e2)
20458
20611
  );
20612
+ } else if (isKillSwitchError(e)) {
20613
+ setCloudToken(void 0);
20614
+ setCloudDeviceId(void 0);
20615
+ setEvents((es) => [
20616
+ ...es,
20617
+ { kind: "service_ended", key: mkKey(), endedAt: e.endedAt }
20618
+ ]);
20459
20619
  } else if (cfg?.cloudMode && isCloudQuotaExhaustedError(e)) {
20460
20620
  const token = cloudToken ?? initialCloudToken;
20461
20621
  const did = cloudDeviceId ?? initialCloudDeviceId;
@@ -20551,7 +20711,7 @@ ${lines.join("\n")}` }]);
20551
20711
  }
20552
20712
  }, [usage]);
20553
20713
  if (!cfg) {
20554
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(
20714
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(
20555
20715
  Onboarding,
20556
20716
  {
20557
20717
  onCancel: () => exit(),
@@ -20583,7 +20743,7 @@ ${lines.join("\n")}` }]);
20583
20743
  ) });
20584
20744
  }
20585
20745
  if (checkpointSession !== null) {
20586
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(
20746
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(
20587
20747
  CheckpointPicker,
20588
20748
  {
20589
20749
  session: checkpointSession,
@@ -20593,10 +20753,10 @@ ${lines.join("\n")}` }]);
20593
20753
  ) }) });
20594
20754
  }
20595
20755
  if (resumeSessions !== null) {
20596
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
20756
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
20597
20757
  }
20598
20758
  if (showRemoteDashboard) {
20599
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx25(
20759
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx26(
20600
20760
  RemoteSessionDetail,
20601
20761
  {
20602
20762
  session: selectedRemoteSession,
@@ -20619,7 +20779,7 @@ ${lines.join("\n")}` }]);
20619
20779
  setShowRemoteDashboard(false);
20620
20780
  }
20621
20781
  }
20622
- ) : /* @__PURE__ */ jsx25(
20782
+ ) : /* @__PURE__ */ jsx26(
20623
20783
  RemoteDashboard,
20624
20784
  {
20625
20785
  onSelect: (session) => setSelectedRemoteSession(session),
@@ -20628,7 +20788,7 @@ ${lines.join("\n")}` }]);
20628
20788
  ) }) });
20629
20789
  }
20630
20790
  if (showLspWizard) {
20631
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(
20791
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(
20632
20792
  LspWizard,
20633
20793
  {
20634
20794
  servers: cfg?.lspServers ?? {},
@@ -20665,7 +20825,7 @@ ${lines.join("\n")}` }]);
20665
20825
  ) }) });
20666
20826
  }
20667
20827
  if (commandWizard) {
20668
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(
20828
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(
20669
20829
  CommandWizard,
20670
20830
  {
20671
20831
  mode: commandWizard.mode,
@@ -20678,7 +20838,7 @@ ${lines.join("\n")}` }]);
20678
20838
  ) }) });
20679
20839
  }
20680
20840
  if (commandPicker) {
20681
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(
20841
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(
20682
20842
  CommandPicker,
20683
20843
  {
20684
20844
  commands: customCommandsRef.current,
@@ -20696,14 +20856,14 @@ ${lines.join("\n")}` }]);
20696
20856
  ) }) });
20697
20857
  }
20698
20858
  if (commandToDelete) {
20699
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
20700
- /* @__PURE__ */ jsxs23(Text24, { color: theme.accent, bold: true, children: [
20859
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
20860
+ /* @__PURE__ */ jsxs24(Text25, { color: theme.accent, bold: true, children: [
20701
20861
  "Delete /",
20702
20862
  commandToDelete.name,
20703
20863
  "?"
20704
20864
  ] }),
20705
- /* @__PURE__ */ jsx25(Text24, { color: theme.info.color, children: commandToDelete.filepath }),
20706
- /* @__PURE__ */ jsx25(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx25(
20865
+ /* @__PURE__ */ jsx26(Text25, { color: theme.info.color, children: commandToDelete.filepath }),
20866
+ /* @__PURE__ */ jsx26(Box24, { marginTop: 1, children: /* @__PURE__ */ jsx26(
20707
20867
  SelectInput10,
20708
20868
  {
20709
20869
  items: [
@@ -20722,7 +20882,7 @@ ${lines.join("\n")}` }]);
20722
20882
  ] }) });
20723
20883
  }
20724
20884
  if (showCommandList) {
20725
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(
20885
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(
20726
20886
  CommandList,
20727
20887
  {
20728
20888
  commands: customCommandsRef.current,
@@ -20731,12 +20891,12 @@ ${lines.join("\n")}` }]);
20731
20891
  ) }) });
20732
20892
  }
20733
20893
  if (showThemePicker) {
20734
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", children: /* @__PURE__ */ jsx25(ThemePicker, { themes: themeList(), onPick: handleThemePick }) }) });
20894
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", children: /* @__PURE__ */ jsx26(ThemePicker, { themes: themeList(), onPick: handleThemePick }) }) });
20735
20895
  }
20736
20896
  const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
20737
- return /* @__PURE__ */ jsx25(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", children: [
20738
- !hasConversation && events.length === 0 ? /* @__PURE__ */ jsx25(Welcome, {}) : /* @__PURE__ */ jsx25(ChatView, { events, showReasoning, verbose, intentTier: intentTier ?? void 0 }),
20739
- perm ? /* @__PURE__ */ jsx25(
20897
+ return /* @__PURE__ */ jsx26(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", children: [
20898
+ !hasConversation && events.length === 0 ? /* @__PURE__ */ jsx26(Welcome, {}) : /* @__PURE__ */ jsx26(ChatView, { events, showReasoning, verbose, intentTier: intentTier ?? void 0 }),
20899
+ perm ? /* @__PURE__ */ jsx26(
20740
20900
  PermissionModal,
20741
20901
  {
20742
20902
  tool: perm.tool,
@@ -20750,7 +20910,7 @@ ${lines.join("\n")}` }]);
20750
20910
  submitRef.current(text);
20751
20911
  }
20752
20912
  }
20753
- ) : limitModal ? /* @__PURE__ */ jsx25(
20913
+ ) : limitModal ? /* @__PURE__ */ jsx26(
20754
20914
  LimitModal,
20755
20915
  {
20756
20916
  limit: limitModal.limit,
@@ -20760,8 +20920,20 @@ ${lines.join("\n")}` }]);
20760
20920
  setLimitModal(null);
20761
20921
  }
20762
20922
  }
20763
- ) : /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", marginTop: 1, children: [
20764
- tasks.length > 0 && /* @__PURE__ */ jsx25(
20923
+ ) : loopModal ? /* @__PURE__ */ jsx26(
20924
+ LimitModal,
20925
+ {
20926
+ limit: 50,
20927
+ title: "Agent stuck in a loop",
20928
+ description: "The agent kept calling the same tools with identical arguments. What would you like to do?",
20929
+ onDecide: (d) => {
20930
+ loopModal.resolve(d);
20931
+ loopResolveRef.current = null;
20932
+ setLoopModal(null);
20933
+ }
20934
+ }
20935
+ ) : /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", marginTop: 1, children: [
20936
+ tasks.length > 0 && /* @__PURE__ */ jsx26(
20765
20937
  TaskList,
20766
20938
  {
20767
20939
  tasks,
@@ -20769,11 +20941,11 @@ ${lines.join("\n")}` }]);
20769
20941
  tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
20770
20942
  }
20771
20943
  ),
20772
- queue.length > 0 && /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs23(Text24, { color: theme.info.color, dimColor: theme.info.dim, children: [
20944
+ queue.length > 0 && /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs24(Text25, { color: theme.info.color, dimColor: theme.info.dim, children: [
20773
20945
  "\u23F3 ",
20774
20946
  q.display
20775
20947
  ] }, `queue_${i}`)) }),
20776
- /* @__PURE__ */ jsx25(
20948
+ /* @__PURE__ */ jsx26(
20777
20949
  StatusBar,
20778
20950
  {
20779
20951
  usage,
@@ -20796,7 +20968,7 @@ ${lines.join("\n")}` }]);
20796
20968
  intentTier: intentTier ?? void 0
20797
20969
  }
20798
20970
  ),
20799
- activePicker?.kind === "file" && /* @__PURE__ */ jsx25(
20971
+ activePicker?.kind === "file" && /* @__PURE__ */ jsx26(
20800
20972
  FilePicker,
20801
20973
  {
20802
20974
  items: filteredFileItems,
@@ -20805,7 +20977,7 @@ ${lines.join("\n")}` }]);
20805
20977
  recentFiles: new Set(recentFilesRef.current.keys())
20806
20978
  }
20807
20979
  ),
20808
- activePicker?.kind === "slash" && /* @__PURE__ */ jsx25(
20980
+ activePicker?.kind === "slash" && /* @__PURE__ */ jsx26(
20809
20981
  SlashPicker,
20810
20982
  {
20811
20983
  items: filteredSlashItems,
@@ -20813,9 +20985,9 @@ ${lines.join("\n")}` }]);
20813
20985
  query: pickerQuery ?? ""
20814
20986
  }
20815
20987
  ),
20816
- /* @__PURE__ */ jsxs23(Box23, { marginTop: 1, children: [
20817
- /* @__PURE__ */ jsx25(Text24, { color: theme.prompt ?? theme.accent, children: "\u203A " }),
20818
- /* @__PURE__ */ jsx25(
20988
+ /* @__PURE__ */ jsxs24(Box24, { marginTop: 1, children: [
20989
+ /* @__PURE__ */ jsx26(Text25, { color: theme.prompt ?? theme.accent, children: "\u203A " }),
20990
+ /* @__PURE__ */ jsx26(
20819
20991
  CustomTextInput,
20820
20992
  {
20821
20993
  value: input,
@@ -20872,7 +21044,7 @@ ${lines.join("\n")}` }]);
20872
21044
  }
20873
21045
  async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken, cloudDeviceId) {
20874
21046
  const instance = render(
20875
- /* @__PURE__ */ jsx25(
21047
+ /* @__PURE__ */ jsx26(
20876
21048
  App,
20877
21049
  {
20878
21050
  initialCfg: cfg,
@@ -21107,6 +21279,7 @@ program.command("usage").description("Show Kimiflare Cloud token usage (requires
21107
21279
  console.log(`Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
21108
21280
  console.log(`Used: ${usage.input_tokens_used.toLocaleString()}`);
21109
21281
  console.log(`Grant expires: ${usage.expires_at}`);
21282
+ console.log("Or when the global pool of free tokens runs out.");
21110
21283
  });
21111
21284
  program.addCommand(createRemoteCommand());
21112
21285
  program.command("auth").description("Authenticate with external services").addCommand(
@@ -21147,8 +21320,15 @@ Kimiflare Cloud Authentication`);
21147
21320
  console.log(`
21148
21321
  Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
21149
21322
  console.log(`Grant expires: ${usage.expires_at}`);
21323
+ console.log("Or when the global pool of free tokens runs out.");
21150
21324
  }
21151
21325
  } catch (err) {
21326
+ if (isKillSwitchError(err)) {
21327
+ console.error(
21328
+ "\nKimiFlare Cloud has reached its maximum budget across all users.\nThe free credits period has ended.\n\nTo continue using KimiFlare, switch to BYOK mode:\n \u2022 kimiflare config set-key <your-cloudflare-api-key>\n \u2022 kimiflare config set-account <your-account-id>\n \u2022 Or re-run kimiflare and select BYOK\n"
21329
+ );
21330
+ process.exit(0);
21331
+ }
21152
21332
  console.error("Authentication failed:", err instanceof Error ? err.message : String(err));
21153
21333
  process.exit(1);
21154
21334
  }
@@ -21187,8 +21367,19 @@ async function main() {
21187
21367
  }
21188
21368
  cloudToken = cloudCreds.accessToken;
21189
21369
  cloudDeviceId = cloudCreds.deviceId;
21370
+ try {
21371
+ const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
21372
+ await fetchCloudUsage2(cloudToken, cloudDeviceId);
21373
+ } catch (err) {
21374
+ if (isKillSwitchError(err)) {
21375
+ console.error(
21376
+ "\nKimiFlare Cloud has reached its maximum budget across all users.\nThe free credits period has ended.\n\nTo continue using KimiFlare, switch to BYOK mode:\n \u2022 kimiflare config set-key <your-cloudflare-api-key>\n \u2022 kimiflare config set-account <your-account-id>\n \u2022 Or re-run kimiflare and select BYOK\n"
21377
+ );
21378
+ process.exit(0);
21379
+ }
21380
+ }
21190
21381
  cfg = {
21191
- ...cfg ?? { accountId: "", apiToken: "", model: DEFAULT_MODEL, memoryEnabled: true },
21382
+ ...cfg ?? { accountId: "", apiToken: "", model: DEFAULT_MODEL, memoryEnabled: false },
21192
21383
  cloudMode: true
21193
21384
  };
21194
21385
  }
@@ -21334,6 +21525,13 @@ async function runPrintMode(opts2) {
21334
21525
  process.exitCode = 43;
21335
21526
  return;
21336
21527
  }
21528
+ if (isKillSwitchError(err)) {
21529
+ process.stderr.write(
21530
+ "\n\x1B[31m\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\u2551 KimiFlare Cloud has reached its maximum budget across \u2551\n\u2551 all users. The free credits period has ended. \u2551\n\u2551 \u2551\n\u2551 To continue using KimiFlare, switch to BYOK mode: \u2551\n\u2551 \u2022 kimiflare config set-key <your-cloudflare-api-key> \u2551\n\u2551 \u2022 kimiflare config set-account <your-account-id> \u2551\n\u2551 \u2022 Or re-run kimiflare and select BYOK \u2551\n\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n\x1B[0m\n"
21531
+ );
21532
+ process.exitCode = 0;
21533
+ return;
21534
+ }
21337
21535
  if (err instanceof KimiApiError) {
21338
21536
  process.stderr.write(`
21339
21537
  \x1B[31mError: ${humanizeCloudflareError(err)}\x1B[0m