kimiflare 0.42.0 → 0.44.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
@@ -1082,7 +1082,8 @@ async function logTurnDebug(ctx) {
1082
1082
  shadowStrip: ctx.shadowStrip,
1083
1083
  durationMs: ctx.durationMs,
1084
1084
  intentClassification: ctx.intentClassification,
1085
- codeMode: ctx.codeMode
1085
+ codeMode: ctx.codeMode,
1086
+ selectedSkills: ctx.selectedSkills?.map((s) => s.name)
1086
1087
  });
1087
1088
  }
1088
1089
  var LOG_VERSION;
@@ -2316,7 +2317,8 @@ ${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
2316
2317
  shadowStrip: shadowStripMetrics,
2317
2318
  durationMs: Math.round(performance.now() - turnStart),
2318
2319
  intentClassification: opts2.intentClassification,
2319
- codeMode: opts2.codeMode
2320
+ codeMode: opts2.codeMode,
2321
+ selectedSkills: opts2.selectedSkills
2320
2322
  });
2321
2323
  }
2322
2324
  if (budgetExhausted) {
@@ -2636,7 +2638,12 @@ ${toolsBlock}`;
2636
2638
  Project context from ${ctx.name} (${ctx.lineCount} lines, treat as authoritative):
2637
2639
  ${ctx.content.trim()}` : "";
2638
2640
  const modeBlock = opts2.mode ? systemPromptForMode(opts2.mode) : "";
2639
- return env2 + "\n\n" + tools + lspBlock + contextBlock + modeBlock;
2641
+ const skillsBlock = opts2.selectedSkills && opts2.selectedSkills.length > 0 ? `
2642
+
2643
+ Active skills for this turn:
2644
+ ${opts2.selectedSkills.map((s) => `--- ${s.name} ---
2645
+ ${s.body}`).join("\n\n")}` : "";
2646
+ return env2 + "\n\n" + tools + lspBlock + contextBlock + modeBlock + skillsBlock;
2640
2647
  }
2641
2648
  function buildSystemPrompt(opts2) {
2642
2649
  return buildStaticPrefix(opts2) + "\n\n" + buildSessionPrefix(opts2);
@@ -2686,6 +2693,9 @@ function collapsePath(input, cwd, maxLen = 40) {
2686
2693
  if (parts.length <= 2) return input;
2687
2694
  return `\u2026/${parts.slice(-2).join(sep)}`;
2688
2695
  }
2696
+ function collapsePathsInText(s, cwd, maxLen = 40) {
2697
+ return s.replace(/([~/][^\s"',)}\]]+)/g, (match) => collapsePath(match, cwd, maxLen));
2698
+ }
2689
2699
  var init_paths = __esm({
2690
2700
  "src/util/paths.ts"() {
2691
2701
  "use strict";
@@ -5016,8 +5026,8 @@ async function saveCloudCredentials(creds) {
5016
5026
  }
5017
5027
  async function clearCloudCredentials() {
5018
5028
  try {
5019
- const { unlink: unlink4 } = await import("fs/promises");
5020
- await unlink4(cloudCredPath());
5029
+ const { unlink: unlink5 } = await import("fs/promises");
5030
+ await unlink5(cloudCredPath());
5021
5031
  } catch {
5022
5032
  }
5023
5033
  }
@@ -6748,186 +6758,6 @@ var init_diff_view = __esm({
6748
6758
  }
6749
6759
  });
6750
6760
 
6751
- // src/ui/narrative.ts
6752
- function countByCategory(items) {
6753
- let reads = 0;
6754
- let writes = 0;
6755
- let shells = 0;
6756
- let webs = 0;
6757
- let memories = 0;
6758
- let others = 0;
6759
- for (const t of items) {
6760
- if (READING_TOOLS.has(t.name)) reads++;
6761
- else if (WRITING_TOOLS.has(t.name)) writes++;
6762
- else if (SHELL_TOOLS.has(t.name)) shells++;
6763
- else if (WEB_TOOLS.has(t.name)) webs++;
6764
- else if (MEMORY_TOOLS.has(t.name)) memories++;
6765
- else others++;
6766
- }
6767
- return { reads, writes, shells, webs, memories, others };
6768
- }
6769
- function pickOne(arr) {
6770
- return arr[Math.floor(Math.random() * arr.length)];
6771
- }
6772
- function generateActivityText(items, _ctx) {
6773
- if (items.length === 0) return null;
6774
- const { reads, writes, shells, webs, memories } = countByCategory(items);
6775
- const total = items.length;
6776
- if (total === 1) {
6777
- const t = items[0];
6778
- if (t.name === "read") {
6779
- const path = typeof t.args?.path === "string" ? t.args.path : "a file";
6780
- return pickOne([`Reading ${path}\u2026`, `Opening ${path}\u2026`, `Taking a look at ${path}\u2026`]);
6781
- }
6782
- if (t.name === "grep") {
6783
- const pattern = typeof t.args?.pattern === "string" ? `"${t.args.pattern}"` : "for patterns";
6784
- return pickOne([`Searching for ${pattern}\u2026`, `Hunting for ${pattern}\u2026`]);
6785
- }
6786
- if (t.name === "glob") {
6787
- const pattern = typeof t.args?.pattern === "string" ? t.args.pattern : "files";
6788
- return pickOne([`Finding ${pattern}\u2026`, `Gathering ${pattern}\u2026`]);
6789
- }
6790
- if (t.name === "write") {
6791
- const path = typeof t.args?.path === "string" ? t.args.path : "a file";
6792
- return pickOne([`Creating ${path}\u2026`, `Writing ${path}\u2026`]);
6793
- }
6794
- if (t.name === "edit") {
6795
- const path = typeof t.args?.path === "string" ? t.args.path : "a file";
6796
- return pickOne([`Patching ${path}\u2026`, `Editing ${path}\u2026`]);
6797
- }
6798
- if (t.name === "bash") {
6799
- return pickOne([`Running a shell command\u2026`, `Executing something in the terminal\u2026`]);
6800
- }
6801
- if (t.name === "web_fetch") {
6802
- return pickOne([`Fetching docs\u2026`, `Checking a reference\u2026`, `Looking something up\u2026`]);
6803
- }
6804
- if (t.name === "memory_remember") {
6805
- return pickOne([`Taking notes for next time\u2026`, `Committing that to memory\u2026`]);
6806
- }
6807
- if (t.name === "memory_recall") {
6808
- return pickOne([`Recalling what we know\u2026`, `Searching past notes\u2026`]);
6809
- }
6810
- return null;
6811
- }
6812
- if (webs >= 2) {
6813
- return pickOne([`Digging through documentation\u2026`, `Cross-referencing sources\u2026`, `Reading up on this\u2026`]);
6814
- }
6815
- if (reads >= 2 && writes === 0 && shells === 0) {
6816
- return pickOne([`Surveying the landscape\u2026`, `Getting the lay of the land\u2026`, `Mapping out the files\u2026`]);
6817
- }
6818
- if (reads >= 1 && (writes >= 1 || shells >= 1)) {
6819
- return pickOne([`Reading, then making changes\u2026`, `Exploring and editing\u2026`, `Survey and patch\u2026`]);
6820
- }
6821
- if (writes >= 1 && shells >= 1) {
6822
- return pickOne([`Committing the changes\u2026`, `Writing and verifying\u2026`, `Editing and checking\u2026`]);
6823
- }
6824
- if (reads >= 1 && webs >= 1) {
6825
- return pickOne([`Exploring the codebase and docs\u2026`, `Cross-referencing code with references\u2026`]);
6826
- }
6827
- if (memories >= 1) {
6828
- return pickOne([`Jogging the memory\u2026`, `Checking past notes\u2026`]);
6829
- }
6830
- if (shells >= 1) {
6831
- return pickOne([`Running some commands\u2026`, `Working in the shell\u2026`]);
6832
- }
6833
- return null;
6834
- }
6835
- function narrativizeInfo(text, ctx) {
6836
- if (ctx?.tier === "heavy") {
6837
- return { kind: "activity", text: "Sizing this up\u2026 feels like a deep one.", feature: "triage" };
6838
- }
6839
- if (ctx?.tier === "light") {
6840
- return { kind: "activity", text: "Quick check \u2014 this looks light.", feature: "triage" };
6841
- }
6842
- if (ctx?.tier === "medium") {
6843
- return { kind: "activity", text: "This one feels medium weight.", feature: "triage" };
6844
- }
6845
- if (ctx?.codeMode) {
6846
- return { kind: "activity", text: "The toolbox feels right for this. Switching to code mode\u2026", feature: "code" };
6847
- }
6848
- if (text.includes("auto-compacted") || text.includes("compacted")) {
6849
- return { kind: "activity", text: "Making room by summarizing older turns\u2026", feature: "compact" };
6850
- }
6851
- if (text.includes("recalled") && text.includes("memory")) {
6852
- return { kind: "activity", text: "Remembering what we learned before\u2026", feature: "memory" };
6853
- }
6854
- if (text.includes("memory cleanup") || text.includes("memory backfill")) {
6855
- return null;
6856
- }
6857
- if (text.startsWith("LSP ready")) {
6858
- return { kind: "activity", text: "Waking up the language servers\u2026" };
6859
- }
6860
- if (text.startsWith("LSP reload complete")) {
6861
- return null;
6862
- }
6863
- if (text.startsWith("MCP connected")) {
6864
- return { kind: "activity", text: "Plugging in external tools\u2026" };
6865
- }
6866
- if (text.includes("research budget") || text.includes("web request")) {
6867
- return { kind: "activity", text: "Researching\u2026 gathering what we can from the web.", feature: "explore" };
6868
- }
6869
- return null;
6870
- }
6871
- function humanizeToolTitle(name, args) {
6872
- const path = typeof args?.path === "string" ? args.path : void 0;
6873
- const pattern = typeof args?.pattern === "string" ? args.pattern : void 0;
6874
- const command = typeof args?.command === "string" ? args.command : void 0;
6875
- const url = typeof args?.url === "string" ? args.url : void 0;
6876
- switch (name) {
6877
- case "read":
6878
- return path ? `Reading ${path}` : "Reading a file\u2026";
6879
- case "grep":
6880
- return pattern ? `Searching for "${pattern}"` : "Searching\u2026";
6881
- case "glob":
6882
- return pattern ? `Finding ${pattern}` : "Finding files\u2026";
6883
- case "write":
6884
- return path ? `Creating ${path}` : "Creating a file\u2026";
6885
- case "edit":
6886
- return path ? `Patching ${path}` : "Patching a file\u2026";
6887
- case "bash":
6888
- return command ? `Running: ${command.split(/\s+/).slice(0, 4).join(" ")}${command.split(/\s+/).length > 4 ? "\u2026" : ""}` : "Running shell command\u2026";
6889
- case "web_fetch":
6890
- return url ? `Fetching ${url.replace(/^https?:\/\//, "").split("/")[0]}` : "Fetching docs\u2026";
6891
- case "memory_remember":
6892
- return "Committing to memory\u2026";
6893
- case "memory_recall":
6894
- return "Recalling memories\u2026";
6895
- case "memory_forget":
6896
- return "Forgetting a memory\u2026";
6897
- case "lsp_hover":
6898
- return "Inspecting symbol\u2026";
6899
- case "lsp_definition":
6900
- return "Jumping to definition\u2026";
6901
- case "lsp_references":
6902
- return "Finding references\u2026";
6903
- case "lsp_implementation":
6904
- return "Finding implementations\u2026";
6905
- case "lsp_typeDefinition":
6906
- return "Finding type definition\u2026";
6907
- case "lsp_documentSymbols":
6908
- return "Listing symbols\u2026";
6909
- case "lsp_workspaceSymbol":
6910
- return "Searching workspace symbols\u2026";
6911
- case "lsp_rename":
6912
- return "Renaming symbol\u2026";
6913
- case "lsp_codeAction":
6914
- return "Applying quick fix\u2026";
6915
- default:
6916
- return name;
6917
- }
6918
- }
6919
- var READING_TOOLS, WRITING_TOOLS, SHELL_TOOLS, WEB_TOOLS, MEMORY_TOOLS;
6920
- var init_narrative = __esm({
6921
- "src/ui/narrative.ts"() {
6922
- "use strict";
6923
- READING_TOOLS = /* @__PURE__ */ new Set(["read", "glob", "grep", "lsp_hover", "lsp_definition", "lsp_references", "lsp_implementation", "lsp_typeDefinition", "lsp_documentSymbols", "lsp_workspaceSymbol"]);
6924
- WRITING_TOOLS = /* @__PURE__ */ new Set(["write", "edit", "lsp_rename", "lsp_codeAction"]);
6925
- SHELL_TOOLS = /* @__PURE__ */ new Set(["bash"]);
6926
- WEB_TOOLS = /* @__PURE__ */ new Set(["web_fetch"]);
6927
- MEMORY_TOOLS = /* @__PURE__ */ new Set(["memory_remember", "memory_recall", "memory_forget"]);
6928
- }
6929
- });
6930
-
6931
6761
  // src/ui/tool-view.tsx
6932
6762
  import React2, { useEffect, useState } from "react";
6933
6763
  import { Box as Box2, Text as Text2 } from "ink";
@@ -6941,6 +6771,11 @@ function formatElapsed(ms) {
6941
6771
  if (m === 0) return `${s}s`;
6942
6772
  return `${m}m ${s}s`;
6943
6773
  }
6774
+ function compactArgs(raw) {
6775
+ const collapsed = collapsePathsInText(raw, process.cwd());
6776
+ const s = collapsed.replace(/\s+/g, " ");
6777
+ return s.length <= 80 ? s : s.slice(0, 80) + "\u2026";
6778
+ }
6944
6779
  function firstLine(s) {
6945
6780
  const line = s.split("\n").find((l) => l.trim().length > 0) ?? "";
6946
6781
  return line.length <= 120 ? line : line.slice(0, 120) + "\u2026";
@@ -6952,7 +6787,6 @@ var init_tool_view = __esm({
6952
6787
  init_diff_view();
6953
6788
  init_paths();
6954
6789
  init_theme_context();
6955
- init_narrative();
6956
6790
  ToolView = React2.memo(function ToolView2({ evt, verbose, isRepeated }) {
6957
6791
  const theme = useTheme();
6958
6792
  const [now2, setNow] = useState(Date.now());
@@ -6966,14 +6800,7 @@ var init_tool_view = __esm({
6966
6800
  return () => clearInterval(id);
6967
6801
  }, [evt.status, evt.startedAt]);
6968
6802
  const statusIcon = evt.status === "running" ? /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, children: /* @__PURE__ */ jsx3(Spinner, { type: "dots" }) }) : evt.status === "error" ? /* @__PURE__ */ jsx3(Text2, { color: theme.palette.error, children: "\u2717" }) : /* @__PURE__ */ jsx3(Text2, { color: theme.palette.success, children: "\u2713" });
6969
- let title = evt.render?.title ?? (() => {
6970
- try {
6971
- const args = evt.args ? JSON.parse(evt.args) : {};
6972
- return humanizeToolTitle(evt.name, args);
6973
- } catch {
6974
- return humanizeToolTitle(evt.name);
6975
- }
6976
- })();
6803
+ let title = evt.render?.title ?? `${evt.name}(${compactArgs(evt.args)})`;
6977
6804
  if (evt.startedAt !== void 0) {
6978
6805
  title += ` \xB7 ${formatElapsed(now2 - evt.startedAt)}`;
6979
6806
  }
@@ -7295,7 +7122,7 @@ var init_chat = __esm({
7295
7122
  init_tool_view();
7296
7123
  init_markdown();
7297
7124
  init_theme_context();
7298
- ChatView = React4.memo(function ChatView2({ events, showReasoning, verbose, suppressTools }) {
7125
+ ChatView = React4.memo(function ChatView2({ events, showReasoning, verbose }) {
7299
7126
  const theme = useTheme();
7300
7127
  const finalized = [];
7301
7128
  const active = [];
@@ -7312,7 +7139,6 @@ var init_chat = __esm({
7312
7139
  }
7313
7140
  for (let i = 0; i < events.length; i++) {
7314
7141
  const e = events[i];
7315
- if (suppressTools && e.kind === "tool") continue;
7316
7142
  const isStreaming = e.kind === "assistant" && e.streaming;
7317
7143
  if (isStreaming) {
7318
7144
  active.push(e);
@@ -7386,11 +7212,21 @@ var init_chat = __esm({
7386
7212
  evt.text
7387
7213
  ] });
7388
7214
  }
7389
- if (evt.kind === "activity") {
7390
- return /* @__PURE__ */ jsxs4(Text4, { italic: true, color: theme.info.dim ? theme.info.color : theme.palette.secondary, children: [
7391
- "~ ",
7392
- evt.text
7393
- ] });
7215
+ if (evt.kind === "meta") {
7216
+ const parts = [];
7217
+ if (evt.intentTier) {
7218
+ parts.push(
7219
+ evt.intentTier === "light" ? "Quick thought" : evt.intentTier === "medium" ? "Deep dive" : "Heavy lifting"
7220
+ );
7221
+ }
7222
+ if (evt.skillsActive !== void 0 && evt.skillsActive > 0) {
7223
+ parts.push(`${evt.skillsActive} skill${evt.skillsActive === 1 ? "" : "s"} on deck`);
7224
+ }
7225
+ if (evt.memoryRecalled) {
7226
+ parts.push("Memory recalled");
7227
+ }
7228
+ if (parts.length === 0) return null;
7229
+ return /* @__PURE__ */ jsx5(Text4, { color: theme.info.color, dimColor: true, children: parts.join(" \xB7 ") });
7394
7230
  }
7395
7231
  return /* @__PURE__ */ jsxs4(Text4, { color: theme.error, children: [
7396
7232
  "! ",
@@ -7423,7 +7259,7 @@ import { useEffect as useEffect2, useState as useState2 } from "react";
7423
7259
  import { Box as Box5, Text as Text5 } from "ink";
7424
7260
  import Spinner3 from "ink-spinner";
7425
7261
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
7426
- function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget, phase, currentTool, lastActivityAt, kimiMdStale }) {
7262
+ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget, skillsActive, memoryRecalled, phase, currentTool, lastActivityAt, kimiMdStale, gitBranch }) {
7427
7263
  const theme = useTheme();
7428
7264
  const [now2, setNow] = useState2(Date.now());
7429
7265
  const modeColor = mode === "plan" ? theme.modeBadge.plan : mode === "auto" ? theme.modeBadge.auto : theme.modeBadge.edit;
@@ -7435,8 +7271,16 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
7435
7271
  }, [thinking, turnStartedAt]);
7436
7272
  const elapsed = turnStartedAt !== null ? formatElapsed2(now2 - turnStartedAt) : null;
7437
7273
  const leftParts = [`${shortModel(model)}`, effort];
7274
+ if (gitBranch) leftParts.push(gitBranch);
7438
7275
  if (cloudMode) leftParts.push("CLOUD");
7439
7276
  if (codeMode) leftParts.push("CODE");
7277
+ const labelParts = [];
7278
+ if (skillsActive !== void 0 && skillsActive > 0) {
7279
+ labelParts.push(`${skillsActive} skill${skillsActive === 1 ? "" : "s"} on deck`);
7280
+ }
7281
+ if (memoryRecalled) {
7282
+ labelParts.push("Memory recalled");
7283
+ }
7440
7284
  const phaseLabel = phase === "generating" ? "generating" : phase === "executing" ? `executing ${currentTool ?? ""}` : phase === "waiting" ? "waiting" : "thinking";
7441
7285
  const idleMs = lastActivityAt && thinking ? now2 - lastActivityAt : 0;
7442
7286
  const idleLabel = idleMs > 3e4 ? ` (idle ${formatElapsed2(Math.floor(idleMs / 1e3))})` : "";
@@ -7459,6 +7303,7 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
7459
7303
  " \xB7 ready"
7460
7304
  ] })
7461
7305
  ] }),
7306
+ labelParts.length > 0 && /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsx6(Text5, { color: theme.info.color, dimColor: true, children: labelParts.join(" \xB7 ") }) }),
7462
7307
  usage && /* @__PURE__ */ jsxs5(Box5, { children: [
7463
7308
  /* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget).join(" \xB7 ") }),
7464
7309
  warn ? /* @__PURE__ */ jsxs5(Text5, { color: theme.warn, bold: true, children: [
@@ -7475,7 +7320,8 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
7475
7320
  " \xB7 ",
7476
7321
  "\u26A0 KIMI.md stale \xB7 run /init"
7477
7322
  ] }) : null
7478
- ] })
7323
+ ] }),
7324
+ !thinking && /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsx6(Text5, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim, children: "tip: shift+tab cycles mode" }) })
7479
7325
  ] });
7480
7326
  }
7481
7327
  function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget) {
@@ -8942,7 +8788,7 @@ var init_onboarding = __esm({
8942
8788
  // src/ui/welcome.tsx
8943
8789
  import { Box as Box11, Text as Text12 } from "ink";
8944
8790
  import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
8945
- function Welcome({ accountId }) {
8791
+ function Welcome({ accountId, cloudMode }) {
8946
8792
  const theme = useTheme();
8947
8793
  return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
8948
8794
  /* @__PURE__ */ jsxs11(Box11, { marginBottom: 1, children: [
@@ -8952,7 +8798,7 @@ function Welcome({ accountId }) {
8952
8798
  "Ready when you are."
8953
8799
  ] })
8954
8800
  ] }),
8955
- accountId && /* @__PURE__ */ jsx13(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
8801
+ accountId && !cloudMode && /* @__PURE__ */ jsx13(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: theme.info.color, children: [
8956
8802
  " ",
8957
8803
  "Check your Cloudflare billing: https://dash.cloudflare.com/",
8958
8804
  accountId,
@@ -8983,237 +8829,6 @@ var init_welcome = __esm({
8983
8829
  }
8984
8830
  });
8985
8831
 
8986
- // src/ui/help-menu.tsx
8987
- import { useState as useState7 } from "react";
8988
- import { Box as Box12, Text as Text13, useInput as useInput3 } from "ink";
8989
- import SelectInput5 from "ink-select-input";
8990
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
8991
- function HelpMenu({ customCommands, costAttributionEnabled, cloudMode, onDone, onCommand }) {
8992
- const theme = useTheme();
8993
- const [page, setPage] = useState7("main");
8994
- const customs = customCommands ?? [];
8995
- useInput3((_input, key) => {
8996
- if (key.escape) {
8997
- if (page !== "main") {
8998
- setPage("main");
8999
- } else {
9000
- onDone();
9001
- }
9002
- }
9003
- });
9004
- const handleSelect = (command) => {
9005
- onCommand(command);
9006
- onDone();
9007
- };
9008
- const categories = cloudMode ? CATEGORIES.filter((c) => c.key !== "gateway") : CATEGORIES;
9009
- if (page === "main") {
9010
- const items2 = categories.map((cat) => ({
9011
- label: cat.label,
9012
- value: cat.key,
9013
- key: cat.key
9014
- }));
9015
- if (customs.length > 0) {
9016
- items2.push({ label: "Run custom commands", value: "custom", key: "custom" });
9017
- }
9018
- items2.push({ label: "(close)", value: "__close__", key: "__close__" });
9019
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
9020
- /* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: "Help" }),
9021
- /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to close." }),
9022
- /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
9023
- SelectInput5,
9024
- {
9025
- items: items2,
9026
- onSelect: (item) => {
9027
- if (item.value === "__close__") {
9028
- onDone();
9029
- } else {
9030
- setPage(item.value);
9031
- }
9032
- }
9033
- }
9034
- ) }),
9035
- /* @__PURE__ */ jsx14(Box12, { marginTop: 1, flexDirection: "column", children: SINGLE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: ` ${cmd.command.padEnd(20)} ${cmd.description}` }, cmd.command)) }),
9036
- /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "keys: ctrl-c interrupt/exit \xB7 ctrl-r toggle reasoning \xB7 ctrl-o verbose \xB7 shift+tab cycle mode \xB7 \u2191/\u2193 history" }) })
9037
- ] });
9038
- }
9039
- if (page === "custom") {
9040
- const items2 = customs.map((c) => ({
9041
- label: `${`/${c.name}`.padEnd(28)} ${c.description ?? ""}`.trimEnd(),
9042
- value: `/${c.name}`,
9043
- key: c.name
9044
- }));
9045
- items2.push({ label: "\u2190 Back", value: "__back__", key: "__back__" });
9046
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
9047
- /* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: "Custom commands" }),
9048
- /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: customs.length === 0 ? "no custom commands found in .kimiflare/commands/" : "Arrow keys to navigate, Enter to run, Esc to go back." }),
9049
- /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
9050
- SelectInput5,
9051
- {
9052
- items: items2,
9053
- onSelect: (item) => {
9054
- if (item.value === "__back__") {
9055
- setPage("main");
9056
- } else {
9057
- handleSelect(item.value);
9058
- }
9059
- }
9060
- }
9061
- ) })
9062
- ] });
9063
- }
9064
- const category = categories.find((c) => c.key === page);
9065
- const selectable = category.commands.filter((cmd) => cmd.selectable !== false);
9066
- const staticCmds = category.commands.filter((cmd) => cmd.selectable === false);
9067
- const items = selectable.map((cmd) => ({
9068
- label: `${cmd.command.padEnd(28)} ${cmd.description}`,
9069
- value: cmd.command,
9070
- key: cmd.command
9071
- }));
9072
- items.push({ label: "\u2190 Back", value: "__back__", key: "__back__" });
9073
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
9074
- /* @__PURE__ */ jsx14(Text13, { color: theme.accent, bold: true, children: category.label }),
9075
- /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to execute, Esc to go back." }),
9076
- /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
9077
- SelectInput5,
9078
- {
9079
- items,
9080
- onSelect: (item) => {
9081
- if (item.value === "__back__") {
9082
- setPage("main");
9083
- } else {
9084
- handleSelect(item.value);
9085
- }
9086
- }
9087
- }
9088
- ) }),
9089
- staticCmds.length > 0 && /* @__PURE__ */ jsx14(Box12, { marginTop: 1, flexDirection: "column", children: staticCmds.map((cmd) => /* @__PURE__ */ jsx14(Text13, { color: theme.info.color, children: ` ${cmd.command.padEnd(28)} ${cmd.description}` }, cmd.command)) })
9090
- ] });
9091
- }
9092
- var CATEGORIES, SINGLE_COMMANDS;
9093
- var init_help_menu = __esm({
9094
- "src/ui/help-menu.tsx"() {
9095
- "use strict";
9096
- init_theme_context();
9097
- CATEGORIES = [
9098
- {
9099
- key: "mode",
9100
- label: "Mode",
9101
- commands: [
9102
- { command: "/mode edit", description: "switch to edit mode" },
9103
- { command: "/mode plan", description: "switch to plan mode" },
9104
- { command: "/mode auto", description: "switch to auto mode" }
9105
- ]
9106
- },
9107
- {
9108
- key: "thinking",
9109
- label: "Thinking",
9110
- commands: [
9111
- { command: "/thinking low", description: "fast, lower quality" },
9112
- { command: "/thinking medium", description: "balanced" },
9113
- { command: "/thinking high", description: "slow, higher quality" }
9114
- ]
9115
- },
9116
- {
9117
- key: "session",
9118
- label: "Session",
9119
- commands: [
9120
- { command: "/resume", description: "pick a past conversation" },
9121
- { command: "/compact", description: "summarize old turns to free context" },
9122
- { command: "/clear", description: "clear current conversation" }
9123
- ]
9124
- },
9125
- {
9126
- key: "memory",
9127
- label: "Memory",
9128
- commands: [
9129
- { command: "/memory", description: "show memory stats" },
9130
- { command: "/memory on", description: "enable memory" },
9131
- { command: "/memory off", description: "disable memory" },
9132
- { command: "/memory clear", description: "wipe memories for this repo" },
9133
- { command: "/memory search <query>", description: "search stored memories", selectable: false }
9134
- ]
9135
- },
9136
- {
9137
- key: "cost",
9138
- label: "Cost",
9139
- commands: [
9140
- { command: "/cost", description: "show cost report" },
9141
- { command: "/cost on", description: "enable cost attribution by task type" },
9142
- { command: "/cost off", description: "disable cost attribution by task type" }
9143
- ]
9144
- },
9145
- {
9146
- key: "mcp",
9147
- label: "MCP",
9148
- commands: [
9149
- { command: "/mcp list", description: "list connected MCP servers and tools" },
9150
- { command: "/mcp reload", description: "reconnect all configured MCP servers" }
9151
- ]
9152
- },
9153
- {
9154
- key: "lsp",
9155
- label: "LSP",
9156
- commands: [
9157
- { command: "/lsp config", description: "add, edit, or remove language servers" },
9158
- { command: "/lsp list", description: "list active LSP servers" },
9159
- { command: "/lsp reload", description: "restart all configured LSP servers" },
9160
- { command: "/lsp scope", description: "show whether LSP config is project or global" }
9161
- ]
9162
- },
9163
- {
9164
- key: "gateway",
9165
- label: "Gateway",
9166
- commands: [
9167
- { command: "/gateway", description: "show gateway status" },
9168
- { command: "/gateway off", description: "disable AI Gateway (direct Workers AI)" },
9169
- { command: "/gateway skip-cache true", description: "enable skip-cache" },
9170
- { command: "/gateway skip-cache false", description: "disable skip-cache" },
9171
- { command: "/gateway collect-logs true", description: "enable log collection" },
9172
- { command: "/gateway collect-logs false", description: "disable log collection" },
9173
- { command: "/gateway metadata clear", description: "remove all metadata" },
9174
- { command: "/gateway <id>", description: "enable AI Gateway", selectable: false },
9175
- { command: "/gateway cache-ttl <seconds>", description: "set cache TTL", selectable: false },
9176
- { command: "/gateway metadata <key>=<value>", description: "add metadata", selectable: false }
9177
- ]
9178
- },
9179
- {
9180
- key: "info",
9181
- label: "Info",
9182
- commands: [
9183
- { command: "/cost", description: "show cost report" },
9184
- { command: "/model", description: "show current model" },
9185
- { command: "/update", description: "check for updates" },
9186
- { command: "/hello", description: "send a voice note to the creator" }
9187
- ]
9188
- },
9189
- {
9190
- key: "commands",
9191
- label: "Commands",
9192
- commands: [
9193
- { command: "/command create", description: "create a new custom slash command" },
9194
- { command: "/command edit", description: "edit an existing custom command" },
9195
- { command: "/command delete", description: "delete a custom command" },
9196
- { command: "/command list", description: "list all custom commands" }
9197
- ]
9198
- },
9199
- {
9200
- key: "config",
9201
- label: "Config",
9202
- commands: [
9203
- { command: "/init", description: "scan this repo and write a KIMI.md" },
9204
- { command: "/logout", description: "clear credentials" },
9205
- { command: "filePicker", description: "enabled by default; disable with KIMIFLARE_FILE_PICKER=0 or filePicker: false in config", selectable: false }
9206
- ]
9207
- }
9208
- ];
9209
- SINGLE_COMMANDS = [
9210
- { command: "/reasoning", description: "toggle show/hide model reasoning" },
9211
- { command: "/help", description: "show this menu" },
9212
- { command: "/exit", description: "exit kimiflare" }
9213
- ];
9214
- }
9215
- });
9216
-
9217
8832
  // src/remote/worker-client.ts
9218
8833
  var worker_client_exports = {};
9219
8834
  __export(worker_client_exports, {
@@ -9318,16 +8933,16 @@ var init_tui_deploy = __esm({
9318
8933
  });
9319
8934
 
9320
8935
  // src/ui/remote-dashboard.tsx
9321
- import { useEffect as useEffect6, useState as useState8 } from "react";
9322
- import { Box as Box13, Text as Text14, useInput as useInput4 } from "ink";
9323
- import SelectInput6 from "ink-select-input";
9324
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
8936
+ import { useEffect as useEffect6, useState as useState7 } from "react";
8937
+ import { Box as Box12, Text as Text13, useInput as useInput3 } from "ink";
8938
+ import SelectInput5 from "ink-select-input";
8939
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
9325
8940
  function RemoteDashboard({ onSelect, onCancel }) {
9326
8941
  const theme = useTheme();
9327
- const [sessions, setSessions] = useState8([]);
9328
- const [loading, setLoading] = useState8(true);
9329
- const [error, setError] = useState8(null);
9330
- const [refreshing, setRefreshing] = useState8(false);
8942
+ const [sessions, setSessions] = useState7([]);
8943
+ const [loading, setLoading] = useState7(true);
8944
+ const [error, setError] = useState7(null);
8945
+ const [refreshing, setRefreshing] = useState7(false);
9331
8946
  useEffect6(() => {
9332
8947
  loadSessions();
9333
8948
  }, []);
@@ -9364,7 +8979,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
9364
8979
  setRefreshing(false);
9365
8980
  }
9366
8981
  }
9367
- useInput4((input, key) => {
8982
+ useInput3((input, key) => {
9368
8983
  if (input === "r" || input === "R") {
9369
8984
  void loadSessions();
9370
8985
  }
@@ -9377,31 +8992,31 @@ function RemoteDashboard({ onSelect, onCancel }) {
9377
8992
  value: s.sessionId
9378
8993
  }));
9379
8994
  if (loading) {
9380
- return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "Loading remote sessions..." }) });
8995
+ return /* @__PURE__ */ jsx14(Box12, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx14(Text13, { color: theme.accent, children: "Loading remote sessions..." }) });
9381
8996
  }
9382
8997
  if (error) {
9383
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
9384
- /* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
8998
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
8999
+ /* @__PURE__ */ jsxs12(Text13, { color: theme.error, children: [
9385
9000
  "Error: ",
9386
9001
  error
9387
9002
  ] }),
9388
- /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press R to retry, Esc to close" })
9003
+ /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Press R to retry, Esc to close" })
9389
9004
  ] });
9390
9005
  }
9391
9006
  if (sessions.length === 0) {
9392
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
9393
- /* @__PURE__ */ jsx15(Text14, { color: theme.accent, children: "No remote sessions yet." }),
9394
- /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Type /remote <prompt> to start one." }),
9395
- /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Press Esc to close" })
9007
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
9008
+ /* @__PURE__ */ jsx14(Text13, { color: theme.accent, children: "No remote sessions yet." }),
9009
+ /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Type /remote <prompt> to start one." }),
9010
+ /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Press Esc to close" })
9396
9011
  ] });
9397
9012
  }
9398
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
9399
- /* @__PURE__ */ jsxs13(Text14, { bold: true, color: theme.accent, children: [
9013
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
9014
+ /* @__PURE__ */ jsxs12(Text13, { bold: true, color: theme.accent, children: [
9400
9015
  "Recent remote tasks ",
9401
9016
  refreshing ? "(refreshing...)" : ""
9402
9017
  ] }),
9403
- /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
9404
- SelectInput6,
9018
+ /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(
9019
+ SelectInput5,
9405
9020
  {
9406
9021
  items,
9407
9022
  onSelect: (item) => {
@@ -9410,7 +9025,7 @@ function RemoteDashboard({ onSelect, onCancel }) {
9410
9025
  }
9411
9026
  }
9412
9027
  ) }),
9413
- /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
9028
+ /* @__PURE__ */ jsx14(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter select \u2022 R refresh \u2022 Esc close" }) })
9414
9029
  ] });
9415
9030
  }
9416
9031
  function formatSessionLine(s) {
@@ -9442,8 +9057,8 @@ function RemoteSessionDetail({
9442
9057
  onCancel
9443
9058
  }) {
9444
9059
  const theme = useTheme();
9445
- const [cancelling, setCancelling] = useState8(false);
9446
- useInput4((input, key) => {
9060
+ const [cancelling, setCancelling] = useState7(false);
9061
+ useInput3((input, key) => {
9447
9062
  if (key.escape) {
9448
9063
  onBack();
9449
9064
  }
@@ -9463,50 +9078,50 @@ function RemoteSessionDetail({
9463
9078
  }
9464
9079
  }
9465
9080
  const isRunning = session.status === "running" || session.status === "pending";
9466
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", padding: 1, children: [
9467
- /* @__PURE__ */ jsx15(Text14, { bold: true, color: theme.accent, children: "Remote Session" }),
9468
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
9469
- /* @__PURE__ */ jsxs13(Text14, { children: [
9081
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", padding: 1, children: [
9082
+ /* @__PURE__ */ jsx14(Text13, { bold: true, color: theme.accent, children: "Remote Session" }),
9083
+ /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
9084
+ /* @__PURE__ */ jsxs12(Text13, { children: [
9470
9085
  "ID: ",
9471
9086
  session.sessionId
9472
9087
  ] }),
9473
- /* @__PURE__ */ jsxs13(Text14, { children: [
9088
+ /* @__PURE__ */ jsxs12(Text13, { children: [
9474
9089
  "Repo: ",
9475
9090
  session.repo
9476
9091
  ] }),
9477
- /* @__PURE__ */ jsxs13(Text14, { children: [
9092
+ /* @__PURE__ */ jsxs12(Text13, { children: [
9478
9093
  "Status: ",
9479
9094
  session.status
9480
9095
  ] }),
9481
- /* @__PURE__ */ jsxs13(Text14, { children: [
9096
+ /* @__PURE__ */ jsxs12(Text13, { children: [
9482
9097
  "Prompt: ",
9483
9098
  session.prompt
9484
9099
  ] }),
9485
- session.prUrl && /* @__PURE__ */ jsxs13(Text14, { children: [
9100
+ session.prUrl && /* @__PURE__ */ jsxs12(Text13, { children: [
9486
9101
  "PR: ",
9487
9102
  session.prUrl
9488
9103
  ] }),
9489
- session.errorMessage && /* @__PURE__ */ jsxs13(Text14, { color: theme.error, children: [
9104
+ session.errorMessage && /* @__PURE__ */ jsxs12(Text13, { color: theme.error, children: [
9490
9105
  "Error: ",
9491
9106
  session.errorMessage
9492
9107
  ] }),
9493
- session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs13(Text14, { children: [
9108
+ session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs12(Text13, { children: [
9494
9109
  "Tokens: ",
9495
9110
  formatTokens3(session.tokensUsed),
9496
9111
  session.tokensBudget ? ` / ${formatTokens3(session.tokensBudget)}` : ""
9497
9112
  ] }),
9498
- /* @__PURE__ */ jsxs13(Text14, { children: [
9113
+ /* @__PURE__ */ jsxs12(Text13, { children: [
9499
9114
  "Created: ",
9500
9115
  new Date(session.createdAt).toLocaleString()
9501
9116
  ] }),
9502
- session.finishedAt && /* @__PURE__ */ jsxs13(Text14, { children: [
9117
+ session.finishedAt && /* @__PURE__ */ jsxs12(Text13, { children: [
9503
9118
  "Finished: ",
9504
9119
  new Date(session.finishedAt).toLocaleString()
9505
9120
  ] })
9506
9121
  ] }),
9507
- /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "row", gap: 2, children: [
9508
- isRunning && onCancel && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
9509
- /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: "Esc back" })
9122
+ /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", gap: 2, children: [
9123
+ isRunning && onCancel && /* @__PURE__ */ jsx14(Text13, { color: theme.error, children: cancelling ? "Cancelling..." : "[C] Cancel session" }),
9124
+ /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Esc back" })
9510
9125
  ] })
9511
9126
  ] });
9512
9127
  }
@@ -9563,6 +9178,240 @@ var init_classify = __esm({
9563
9178
  }
9564
9179
  });
9565
9180
 
9181
+ // src/skills/loader.ts
9182
+ import { readFile as readFile12, readdir as readdir3, stat as stat4 } from "fs/promises";
9183
+ import { join as join15, extname } from "path";
9184
+ import matter from "gray-matter";
9185
+ function normalizeManifest(raw, filePath) {
9186
+ const name = typeof raw.name === "string" ? raw.name : "";
9187
+ const description = typeof raw.description === "string" ? raw.description : "";
9188
+ const match = Array.isArray(raw.match) ? raw.match.filter((m) => typeof m === "string") : DEFAULTS.match;
9189
+ const scope = raw.scope === "project" ? "project" : DEFAULTS.scope;
9190
+ const priority = typeof raw.priority === "number" ? raw.priority : DEFAULTS.priority;
9191
+ const enabled = typeof raw.enabled === "boolean" ? raw.enabled : DEFAULTS.enabled;
9192
+ if (!name) {
9193
+ throw new Error(`Skill file missing required 'name' field: ${filePath}`);
9194
+ }
9195
+ return { name, description, match, scope, priority, enabled };
9196
+ }
9197
+ async function loadSkillFile(filePath) {
9198
+ const raw = await readFile12(filePath, "utf-8");
9199
+ const parsed = matter(raw);
9200
+ const manifest = normalizeManifest(parsed.data, filePath);
9201
+ const body = parsed.content.trim();
9202
+ const estimatedTokens = Math.ceil(body.length / 4);
9203
+ return {
9204
+ name: manifest.name,
9205
+ description: manifest.description,
9206
+ match: manifest.match ?? DEFAULTS.match,
9207
+ scope: manifest.scope ?? DEFAULTS.scope,
9208
+ priority: manifest.priority ?? DEFAULTS.priority,
9209
+ enabled: manifest.enabled ?? DEFAULTS.enabled,
9210
+ body,
9211
+ filePath,
9212
+ estimatedTokens
9213
+ };
9214
+ }
9215
+ async function loadSkillsFromDir(dirPath) {
9216
+ try {
9217
+ const entries = await readdir3(dirPath);
9218
+ const files = [];
9219
+ for (const entry of entries) {
9220
+ const full = join15(dirPath, entry);
9221
+ const s = await stat4(full);
9222
+ if (s.isFile() && extname(entry) === ".md") {
9223
+ files.push(full);
9224
+ }
9225
+ }
9226
+ const skills = await Promise.all(files.map(loadSkillFile));
9227
+ skills.sort((a, b) => a.priority - b.priority);
9228
+ return skills;
9229
+ } catch {
9230
+ return [];
9231
+ }
9232
+ }
9233
+ var DEFAULTS;
9234
+ var init_loader = __esm({
9235
+ "src/skills/loader.ts"() {
9236
+ "use strict";
9237
+ DEFAULTS = {
9238
+ scope: "global",
9239
+ priority: 0,
9240
+ enabled: true,
9241
+ match: []
9242
+ };
9243
+ }
9244
+ });
9245
+
9246
+ // src/skills/router.ts
9247
+ import { minimatch } from "minimatch";
9248
+ function matchSkill(skill, prompt, cwd) {
9249
+ if (!skill.enabled) return false;
9250
+ if (skill.match.length === 0) return true;
9251
+ for (const pattern of skill.match) {
9252
+ if (pattern.includes("/") || pattern.includes("*")) {
9253
+ if (minimatch(cwd, pattern) || minimatch(cwd, `**/${pattern}`)) {
9254
+ return true;
9255
+ }
9256
+ }
9257
+ if (prompt.toLowerCase().includes(pattern.toLowerCase())) {
9258
+ return true;
9259
+ }
9260
+ }
9261
+ return false;
9262
+ }
9263
+ function findConflicts(skill, memorySnippets) {
9264
+ const conflicts = [];
9265
+ for (const mem of memorySnippets) {
9266
+ const memLower = mem.toLowerCase();
9267
+ const skillLower = skill.name.toLowerCase();
9268
+ if (memLower.includes(skillLower) || skillLower.includes(memLower)) {
9269
+ conflicts.push({
9270
+ skillName: skill.name,
9271
+ memoryContent: mem.slice(0, 200),
9272
+ memoryId: ""
9273
+ // populated by caller if available
9274
+ });
9275
+ }
9276
+ }
9277
+ return conflicts;
9278
+ }
9279
+ function selectSkills(skills, options) {
9280
+ const tierBudget = TIER_BUDGETS[options.tier];
9281
+ const effectiveBudget = Math.min(tierBudget, options.maxSkillTokens);
9282
+ const matched = skills.filter((s) => matchSkill(s, options.prompt, options.cwd));
9283
+ const selected = [];
9284
+ const dropped = [];
9285
+ const allConflicts = [];
9286
+ let runningTotal = 0;
9287
+ for (const skill of matched) {
9288
+ const conflicts = findConflicts(skill, options.memorySnippets);
9289
+ allConflicts.push(...conflicts);
9290
+ if (runningTotal + skill.estimatedTokens <= effectiveBudget) {
9291
+ selected.push(skill);
9292
+ runningTotal += skill.estimatedTokens;
9293
+ } else {
9294
+ dropped.push(skill);
9295
+ }
9296
+ }
9297
+ const budgetUsed = effectiveBudget > 0 ? Math.round(runningTotal / effectiveBudget * 100) : 0;
9298
+ return {
9299
+ selectedSkills: selected,
9300
+ droppedSkills: dropped,
9301
+ totalSkillTokens: runningTotal,
9302
+ budgetUsed,
9303
+ memoryConflicts: allConflicts
9304
+ };
9305
+ }
9306
+ var TIER_BUDGETS;
9307
+ var init_router = __esm({
9308
+ "src/skills/router.ts"() {
9309
+ "use strict";
9310
+ TIER_BUDGETS = {
9311
+ light: 2e3,
9312
+ medium: 8e3,
9313
+ heavy: 24e3
9314
+ };
9315
+ }
9316
+ });
9317
+
9318
+ // src/skills/index.ts
9319
+ async function routeSkills(skillDir, opts2) {
9320
+ const skills = await loadSkillsFromDir(skillDir);
9321
+ return selectSkills(skills, opts2);
9322
+ }
9323
+ var init_skills = __esm({
9324
+ "src/skills/index.ts"() {
9325
+ "use strict";
9326
+ init_loader();
9327
+ init_router();
9328
+ }
9329
+ });
9330
+
9331
+ // src/skills/manager.ts
9332
+ import { mkdir as mkdir7, writeFile as writeFile8, unlink as unlink2, readFile as readFile13 } from "fs/promises";
9333
+ import { join as join16 } from "path";
9334
+ import matter2 from "gray-matter";
9335
+ function getSkillDirs(cwd) {
9336
+ return {
9337
+ projectDir: join16(cwd, ".kimiflare", "skills"),
9338
+ globalDir: join16(process.env.HOME ?? "", ".config", "kimiflare", "skills")
9339
+ };
9340
+ }
9341
+ async function listAllSkills(cwd) {
9342
+ const dirs = getSkillDirs(cwd);
9343
+ const [project, global] = await Promise.all([
9344
+ loadSkillsFromDir(dirs.projectDir).catch(() => []),
9345
+ loadSkillsFromDir(dirs.globalDir).catch(() => [])
9346
+ ]);
9347
+ return { project, global };
9348
+ }
9349
+ async function createSkill(opts2) {
9350
+ const dirs = getSkillDirs(opts2.cwd);
9351
+ const dir = opts2.scope === "project" ? dirs.projectDir : dirs.globalDir;
9352
+ const filepath = join16(dir, `${opts2.name}.md`);
9353
+ const frontmatter = {
9354
+ name: opts2.name,
9355
+ enabled: true,
9356
+ priority: 0
9357
+ };
9358
+ if (opts2.description) frontmatter.description = opts2.description;
9359
+ if (opts2.match && opts2.match.length > 0) frontmatter.match = opts2.match;
9360
+ const yaml = Object.entries(frontmatter).map(([k, v]) => {
9361
+ if (Array.isArray(v)) return `${k}:
9362
+ ${v.map((item) => ` - ${item}`).join("\n")}`;
9363
+ return `${k}: ${v}`;
9364
+ }).join("\n");
9365
+ const content = `---
9366
+ ${yaml}
9367
+ ---
9368
+
9369
+ # ${opts2.name}
9370
+
9371
+ Add your instructions here.
9372
+ `;
9373
+ await mkdir7(dir, { recursive: true });
9374
+ await writeFile8(filepath, content, "utf8");
9375
+ return { filepath };
9376
+ }
9377
+ async function deleteSkill(name, cwd) {
9378
+ const all = await listAllSkills(cwd);
9379
+ const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
9380
+ if (!skill) throw new Error(`skill "${name}" not found`);
9381
+ await unlink2(skill.filePath);
9382
+ return { filepath: skill.filePath };
9383
+ }
9384
+ async function setSkillEnabled(name, enabled, cwd) {
9385
+ const all = await listAllSkills(cwd);
9386
+ const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
9387
+ if (!skill) throw new Error(`skill "${name}" not found`);
9388
+ const raw = await readFile13(skill.filePath, "utf-8");
9389
+ const parsed = matter2(raw);
9390
+ parsed.data.enabled = enabled;
9391
+ const yaml = Object.entries(parsed.data).map(([k, v]) => {
9392
+ if (Array.isArray(v)) return `${k}:
9393
+ ${v.map((item) => ` - ${item}`).join("\n")}`;
9394
+ return `${k}: ${v}`;
9395
+ }).join("\n");
9396
+ const content = `---
9397
+ ${yaml}
9398
+ ---
9399
+ ${parsed.content}`;
9400
+ await writeFile8(skill.filePath, content, "utf8");
9401
+ return { filepath: skill.filePath };
9402
+ }
9403
+ async function findSkillFile(name, cwd) {
9404
+ const all = await listAllSkills(cwd);
9405
+ const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
9406
+ return skill?.filePath ?? null;
9407
+ }
9408
+ var init_manager3 = __esm({
9409
+ "src/skills/manager.ts"() {
9410
+ "use strict";
9411
+ init_loader();
9412
+ }
9413
+ });
9414
+
9566
9415
  // src/sessions.ts
9567
9416
  var sessions_exports = {};
9568
9417
  __export(sessions_exports, {
@@ -9572,12 +9421,12 @@ __export(sessions_exports, {
9572
9421
  pruneSessions: () => pruneSessions,
9573
9422
  saveSession: () => saveSession
9574
9423
  });
9575
- import { readFile as readFile12, writeFile as writeFile8, mkdir as mkdir7, readdir as readdir3, stat as stat4 } from "fs/promises";
9424
+ import { readFile as readFile14, writeFile as writeFile9, mkdir as mkdir8, readdir as readdir4, stat as stat5 } from "fs/promises";
9576
9425
  import { homedir as homedir10 } from "os";
9577
- import { join as join15 } from "path";
9426
+ import { join as join17 } from "path";
9578
9427
  function sessionsDir2() {
9579
- const xdg = process.env.XDG_DATA_HOME || join15(homedir10(), ".local", "share");
9580
- return join15(xdg, "kimiflare", "sessions");
9428
+ const xdg = process.env.XDG_DATA_HOME || join17(homedir10(), ".local", "share");
9429
+ return join17(xdg, "kimiflare", "sessions");
9581
9430
  }
9582
9431
  function sanitize(text) {
9583
9432
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
@@ -9589,9 +9438,9 @@ function makeSessionId(firstPrompt) {
9589
9438
  }
9590
9439
  async function saveSession(file) {
9591
9440
  const dir = sessionsDir2();
9592
- await mkdir7(dir, { recursive: true });
9593
- const path = join15(dir, `${file.id}.json`);
9594
- await writeFile8(path, JSON.stringify(file, null, 2), "utf8");
9441
+ await mkdir8(dir, { recursive: true });
9442
+ const path = join17(dir, `${file.id}.json`);
9443
+ await writeFile9(path, JSON.stringify(file, null, 2), "utf8");
9595
9444
  return path;
9596
9445
  }
9597
9446
  async function pruneSessions() {
@@ -9603,16 +9452,16 @@ async function listSessions(limit = 30, cwd) {
9603
9452
  const dir = sessionsDir2();
9604
9453
  let entries;
9605
9454
  try {
9606
- entries = await readdir3(dir);
9455
+ entries = await readdir4(dir);
9607
9456
  } catch {
9608
9457
  return [];
9609
9458
  }
9610
9459
  const summaries = [];
9611
9460
  for (const name of entries) {
9612
9461
  if (!name.endsWith(".json")) continue;
9613
- const path = join15(dir, name);
9462
+ const path = join17(dir, name);
9614
9463
  try {
9615
- const [s, raw] = await Promise.all([stat4(path), readFile12(path, "utf8")]);
9464
+ const [s, raw] = await Promise.all([stat5(path), readFile14(path, "utf8")]);
9616
9465
  const parsed = JSON.parse(raw);
9617
9466
  if (cwd && parsed.cwd !== cwd) continue;
9618
9467
  const firstUser = parsed.messages.find((m) => m.role === "user");
@@ -9632,7 +9481,7 @@ async function listSessions(limit = 30, cwd) {
9632
9481
  return summaries.slice(0, limit);
9633
9482
  }
9634
9483
  async function loadSession(filePath) {
9635
- const raw = await readFile12(filePath, "utf8");
9484
+ const raw = await readFile14(filePath, "utf8");
9636
9485
  return JSON.parse(raw);
9637
9486
  }
9638
9487
  var init_sessions = __esm({
@@ -9643,10 +9492,10 @@ var init_sessions = __esm({
9643
9492
  });
9644
9493
 
9645
9494
  // src/util/image.ts
9646
- import { readFile as readFile13 } from "fs/promises";
9495
+ import { readFile as readFile15 } from "fs/promises";
9647
9496
  import { basename as basename3 } from "path";
9648
9497
  async function encodeImageFile(filePath) {
9649
- const buf = await readFile13(filePath);
9498
+ const buf = await readFile15(filePath);
9650
9499
  if (buf.byteLength > MAX_IMAGE_BYTES) {
9651
9500
  throw new Error(
9652
9501
  `image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
@@ -9682,15 +9531,15 @@ var init_image = __esm({
9682
9531
  });
9683
9532
 
9684
9533
  // src/usage-tracker.ts
9685
- import { readFile as readFile14, writeFile as writeFile9, mkdir as mkdir8 } from "fs/promises";
9534
+ import { readFile as readFile16, writeFile as writeFile10, mkdir as mkdir9 } from "fs/promises";
9686
9535
  import { homedir as homedir11 } from "os";
9687
- import { join as join16 } from "path";
9536
+ import { join as join18 } from "path";
9688
9537
  function usageDir2() {
9689
- const xdg = process.env.XDG_DATA_HOME || join16(homedir11(), ".local", "share");
9690
- return join16(xdg, "kimiflare");
9538
+ const xdg = process.env.XDG_DATA_HOME || join18(homedir11(), ".local", "share");
9539
+ return join18(xdg, "kimiflare");
9691
9540
  }
9692
9541
  function usagePath2() {
9693
- return join16(usageDir2(), "usage.json");
9542
+ return join18(usageDir2(), "usage.json");
9694
9543
  }
9695
9544
  function today2() {
9696
9545
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -9701,7 +9550,7 @@ function cutoffDate(daysBack) {
9701
9550
  }
9702
9551
  async function loadLog2() {
9703
9552
  try {
9704
- const raw = await readFile14(usagePath2(), "utf8");
9553
+ const raw = await readFile16(usagePath2(), "utf8");
9705
9554
  const parsed = JSON.parse(raw);
9706
9555
  if (parsed.version === LOG_VERSION2) return parsed;
9707
9556
  } catch {
@@ -9709,8 +9558,8 @@ async function loadLog2() {
9709
9558
  return { version: LOG_VERSION2, days: [], sessions: [] };
9710
9559
  }
9711
9560
  async function saveLog(log) {
9712
- await mkdir8(usageDir2(), { recursive: true });
9713
- await writeFile9(usagePath2(), JSON.stringify(log, null, 2), "utf8");
9561
+ await mkdir9(usageDir2(), { recursive: true });
9562
+ await writeFile10(usagePath2(), JSON.stringify(log, null, 2), "utf8");
9714
9563
  }
9715
9564
  function getOrCreateDay(log, date) {
9716
9565
  let day = log.days.find((d) => d.date === date);
@@ -9926,7 +9775,7 @@ __export(db_exports, {
9926
9775
  updateMemoryEmbedding: () => updateMemoryEmbedding
9927
9776
  });
9928
9777
  import Database from "better-sqlite3";
9929
- import { dirname as dirname7 } from "path";
9778
+ import { dirname as dirname8 } from "path";
9930
9779
  import { mkdirSync, statSync as statSync2 } from "fs";
9931
9780
  function initSchema(db) {
9932
9781
  db.exec(`
@@ -10011,7 +9860,7 @@ function openMemoryDb(dbPath) {
10011
9860
  if (dbInstance) {
10012
9861
  dbInstance.close();
10013
9862
  }
10014
- mkdirSync(dirname7(dbPath), { recursive: true });
9863
+ mkdirSync(dirname8(dbPath), { recursive: true });
10015
9864
  dbInstance = new Database(dbPath);
10016
9865
  dbInstance.pragma("journal_mode = WAL");
10017
9866
  dbInstance.pragma("foreign_keys = ON");
@@ -10661,7 +10510,7 @@ function pickTopicKey(content, existingKeys) {
10661
10510
  return normalized;
10662
10511
  }
10663
10512
  var SECRET_PATTERNS, VERIFY_SYSTEM, HYPOTHETICAL_QUERIES_SYSTEM, MemoryManager;
10664
- var init_manager3 = __esm({
10513
+ var init_manager4 = __esm({
10665
10514
  "src/memory/manager.ts"() {
10666
10515
  "use strict";
10667
10516
  init_client();
@@ -11006,16 +10855,16 @@ Context: This memory was explicitly provided by the user during a conversation.`
11006
10855
  });
11007
10856
 
11008
10857
  // src/util/state.ts
11009
- import { readFile as readFile15, writeFile as writeFile10, mkdir as mkdir9 } from "fs/promises";
10858
+ import { readFile as readFile17, writeFile as writeFile11, mkdir as mkdir10 } from "fs/promises";
11010
10859
  import { homedir as homedir12 } from "os";
11011
- import { join as join18 } from "path";
10860
+ import { join as join20 } from "path";
11012
10861
  function statePath() {
11013
- const xdg = process.env.XDG_CONFIG_HOME || join18(homedir12(), ".config");
11014
- return join18(xdg, "kimiflare", "state.json");
10862
+ const xdg = process.env.XDG_CONFIG_HOME || join20(homedir12(), ".config");
10863
+ return join20(xdg, "kimiflare", "state.json");
11015
10864
  }
11016
10865
  async function readState() {
11017
10866
  try {
11018
- const raw = await readFile15(statePath(), "utf8");
10867
+ const raw = await readFile17(statePath(), "utf8");
11019
10868
  return JSON.parse(raw);
11020
10869
  } catch {
11021
10870
  return {};
@@ -11023,8 +10872,8 @@ async function readState() {
11023
10872
  }
11024
10873
  async function writeState(state) {
11025
10874
  const path = statePath();
11026
- await mkdir9(join18(path, ".."), { recursive: true });
11027
- await writeFile10(path, JSON.stringify(state, null, 2) + "\n", "utf8");
10875
+ await mkdir10(join20(path, ".."), { recursive: true });
10876
+ await writeFile11(path, JSON.stringify(state, null, 2) + "\n", "utf8");
11028
10877
  }
11029
10878
  async function markCreatorMessageSeen(version) {
11030
10879
  const state = await readState();
@@ -11098,14 +10947,14 @@ var init_frontmatter = __esm({
11098
10947
  // src/commands/loader.ts
11099
10948
  import { open, realpath } from "fs/promises";
11100
10949
  import { homedir as homedir13 } from "os";
11101
- import { join as join19, relative as relative4, sep as sep2 } from "path";
10950
+ import { join as join21, relative as relative4, sep as sep2 } from "path";
11102
10951
  import fg3 from "fast-glob";
11103
10952
  function projectCommandsDir(cwd = process.cwd()) {
11104
- return join19(cwd, ".kimiflare", "commands");
10953
+ return join21(cwd, ".kimiflare", "commands");
11105
10954
  }
11106
10955
  function globalCommandsDir() {
11107
- const xdg = process.env.XDG_CONFIG_HOME || join19(homedir13(), ".config");
11108
- return join19(xdg, "kimiflare", "commands");
10956
+ const xdg = process.env.XDG_CONFIG_HOME || join21(homedir13(), ".config");
10957
+ return join21(xdg, "kimiflare", "commands");
11109
10958
  }
11110
10959
  async function loadCustomCommands(cwd = process.cwd()) {
11111
10960
  const warnings = [];
@@ -11244,7 +11093,7 @@ function filenameToCommandName(file, rootDir) {
11244
11093
  return parts.join("/");
11245
11094
  }
11246
11095
  var MAX_COMMAND_FILE_BYTES;
11247
- var init_loader = __esm({
11096
+ var init_loader2 = __esm({
11248
11097
  "src/commands/loader.ts"() {
11249
11098
  "use strict";
11250
11099
  init_mode();
@@ -11462,6 +11311,7 @@ var init_builtins = __esm({
11462
11311
  { name: "gateway", argHint: "[status|off|<id>|cache-ttl|skip-cache|...]", description: "Manage AI Gateway", source: "builtin" },
11463
11312
  { name: "mcp", argHint: "[list|reload]", description: "Manage MCP servers", source: "builtin" },
11464
11313
  { name: "lsp", argHint: "[config|list|reload|scope]", description: "Manage language servers", source: "builtin" },
11314
+ { name: "skills", argHint: "[list|add|edit|delete|enable|disable]", description: "Manage skills", source: "builtin" },
11465
11315
  { name: "command", argHint: "[create|edit|delete|list]", description: "Manage custom slash commands", source: "builtin" },
11466
11316
  { name: "resume", description: "Pick a past conversation to resume", source: "builtin" },
11467
11317
  { name: "compact", description: "Summarize old turns to free context", source: "builtin" },
@@ -11481,8 +11331,8 @@ var init_builtins = __esm({
11481
11331
  });
11482
11332
 
11483
11333
  // src/commands/save.ts
11484
- import { mkdir as mkdir10, writeFile as writeFile11, unlink as unlink2 } from "fs/promises";
11485
- import { dirname as dirname8 } from "path";
11334
+ import { mkdir as mkdir11, writeFile as writeFile12, unlink as unlink3 } from "fs/promises";
11335
+ import { dirname as dirname9 } from "path";
11486
11336
  async function saveCustomCommand(opts2) {
11487
11337
  const dir = opts2.source === "project" ? projectCommandsDir(opts2.cwd) : globalCommandsDir();
11488
11338
  const filepath = `${dir}/${opts2.name}.md`;
@@ -11493,37 +11343,37 @@ async function saveCustomCommand(opts2) {
11493
11343
  if (opts2.effort) data.effort = opts2.effort;
11494
11344
  const frontmatter = serializeFrontmatter(data);
11495
11345
  const content = frontmatter + opts2.template;
11496
- await mkdir10(dirname8(filepath), { recursive: true });
11497
- await writeFile11(filepath, content, "utf8");
11346
+ await mkdir11(dirname9(filepath), { recursive: true });
11347
+ await writeFile12(filepath, content, "utf8");
11498
11348
  return { filepath };
11499
11349
  }
11500
11350
  async function deleteCustomCommand(cmd) {
11501
- await unlink2(cmd.filepath);
11351
+ await unlink3(cmd.filepath);
11502
11352
  }
11503
11353
  var init_save = __esm({
11504
11354
  "src/commands/save.ts"() {
11505
11355
  "use strict";
11506
11356
  init_frontmatter();
11507
- init_loader();
11357
+ init_loader2();
11508
11358
  }
11509
11359
  });
11510
11360
 
11511
11361
  // src/ui/command-wizard.tsx
11512
- import { useState as useState9 } from "react";
11513
- import { Box as Box14, Text as Text15, useInput as useInput5, useWindowSize as useWindowSize2 } from "ink";
11514
- import SelectInput7 from "ink-select-input";
11515
- import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
11362
+ import { useState as useState8 } from "react";
11363
+ import { Box as Box13, Text as Text14, useInput as useInput4, useWindowSize as useWindowSize2 } from "ink";
11364
+ import SelectInput6 from "ink-select-input";
11365
+ import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
11516
11366
  function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onSave }) {
11517
11367
  const theme = useTheme();
11518
- const [step, setStep] = useState9("name");
11519
- const [name, setName] = useState9(initial?.name ?? "");
11520
- const [description, setDescription] = useState9(initial?.description ?? "");
11521
- const [template, setTemplate] = useState9(initial?.template ?? "");
11522
- const [cmdMode, setCmdMode] = useState9(initial?.mode);
11523
- const [cmdEffort, setCmdEffort] = useState9(initial?.effort);
11524
- const [cmdModel, setCmdModel] = useState9(initial?.model);
11525
- const [source, setSource] = useState9(initial?.source ?? "project");
11526
- const [error, setError] = useState9(null);
11368
+ const [step, setStep] = useState8("name");
11369
+ const [name, setName] = useState8(initial?.name ?? "");
11370
+ const [description, setDescription] = useState8(initial?.description ?? "");
11371
+ const [template, setTemplate] = useState8(initial?.template ?? "");
11372
+ const [cmdMode, setCmdMode] = useState8(initial?.mode);
11373
+ const [cmdEffort, setCmdEffort] = useState8(initial?.effort);
11374
+ const [cmdModel, setCmdModel] = useState8(initial?.model);
11375
+ const [source, setSource] = useState8(initial?.source ?? "project");
11376
+ const [error, setError] = useState8(null);
11527
11377
  const { columns } = useWindowSize2();
11528
11378
  const totalSteps = 5;
11529
11379
  const stepIndex = step === "name" ? 1 : step === "description" ? 2 : step === "template" ? 3 : step === "advanced" || step === "mode" || step === "effort" || step === "model" ? 4 : step === "location" ? 4 : 5;
@@ -11536,7 +11386,7 @@ function CommandWizard({ mode, initial, existingNames, builtinNames, onDone, onS
11536
11386
  if (existingNames.includes(trimmed) && !isEditingSelf(trimmed)) return `/${trimmed} already exists`;
11537
11387
  return null;
11538
11388
  };
11539
- useInput5((_input, key) => {
11389
+ useInput4((_input, key) => {
11540
11390
  if (key.escape) {
11541
11391
  onDone();
11542
11392
  }
@@ -11636,8 +11486,8 @@ ${template}`;
11636
11486
  const renderStep = () => {
11637
11487
  switch (step) {
11638
11488
  case "name":
11639
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11640
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11489
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11490
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11641
11491
  mode === "create" ? "Create" : "Edit",
11642
11492
  " custom command \u2014 Name (",
11643
11493
  stepIndex,
@@ -11645,8 +11495,8 @@ ${template}`;
11645
11495
  totalSteps,
11646
11496
  ")"
11647
11497
  ] }),
11648
- error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
11649
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11498
+ error && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: error }),
11499
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11650
11500
  CustomTextInput,
11651
11501
  {
11652
11502
  value: name,
@@ -11655,11 +11505,11 @@ ${template}`;
11655
11505
  focus: true
11656
11506
  }
11657
11507
  ) }),
11658
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
11508
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "letters, numbers, _ - / only; must start with a letter" })
11659
11509
  ] });
11660
11510
  case "description":
11661
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11662
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11511
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11512
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11663
11513
  mode === "create" ? "Create" : "Edit",
11664
11514
  " custom command \u2014 Description (",
11665
11515
  stepIndex,
@@ -11667,7 +11517,7 @@ ${template}`;
11667
11517
  totalSteps,
11668
11518
  ")"
11669
11519
  ] }),
11670
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11520
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11671
11521
  CustomTextInput,
11672
11522
  {
11673
11523
  value: description,
@@ -11676,49 +11526,49 @@ ${template}`;
11676
11526
  focus: true
11677
11527
  }
11678
11528
  ) }),
11679
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
11529
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Press Enter to skip" })
11680
11530
  ] });
11681
11531
  case "template": {
11682
- const guide = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", paddingLeft: 1, children: [
11683
- /* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "What is this?" }),
11684
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
11685
- /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
11532
+ const guide = /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingLeft: 1, children: [
11533
+ /* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "What is this?" }),
11534
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "A prompt template \u2014 instructions to the AI." }),
11535
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
11686
11536
  "When you type /",
11687
11537
  name || "yourcommand",
11688
11538
  " later, this gets sent to the model."
11689
11539
  ] }),
11690
- /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
11691
- /* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Variables" }),
11692
- /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
11540
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
11541
+ /* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "Variables" }),
11542
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
11693
11543
  " ",
11694
11544
  "$1, $2 ... \u2192 arguments you type"
11695
11545
  ] }),
11696
- /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
11546
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
11697
11547
  " ",
11698
11548
  "$ARGUMENTS \u2192 everything after the command"
11699
11549
  ] })
11700
11550
  ] }),
11701
- /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
11702
- /* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
11703
- /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
11551
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
11552
+ /* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "Dynamic inlines" }),
11553
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
11704
11554
  " ",
11705
11555
  "!`git diff` \u2192 shell output inlined"
11706
11556
  ] }),
11707
- /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
11557
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
11708
11558
  " ",
11709
11559
  "@README.md \u2192 file contents inlined"
11710
11560
  ] })
11711
11561
  ] }),
11712
- /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
11713
- /* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: "Example" }),
11714
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Review this PR diff:" }),
11715
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
11716
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Focus on: $1" })
11562
+ /* @__PURE__ */ jsxs13(Box13, { marginTop: 1, flexDirection: "column", children: [
11563
+ /* @__PURE__ */ jsx15(Text14, { color: theme.accent, bold: true, children: "Example" }),
11564
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Review this PR diff:" }),
11565
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "!`git diff main...HEAD`" }),
11566
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Focus on: $1" })
11717
11567
  ] })
11718
11568
  ] });
11719
- const inputArea = /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexGrow: 1, children: [
11720
- error && /* @__PURE__ */ jsx16(Text15, { color: theme.error, children: error }),
11721
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11569
+ const inputArea = /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", flexGrow: 1, children: [
11570
+ error && /* @__PURE__ */ jsx15(Text14, { color: theme.error, children: error }),
11571
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11722
11572
  CustomTextInput,
11723
11573
  {
11724
11574
  value: template,
@@ -11728,13 +11578,13 @@ ${template}`;
11728
11578
  enablePaste: true
11729
11579
  }
11730
11580
  ) }),
11731
- columns < 100 && /* @__PURE__ */ jsxs14(Fragment2, { children: [
11732
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
11733
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
11581
+ columns < 100 && /* @__PURE__ */ jsxs13(Fragment2, { children: [
11582
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Paste multi-line templates with Ctrl+V." }),
11583
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Variables: $1 $2 ... $ARGUMENTS Shell: !`cmd` File: @path" })
11734
11584
  ] })
11735
11585
  ] });
11736
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11737
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11586
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11587
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11738
11588
  mode === "create" ? "Create" : "Edit",
11739
11589
  " custom command \u2014 Template (",
11740
11590
  stepIndex,
@@ -11742,10 +11592,10 @@ ${template}`;
11742
11592
  totalSteps,
11743
11593
  ")"
11744
11594
  ] }),
11745
- columns >= 100 ? /* @__PURE__ */ jsxs14(Box14, { flexDirection: "row", marginTop: 1, children: [
11746
- /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: inputArea }),
11747
- /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", width: "50%", children: guide })
11748
- ] }) : /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", marginTop: 1, children: inputArea })
11595
+ columns >= 100 ? /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", marginTop: 1, children: [
11596
+ /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", width: "50%", children: inputArea }),
11597
+ /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", width: "50%", children: guide })
11598
+ ] }) : /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", marginTop: 1, children: inputArea })
11749
11599
  ] });
11750
11600
  }
11751
11601
  case "advanced": {
@@ -11754,8 +11604,8 @@ ${template}`;
11754
11604
  { label: "Skip", value: "skip", key: "skip" },
11755
11605
  { label: "\u2190 Cancel", value: "cancel", key: "cancel" }
11756
11606
  ];
11757
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11758
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11607
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11608
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11759
11609
  mode === "create" ? "Create" : "Edit",
11760
11610
  " custom command \u2014 Options (",
11761
11611
  stepIndex,
@@ -11763,8 +11613,8 @@ ${template}`;
11763
11613
  totalSteps,
11764
11614
  ")"
11765
11615
  ] }),
11766
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11767
- SelectInput7,
11616
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11617
+ SelectInput6,
11768
11618
  {
11769
11619
  items,
11770
11620
  onSelect: (item) => {
@@ -11783,17 +11633,17 @@ ${template}`;
11783
11633
  { label: cmdMode === "auto" ? "auto \xB7 current" : "auto", value: "auto", key: "auto" },
11784
11634
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
11785
11635
  ];
11786
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11787
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11636
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11637
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11788
11638
  "Mode override (",
11789
11639
  stepIndex,
11790
11640
  "/",
11791
11641
  totalSteps,
11792
11642
  ")"
11793
11643
  ] }),
11794
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
11795
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11796
- SelectInput7,
11644
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Saved to file but not yet enforced at runtime" }),
11645
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11646
+ SelectInput6,
11797
11647
  {
11798
11648
  items,
11799
11649
  onSelect: (item) => {
@@ -11812,16 +11662,16 @@ ${template}`;
11812
11662
  { label: cmdEffort === "high" ? "high \xB7 current" : "high", value: "high", key: "high" },
11813
11663
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
11814
11664
  ];
11815
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11816
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11665
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11666
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11817
11667
  "Reasoning effort (",
11818
11668
  stepIndex,
11819
11669
  "/",
11820
11670
  totalSteps,
11821
11671
  ")"
11822
11672
  ] }),
11823
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11824
- SelectInput7,
11673
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11674
+ SelectInput6,
11825
11675
  {
11826
11676
  items,
11827
11677
  onSelect: (item) => {
@@ -11833,15 +11683,15 @@ ${template}`;
11833
11683
  ] });
11834
11684
  }
11835
11685
  case "model":
11836
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11837
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11686
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11687
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11838
11688
  "Model override (",
11839
11689
  stepIndex,
11840
11690
  "/",
11841
11691
  totalSteps,
11842
11692
  ")"
11843
11693
  ] }),
11844
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11694
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11845
11695
  CustomTextInput,
11846
11696
  {
11847
11697
  value: cmdModel ?? "",
@@ -11850,7 +11700,7 @@ ${template}`;
11850
11700
  focus: true
11851
11701
  }
11852
11702
  ) }),
11853
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Press Enter to skip" })
11703
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Press Enter to skip" })
11854
11704
  ] });
11855
11705
  case "location": {
11856
11706
  const items = [
@@ -11858,16 +11708,16 @@ ${template}`;
11858
11708
  { label: source === "global" ? "Global \xB7 current" : "Global", value: "global", key: "global" },
11859
11709
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
11860
11710
  ];
11861
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11862
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11711
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11712
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11863
11713
  "Save location (",
11864
11714
  stepIndex,
11865
11715
  "/",
11866
11716
  totalSteps,
11867
11717
  ")"
11868
11718
  ] }),
11869
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11870
- SelectInput7,
11719
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11720
+ SelectInput6,
11871
11721
  {
11872
11722
  items,
11873
11723
  onSelect: (item) => {
@@ -11876,7 +11726,7 @@ ${template}`;
11876
11726
  }
11877
11727
  }
11878
11728
  ) }),
11879
- /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
11729
+ /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: "Project: .kimiflare/commands/ Global: ~/.config/kimiflare/commands/" })
11880
11730
  ] });
11881
11731
  }
11882
11732
  case "confirm": {
@@ -11884,8 +11734,8 @@ ${template}`;
11884
11734
  { label: "Save", value: "save", key: "save" },
11885
11735
  { label: "Cancel", value: "cancel", key: "cancel" }
11886
11736
  ];
11887
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
11888
- /* @__PURE__ */ jsxs14(Text15, { color: theme.accent, bold: true, children: [
11737
+ return /* @__PURE__ */ jsxs13(Fragment2, { children: [
11738
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.accent, bold: true, children: [
11889
11739
  mode === "create" ? "Create" : "Edit",
11890
11740
  " custom command \u2014 Confirm (",
11891
11741
  stepIndex,
@@ -11893,14 +11743,14 @@ ${template}`;
11893
11743
  totalSteps,
11894
11744
  ")"
11895
11745
  ] }),
11896
- /* @__PURE__ */ jsxs14(Text15, { color: theme.info.color, children: [
11746
+ /* @__PURE__ */ jsxs13(Text14, { color: theme.info.color, children: [
11897
11747
  source === "project" ? ".kimiflare/commands/" : "~/.config/kimiflare/commands/",
11898
11748
  name,
11899
11749
  ".md"
11900
11750
  ] }),
11901
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, children: line || " " }, i)) }),
11902
- /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
11903
- SelectInput7,
11751
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, flexDirection: "column", children: previewContent().split("\n").map((line, i) => /* @__PURE__ */ jsx15(Text14, { color: theme.info.color, children: line || " " }, i)) }),
11752
+ /* @__PURE__ */ jsx15(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx15(
11753
+ SelectInput6,
11904
11754
  {
11905
11755
  items,
11906
11756
  onSelect: (item) => handleConfirm(item.value)
@@ -11910,7 +11760,7 @@ ${template}`;
11910
11760
  }
11911
11761
  }
11912
11762
  };
11913
- return /* @__PURE__ */ jsx16(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
11763
+ return /* @__PURE__ */ jsx15(Box13, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: renderStep() });
11914
11764
  }
11915
11765
  var NAME_RE;
11916
11766
  var init_command_wizard = __esm({
@@ -11924,12 +11774,12 @@ var init_command_wizard = __esm({
11924
11774
 
11925
11775
  // src/init/context-generator.ts
11926
11776
  import { existsSync as existsSync2, statSync as statSync3 } from "fs";
11927
- import { join as join20 } from "path";
11777
+ import { join as join22 } from "path";
11928
11778
  function detectFlavor(cwd) {
11929
11779
  for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
11930
11780
  if (flavor === "generic") continue;
11931
11781
  for (const sig of signatures) {
11932
- const path = join20(cwd, sig);
11782
+ const path = join22(cwd, sig);
11933
11783
  if (sig.includes("*")) {
11934
11784
  try {
11935
11785
  const parts = sig.split("*");
@@ -11950,14 +11800,14 @@ function detectFlavor(cwd) {
11950
11800
  }
11951
11801
  function findFile(cwd, candidates) {
11952
11802
  for (const c of candidates) {
11953
- if (existsSync2(join20(cwd, c))) return c;
11803
+ if (existsSync2(join22(cwd, c))) return c;
11954
11804
  }
11955
11805
  return null;
11956
11806
  }
11957
11807
  function findSourceRoots(cwd) {
11958
11808
  const roots = [];
11959
11809
  for (const r of SOURCE_ROOT_CANDIDATES) {
11960
- const p = join20(cwd, r);
11810
+ const p = join22(cwd, r);
11961
11811
  try {
11962
11812
  const s = statSync3(p);
11963
11813
  if (s.isDirectory()) roots.push(r);
@@ -11968,9 +11818,9 @@ function findSourceRoots(cwd) {
11968
11818
  }
11969
11819
  function findCiConfig(cwd) {
11970
11820
  for (const c of CI_PATHS) {
11971
- if (existsSync2(join20(cwd, c))) {
11821
+ if (existsSync2(join22(cwd, c))) {
11972
11822
  try {
11973
- const s = statSync3(join20(cwd, c));
11823
+ const s = statSync3(join22(cwd, c));
11974
11824
  return s.isDirectory() ? c : c;
11975
11825
  } catch {
11976
11826
  }
@@ -12107,7 +11957,7 @@ function analyzeProject(cwd) {
12107
11957
  ciConfig: findCiConfig(cwd),
12108
11958
  readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
12109
11959
  sourceRoots: findSourceRoots(cwd),
12110
- hasGit: existsSync2(join20(cwd, ".git"))
11960
+ hasGit: existsSync2(join22(cwd, ".git"))
12111
11961
  };
12112
11962
  }
12113
11963
  function bashDiscoveryCommands(profile) {
@@ -12272,7 +12122,7 @@ Aim for 100\u2013200 lines total. Use markdown tables where they save space.
12272
12122
  }
12273
12123
  function buildInitPrompt(cwd) {
12274
12124
  const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
12275
- (n) => existsSync2(join20(cwd, n))
12125
+ (n) => existsSync2(join22(cwd, n))
12276
12126
  );
12277
12127
  const isRefresh = existingName !== void 0;
12278
12128
  const targetFilename = existingName ?? "KIMI.md";
@@ -12355,9 +12205,9 @@ var init_context_generator = __esm({
12355
12205
  });
12356
12206
 
12357
12207
  // src/ui/command-picker.tsx
12358
- import { Box as Box15, Text as Text16 } from "ink";
12359
- import SelectInput8 from "ink-select-input";
12360
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
12208
+ import { Box as Box14, Text as Text15 } from "ink";
12209
+ import SelectInput7 from "ink-select-input";
12210
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
12361
12211
  function CommandPicker({ commands, title, onPick }) {
12362
12212
  const theme = useTheme();
12363
12213
  const items = commands.map((cmd) => ({
@@ -12366,11 +12216,11 @@ function CommandPicker({ commands, title, onPick }) {
12366
12216
  key: cmd.name
12367
12217
  }));
12368
12218
  items.push({ label: "\u2190 Cancel", value: null, key: "__cancel__" });
12369
- return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12370
- /* @__PURE__ */ jsx17(Text16, { color: theme.accent, bold: true, children: title }),
12371
- /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
12372
- /* @__PURE__ */ jsx17(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx17(
12373
- SelectInput8,
12219
+ return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12220
+ /* @__PURE__ */ jsx16(Text15, { color: theme.accent, bold: true, children: title }),
12221
+ /* @__PURE__ */ jsx16(Text15, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
12222
+ /* @__PURE__ */ jsx16(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx16(
12223
+ SelectInput7,
12374
12224
  {
12375
12225
  items,
12376
12226
  onSelect: (item) => {
@@ -12392,64 +12242,64 @@ var init_command_picker = __esm({
12392
12242
  });
12393
12243
 
12394
12244
  // src/ui/command-list.tsx
12395
- import { Box as Box16, Text as Text17, useInput as useInput6 } from "ink";
12396
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
12245
+ import { Box as Box15, Text as Text16, useInput as useInput5 } from "ink";
12246
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
12397
12247
  function CommandList({ commands, onDone }) {
12398
12248
  const theme = useTheme();
12399
- useInput6((_input, key) => {
12249
+ useInput5((_input, key) => {
12400
12250
  if (key.escape) {
12401
12251
  onDone();
12402
12252
  }
12403
12253
  });
12404
- return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12405
- /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom commands" }),
12406
- /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
12407
- /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
12408
- commands.length === 0 && /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No custom commands found." }),
12409
- commands.map((cmd) => /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginBottom: 1, children: [
12410
- /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
12254
+ return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12255
+ /* @__PURE__ */ jsx17(Text16, { color: theme.accent, bold: true, children: "Custom commands" }),
12256
+ /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, dimColor: false, children: "Esc to close." }),
12257
+ /* @__PURE__ */ jsxs15(Box15, { marginTop: 1, flexDirection: "column", children: [
12258
+ commands.length === 0 && /* @__PURE__ */ jsx17(Text16, { color: theme.info.color, children: "No custom commands found." }),
12259
+ commands.map((cmd) => /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginBottom: 1, children: [
12260
+ /* @__PURE__ */ jsxs15(Text16, { color: theme.accent, bold: true, children: [
12411
12261
  "/",
12412
12262
  cmd.name
12413
12263
  ] }),
12414
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12264
+ /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12415
12265
  " ",
12416
12266
  "source: ",
12417
12267
  cmd.source
12418
12268
  ] }),
12419
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12269
+ /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12420
12270
  " ",
12421
12271
  "path: ",
12422
12272
  cmd.filepath
12423
12273
  ] }),
12424
- cmd.description && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12274
+ cmd.description && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12425
12275
  " ",
12426
12276
  "desc: ",
12427
12277
  cmd.description
12428
12278
  ] }),
12429
- cmd.mode && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12279
+ cmd.mode && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12430
12280
  " ",
12431
12281
  "mode: ",
12432
12282
  cmd.mode
12433
12283
  ] }),
12434
- cmd.effort && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12284
+ cmd.effort && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12435
12285
  " ",
12436
12286
  "effort: ",
12437
12287
  cmd.effort
12438
12288
  ] }),
12439
- cmd.model && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12289
+ cmd.model && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12440
12290
  " ",
12441
12291
  "model: ",
12442
12292
  cmd.model
12443
12293
  ] }),
12444
- /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12294
+ /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12445
12295
  " ",
12446
12296
  "template:"
12447
12297
  ] }),
12448
- cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12298
+ cmd.template.split("\n").slice(0, 5).map((line, i) => /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12449
12299
  " ",
12450
12300
  line || " "
12451
12301
  ] }, i)),
12452
- cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs16(Text17, { color: theme.info.color, children: [
12302
+ cmd.template.split("\n").length > 5 && /* @__PURE__ */ jsxs15(Text16, { color: theme.info.color, children: [
12453
12303
  " ",
12454
12304
  "..."
12455
12305
  ] })
@@ -12465,20 +12315,20 @@ var init_command_list = __esm({
12465
12315
  });
12466
12316
 
12467
12317
  // src/ui/lsp-wizard.tsx
12468
- import { useState as useState10 } from "react";
12469
- import { Box as Box17, Text as Text18 } from "ink";
12470
- import SelectInput9 from "ink-select-input";
12318
+ import { useState as useState9 } from "react";
12319
+ import { Box as Box16, Text as Text17 } from "ink";
12320
+ import SelectInput8 from "ink-select-input";
12471
12321
  import { spawn as spawn3 } from "child_process";
12472
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
12322
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
12473
12323
  function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12474
12324
  const theme = useTheme();
12475
- const [page, setPage] = useState10("main");
12476
- const [selectedPreset, setSelectedPreset] = useState10(null);
12477
- const [customName, setCustomName] = useState10("");
12478
- const [customCommand, setCustomCommand] = useState10("");
12479
- const [installState, setInstallState] = useState10({ status: "idle", output: "" });
12480
- const [pendingServers, setPendingServers] = useState10(null);
12481
- const [pendingEnabled, setPendingEnabled] = useState10(true);
12325
+ const [page, setPage] = useState9("main");
12326
+ const [selectedPreset, setSelectedPreset] = useState9(null);
12327
+ const [customName, setCustomName] = useState9("");
12328
+ const [customCommand, setCustomCommand] = useState9("");
12329
+ const [installState, setInstallState] = useState9({ status: "idle", output: "" });
12330
+ const [pendingServers, setPendingServers] = useState9(null);
12331
+ const [pendingEnabled, setPendingEnabled] = useState9(true);
12482
12332
  const runInstall = (command) => {
12483
12333
  setInstallState({ status: "running", output: "Installing..." });
12484
12334
  const child = spawn3("bash", ["-lc", command], {
@@ -12580,11 +12430,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12580
12430
  { label: "(close)", value: "__close__", key: "__close__" }
12581
12431
  ];
12582
12432
  if (page === "main") {
12583
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12584
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "LSP Servers" }),
12585
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
12586
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12587
- SelectInput9,
12433
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12434
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "LSP Servers" }),
12435
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select." }),
12436
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12437
+ SelectInput8,
12588
12438
  {
12589
12439
  items: mainItems,
12590
12440
  onSelect: (item) => {
@@ -12611,11 +12461,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12611
12461
  }),
12612
12462
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
12613
12463
  ];
12614
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12615
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Add LSP Server" }),
12616
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
12617
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12618
- SelectInput9,
12464
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12465
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Add LSP Server" }),
12466
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a language server to configure." }),
12467
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12468
+ SelectInput8,
12619
12469
  {
12620
12470
  items,
12621
12471
  onSelect: (item) => {
@@ -12642,19 +12492,19 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12642
12492
  { label: isSuccess ? "Save to config \u2713" : "Save anyway", value: "save", key: "save" },
12643
12493
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
12644
12494
  ];
12645
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12646
- /* @__PURE__ */ jsxs17(Text18, { color: theme.accent, bold: true, children: [
12495
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12496
+ /* @__PURE__ */ jsxs16(Text17, { color: theme.accent, bold: true, children: [
12647
12497
  "Install ",
12648
12498
  selectedPreset.name
12649
12499
  ] }),
12650
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
12651
- /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, flexDirection: "column", children: [
12652
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Command:" }),
12653
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
12500
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: selectedPreset.installHint }),
12501
+ /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, flexDirection: "column", children: [
12502
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Command:" }),
12503
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: selectedPreset.installCommand || "(none required)" })
12654
12504
  ] }),
12655
- installState.output && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx19(Text18, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
12656
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12657
- SelectInput9,
12505
+ installState.output && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx18(Text17, { color: isSuccess ? theme.accent : theme.error, children: installState.output.slice(-500) }) }),
12506
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12507
+ SelectInput8,
12658
12508
  {
12659
12509
  items,
12660
12510
  onSelect: (item) => {
@@ -12671,16 +12521,16 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12671
12521
  }
12672
12522
  }
12673
12523
  ) }),
12674
- isSuccess && /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
12524
+ isSuccess && /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "Server saved. Run /lsp reload to start it." }) })
12675
12525
  ] });
12676
12526
  }
12677
12527
  if (page === "custom-name") {
12678
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12679
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
12680
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
12681
- /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
12682
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
12683
- /* @__PURE__ */ jsx19(
12528
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12529
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Name" }),
12530
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Enter a name for this server (e.g., my-server)." }),
12531
+ /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, children: [
12532
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "\u203A " }),
12533
+ /* @__PURE__ */ jsx18(
12684
12534
  CustomTextInput,
12685
12535
  {
12686
12536
  value: customName,
@@ -12694,8 +12544,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12694
12544
  }
12695
12545
  )
12696
12546
  ] }),
12697
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12698
- SelectInput9,
12547
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12548
+ SelectInput8,
12699
12549
  {
12700
12550
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
12701
12551
  onSelect: () => setPage("add")
@@ -12704,12 +12554,12 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12704
12554
  ] });
12705
12555
  }
12706
12556
  if (page === "custom-command") {
12707
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12708
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
12709
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
12710
- /* @__PURE__ */ jsxs17(Box17, { marginTop: 1, children: [
12711
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, children: "\u203A " }),
12712
- /* @__PURE__ */ jsx19(
12557
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12558
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Custom LSP Server \u2014 Command" }),
12559
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Enter the command to start the server (space-separated)." }),
12560
+ /* @__PURE__ */ jsxs16(Box16, { marginTop: 1, children: [
12561
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, children: "\u203A " }),
12562
+ /* @__PURE__ */ jsx18(
12713
12563
  CustomTextInput,
12714
12564
  {
12715
12565
  value: customCommand,
@@ -12723,8 +12573,8 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12723
12573
  }
12724
12574
  )
12725
12575
  ] }),
12726
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12727
- SelectInput9,
12576
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12577
+ SelectInput8,
12728
12578
  {
12729
12579
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
12730
12580
  onSelect: () => setPage("custom-name")
@@ -12747,11 +12597,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12747
12597
  },
12748
12598
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
12749
12599
  ];
12750
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12751
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Save LSP Config" }),
12752
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
12753
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12754
- SelectInput9,
12600
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12601
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Save LSP Config" }),
12602
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Where should this server configuration be saved?" }),
12603
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12604
+ SelectInput8,
12755
12605
  {
12756
12606
  items,
12757
12607
  onSelect: (item) => {
@@ -12769,11 +12619,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12769
12619
  if (page === "edit") {
12770
12620
  const keys = Object.keys(servers);
12771
12621
  if (keys.length === 0) {
12772
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12773
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
12774
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
12775
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12776
- SelectInput9,
12622
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12623
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
12624
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }),
12625
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12626
+ SelectInput8,
12777
12627
  {
12778
12628
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
12779
12629
  onSelect: () => setPage("main")
@@ -12793,11 +12643,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12793
12643
  }),
12794
12644
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
12795
12645
  ];
12796
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12797
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
12798
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
12799
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12800
- SelectInput9,
12646
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12647
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Edit LSP Server" }),
12648
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a server to toggle enabled/disabled." }),
12649
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12650
+ SelectInput8,
12801
12651
  {
12802
12652
  items,
12803
12653
  onSelect: (item) => {
@@ -12814,11 +12664,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12814
12664
  if (page === "delete") {
12815
12665
  const keys = Object.keys(servers);
12816
12666
  if (keys.length === 0) {
12817
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12818
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
12819
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }),
12820
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12821
- SelectInput9,
12667
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12668
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
12669
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }),
12670
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12671
+ SelectInput8,
12822
12672
  {
12823
12673
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
12824
12674
  onSelect: () => setPage("main")
@@ -12834,11 +12684,11 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12834
12684
  })),
12835
12685
  { label: "\u2190 Back", value: "__back__", key: "__back__" }
12836
12686
  ];
12837
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12838
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
12839
- /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
12840
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12841
- SelectInput9,
12687
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12688
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Delete LSP Server" }),
12689
+ /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, dimColor: false, children: "Select a server to remove from config." }),
12690
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12691
+ SelectInput8,
12842
12692
  {
12843
12693
  items,
12844
12694
  onSelect: (item) => {
@@ -12854,15 +12704,15 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
12854
12704
  }
12855
12705
  if (page === "list") {
12856
12706
  const keys = Object.keys(servers);
12857
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12858
- /* @__PURE__ */ jsx19(Text18, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
12859
- keys.length === 0 ? /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx19(Box17, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
12707
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
12708
+ /* @__PURE__ */ jsx18(Text17, { color: theme.accent, bold: true, children: "Configured LSP Servers" }),
12709
+ keys.length === 0 ? /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: "No servers configured." }) : /* @__PURE__ */ jsx18(Box16, { marginTop: 1, flexDirection: "column", children: keys.map((k) => {
12860
12710
  const s = servers[k];
12861
12711
  const status = s.enabled !== false ? "enabled" : "disabled";
12862
- return /* @__PURE__ */ jsx19(Text18, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
12712
+ return /* @__PURE__ */ jsx18(Text17, { color: theme.info.color, children: ` ${k.padEnd(16)} ${status} ${s.command.join(" ")}` }, k);
12863
12713
  }) }),
12864
- /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12865
- SelectInput9,
12714
+ /* @__PURE__ */ jsx18(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx18(
12715
+ SelectInput8,
12866
12716
  {
12867
12717
  items: [{ label: "\u2190 Back", value: "__back__", key: "__back__" }],
12868
12718
  onSelect: () => setPage("main")
@@ -12988,9 +12838,9 @@ var init_lsp_wizard = __esm({
12988
12838
  });
12989
12839
 
12990
12840
  // src/ui/theme-picker.tsx
12991
- import { Box as Box18, Text as Text19 } from "ink";
12992
- import SelectInput10 from "ink-select-input";
12993
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
12841
+ import { Box as Box17, Text as Text18 } from "ink";
12842
+ import SelectInput9 from "ink-select-input";
12843
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
12994
12844
  function PaletteSwatches({ palette }) {
12995
12845
  const colors = [
12996
12846
  palette.primary,
@@ -12998,7 +12848,7 @@ function PaletteSwatches({ palette }) {
12998
12848
  palette.success,
12999
12849
  palette.error
13000
12850
  ];
13001
- return /* @__PURE__ */ jsx20(Box18, { children: colors.map((c, i) => /* @__PURE__ */ jsx20(Text19, { color: c, children: "\u2588" }, i)) });
12851
+ return /* @__PURE__ */ jsx19(Box17, { children: colors.map((c, i) => /* @__PURE__ */ jsx19(Text18, { color: c, children: "\u2588" }, i)) });
13002
12852
  }
13003
12853
  function ThemePicker({ themes, onPick }) {
13004
12854
  const current = useTheme();
@@ -13006,10 +12856,10 @@ function ThemePicker({ themes, onPick }) {
13006
12856
  ...themes.map((t) => ({ label: t.label, value: t.name })),
13007
12857
  { label: "< Back", value: "__back__" }
13008
12858
  ];
13009
- return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
13010
- /* @__PURE__ */ jsx20(Text19, { color: current.accent, bold: true, children: "Pick a theme (restart to apply)" }),
13011
- /* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(
13012
- SelectInput10,
12859
+ return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", borderStyle: "round", borderColor: current.accent, paddingX: 1, children: [
12860
+ /* @__PURE__ */ jsx19(Text18, { color: current.accent, bold: true, children: "Pick a theme (restart to apply)" }),
12861
+ /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(
12862
+ SelectInput9,
13013
12863
  {
13014
12864
  items,
13015
12865
  onSelect: (item) => {
@@ -13023,9 +12873,9 @@ function ThemePicker({ themes, onPick }) {
13023
12873
  itemComponent: ({ label, isSelected }) => {
13024
12874
  const t = themes.find((x) => x.label === label);
13025
12875
  const color = t?.accent ?? current.accent;
13026
- return /* @__PURE__ */ jsxs18(Box18, { children: [
13027
- /* @__PURE__ */ jsx20(Text19, { color, bold: isSelected, dimColor: !isSelected, children: label }),
13028
- t && /* @__PURE__ */ jsx20(Box18, { marginLeft: 1, children: /* @__PURE__ */ jsx20(PaletteSwatches, { palette: t.palette }) })
12876
+ return /* @__PURE__ */ jsxs17(Box17, { children: [
12877
+ /* @__PURE__ */ jsx19(Text18, { color, bold: isSelected, dimColor: !isSelected, children: label }),
12878
+ t && /* @__PURE__ */ jsx19(Box17, { marginLeft: 1, children: /* @__PURE__ */ jsx19(PaletteSwatches, { palette: t.palette }) })
13029
12879
  ] });
13030
12880
  }
13031
12881
  }
@@ -13755,11 +13605,11 @@ var init_wcag = __esm({
13755
13605
  });
13756
13606
 
13757
13607
  // src/ui/theme-loader.ts
13758
- import { readFile as readFile16, readdir as readdir4 } from "fs/promises";
13759
- import { join as join21 } from "path";
13608
+ import { readFile as readFile18, readdir as readdir5 } from "fs/promises";
13609
+ import { join as join23 } from "path";
13760
13610
  import { homedir as homedir14 } from "os";
13761
13611
  function projectThemesDir(cwd = process.cwd()) {
13762
- return join21(cwd, ".kimiflare", "themes");
13612
+ return join23(cwd, ".kimiflare", "themes");
13763
13613
  }
13764
13614
  function isHexColor(c) {
13765
13615
  return /^#[0-9a-fA-F]{6}$/.test(c);
@@ -13844,15 +13694,15 @@ async function loadThemesFromDir(dir, source) {
13844
13694
  const errors = [];
13845
13695
  let files;
13846
13696
  try {
13847
- files = await readdir4(dir);
13697
+ files = await readdir5(dir);
13848
13698
  } catch {
13849
13699
  return { themes, errors };
13850
13700
  }
13851
13701
  for (const file of files.filter((f) => f.endsWith(".json"))) {
13852
- const path = join21(dir, file);
13702
+ const path = join23(dir, file);
13853
13703
  let raw;
13854
13704
  try {
13855
- raw = await readFile16(path, "utf-8");
13705
+ raw = await readFile18(path, "utf-8");
13856
13706
  } catch (e) {
13857
13707
  errors.push(`${path}: ${e instanceof Error ? e.message : String(e)}`);
13858
13708
  continue;
@@ -13997,8 +13847,8 @@ var init_theme_loader = __esm({
13997
13847
  "use strict";
13998
13848
  init_wcag();
13999
13849
  init_theme();
14000
- USER_THEMES_DIR = join21(
14001
- process.env.XDG_CONFIG_HOME || join21(homedir14(), ".config"),
13850
+ USER_THEMES_DIR = join23(
13851
+ process.env.XDG_CONFIG_HOME || join23(homedir14(), ".config"),
14002
13852
  "kimiflare",
14003
13853
  "themes"
14004
13854
  );
@@ -14055,8 +13905,8 @@ var init_lsp_nudge = __esm({
14055
13905
  });
14056
13906
 
14057
13907
  // src/ui/file-picker.tsx
14058
- import { Box as Box19, Text as Text20 } from "ink";
14059
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
13908
+ import { Box as Box18, Text as Text19 } from "ink";
13909
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
14060
13910
  function FilePicker({ items, selectedIndex, query }) {
14061
13911
  const theme = useTheme();
14062
13912
  let startIndex = 0;
@@ -14066,12 +13916,12 @@ function FilePicker({ items, selectedIndex, query }) {
14066
13916
  const visible = items.slice(startIndex, startIndex + VISIBLE_LIMIT);
14067
13917
  const hasMoreAbove = startIndex > 0;
14068
13918
  const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT;
14069
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
14070
- /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
14071
- /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
14072
- /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
14073
- visible.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No matches" }),
14074
- hasMoreAbove && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
13919
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
13920
+ /* @__PURE__ */ jsx20(Text19, { color: theme.accent, bold: true, children: query ? `Files matching "${query}"` : "Mention a file" }),
13921
+ /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
13922
+ /* @__PURE__ */ jsxs18(Box18, { marginTop: 1, flexDirection: "column", children: [
13923
+ visible.length === 0 && /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, children: "No matches" }),
13924
+ hasMoreAbove && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
14075
13925
  "\u2026 ",
14076
13926
  startIndex,
14077
13927
  " more above"
@@ -14080,12 +13930,12 @@ function FilePicker({ items, selectedIndex, query }) {
14080
13930
  const actualIndex = startIndex + i;
14081
13931
  const isSelected = actualIndex === selectedIndex;
14082
13932
  const label = item.isDirectory ? `${item.name}/` : item.name;
14083
- return /* @__PURE__ */ jsxs19(Text20, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
13933
+ return /* @__PURE__ */ jsxs18(Text19, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
14084
13934
  isSelected ? "\u203A " : " ",
14085
13935
  label
14086
13936
  ] }, item.name);
14087
13937
  }),
14088
- hasMoreBelow && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
13938
+ hasMoreBelow && /* @__PURE__ */ jsxs18(Text19, { color: theme.info.color, children: [
14089
13939
  "\u2026 ",
14090
13940
  items.length - (startIndex + VISIBLE_LIMIT),
14091
13941
  " more below"
@@ -14103,8 +13953,8 @@ var init_file_picker = __esm({
14103
13953
  });
14104
13954
 
14105
13955
  // src/ui/slash-picker.tsx
14106
- import { Box as Box20, Text as Text21 } from "ink";
14107
- import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
13956
+ import { Box as Box19, Text as Text20 } from "ink";
13957
+ import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
14108
13958
  function sourceBadge(source) {
14109
13959
  if (source === "builtin") return "";
14110
13960
  if (source === "project") return "project";
@@ -14124,12 +13974,12 @@ function SlashPicker({ items, selectedIndex, query }) {
14124
13974
  const hasMoreBelow = items.length > startIndex + VISIBLE_LIMIT2;
14125
13975
  const longestLabel = visible.reduce((m, it) => Math.max(m, commandLabel(it).length), 0);
14126
13976
  const nameColWidth = Math.max(NAME_COL_MIN_WIDTH, longestLabel + NAME_DESC_GAP);
14127
- return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
14128
- /* @__PURE__ */ jsx22(Text21, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
14129
- /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
14130
- /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, flexDirection: "column", children: [
14131
- visible.length === 0 && /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: "No matches" }),
14132
- hasMoreAbove && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
13977
+ return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
13978
+ /* @__PURE__ */ jsx21(Text20, { color: theme.accent, bold: true, children: query ? `Commands matching "/${query}"` : "Slash commands" }),
13979
+ /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
13980
+ /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
13981
+ visible.length === 0 && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "No matches" }),
13982
+ hasMoreAbove && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
14133
13983
  "\u2026 ",
14134
13984
  startIndex,
14135
13985
  " more above"
@@ -14139,16 +13989,16 @@ function SlashPicker({ items, selectedIndex, query }) {
14139
13989
  const isSelected = actualIndex === selectedIndex;
14140
13990
  const nameCol = commandLabel(item).padEnd(nameColWidth);
14141
13991
  const badge = sourceBadge(item.source);
14142
- return /* @__PURE__ */ jsxs20(Text21, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
13992
+ return /* @__PURE__ */ jsxs19(Text20, { color: isSelected ? theme.accent : void 0, bold: isSelected, children: [
14143
13993
  isSelected ? "\u203A " : " ",
14144
13994
  nameCol,
14145
- /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
13995
+ /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
14146
13996
  item.description,
14147
13997
  badge && ` [${badge}]`
14148
13998
  ] })
14149
13999
  ] }, item.name);
14150
14000
  }),
14151
- hasMoreBelow && /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
14001
+ hasMoreBelow && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
14152
14002
  "\u2026 ",
14153
14003
  items.length - (startIndex + VISIBLE_LIMIT2),
14154
14004
  " more below"
@@ -14228,15 +14078,15 @@ var tui_report_exports = {};
14228
14078
  __export(tui_report_exports, {
14229
14079
  getCategoryReportText: () => getCategoryReportText
14230
14080
  });
14231
- import { readFile as readFile17 } from "fs/promises";
14232
- import { join as join22 } from "path";
14081
+ import { readFile as readFile19 } from "fs/promises";
14082
+ import { join as join24 } from "path";
14233
14083
  import { homedir as homedir15 } from "os";
14234
14084
  function usageDir3() {
14235
- const xdg = process.env.XDG_DATA_HOME || join22(homedir15(), ".local", "share");
14236
- return join22(xdg, "kimiflare");
14085
+ const xdg = process.env.XDG_DATA_HOME || join24(homedir15(), ".local", "share");
14086
+ return join24(xdg, "kimiflare");
14237
14087
  }
14238
14088
  function usagePath3() {
14239
- return join22(usageDir3(), "usage.json");
14089
+ return join24(usageDir3(), "usage.json");
14240
14090
  }
14241
14091
  function today3() {
14242
14092
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -14248,7 +14098,7 @@ function daysAgo2(n) {
14248
14098
  }
14249
14099
  async function loadLog3() {
14250
14100
  try {
14251
- const raw = await readFile17(usagePath3(), "utf8");
14101
+ const raw = await readFile19(usagePath3(), "utf8");
14252
14102
  return JSON.parse(raw);
14253
14103
  } catch {
14254
14104
  return { version: 1, days: [], sessions: [] };
@@ -14314,18 +14164,18 @@ __export(app_exports, {
14314
14164
  shouldOpenMentionPicker: () => shouldOpenMentionPicker,
14315
14165
  shouldOpenSlashPicker: () => shouldOpenSlashPicker
14316
14166
  });
14317
- import React14, { useState as useState11, useRef as useRef3, useEffect as useEffect7, useCallback as useCallback2 } from "react";
14318
- import { Box as Box21, Text as Text22, useApp, useInput as useInput7, render } from "ink";
14319
- import SelectInput11 from "ink-select-input";
14167
+ import React13, { useState as useState10, useRef as useRef3, useEffect as useEffect7, useCallback as useCallback2 } from "react";
14168
+ import { Box as Box20, Text as Text21, useApp, useInput as useInput6, render } from "ink";
14169
+ import SelectInput10 from "ink-select-input";
14320
14170
  import { existsSync as existsSync3, statSync as statSync4 } from "fs";
14321
- import { join as join23 } from "path";
14322
- import { unlink as unlink3 } from "fs/promises";
14171
+ import { join as join25 } from "path";
14172
+ import { unlink as unlink4 } from "fs/promises";
14323
14173
  import { execSync as execSync2 } from "child_process";
14324
14174
  import { spawn as spawn4 } from "child_process";
14325
14175
  import { platform as platform2 } from "os";
14326
14176
  import fg4 from "fast-glob";
14327
14177
  import { readFileSync as readFileSync3 } from "fs";
14328
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
14178
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
14329
14179
  function buildFilePickerIgnoreList(cwd) {
14330
14180
  const hardcoded = [
14331
14181
  // Dependencies
@@ -14396,7 +14246,7 @@ function buildFilePickerIgnoreList(cwd) {
14396
14246
  ];
14397
14247
  const gitignorePatterns = [];
14398
14248
  try {
14399
- const gitignorePath = join23(cwd, ".gitignore");
14249
+ const gitignorePath = join25(cwd, ".gitignore");
14400
14250
  const stats = statSync4(gitignorePath);
14401
14251
  if (stats.size > MAX_GITIGNORE_SIZE) {
14402
14252
  return hardcoded;
@@ -14485,6 +14335,13 @@ function detectGitHubRepo(cachedRepo) {
14485
14335
  }
14486
14336
  return null;
14487
14337
  }
14338
+ function detectGitBranch() {
14339
+ try {
14340
+ return execSync2("git branch --show-current", { cwd: process.cwd(), encoding: "utf8" }).trim() || null;
14341
+ } catch {
14342
+ return null;
14343
+ }
14344
+ }
14488
14345
  function formatTokens4(n) {
14489
14346
  if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
14490
14347
  if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
@@ -14554,12 +14411,12 @@ function App({
14554
14411
  initialCloudDeviceId
14555
14412
  }) {
14556
14413
  const { exit } = useApp();
14557
- const [cfg, setCfg] = useState11(initialCfg);
14558
- const [lspScope, setLspScope] = useState11(initialLspScope);
14559
- const [lspProjectPath, setLspProjectPath] = useState11(initialLspProjectPath);
14560
- const [cloudToken, setCloudToken] = useState11(initialCloudToken);
14561
- const [cloudDeviceId, setCloudDeviceId] = useState11(initialCloudDeviceId);
14562
- const [events, setRawEvents] = useState11([]);
14414
+ const [cfg, setCfg] = useState10(initialCfg);
14415
+ const [lspScope, setLspScope] = useState10(initialLspScope);
14416
+ const [lspProjectPath, setLspProjectPath] = useState10(initialLspProjectPath);
14417
+ const [cloudToken, setCloudToken] = useState10(initialCloudToken);
14418
+ const [cloudDeviceId, setCloudDeviceId] = useState10(initialCloudDeviceId);
14419
+ const [events, setRawEvents] = useState10([]);
14563
14420
  const setEvents = useCallback2(
14564
14421
  (updater) => {
14565
14422
  setRawEvents((prev) => {
@@ -14569,47 +14426,55 @@ function App({
14569
14426
  },
14570
14427
  []
14571
14428
  );
14572
- const [input, setInput] = useState11("");
14573
- const [busy, setBusy] = useState11(false);
14574
- const [usage, setUsage] = useState11(null);
14575
- const [sessionUsage, setSessionUsage] = useState11(null);
14576
- const [gatewayMeta, setGatewayMeta] = useState11(null);
14577
- const [cloudBudget, setCloudBudget] = useState11(null);
14578
- const [showReasoning, setShowReasoning] = useState11(false);
14579
- const [perm, setPerm] = useState11(null);
14580
- const [limitModal, setLimitModal] = useState11(null);
14581
- const [queue, setQueue] = useState11([]);
14582
- const [history, setHistory] = useState11([]);
14583
- const [historyIndex, setHistoryIndex] = useState11(-1);
14584
- const [draftInput, setDraftInput] = useState11("");
14585
- const [mode, setMode] = useState11("edit");
14586
- const [codeMode, setCodeMode] = useState11(false);
14429
+ const [input, setInput] = useState10("");
14430
+ const [busy, setBusy] = useState10(false);
14431
+ const [usage, setUsage] = useState10(null);
14432
+ const [sessionUsage, setSessionUsage] = useState10(null);
14433
+ const [gatewayMeta, setGatewayMeta] = useState10(null);
14434
+ const [cloudBudget, setCloudBudget] = useState10(null);
14435
+ const [showReasoning, setShowReasoning] = useState10(false);
14436
+ const [perm, setPerm] = useState10(null);
14437
+ const [limitModal, setLimitModal] = useState10(null);
14438
+ const [queue, setQueue] = useState10([]);
14439
+ const [history, setHistory] = useState10([]);
14440
+ const [historyIndex, setHistoryIndex] = useState10(-1);
14441
+ const [draftInput, setDraftInput] = useState10("");
14442
+ const [mode, setMode] = useState10("edit");
14443
+ const [codeMode, setCodeMode] = useState10(false);
14587
14444
  const filePickerEnabled = initialCfg?.filePicker ?? true;
14588
- const [effort, setEffort] = useState11(
14445
+ const [effort, setEffort] = useState10(
14589
14446
  initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
14590
14447
  );
14591
- const [resumeSessions, setResumeSessions] = useState11(null);
14592
- const [showHelpMenu, setShowHelpMenu] = useState11(false);
14593
- const [commandWizard, setCommandWizard] = useState11(null);
14594
- const [commandPicker, setCommandPicker] = useState11(null);
14595
- const [commandToDelete, setCommandToDelete] = useState11(null);
14596
- const [showCommandList, setShowCommandList] = useState11(false);
14597
- const [showLspWizard, setShowLspWizard] = useState11(false);
14598
- const [showRemoteDashboard, setShowRemoteDashboard] = useState11(false);
14599
- const [selectedRemoteSession, setSelectedRemoteSession] = useState11(null);
14600
- const [tasks, setTasks] = useState11([]);
14601
- const [tasksStartedAt, setTasksStartedAt] = useState11(null);
14602
- const [tasksStartTokens, setTasksStartTokens] = useState11(0);
14603
- const [turnStartedAt, setTurnStartedAt] = useState11(null);
14604
- const [turnPhase, setTurnPhase] = useState11("waiting");
14605
- const [currentToolName, setCurrentToolName] = useState11(null);
14606
- const [lastActivityAt, setLastActivityAt] = useState11(null);
14607
- const [verbose, setVerbose] = useState11(false);
14608
- const [hasUpdate, setHasUpdate] = useState11(initialUpdateResult?.hasUpdate ?? false);
14609
- const [latestVersion, setLatestVersion] = useState11(initialUpdateResult?.latestVersion ?? null);
14610
- const [theme, setTheme] = useState11(resolveTheme(initialCfg?.theme));
14611
- const [showThemePicker, setShowThemePicker] = useState11(false);
14612
- const [kimiMdStale, setKimiMdStale] = useState11(false);
14448
+ const [resumeSessions, setResumeSessions] = useState10(null);
14449
+ const [commandWizard, setCommandWizard] = useState10(null);
14450
+ const [commandPicker, setCommandPicker] = useState10(null);
14451
+ const [commandToDelete, setCommandToDelete] = useState10(null);
14452
+ const [showCommandList, setShowCommandList] = useState10(false);
14453
+ const [showLspWizard, setShowLspWizard] = useState10(false);
14454
+ const [showRemoteDashboard, setShowRemoteDashboard] = useState10(false);
14455
+ const [selectedRemoteSession, setSelectedRemoteSession] = useState10(null);
14456
+ const [tasks, setTasks] = useState10([]);
14457
+ const [tasksStartedAt, setTasksStartedAt] = useState10(null);
14458
+ const [tasksStartTokens, setTasksStartTokens] = useState10(0);
14459
+ const [turnStartedAt, setTurnStartedAt] = useState10(null);
14460
+ const [turnPhase, setTurnPhase] = useState10("waiting");
14461
+ const [currentToolName, setCurrentToolName] = useState10(null);
14462
+ const [lastActivityAt, setLastActivityAt] = useState10(null);
14463
+ const [verbose, setVerbose] = useState10(false);
14464
+ const [hasUpdate, setHasUpdate] = useState10(initialUpdateResult?.hasUpdate ?? false);
14465
+ const [latestVersion, setLatestVersion] = useState10(initialUpdateResult?.latestVersion ?? null);
14466
+ const [theme, setTheme] = useState10(resolveTheme(initialCfg?.theme));
14467
+ const [showThemePicker, setShowThemePicker] = useState10(false);
14468
+ const [originalTheme, setOriginalTheme] = useState10(null);
14469
+ const [skillsActive, setSkillsActive] = useState10(0);
14470
+ const [memoryRecalled, setMemoryRecalled] = useState10(false);
14471
+ const [intentTier, setIntentTier] = useState10(null);
14472
+ const skillsDirRef = useRef3(join25(process.cwd(), ".kimiflare", "skills"));
14473
+ const [kimiMdStale, setKimiMdStale] = useState10(false);
14474
+ const [gitBranch, setGitBranch] = useState10(null);
14475
+ useEffect7(() => {
14476
+ setGitBranch(detectGitBranch());
14477
+ }, []);
14613
14478
  useEffect7(() => {
14614
14479
  let cancelled = false;
14615
14480
  loadAndMergeThemes().then(({ errors, wcagWarnings }) => {
@@ -14649,11 +14514,11 @@ ${wcagWarnings.join("\n")}` }
14649
14514
  cancelled = true;
14650
14515
  };
14651
14516
  }, [cfg?.cloudMode, initialCloudToken]);
14652
- const [cursorOffset, setCursorOffset] = useState11(0);
14653
- const [activePicker, setActivePicker] = useState11(null);
14654
- const [filePickerItems, setFilePickerItems] = useState11([]);
14517
+ const [cursorOffset, setCursorOffset] = useState10(0);
14518
+ const [activePicker, setActivePicker] = useState10(null);
14519
+ const [filePickerItems, setFilePickerItems] = useState10([]);
14655
14520
  const filePickerLoadedRef = useRef3(false);
14656
- const [customCommandsVersion, setCustomCommandsVersion] = useState11(0);
14521
+ const [customCommandsVersion, setCustomCommandsVersion] = useState10(0);
14657
14522
  const cacheStableRef = useRef3(initialCfg?.cacheStablePrompts !== false);
14658
14523
  const messagesRef = useRef3(
14659
14524
  makePrefixMessages(cacheStableRef.current, cfg?.model ?? DEFAULT_MODEL, "edit", ALL_TOOLS)
@@ -14664,8 +14529,6 @@ ${wcagWarnings.join("\n")}` }
14664
14529
  const permResolveRef = useRef3(null);
14665
14530
  const limitResolveRef = useRef3(null);
14666
14531
  const pendingToolCallsRef = useRef3(/* @__PURE__ */ new Map());
14667
- const toolBatchRef = useRef3([]);
14668
- const toolBatchTimerRef = useRef3(null);
14669
14532
  const sessionIdRef = useRef3(null);
14670
14533
  const modeRef = useRef3(mode);
14671
14534
  const effortRef = useRef3(effort);
@@ -14700,15 +14563,15 @@ ${wcagWarnings.join("\n")}` }
14700
14563
  }, [busy]);
14701
14564
  const pickerAnchor = activePicker?.anchor ?? null;
14702
14565
  const pickerKind = activePicker?.kind ?? null;
14703
- const pickerQuery = React14.useMemo(() => {
14566
+ const pickerQuery = React13.useMemo(() => {
14704
14567
  if (pickerAnchor === null) return null;
14705
14568
  return input.slice(pickerAnchor + 1, cursorOffset);
14706
14569
  }, [input, cursorOffset, pickerAnchor]);
14707
- const filteredFileItems = React14.useMemo(() => {
14570
+ const filteredFileItems = React13.useMemo(() => {
14708
14571
  if (pickerKind !== "file" || pickerQuery === null) return [];
14709
14572
  return filterPickerItems(filePickerItems, pickerQuery);
14710
14573
  }, [pickerKind, filePickerItems, pickerQuery]);
14711
- const allSlashCommands = React14.useMemo(() => {
14574
+ const allSlashCommands = React13.useMemo(() => {
14712
14575
  const customs = customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({
14713
14576
  name: c.name,
14714
14577
  description: c.description ?? "",
@@ -14716,7 +14579,7 @@ ${wcagWarnings.join("\n")}` }
14716
14579
  }));
14717
14580
  return [...BUILTIN_COMMANDS, ...customs];
14718
14581
  }, [customCommandsVersion]);
14719
- const filteredSlashItems = React14.useMemo(() => {
14582
+ const filteredSlashItems = React13.useMemo(() => {
14720
14583
  if (pickerKind !== "slash" || pickerQuery === null) return [];
14721
14584
  return fuzzyFilter(allSlashCommands, pickerQuery, (c) => c.name).slice(0, 50);
14722
14585
  }, [pickerKind, allSlashCommands, pickerQuery]);
@@ -14829,12 +14692,11 @@ ${wcagWarnings.join("\n")}` }
14829
14692
  setActivePicker(null);
14830
14693
  }, [cursorOffset]);
14831
14694
  useEffect7(() => {
14832
- const modalActive = showHelpMenu || commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null || limitModal !== null;
14695
+ const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || perm !== null || limitModal !== null;
14833
14696
  if (modalActive && activePicker !== null) {
14834
14697
  setActivePicker(null);
14835
14698
  }
14836
14699
  }, [
14837
- showHelpMenu,
14838
14700
  commandWizard,
14839
14701
  commandPicker,
14840
14702
  commandToDelete,
@@ -14871,7 +14733,7 @@ ${wcagWarnings.join("\n")}` }
14871
14733
  }
14872
14734
  });
14873
14735
  if (cfg.memoryEnabled) {
14874
- const dbPath = cfg.memoryDbPath ?? join23(process.cwd(), ".kimiflare", "memory.db");
14736
+ const dbPath = cfg.memoryDbPath ?? join25(process.cwd(), ".kimiflare", "memory.db");
14875
14737
  const manager = new MemoryManager({
14876
14738
  dbPath,
14877
14739
  accountId: cfg.accountId,
@@ -14914,13 +14776,13 @@ ${wcagWarnings.join("\n")}` }
14914
14776
  messagesRef.current.splice(insertIdx, 0, { role: "system", content: text });
14915
14777
  setEvents((e) => [
14916
14778
  ...e,
14917
- { kind: "activity", key: mkKey(), text: "Remembering what we know about this repo\u2026", feature: "memory" }
14779
+ { kind: "memory", key: mkKey(), text: `recalled ${results.length} memory${results.length === 1 ? "" : "ies"} about this repo` }
14918
14780
  ]);
14919
14781
  }
14920
14782
  } catch {
14921
14783
  }
14922
14784
  })();
14923
- if (existsSync3(join23(cwd, "KIMI.md"))) {
14785
+ if (existsSync3(join25(cwd, "KIMI.md"))) {
14924
14786
  const lastRefresh = manager.getLastKimiMdRefreshTime(cwd);
14925
14787
  const driftCount = manager.countHighSignalMemoriesSince(cwd, lastRefresh);
14926
14788
  if (driftCount >= 5) {
@@ -15140,7 +15002,7 @@ ${wcagWarnings.join("\n")}` }
15140
15002
  }
15141
15003
  setEvents((e) => [
15142
15004
  ...e,
15143
- { kind: "activity", key: mkKey(), text: "Plugging in external tools\u2026" }
15005
+ { kind: "info", key: mkKey(), text: `MCP connected \u2014 ${totalTools} external tool${totalTools === 1 ? "" : "s"} available` }
15144
15006
  ]);
15145
15007
  }
15146
15008
  }, [cfg]);
@@ -15198,7 +15060,7 @@ ${wcagWarnings.join("\n")}` }
15198
15060
  }
15199
15061
  setEvents((e) => [
15200
15062
  ...e,
15201
- { kind: "activity", key: mkKey(), text: "Waking up the language servers\u2026" }
15063
+ { kind: "info", key: mkKey(), text: `LSP ready \u2014 ${totalServers} server${totalServers === 1 ? "" : "s"} active` }
15202
15064
  ]);
15203
15065
  } else {
15204
15066
  setEvents((e) => [
@@ -15323,7 +15185,7 @@ ${wcagWarnings.join("\n")}` }
15323
15185
  },
15324
15186
  [cfg]
15325
15187
  );
15326
- useInput7((inputChar, key) => {
15188
+ useInput6((inputChar, key) => {
15327
15189
  if (key.ctrl && inputChar === "c") {
15328
15190
  const hadPerm = permResolveRef.current !== null;
15329
15191
  const hadLimit = limitResolveRef.current !== null;
@@ -15347,7 +15209,7 @@ ${wcagWarnings.join("\n")}` }
15347
15209
  return;
15348
15210
  }
15349
15211
  if (key.escape) {
15350
- const modalOpen = perm !== null || limitModal !== null || showHelpMenu || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null || showThemePicker;
15212
+ const modalOpen = perm !== null || limitModal !== null || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null || showThemePicker;
15351
15213
  if (!modalOpen && busyRef.current && activeControllerRef.current) {
15352
15214
  if (permResolveRef.current) {
15353
15215
  permResolveRef.current("deny");
@@ -15435,16 +15297,6 @@ ${wcagWarnings.join("\n")}` }
15435
15297
  },
15436
15298
  []
15437
15299
  );
15438
- const flushToolBatch = useCallback2(() => {
15439
- toolBatchTimerRef.current = null;
15440
- const batch = toolBatchRef.current;
15441
- toolBatchRef.current = [];
15442
- if (batch.length === 0) return;
15443
- const text = generateActivityText(batch, { mode: modeRef.current });
15444
- if (text) {
15445
- setEvents((e) => [...e, { kind: "activity", key: mkKey(), text, feature: "explore" }]);
15446
- }
15447
- }, []);
15448
15300
  const updateGatewayMeta = useCallback2((meta) => {
15449
15301
  gatewayMetaRef.current = meta;
15450
15302
  setGatewayMeta(meta);
@@ -15594,7 +15446,7 @@ ${wcagWarnings.join("\n")}` }
15594
15446
  lspManagerRef.current.notifyChange(path, content);
15595
15447
  } else {
15596
15448
  void import("fs/promises").then(
15597
- ({ readFile: readFile18 }) => readFile18(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
15449
+ ({ readFile: readFile20 }) => readFile20(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
15598
15450
  })
15599
15451
  );
15600
15452
  }
@@ -15624,16 +15476,11 @@ ${wcagWarnings.join("\n")}` }
15624
15476
  pendingToolCallsRef.current.set(call.id, call.function.name);
15625
15477
  const spec = executorRef.current.list().find((t) => t.name === call.function.name);
15626
15478
  let renderMeta;
15627
- let argsParsed = {};
15628
15479
  try {
15629
- argsParsed = call.function.arguments ? JSON.parse(call.function.arguments) : {};
15630
- renderMeta = spec?.render?.(argsParsed);
15480
+ const args = call.function.arguments ? JSON.parse(call.function.arguments) : {};
15481
+ renderMeta = spec?.render?.(args);
15631
15482
  } catch {
15632
15483
  }
15633
- toolBatchRef.current.push({ name: call.function.name, args: argsParsed });
15634
- if (toolBatchTimerRef.current) clearTimeout(toolBatchTimerRef.current);
15635
- toolBatchTimerRef.current = setTimeout(flushToolBatch, 120);
15636
- if (modeRef.current === "plan") return;
15637
15484
  setEvents((e) => [
15638
15485
  ...e,
15639
15486
  {
@@ -15714,7 +15561,7 @@ ${wcagWarnings.join("\n")}` }
15714
15561
  }
15715
15562
  }
15716
15563
  });
15717
- if (existsSync3(join23(cwd, "KIMI.md"))) {
15564
+ if (existsSync3(join25(cwd, "KIMI.md"))) {
15718
15565
  if (cacheStableRef.current) {
15719
15566
  messagesRef.current[1] = {
15720
15567
  role: "system",
@@ -15777,15 +15624,8 @@ ${wcagWarnings.join("\n")}` }
15777
15624
  permResolveRef.current = null;
15778
15625
  limitResolveRef.current = null;
15779
15626
  pendingToolCallsRef.current.clear();
15780
- tasksRef.current = [];
15781
- setTasks([]);
15782
- setTasksStartedAt(null);
15783
- setTasksStartTokens(0);
15784
- setEvents(
15785
- (evts) => evts.map((e) => e.kind === "tool" && e.status === "running" ? { ...e, status: "error", result: "(interrupted)" } : e)
15786
- );
15787
15627
  }
15788
- }, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta, flushToolBatch]);
15628
+ }, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
15789
15629
  const handleThemePick = useCallback2(
15790
15630
  (picked) => {
15791
15631
  setShowThemePicker(false);
@@ -16154,6 +15994,118 @@ use: /thinking low | medium | high`
16154
15994
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "mode: edit" }]);
16155
15995
  return true;
16156
15996
  }
15997
+ if (c === "/skills") {
15998
+ const sub = rest[0]?.toLowerCase() ?? "";
15999
+ const subRest = rest.slice(1).join(" ").trim();
16000
+ if (sub === "list" || sub === "") {
16001
+ void listAllSkills(process.cwd()).then((all) => {
16002
+ const lines = [];
16003
+ if (all.project.length > 0) {
16004
+ lines.push("project skills:");
16005
+ for (const s of all.project) {
16006
+ const status = s.enabled ? "\u2713" : "\u2717";
16007
+ lines.push(` ${status} ${s.name} \u2014 ${s.description || "no description"} (${s.estimatedTokens} tokens)`);
16008
+ }
16009
+ }
16010
+ if (all.global.length > 0) {
16011
+ lines.push("global skills:");
16012
+ for (const s of all.global) {
16013
+ const status = s.enabled ? "\u2713" : "\u2717";
16014
+ lines.push(` ${status} ${s.name} \u2014 ${s.description || "no description"} (${s.estimatedTokens} tokens)`);
16015
+ }
16016
+ }
16017
+ if (lines.length === 0) {
16018
+ lines.push("no skills found. create one with /skills add <name>");
16019
+ }
16020
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: lines.join("\n") }]);
16021
+ }).catch((err) => {
16022
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `failed to list skills: ${err.message}` }]);
16023
+ });
16024
+ return true;
16025
+ }
16026
+ if (sub === "add") {
16027
+ const name = subRest.trim();
16028
+ if (!name) {
16029
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "usage: /skills add <name>" }]);
16030
+ return true;
16031
+ }
16032
+ void createSkill({ name, scope: "project", cwd: process.cwd() }).then((result) => {
16033
+ setEvents((e) => [
16034
+ ...e,
16035
+ { kind: "info", key: mkKey(), text: `created skill '${name}' \u2192 ${result.filepath}` },
16036
+ { kind: "info", key: mkKey(), text: `edit the file to add your instructions` }
16037
+ ]);
16038
+ }).catch((err) => {
16039
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `failed to create skill: ${err.message}` }]);
16040
+ });
16041
+ return true;
16042
+ }
16043
+ if (sub === "edit") {
16044
+ const name = subRest.trim();
16045
+ if (!name) {
16046
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "usage: /skills edit <name>" }]);
16047
+ return true;
16048
+ }
16049
+ void findSkillFile(name, process.cwd()).then((filepath) => {
16050
+ if (!filepath) {
16051
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `skill '${name}' not found` }]);
16052
+ return;
16053
+ }
16054
+ setEvents((e) => [
16055
+ ...e,
16056
+ { kind: "info", key: mkKey(), text: `skill '${name}' \u2192 ${filepath}` },
16057
+ { kind: "info", key: mkKey(), text: `open it in your editor to make changes` }
16058
+ ]);
16059
+ }).catch((err) => {
16060
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `failed to find skill: ${err.message}` }]);
16061
+ });
16062
+ return true;
16063
+ }
16064
+ if (sub === "delete") {
16065
+ const name = subRest.trim();
16066
+ if (!name) {
16067
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "usage: /skills delete <name>" }]);
16068
+ return true;
16069
+ }
16070
+ void deleteSkill(name, process.cwd()).then((result) => {
16071
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: `deleted skill '${name}' (${result.filepath})` }]);
16072
+ }).catch((err) => {
16073
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `failed to delete skill: ${err.message}` }]);
16074
+ });
16075
+ return true;
16076
+ }
16077
+ if (sub === "enable") {
16078
+ const name = subRest.trim();
16079
+ if (!name) {
16080
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "usage: /skills enable <name>" }]);
16081
+ return true;
16082
+ }
16083
+ void setSkillEnabled(name, true, process.cwd()).then((result) => {
16084
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: `enabled skill '${name}' (${result.filepath})` }]);
16085
+ }).catch((err) => {
16086
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `failed to enable skill: ${err.message}` }]);
16087
+ });
16088
+ return true;
16089
+ }
16090
+ if (sub === "disable") {
16091
+ const name = subRest.trim();
16092
+ if (!name) {
16093
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "usage: /skills disable <name>" }]);
16094
+ return true;
16095
+ }
16096
+ void setSkillEnabled(name, false, process.cwd()).then((result) => {
16097
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: `disabled skill '${name}' (${result.filepath})` }]);
16098
+ }).catch((err) => {
16099
+ setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `failed to disable skill: ${err.message}` }]);
16100
+ });
16101
+ return true;
16102
+ }
16103
+ setEvents((e) => [
16104
+ ...e,
16105
+ { kind: "info", key: mkKey(), text: "usage: /skills list | add <name> | edit <name> | delete <name> | enable <name> | disable <name>" }
16106
+ ]);
16107
+ return true;
16108
+ }
16157
16109
  if (c === "/memory") {
16158
16110
  if (!cfg) return true;
16159
16111
  if (arg === "on") {
@@ -16358,7 +16310,7 @@ ${lines.join("\n")}` }]);
16358
16310
  return true;
16359
16311
  }
16360
16312
  if (c === "/logout") {
16361
- unlink3(configPath()).catch(() => {
16313
+ unlink4(configPath()).catch(() => {
16362
16314
  });
16363
16315
  setEvents((e) => [
16364
16316
  ...e,
@@ -16556,23 +16508,27 @@ ${lines.join("\n")}` }]);
16556
16508
  return true;
16557
16509
  }
16558
16510
  if (c === "/help") {
16559
- setShowHelpMenu(true);
16511
+ const lines = [
16512
+ "commands:",
16513
+ " /mode edit|plan|auto switch agent mode",
16514
+ " /thinking low|medium|high set reasoning effort",
16515
+ " /skills list|add|edit|... manage skills",
16516
+ " /memory on|off|clear manage memory",
16517
+ " /cost show cost report",
16518
+ " /compact summarize old turns",
16519
+ " /resume pick a past session",
16520
+ " /clear clear conversation",
16521
+ " /init scan repo and write KIMI.md",
16522
+ " /update check for updates",
16523
+ " /exit exit kimiflare"
16524
+ ];
16525
+ setEvents((e) => [...e, { kind: "info", key: mkKey(), text: lines.join("\n") }]);
16560
16526
  return true;
16561
16527
  }
16562
16528
  return false;
16563
16529
  },
16564
16530
  [cfg, exit, usage, effort, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
16565
16531
  );
16566
- const handleHelpCommand = useCallback2(
16567
- (command) => {
16568
- setShowHelpMenu(false);
16569
- const executed = handleSlash(command);
16570
- if (!executed) {
16571
- setEvents((e) => [...e, { kind: "error", key: mkKey(), text: `unknown command: ${command}` }]);
16572
- }
16573
- },
16574
- [handleSlash]
16575
- );
16576
16532
  const handleCommandSave = useCallback2(
16577
16533
  async (opts2) => {
16578
16534
  setCommandWizard(null);
@@ -16701,7 +16657,7 @@ ${lines.join("\n")}` }]);
16701
16657
  }
16702
16658
  }
16703
16659
  turnCounterRef.current += 1;
16704
- if (turnCounterRef.current % 15 === 0 && existsSync3(join23(process.cwd(), "KIMI.md")) && !kimiMdStale) {
16660
+ if (turnCounterRef.current % 15 === 0 && existsSync3(join25(process.cwd(), "KIMI.md")) && !kimiMdStale) {
16705
16661
  setEvents((e) => [
16706
16662
  ...e,
16707
16663
  { kind: "info", key: mkKey(), text: "Tip: Rerunning /init occasionally helps KimiFlare stay accurate as your project evolves." }
@@ -16712,6 +16668,22 @@ ${lines.join("\n")}` }]);
16712
16668
  setGatewayMeta(null);
16713
16669
  setTurnStartedAt(Date.now());
16714
16670
  const classification = classifyIntent(trimmed);
16671
+ setIntentTier(classification.tier);
16672
+ let skillResult;
16673
+ try {
16674
+ skillResult = await routeSkills(skillsDirRef.current, {
16675
+ cwd: process.cwd(),
16676
+ prompt: trimmed,
16677
+ memorySnippets: [],
16678
+ // TODO: wire memory snippets when available
16679
+ tier: classification.tier,
16680
+ maxSkillTokens: CONTEXT_LIMIT - 1e4
16681
+ // leave headroom
16682
+ });
16683
+ setSkillsActive(skillResult.selectedSkills.length);
16684
+ } catch {
16685
+ setSkillsActive(0);
16686
+ }
16715
16687
  const effortForTier = {
16716
16688
  light: "low",
16717
16689
  medium: "medium",
@@ -16720,10 +16692,40 @@ ${lines.join("\n")}` }]);
16720
16692
  const turnReasoningEffort = overrideEffort ?? effortForTier[classification.tier] ?? effortRef.current;
16721
16693
  const effectiveCodeMode = classification.tier === "heavy";
16722
16694
  setCodeMode(effectiveCodeMode);
16723
- const triageActivity = narrativizeInfo("", { tier: classification.tier, codeMode: effectiveCodeMode });
16724
- if (triageActivity) {
16725
- setEvents((e) => [...e, { kind: "activity", key: mkKey(), text: triageActivity.text, feature: triageActivity.feature }]);
16695
+ const selectedSkills = skillResult?.selectedSkills.map((s) => ({ name: s.name, body: s.body }));
16696
+ if (cacheStableRef.current) {
16697
+ messagesRef.current[1] = {
16698
+ role: "system",
16699
+ content: buildSessionPrefix({
16700
+ cwd: process.cwd(),
16701
+ tools: [...ALL_TOOLS, ...mcpToolsRef.current, ...lspToolsRef.current],
16702
+ model: cfg.model,
16703
+ mode: modeRef.current,
16704
+ selectedSkills
16705
+ })
16706
+ };
16707
+ } else {
16708
+ messagesRef.current[0] = {
16709
+ role: "system",
16710
+ content: buildSystemPrompt({
16711
+ cwd: process.cwd(),
16712
+ tools: [...ALL_TOOLS, ...mcpToolsRef.current, ...lspToolsRef.current],
16713
+ model: cfg.model,
16714
+ mode: modeRef.current,
16715
+ selectedSkills
16716
+ })
16717
+ };
16726
16718
  }
16719
+ setEvents((e) => [
16720
+ ...e,
16721
+ {
16722
+ kind: "meta",
16723
+ key: mkKey(),
16724
+ intentTier: classification.tier,
16725
+ skillsActive: skillResult?.selectedSkills.length ?? 0,
16726
+ memoryRecalled: false
16727
+ }
16728
+ ]);
16727
16729
  const controller = new AbortController();
16728
16730
  activeControllerRef.current = controller;
16729
16731
  const sharedCallbacks = {
@@ -16759,16 +16761,11 @@ ${lines.join("\n")}` }]);
16759
16761
  setLastActivityAt(Date.now());
16760
16762
  const spec = executorRef.current.list().find((t) => t.name === call.function.name);
16761
16763
  let renderMeta;
16762
- let argsParsed = {};
16763
16764
  try {
16764
- argsParsed = call.function.arguments ? JSON.parse(call.function.arguments) : {};
16765
- renderMeta = spec?.render?.(argsParsed);
16765
+ const args = call.function.arguments ? JSON.parse(call.function.arguments) : {};
16766
+ renderMeta = spec?.render?.(args);
16766
16767
  } catch {
16767
16768
  }
16768
- toolBatchRef.current.push({ name: call.function.name, args: argsParsed });
16769
- if (toolBatchTimerRef.current) clearTimeout(toolBatchTimerRef.current);
16770
- toolBatchTimerRef.current = setTimeout(flushToolBatch, 120);
16771
- if (modeRef.current === "plan") return;
16772
16769
  setEvents((e) => [
16773
16770
  ...e,
16774
16771
  {
@@ -16892,12 +16889,13 @@ ${lines.join("\n")}` }]);
16892
16889
  cloudDeviceId: cloudDeviceId ?? initialCloudDeviceId,
16893
16890
  onIterationEnd,
16894
16891
  intentClassification: classification,
16892
+ selectedSkills,
16895
16893
  onFileChange: (path, content2) => {
16896
16894
  if (content2) {
16897
16895
  lspManagerRef.current.notifyChange(path, content2);
16898
16896
  } else {
16899
16897
  void import("fs/promises").then(
16900
- ({ readFile: readFile18 }) => readFile18(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
16898
+ ({ readFile: readFile20 }) => readFile20(path, "utf8").then((c) => lspManagerRef.current.notifyChange(path, c)).catch(() => {
16901
16899
  })
16902
16900
  );
16903
16901
  }
@@ -16919,10 +16917,9 @@ ${lines.join("\n")}` }]);
16919
16917
  setEvents((e) => [
16920
16918
  ...e,
16921
16919
  {
16922
- kind: "activity",
16920
+ kind: "info",
16923
16921
  key: mkKey(),
16924
- text: "Making room by summarizing older turns\u2026",
16925
- feature: "compact"
16922
+ text: `auto-compacted: ${result.metrics.estimatedTokensBefore} \u2192 ${result.metrics.estimatedTokensAfter} tokens (${result.metrics.archivedArtifacts} artifacts)`
16926
16923
  }
16927
16924
  ]);
16928
16925
  await saveSessionSafe();
@@ -16942,10 +16939,9 @@ ${lines.join("\n")}` }]);
16942
16939
  setEvents((e) => [
16943
16940
  ...e,
16944
16941
  {
16945
- kind: "activity",
16942
+ kind: "info",
16946
16943
  key: mkKey(),
16947
- text: "Making room by summarizing older turns\u2026",
16948
- feature: "compact"
16944
+ text: `auto-compacted: ${result.replacedCount} messages summarized`
16949
16945
  }
16950
16946
  ]);
16951
16947
  await saveSessionSafe();
@@ -16980,10 +16976,9 @@ ${lines.join("\n")}` }]);
16980
16976
  setEvents((e) => [
16981
16977
  ...e,
16982
16978
  {
16983
- kind: "activity",
16979
+ kind: "memory",
16984
16980
  key: mkKey(),
16985
- text: "Remembering what we learned before\u2026",
16986
- feature: "memory"
16981
+ text: `recalled ${results.length} memory${results.length === 1 ? "" : "ies"} after compaction`
16987
16982
  }
16988
16983
  ]);
16989
16984
  await saveSessionSafe();
@@ -17037,16 +17032,9 @@ ${lines.join("\n")}` }]);
17037
17032
  permResolveRef.current = null;
17038
17033
  limitResolveRef.current = null;
17039
17034
  pendingToolCallsRef.current.clear();
17040
- tasksRef.current = [];
17041
- setTasks([]);
17042
- setTasksStartedAt(null);
17043
- setTasksStartTokens(0);
17044
- setEvents(
17045
- (evts) => evts.map((e) => e.kind === "tool" && e.status === "running" ? { ...e, status: "error", result: "(interrupted)" } : e)
17046
- );
17047
17035
  }
17048
17036
  },
17049
- [cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta, flushToolBatch]
17037
+ [cfg, handleSlash, updateAssistant, updateTool, saveSessionSafe, updateGatewayMeta]
17050
17038
  );
17051
17039
  useEffect7(() => {
17052
17040
  if (!busy && queue.length > 0) {
@@ -17091,7 +17079,7 @@ ${lines.join("\n")}` }]);
17091
17079
  }
17092
17080
  }, [usage]);
17093
17081
  if (!cfg) {
17094
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(
17082
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(
17095
17083
  Onboarding,
17096
17084
  {
17097
17085
  onCancel: () => exit(),
@@ -17123,10 +17111,10 @@ ${lines.join("\n")}` }]);
17123
17111
  ) });
17124
17112
  }
17125
17113
  if (resumeSessions !== null) {
17126
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
17114
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(ResumePicker, { sessions: resumeSessions, onPick: handleResumePick }) }) });
17127
17115
  }
17128
17116
  if (showRemoteDashboard) {
17129
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx23(
17117
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx22(
17130
17118
  RemoteSessionDetail,
17131
17119
  {
17132
17120
  session: selectedRemoteSession,
@@ -17149,7 +17137,7 @@ ${lines.join("\n")}` }]);
17149
17137
  setShowRemoteDashboard(false);
17150
17138
  }
17151
17139
  }
17152
- ) : /* @__PURE__ */ jsx23(
17140
+ ) : /* @__PURE__ */ jsx22(
17153
17141
  RemoteDashboard,
17154
17142
  {
17155
17143
  onSelect: (session) => setSelectedRemoteSession(session),
@@ -17157,25 +17145,13 @@ ${lines.join("\n")}` }]);
17157
17145
  }
17158
17146
  ) }) });
17159
17147
  }
17160
- if (showHelpMenu) {
17161
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
17162
- HelpMenu,
17163
- {
17164
- customCommands: customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({ name: c.name, description: c.description })),
17165
- costAttributionEnabled: cfg?.costAttribution,
17166
- cloudMode: cfg?.cloudMode,
17167
- onDone: () => setShowHelpMenu(false),
17168
- onCommand: handleHelpCommand
17169
- }
17170
- ) }) });
17171
- }
17172
17148
  if (showLspWizard) {
17173
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
17149
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
17174
17150
  LspWizard,
17175
17151
  {
17176
17152
  servers: cfg?.lspServers ?? {},
17177
17153
  currentScope: lspScope,
17178
- hasProjectDir: existsSync3(join23(process.cwd(), ".kimiflare")),
17154
+ hasProjectDir: existsSync3(join25(process.cwd(), ".kimiflare")),
17179
17155
  onDone: () => setShowLspWizard(false),
17180
17156
  onSave: (servers, enabled, scope) => {
17181
17157
  setCfg((c) => c ? { ...c, lspEnabled: enabled, lspServers: servers } : c);
@@ -17207,7 +17183,7 @@ ${lines.join("\n")}` }]);
17207
17183
  ) }) });
17208
17184
  }
17209
17185
  if (commandWizard) {
17210
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
17186
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
17211
17187
  CommandWizard,
17212
17188
  {
17213
17189
  mode: commandWizard.mode,
@@ -17220,7 +17196,7 @@ ${lines.join("\n")}` }]);
17220
17196
  ) }) });
17221
17197
  }
17222
17198
  if (commandPicker) {
17223
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
17199
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
17224
17200
  CommandPicker,
17225
17201
  {
17226
17202
  commands: customCommandsRef.current,
@@ -17238,15 +17214,15 @@ ${lines.join("\n")}` }]);
17238
17214
  ) }) });
17239
17215
  }
17240
17216
  if (commandToDelete) {
17241
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
17242
- /* @__PURE__ */ jsxs21(Text22, { color: theme.accent, bold: true, children: [
17217
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
17218
+ /* @__PURE__ */ jsxs20(Text21, { color: theme.accent, bold: true, children: [
17243
17219
  "Delete /",
17244
17220
  commandToDelete.name,
17245
17221
  "?"
17246
17222
  ] }),
17247
- /* @__PURE__ */ jsx23(Text22, { color: theme.info.color, children: commandToDelete.filepath }),
17248
- /* @__PURE__ */ jsx23(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx23(
17249
- SelectInput11,
17223
+ /* @__PURE__ */ jsx22(Text21, { color: theme.info.color, children: commandToDelete.filepath }),
17224
+ /* @__PURE__ */ jsx22(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx22(
17225
+ SelectInput10,
17250
17226
  {
17251
17227
  items: [
17252
17228
  { label: "Yes, delete", value: "yes", key: "yes" },
@@ -17264,7 +17240,7 @@ ${lines.join("\n")}` }]);
17264
17240
  ] }) });
17265
17241
  }
17266
17242
  if (showCommandList) {
17267
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
17243
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
17268
17244
  CommandList,
17269
17245
  {
17270
17246
  commands: customCommandsRef.current,
@@ -17273,12 +17249,12 @@ ${lines.join("\n")}` }]);
17273
17249
  ) }) });
17274
17250
  }
17275
17251
  if (showThemePicker) {
17276
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsx23(ThemePicker, { themes: themeList(), onPick: handleThemePick }) }) });
17252
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx22(ThemePicker, { themes: themeList(), onPick: handleThemePick }) }) });
17277
17253
  }
17278
17254
  const hasConversation = events.some((e) => e.kind === "user" || e.kind === "assistant");
17279
- return /* @__PURE__ */ jsx23(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
17280
- !hasConversation && events.length === 0 ? /* @__PURE__ */ jsx23(Welcome, { accountId: cfg.accountId }) : /* @__PURE__ */ jsx23(ChatView, { events, showReasoning, verbose, suppressTools: mode === "plan" }),
17281
- perm ? /* @__PURE__ */ jsx23(
17255
+ return /* @__PURE__ */ jsx22(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
17256
+ !hasConversation && events.length === 0 ? /* @__PURE__ */ jsx22(Welcome, { accountId: cfg.accountId, cloudMode: cfg.cloudMode }) : /* @__PURE__ */ jsx22(ChatView, { events, showReasoning, verbose }),
17257
+ perm ? /* @__PURE__ */ jsx22(
17282
17258
  PermissionModal,
17283
17259
  {
17284
17260
  tool: perm.tool,
@@ -17289,7 +17265,7 @@ ${lines.join("\n")}` }]);
17289
17265
  setPerm(null);
17290
17266
  }
17291
17267
  }
17292
- ) : limitModal ? /* @__PURE__ */ jsx23(
17268
+ ) : limitModal ? /* @__PURE__ */ jsx22(
17293
17269
  LimitModal,
17294
17270
  {
17295
17271
  limit: limitModal.limit,
@@ -17299,8 +17275,8 @@ ${lines.join("\n")}` }]);
17299
17275
  setLimitModal(null);
17300
17276
  }
17301
17277
  }
17302
- ) : /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
17303
- tasks.length > 0 && /* @__PURE__ */ jsx23(
17278
+ ) : /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginTop: 1, children: [
17279
+ tasks.length > 0 && /* @__PURE__ */ jsx22(
17304
17280
  TaskList,
17305
17281
  {
17306
17282
  tasks,
@@ -17308,11 +17284,11 @@ ${lines.join("\n")}` }]);
17308
17284
  tokensDelta: Math.max(0, (usage?.prompt_tokens ?? 0) - tasksStartTokens)
17309
17285
  }
17310
17286
  ),
17311
- queue.length > 0 && /* @__PURE__ */ jsx23(Box21, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs21(Text22, { color: theme.info.color, children: [
17287
+ queue.length > 0 && /* @__PURE__ */ jsx22(Box20, { flexDirection: "column", marginBottom: 1, children: queue.map((q, i) => /* @__PURE__ */ jsxs20(Text21, { color: theme.info.color, children: [
17312
17288
  "\u23F3 ",
17313
17289
  q.display
17314
17290
  ] }, `queue_${i}`)) }),
17315
- /* @__PURE__ */ jsx23(
17291
+ /* @__PURE__ */ jsx22(
17316
17292
  StatusBar,
17317
17293
  {
17318
17294
  model: cfg.model,
@@ -17329,13 +17305,16 @@ ${lines.join("\n")}` }]);
17329
17305
  codeMode,
17330
17306
  cloudMode: cfg.cloudMode,
17331
17307
  cloudBudget,
17308
+ skillsActive,
17309
+ memoryRecalled,
17332
17310
  phase: turnPhase,
17333
17311
  currentTool: currentToolName,
17334
17312
  lastActivityAt,
17335
- kimiMdStale
17313
+ kimiMdStale,
17314
+ gitBranch
17336
17315
  }
17337
17316
  ),
17338
- activePicker?.kind === "file" && /* @__PURE__ */ jsx23(
17317
+ activePicker?.kind === "file" && /* @__PURE__ */ jsx22(
17339
17318
  FilePicker,
17340
17319
  {
17341
17320
  items: filteredFileItems,
@@ -17343,7 +17322,7 @@ ${lines.join("\n")}` }]);
17343
17322
  query: pickerQuery ?? ""
17344
17323
  }
17345
17324
  ),
17346
- activePicker?.kind === "slash" && /* @__PURE__ */ jsx23(
17325
+ activePicker?.kind === "slash" && /* @__PURE__ */ jsx22(
17347
17326
  SlashPicker,
17348
17327
  {
17349
17328
  items: filteredSlashItems,
@@ -17351,9 +17330,9 @@ ${lines.join("\n")}` }]);
17351
17330
  query: pickerQuery ?? ""
17352
17331
  }
17353
17332
  ),
17354
- /* @__PURE__ */ jsxs21(Box21, { marginTop: 1, children: [
17355
- /* @__PURE__ */ jsx23(Text22, { color: "#d699b6", children: "\u203A " }),
17356
- /* @__PURE__ */ jsx23(
17333
+ /* @__PURE__ */ jsxs20(Box20, { marginTop: 1, children: [
17334
+ /* @__PURE__ */ jsx22(Text21, { color: "#d699b6", children: "\u203A " }),
17335
+ /* @__PURE__ */ jsx22(
17357
17336
  CustomTextInput,
17358
17337
  {
17359
17338
  value: input,
@@ -17410,7 +17389,7 @@ ${lines.join("\n")}` }]);
17410
17389
  }
17411
17390
  async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken, cloudDeviceId) {
17412
17391
  const instance = render(
17413
- /* @__PURE__ */ jsx23(
17392
+ /* @__PURE__ */ jsx22(
17414
17393
  App,
17415
17394
  {
17416
17395
  initialCfg: cfg,
@@ -17444,7 +17423,6 @@ var init_app = __esm({
17444
17423
  init_errors();
17445
17424
  init_chat();
17446
17425
  init_status();
17447
- init_narrative();
17448
17426
  init_permission();
17449
17427
  init_limit_modal();
17450
17428
  init_resume_picker();
@@ -17453,7 +17431,6 @@ var init_app = __esm({
17453
17431
  init_update_check();
17454
17432
  init_onboarding();
17455
17433
  init_welcome();
17456
- init_help_menu();
17457
17434
  init_config();
17458
17435
  init_worker_client();
17459
17436
  init_session_store();
@@ -17462,14 +17439,16 @@ var init_app = __esm({
17462
17439
  init_remote_dashboard();
17463
17440
  init_mode();
17464
17441
  init_classify();
17442
+ init_skills();
17443
+ init_manager3();
17465
17444
  init_sessions();
17466
17445
  init_image();
17467
17446
  init_usage_tracker();
17468
- init_manager3();
17447
+ init_manager4();
17469
17448
  init_storage_limits();
17470
17449
  init_state();
17471
17450
  init_version();
17472
- init_loader();
17451
+ init_loader2();
17473
17452
  init_renderer2();
17474
17453
  init_builtins();
17475
17454
  init_save();