kimiflare 0.71.0 → 0.72.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
@@ -417,8 +417,8 @@ async function flushAndCloseForTesting() {
417
417
  const s = currentStream;
418
418
  currentStream = null;
419
419
  currentDate = null;
420
- await new Promise((resolve3) => {
421
- s.end(() => resolve3());
420
+ await new Promise((resolve4) => {
421
+ s.end(() => resolve4());
422
422
  });
423
423
  }
424
424
  function isLogSinkEnabled() {
@@ -1297,11 +1297,11 @@ function extractCloudflareError(parsed, rawText) {
1297
1297
  return null;
1298
1298
  }
1299
1299
  function sleep(ms, signal) {
1300
- return new Promise((resolve3, reject) => {
1300
+ return new Promise((resolve4, reject) => {
1301
1301
  if (signal?.aborted) return reject(new DOMException("aborted", "AbortError"));
1302
1302
  const t = setTimeout(() => {
1303
1303
  signal?.removeEventListener("abort", onAbort);
1304
- resolve3();
1304
+ resolve4();
1305
1305
  }, ms);
1306
1306
  const onAbort = () => {
1307
1307
  clearTimeout(t);
@@ -2017,9 +2017,9 @@ var require_node_gyp_build = __commonJS({
2017
2017
  var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
2018
2018
  if (debug) return debug;
2019
2019
  }
2020
- var prebuild = resolve3(dir);
2020
+ var prebuild = resolve4(dir);
2021
2021
  if (prebuild) return prebuild;
2022
- var nearby = resolve3(path.dirname(process.execPath));
2022
+ var nearby = resolve4(path.dirname(process.execPath));
2023
2023
  if (nearby) return nearby;
2024
2024
  var target = [
2025
2025
  "platform=" + platform6,
@@ -2035,7 +2035,7 @@ var require_node_gyp_build = __commonJS({
2035
2035
  // eslint-disable-line
2036
2036
  ].filter(Boolean).join(" ");
2037
2037
  throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
2038
- function resolve3(dir2) {
2038
+ function resolve4(dir2) {
2039
2039
  var tuples = readdirSync2(path.join(dir2, "prebuilds")).map(parseTuple);
2040
2040
  var tuple = tuples.filter(matchTuple(platform6, arch)).sort(compareTuples)[0];
2041
2041
  if (!tuple) return;
@@ -2883,7 +2883,7 @@ function truncateForEmbedding(text) {
2883
2883
  return text.slice(0, MAX_EMBED_CHARS);
2884
2884
  }
2885
2885
  async function sleep2(ms) {
2886
- return new Promise((resolve3) => setTimeout(resolve3, ms));
2886
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
2887
2887
  }
2888
2888
  async function fetchWithRetry(url, init, retries = 3) {
2889
2889
  let lastError;
@@ -4693,7 +4693,7 @@ function runBash(args, ctx) {
4693
4693
  const timeout = Math.min(Math.max(1e3, args.timeout_ms ?? DEFAULT_TIMEOUT), MAX_TIMEOUT);
4694
4694
  const { shell, args: shellArgs, isPosix } = getShellCommand(ctx.shell);
4695
4695
  const command = isPosix ? injectCoauthor(args.command, ctx.coauthor) : args.command;
4696
- return new Promise((resolve3, reject) => {
4696
+ return new Promise((resolve4, reject) => {
4697
4697
  logger.debug("bash:spawn", { command: args.command.slice(0, 200), cwd: ctx.cwd, shell });
4698
4698
  const child = spawn(shell, [...shellArgs, command], {
4699
4699
  cwd: ctx.cwd,
@@ -4746,7 +4746,7 @@ ${stdout.trimEnd()}`);
4746
4746
  ${stderr.trimEnd()}`);
4747
4747
  if (!stdout && !stderr) parts.push("(no output)");
4748
4748
  const raw = parts.join("\n");
4749
- resolve3({
4749
+ resolve4({
4750
4750
  content: raw,
4751
4751
  rawBytes: Buffer.byteLength(raw, "utf8"),
4752
4752
  reducedBytes: Buffer.byteLength(raw, "utf8")
@@ -4785,13 +4785,280 @@ var init_bash = __esm({
4785
4785
  }
4786
4786
  });
4787
4787
 
4788
+ // src/util/glob.ts
4789
+ import { readdir as readdir2, lstat, realpath } from "fs/promises";
4790
+ import { join as join10, relative as relative2, resolve as resolve2 } from "path";
4791
+ function parsePattern(pattern) {
4792
+ const parts = pattern.split(/\//g);
4793
+ return parts.map((p) => {
4794
+ if (p === "**") return { type: "doublestar", value: p };
4795
+ if (p.includes("*") || p.includes("?") || p.includes("[")) {
4796
+ return { type: "glob", value: p };
4797
+ }
4798
+ return { type: "literal", value: p };
4799
+ });
4800
+ }
4801
+ function globToRegex(glob2) {
4802
+ let re = "^";
4803
+ for (let i = 0; i < glob2.length; i++) {
4804
+ const c = glob2[i];
4805
+ if (c === "*") {
4806
+ if (glob2[i + 1] === "*") {
4807
+ re += ".*";
4808
+ i++;
4809
+ } else {
4810
+ re += "[^/]*";
4811
+ }
4812
+ } else if (c === "?") {
4813
+ re += "[^/]";
4814
+ } else if (c === "[") {
4815
+ const close = glob2.indexOf("]", i + 1);
4816
+ if (close === -1) {
4817
+ re += "\\[";
4818
+ } else {
4819
+ re += glob2.slice(i, close + 1);
4820
+ i = close;
4821
+ }
4822
+ } else if ("\\^$.|+(){}".includes(c)) {
4823
+ re += "\\" + c;
4824
+ } else {
4825
+ re += c;
4826
+ }
4827
+ }
4828
+ re += "$";
4829
+ return new RegExp(re);
4830
+ }
4831
+ function matchSegment(segment, pattern) {
4832
+ return globToRegex(pattern).test(segment);
4833
+ }
4834
+ function shouldIgnore(relativePath, ignorePatterns) {
4835
+ for (const pat of ignorePatterns) {
4836
+ const segs = parsePattern(pat);
4837
+ const parts = relativePath.split(/\//g);
4838
+ if (matchIgnoreParts(parts, segs, 0, 0)) return true;
4839
+ }
4840
+ return false;
4841
+ }
4842
+ function matchIgnoreParts(parts, segs, pi, si) {
4843
+ if (si >= segs.length) return pi >= parts.length;
4844
+ const seg = segs[si];
4845
+ if (seg.type === "doublestar") {
4846
+ if (si === segs.length - 1) return true;
4847
+ for (let i = pi; i <= parts.length; i++) {
4848
+ if (matchIgnoreParts(parts, segs, i, si + 1)) return true;
4849
+ }
4850
+ return false;
4851
+ }
4852
+ if (pi >= parts.length) return false;
4853
+ const part = parts[pi];
4854
+ const ok = seg.type === "literal" ? seg.value === part : matchSegment(part, seg.value);
4855
+ return ok && matchIgnoreParts(parts, segs, pi + 1, si + 1);
4856
+ }
4857
+ async function* walk(root, pattern, options) {
4858
+ const dot = options.dot ?? false;
4859
+ const followSymbolicLinks = options.followSymbolicLinks ?? false;
4860
+ const suppressErrors = options.suppressErrors ?? false;
4861
+ const stats = options.stats ?? false;
4862
+ const onlyFiles = options.onlyFiles ?? false;
4863
+ const onlyDirectories = options.onlyDirectories ?? false;
4864
+ const markDirectories = options.markDirectories ?? false;
4865
+ const ignorePatterns = options.ignore ? Array.isArray(options.ignore) ? options.ignore : [options.ignore] : [];
4866
+ const segs = parsePattern(pattern);
4867
+ async function* yieldEntry(fullPath, relPath, isDir) {
4868
+ if (onlyFiles && isDir) return;
4869
+ if (onlyDirectories && !isDir) return;
4870
+ let path = fullPath;
4871
+ if (markDirectories && isDir) path += "/";
4872
+ const entry = { path };
4873
+ if (stats) {
4874
+ try {
4875
+ const s = await lstat(fullPath);
4876
+ entry.stats = { mtimeMs: s.mtimeMs };
4877
+ } catch {
4878
+ }
4879
+ }
4880
+ yield entry;
4881
+ }
4882
+ async function* processEntries(dirPath, segIdx, relativeParts) {
4883
+ if (segIdx >= segs.length) return;
4884
+ const seg = segs[segIdx];
4885
+ if (segIdx + 1 >= segs.length) {
4886
+ let entries2;
4887
+ try {
4888
+ entries2 = await readdir2(dirPath, { withFileTypes: true, encoding: "utf8" });
4889
+ } catch (err) {
4890
+ if (!suppressErrors) throw err;
4891
+ return;
4892
+ }
4893
+ for (const ent of entries2) {
4894
+ const name = String(ent.name);
4895
+ if (name === "." || name === "..") continue;
4896
+ if (!dot && name.startsWith(".")) continue;
4897
+ const matched = seg.type === "literal" ? seg.value === name : matchSegment(name, seg.value);
4898
+ if (!matched) continue;
4899
+ const childPath = join10(dirPath, name);
4900
+ const childRel = [...relativeParts, name];
4901
+ const childRelStr = childRel.join("/");
4902
+ if (shouldIgnore(childRelStr, ignorePatterns)) continue;
4903
+ const isDir = ent.isDirectory();
4904
+ const isFile = ent.isFile() || ent.isSymbolicLink();
4905
+ if (isDir || isFile) {
4906
+ yield* yieldEntry(childPath, childRelStr, isDir);
4907
+ }
4908
+ }
4909
+ return;
4910
+ }
4911
+ let entries;
4912
+ try {
4913
+ entries = await readdir2(dirPath, { withFileTypes: true, encoding: "utf8" });
4914
+ } catch (err) {
4915
+ if (!suppressErrors) throw err;
4916
+ return;
4917
+ }
4918
+ for (const ent of entries) {
4919
+ const name = String(ent.name);
4920
+ if (name === "." || name === "..") continue;
4921
+ if (!dot && name.startsWith(".")) continue;
4922
+ const matched = seg.type === "literal" ? seg.value === name : matchSegment(name, seg.value);
4923
+ if (!matched) continue;
4924
+ const childPath = join10(dirPath, name);
4925
+ const childRel = [...relativeParts, name];
4926
+ const childRelStr = childRel.join("/");
4927
+ if (shouldIgnore(childRelStr, ignorePatterns)) continue;
4928
+ let isDir = ent.isDirectory();
4929
+ if (!isDir && followSymbolicLinks && ent.isSymbolicLink()) {
4930
+ try {
4931
+ const rp = await realpath(childPath);
4932
+ const s = await lstat(rp);
4933
+ isDir = s.isDirectory();
4934
+ } catch {
4935
+ continue;
4936
+ }
4937
+ }
4938
+ if (isDir) {
4939
+ yield* recurse(childPath, segIdx + 1, childRel);
4940
+ }
4941
+ }
4942
+ }
4943
+ async function* recurse(dirPath, segIdx, relativeParts) {
4944
+ if (segIdx >= segs.length) return;
4945
+ const seg = segs[segIdx];
4946
+ if (seg.type === "doublestar") {
4947
+ if (segIdx + 1 >= segs.length) {
4948
+ const rel = relativeParts.join("/");
4949
+ if (!shouldIgnore(rel, ignorePatterns)) {
4950
+ yield* yieldEntry(dirPath, rel, true);
4951
+ }
4952
+ return;
4953
+ }
4954
+ yield* processEntries(dirPath, segIdx + 1, relativeParts);
4955
+ let entries;
4956
+ try {
4957
+ entries = await readdir2(dirPath, { withFileTypes: true, encoding: "utf8" });
4958
+ } catch (err) {
4959
+ if (!suppressErrors) throw err;
4960
+ return;
4961
+ }
4962
+ for (const ent of entries) {
4963
+ const name = String(ent.name);
4964
+ if (name === "." || name === "..") continue;
4965
+ if (!dot && name.startsWith(".")) continue;
4966
+ const childPath = join10(dirPath, name);
4967
+ const childRel = [...relativeParts, name];
4968
+ const childRelStr = childRel.join("/");
4969
+ if (shouldIgnore(childRelStr, ignorePatterns)) continue;
4970
+ if (ent.isDirectory() || followSymbolicLinks && ent.isSymbolicLink()) {
4971
+ let isDir = ent.isDirectory();
4972
+ if (!isDir && followSymbolicLinks && ent.isSymbolicLink()) {
4973
+ try {
4974
+ const rp = await realpath(childPath);
4975
+ const s = await lstat(rp);
4976
+ isDir = s.isDirectory();
4977
+ } catch {
4978
+ continue;
4979
+ }
4980
+ }
4981
+ if (isDir) {
4982
+ if (segIdx + 1 >= segs.length) {
4983
+ yield* yieldEntry(childPath, childRelStr, true);
4984
+ }
4985
+ yield* recurse(childPath, segIdx, childRel);
4986
+ }
4987
+ }
4988
+ }
4989
+ return;
4990
+ }
4991
+ yield* processEntries(dirPath, segIdx, relativeParts);
4992
+ }
4993
+ yield* recurse(root, 0, []);
4994
+ }
4995
+ async function glob(pattern, options = {}) {
4996
+ const cwd = options.cwd ? resolve2(options.cwd) : process.cwd();
4997
+ const results = [];
4998
+ for await (const entry of walk(cwd, pattern, options)) {
4999
+ let path = entry.path;
5000
+ const isDir = path.endsWith("/");
5001
+ if (!options.absolute) {
5002
+ path = relative2(cwd, path);
5003
+ }
5004
+ if (isDir && !path.endsWith("/")) path += "/";
5005
+ results.push(path);
5006
+ }
5007
+ return results;
5008
+ }
5009
+ function globStream(pattern, options = {}) {
5010
+ const cwd = options.cwd ? resolve2(options.cwd) : process.cwd();
5011
+ const absolute = options.absolute ?? false;
5012
+ let destroyed = false;
5013
+ let destroyErr;
5014
+ const iterable = {
5015
+ [Symbol.asyncIterator]() {
5016
+ const generator = walk(cwd, pattern, options);
5017
+ return {
5018
+ async next() {
5019
+ if (destroyed) {
5020
+ return { done: true, value: void 0 };
5021
+ }
5022
+ const result = await generator.next();
5023
+ if (destroyed) {
5024
+ return { done: true, value: void 0 };
5025
+ }
5026
+ if (!absolute && result.value) {
5027
+ const isDir = result.value.path.endsWith("/");
5028
+ result.value.path = relative2(cwd, result.value.path);
5029
+ if (isDir && !result.value.path.endsWith("/")) {
5030
+ result.value.path += "/";
5031
+ }
5032
+ }
5033
+ return result;
5034
+ },
5035
+ async return() {
5036
+ await generator.return?.(void 0);
5037
+ return { done: true, value: void 0 };
5038
+ }
5039
+ };
5040
+ }
5041
+ };
5042
+ return Object.assign(iterable, {
5043
+ destroy(err) {
5044
+ destroyed = true;
5045
+ destroyErr = err;
5046
+ }
5047
+ });
5048
+ }
5049
+ var init_glob = __esm({
5050
+ "src/util/glob.ts"() {
5051
+ "use strict";
5052
+ }
5053
+ });
5054
+
4788
5055
  // src/tools/glob.ts
4789
- import fg from "fast-glob";
4790
5056
  var globTool;
4791
- var init_glob = __esm({
5057
+ var init_glob2 = __esm({
4792
5058
  "src/tools/glob.ts"() {
4793
5059
  "use strict";
4794
5060
  init_paths();
5061
+ init_glob();
4795
5062
  globTool = {
4796
5063
  name: "glob",
4797
5064
  description: "Find files matching a glob pattern (e.g. `**/*.ts`). Returns up to 200 absolute paths, sorted by mtime descending.",
@@ -4809,7 +5076,7 @@ var init_glob = __esm({
4809
5076
  async run(args, ctx) {
4810
5077
  if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
4811
5078
  const root = args.path ? resolvePath(ctx.cwd, args.path) : ctx.cwd;
4812
- const stream = fg.stream(args.pattern, {
5079
+ const stream = globStream(args.pattern, {
4813
5080
  cwd: root,
4814
5081
  absolute: true,
4815
5082
  dot: false,
@@ -4844,7 +5111,6 @@ var init_glob = __esm({
4844
5111
  import { execFile } from "child_process";
4845
5112
  import { promisify } from "util";
4846
5113
  import { readFile as readFile6 } from "fs/promises";
4847
- import fg2 from "fast-glob";
4848
5114
  async function hasRipgrep() {
4849
5115
  if (cachedHasRg !== null) return cachedHasRg;
4850
5116
  try {
@@ -4879,7 +5145,7 @@ async function runRipgrep(args, root, mode, signal) {
4879
5145
  async function runJsFallback(args, root, mode, signal) {
4880
5146
  const re = new RegExp(args.pattern, args.case_insensitive ? "i" : "");
4881
5147
  const globPattern = args.glob ? `**/${args.glob}` : "**/*";
4882
- const files = await fg2(globPattern, {
5148
+ const files = await glob(globPattern, {
4883
5149
  cwd: root,
4884
5150
  absolute: true,
4885
5151
  dot: false,
@@ -4920,6 +5186,7 @@ var init_grep = __esm({
4920
5186
  "src/tools/grep.ts"() {
4921
5187
  "use strict";
4922
5188
  init_paths();
5189
+ init_glob();
4923
5190
  pExecFile = promisify(execFile);
4924
5191
  cachedHasRg = null;
4925
5192
  grepTool = {
@@ -5310,10 +5577,10 @@ var init_github = __esm({
5310
5577
  // src/tools/browser.ts
5311
5578
  import { mkdir as mkdir5 } from "fs/promises";
5312
5579
  import { tmpdir as tmpdir2 } from "os";
5313
- import { join as join10, dirname as dirname5 } from "path";
5580
+ import { join as join11, dirname as dirname5 } from "path";
5314
5581
  async function autoScroll(page) {
5315
5582
  await page.evaluate(async () => {
5316
- await new Promise((resolve3) => {
5583
+ await new Promise((resolve4) => {
5317
5584
  let totalHeight = 0;
5318
5585
  const distance = 300;
5319
5586
  const timer2 = setInterval(() => {
@@ -5322,12 +5589,12 @@ async function autoScroll(page) {
5322
5589
  totalHeight += distance;
5323
5590
  if (totalHeight >= scrollHeight) {
5324
5591
  clearInterval(timer2);
5325
- resolve3();
5592
+ resolve4();
5326
5593
  }
5327
5594
  }, 100);
5328
5595
  setTimeout(() => {
5329
5596
  clearInterval(timer2);
5330
- resolve3();
5597
+ resolve4();
5331
5598
  }, 1e4);
5332
5599
  });
5333
5600
  });
@@ -5386,7 +5653,7 @@ var init_browser = __esm({
5386
5653
  }
5387
5654
  let screenshotPath;
5388
5655
  if (args.screenshot) {
5389
- screenshotPath = join10(tmpdir2(), `kimiflare-browser-${Date.now()}.png`);
5656
+ screenshotPath = join11(tmpdir2(), `kimiflare-browser-${Date.now()}.png`);
5390
5657
  await mkdir5(dirname5(screenshotPath), { recursive: true });
5391
5658
  await page.screenshot({ path: screenshotPath, fullPage: true });
5392
5659
  }
@@ -6258,7 +6525,7 @@ var init_executor = __esm({
6258
6525
  init_write();
6259
6526
  init_edit();
6260
6527
  init_bash();
6261
- init_glob();
6528
+ init_glob2();
6262
6529
  init_grep();
6263
6530
  init_web_fetch();
6264
6531
  init_web_search();
@@ -6500,16 +6767,16 @@ var init_executor = __esm({
6500
6767
  // src/util/update-check.ts
6501
6768
  import { readFile as readFile7, writeFile as writeFile6, mkdir as mkdir6 } from "fs/promises";
6502
6769
  import { homedir as homedir6 } from "os";
6503
- import { join as join11, dirname as dirname6 } from "path";
6770
+ import { join as join12, dirname as dirname6 } from "path";
6504
6771
  import { fileURLToPath as fileURLToPath2 } from "url";
6505
6772
  function cachePath() {
6506
- const xdg = process.env.XDG_CONFIG_HOME || join11(homedir6(), ".config");
6507
- return join11(xdg, "kimiflare", "update-check.json");
6773
+ const xdg = process.env.XDG_CONFIG_HOME || join12(homedir6(), ".config");
6774
+ return join12(xdg, "kimiflare", "update-check.json");
6508
6775
  }
6509
6776
  async function findPackageJson(startDir) {
6510
6777
  let dir = startDir;
6511
6778
  while (true) {
6512
- const candidate = join11(dir, "package.json");
6779
+ const candidate = join12(dir, "package.json");
6513
6780
  try {
6514
6781
  const raw = await readFile7(candidate, "utf8");
6515
6782
  const parsed = JSON.parse(raw);
@@ -6600,22 +6867,22 @@ var init_update_check = __esm({
6600
6867
  });
6601
6868
 
6602
6869
  // src/remote/session-store.ts
6603
- import { readFile as readFile8, writeFile as writeFile7, mkdir as mkdir7, readdir as readdir2 } from "fs/promises";
6870
+ import { readFile as readFile8, writeFile as writeFile7, mkdir as mkdir7, readdir as readdir3 } from "fs/promises";
6604
6871
  import { homedir as homedir7 } from "os";
6605
- import { join as join12 } from "path";
6872
+ import { join as join13 } from "path";
6606
6873
  function remoteDir() {
6607
- const xdg = process.env.XDG_DATA_HOME || join12(homedir7(), ".config");
6608
- return join12(xdg, "kimiflare", "remote");
6874
+ const xdg = process.env.XDG_DATA_HOME || join13(homedir7(), ".config");
6875
+ return join13(xdg, "kimiflare", "remote");
6609
6876
  }
6610
6877
  async function saveRemoteSession(session) {
6611
6878
  const dir = remoteDir();
6612
6879
  await mkdir7(dir, { recursive: true });
6613
- const path = join12(dir, `${session.sessionId}.json`);
6880
+ const path = join13(dir, `${session.sessionId}.json`);
6614
6881
  await writeFile7(path, JSON.stringify(session, null, 2) + "\n", "utf8");
6615
6882
  }
6616
6883
  async function loadRemoteSession(sessionId) {
6617
6884
  try {
6618
- const path = join12(remoteDir(), `${sessionId}.json`);
6885
+ const path = join13(remoteDir(), `${sessionId}.json`);
6619
6886
  const raw = await readFile8(path, "utf8");
6620
6887
  return JSON.parse(raw);
6621
6888
  } catch {
@@ -6625,12 +6892,12 @@ async function loadRemoteSession(sessionId) {
6625
6892
  async function listRemoteSessions() {
6626
6893
  const dir = remoteDir();
6627
6894
  try {
6628
- const files = await readdir2(dir);
6895
+ const files = await readdir3(dir);
6629
6896
  const sessions = [];
6630
6897
  for (const file of files) {
6631
6898
  if (!file.endsWith(".json")) continue;
6632
6899
  try {
6633
- const raw = await readFile8(join12(dir, file), "utf8");
6900
+ const raw = await readFile8(join13(dir, file), "utf8");
6634
6901
  sessions.push(JSON.parse(raw));
6635
6902
  } catch {
6636
6903
  }
@@ -6652,7 +6919,7 @@ var init_session_store = __esm({
6652
6919
 
6653
6920
  // src/remote/deploy.ts
6654
6921
  import { execSync } from "child_process";
6655
- import { join as join13, dirname as dirname7 } from "path";
6922
+ import { join as join14, dirname as dirname7 } from "path";
6656
6923
  import { fileURLToPath as fileURLToPath3 } from "url";
6657
6924
  import { randomBytes } from "crypto";
6658
6925
  function generateSecret() {
@@ -6687,7 +6954,7 @@ async function* deployForTui() {
6687
6954
  yield { message: "Docker OK" };
6688
6955
  yield { message: "Building remote agent bundle..." };
6689
6956
  try {
6690
- runCapture("npm run build:remote-agent", join13(REMOTE_DIR, ".."));
6957
+ runCapture("npm run build:remote-agent", join14(REMOTE_DIR, ".."));
6691
6958
  yield { message: "Agent bundle built" };
6692
6959
  } catch (err) {
6693
6960
  yield { message: `Build failed: ${err instanceof Error ? err.message : String(err)}`, error: true };
@@ -6817,8 +7084,8 @@ var init_deploy = __esm({
6817
7084
  "use strict";
6818
7085
  init_config();
6819
7086
  __dirname2 = dirname7(fileURLToPath3(import.meta.url));
6820
- REMOTE_DIR = join13(__dirname2, "..", "..", "..", "remote");
6821
- WORKER_DIR = join13(REMOTE_DIR, "worker");
7087
+ REMOTE_DIR = join14(__dirname2, "..", "..", "..", "remote");
7088
+ WORKER_DIR = join14(REMOTE_DIR, "worker");
6822
7089
  }
6823
7090
  });
6824
7091
 
@@ -7333,11 +7600,11 @@ var init_heuristic = __esm({
7333
7600
 
7334
7601
  // src/cost-attribution/classify-from-session.ts
7335
7602
  import { readFile as readFile9 } from "fs/promises";
7336
- import { join as join14 } from "path";
7603
+ import { join as join15 } from "path";
7337
7604
  import { homedir as homedir8 } from "os";
7338
7605
  function sessionsDir() {
7339
- const xdg = process.env.XDG_DATA_HOME || join14(homedir8(), ".local", "share");
7340
- return join14(xdg, "kimiflare", "sessions");
7606
+ const xdg = process.env.XDG_DATA_HOME || join15(homedir8(), ".local", "share");
7607
+ return join15(xdg, "kimiflare", "sessions");
7341
7608
  }
7342
7609
  function parseToolCalls(calls) {
7343
7610
  return calls.map((c) => {
@@ -7351,7 +7618,7 @@ function parseToolCalls(calls) {
7351
7618
  }
7352
7619
  async function classifyFromSessionFile(sessionId) {
7353
7620
  try {
7354
- const raw = await readFile9(join14(sessionsDir(), `${sessionId}.json`), "utf8");
7621
+ const raw = await readFile9(join15(sessionsDir(), `${sessionId}.json`), "utf8");
7355
7622
  const session = JSON.parse(raw);
7356
7623
  const messages = session.messages ?? [];
7357
7624
  const turns = [];
@@ -7385,14 +7652,14 @@ __export(cli_exports, {
7385
7652
  runCostCommand: () => runCostCommand
7386
7653
  });
7387
7654
  import { readFile as readFile10 } from "fs/promises";
7388
- import { join as join15 } from "path";
7655
+ import { join as join16 } from "path";
7389
7656
  import { homedir as homedir9 } from "os";
7390
7657
  function usageDir() {
7391
- const xdg = process.env.XDG_DATA_HOME || join15(homedir9(), ".local", "share");
7392
- return join15(xdg, "kimiflare");
7658
+ const xdg = process.env.XDG_DATA_HOME || join16(homedir9(), ".local", "share");
7659
+ return join16(xdg, "kimiflare");
7393
7660
  }
7394
7661
  function usagePath() {
7395
- return join15(usageDir(), "usage.json");
7662
+ return join16(usageDir(), "usage.json");
7396
7663
  }
7397
7664
  function today() {
7398
7665
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -7508,14 +7775,14 @@ __export(auth_exports, {
7508
7775
  import { readFile as readFile11, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
7509
7776
  import { createHash } from "crypto";
7510
7777
  import { homedir as homedir10, hostname, userInfo } from "os";
7511
- import { join as join16 } from "path";
7778
+ import { join as join17 } from "path";
7512
7779
  function cloudCredPath() {
7513
- const xdg = process.env.XDG_CONFIG_HOME || join16(homedir10(), ".config");
7514
- return join16(xdg, "kimiflare", "cloud.json");
7780
+ const xdg = process.env.XDG_CONFIG_HOME || join17(homedir10(), ".config");
7781
+ return join17(xdg, "kimiflare", "cloud.json");
7515
7782
  }
7516
7783
  function deviceIdPath() {
7517
- const xdg = process.env.XDG_DATA_HOME || join16(homedir10(), ".local", "share");
7518
- return join16(xdg, "kimiflare", "device_id");
7784
+ const xdg = process.env.XDG_DATA_HOME || join17(homedir10(), ".local", "share");
7785
+ return join17(xdg, "kimiflare", "device_id");
7519
7786
  }
7520
7787
  function generateCode() {
7521
7788
  const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
@@ -7562,7 +7829,7 @@ async function getOrCreateDeviceId() {
7562
7829
  }
7563
7830
  async function persistDeviceId(deviceId) {
7564
7831
  const p = deviceIdPath();
7565
- await mkdir8(join16(p, ".."), { recursive: true });
7832
+ await mkdir8(join17(p, ".."), { recursive: true });
7566
7833
  await writeFile8(p, deviceId, { mode: 384 });
7567
7834
  }
7568
7835
  async function generateDeviceCodes() {
@@ -7644,7 +7911,7 @@ async function loadCloudCredentials() {
7644
7911
  }
7645
7912
  async function saveCloudCredentials(creds) {
7646
7913
  const p = cloudCredPath();
7647
- await mkdir8(join16(p, ".."), { recursive: true });
7914
+ await mkdir8(join17(p, ".."), { recursive: true });
7648
7915
  await writeFile8(p, JSON.stringify(creds, null, 2), "utf8");
7649
7916
  if (creds.deviceId) {
7650
7917
  await persistDeviceId(creds.deviceId).catch(() => {
@@ -7693,7 +7960,7 @@ __export(tui_auth_exports, {
7693
7960
  authGitHubForTui: () => authGitHubForTui
7694
7961
  });
7695
7962
  function sleep3(ms) {
7696
- return new Promise((resolve3) => setTimeout(resolve3, ms));
7963
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
7697
7964
  }
7698
7965
  async function* authGitHubForTui() {
7699
7966
  yield { message: "Starting GitHub OAuth device flow..." };
@@ -8807,7 +9074,7 @@ var init_connection = __esm({
8807
9074
  if (this.child) {
8808
9075
  throw new Error("LSP connection already started");
8809
9076
  }
8810
- return new Promise((resolve3, reject) => {
9077
+ return new Promise((resolve4, reject) => {
8811
9078
  const abortController = new AbortController();
8812
9079
  const spawnTimer = setTimeout(() => {
8813
9080
  abortController.abort();
@@ -8846,7 +9113,7 @@ var init_connection = __esm({
8846
9113
  if (child.pid) {
8847
9114
  clearTimeout(spawnTimer);
8848
9115
  this.child = child;
8849
- resolve3();
9116
+ resolve4();
8850
9117
  }
8851
9118
  });
8852
9119
  } catch (err) {
@@ -8861,12 +9128,12 @@ var init_connection = __esm({
8861
9128
  }
8862
9129
  const id = this.nextId++;
8863
9130
  const msg = { jsonrpc: "2.0", id, method, params };
8864
- return new Promise((resolve3, reject) => {
9131
+ return new Promise((resolve4, reject) => {
8865
9132
  const timer2 = setTimeout(() => {
8866
9133
  this.pending.delete(id);
8867
9134
  reject(toolTimeoutError(`LSP request '${method}'`, this.requestTimeoutMs));
8868
9135
  }, this.requestTimeoutMs);
8869
- const pending = { resolve: resolve3, reject, signal, timer: timer2 };
9136
+ const pending = { resolve: resolve4, reject, signal, timer: timer2 };
8870
9137
  this.pending.set(id, pending);
8871
9138
  if (signal) {
8872
9139
  const onAbort = () => {
@@ -9411,10 +9678,10 @@ var init_manager2 = __esm({
9411
9678
  });
9412
9679
 
9413
9680
  // src/lsp/adapter.ts
9414
- import { relative as relative2 } from "path";
9681
+ import { relative as relative3 } from "path";
9415
9682
  function formatLocation(loc, cwd) {
9416
9683
  const path = fromUri(loc.uri);
9417
- const rel = relative2(cwd, path) || path;
9684
+ const rel = relative3(cwd, path) || path;
9418
9685
  return `${rel}:${loc.range.start.line + 1}:${loc.range.start.character + 1}`;
9419
9686
  }
9420
9687
  function formatLocations(locs, cwd) {
@@ -9451,7 +9718,7 @@ function formatWorkspaceSymbols(symbols, cwd) {
9451
9718
  if (!symbols || symbols.length === 0) return "No symbols found.";
9452
9719
  return symbols.map((s) => {
9453
9720
  const path = fromUri(s.location.uri);
9454
- const rel = relative2(cwd, path) || path;
9721
+ const rel = relative3(cwd, path) || path;
9455
9722
  const container = s.containerName ? ` in ${s.containerName}` : "";
9456
9723
  return `${s.name} (${symbolKindName(s.kind)})${container} \u2014 ${rel}:${s.location.range.start.line + 1}:${s.location.range.start.character + 1}`;
9457
9724
  }).join("\n");
@@ -9471,7 +9738,7 @@ function formatWorkspaceEdit(edit, cwd) {
9471
9738
  if (edit.changes) {
9472
9739
  for (const [uri, edits] of Object.entries(edit.changes)) {
9473
9740
  const path = fromUri(uri);
9474
- const rel = relative2(cwd, path) || path;
9741
+ const rel = relative3(cwd, path) || path;
9475
9742
  lines.push(`File: ${rel}`);
9476
9743
  for (const e of edits) {
9477
9744
  lines.push(` ${e.range.start.line + 1}:${e.range.start.character + 1}-${e.range.end.line + 1}:${e.range.end.character + 1}: ${e.newText}`);
@@ -9496,7 +9763,7 @@ var init_adapter = __esm({
9496
9763
  });
9497
9764
 
9498
9765
  // src/tools/lsp.ts
9499
- import { relative as relative3 } from "path";
9766
+ import { relative as relative4 } from "path";
9500
9767
  function makeOutput2(content) {
9501
9768
  const bytes = Buffer.byteLength(content, "utf8");
9502
9769
  return { content, rawBytes: bytes, reducedBytes: bytes };
@@ -9504,7 +9771,7 @@ function makeOutput2(content) {
9504
9771
  function resolveLspPath(args, ctx) {
9505
9772
  const raw = typeof args.path === "string" ? args.path : "";
9506
9773
  const resolved = resolvePath(ctx.cwd, raw);
9507
- const rel = relative3(ctx.cwd, resolved);
9774
+ const rel = relative4(ctx.cwd, resolved);
9508
9775
  if (isPathOutside(rel)) {
9509
9776
  throw new Error(`Path outside workspace: ${raw}`);
9510
9777
  }
@@ -9766,12 +10033,12 @@ __export(sessions_exports, {
9766
10033
  saveSession: () => saveSession,
9767
10034
  sessionsDir: () => sessionsDir2
9768
10035
  });
9769
- import { readFile as readFile12, writeFile as writeFile9, mkdir as mkdir9, readdir as readdir3, stat as stat4 } from "fs/promises";
10036
+ import { readFile as readFile12, writeFile as writeFile9, mkdir as mkdir9, readdir as readdir4, stat as stat4 } from "fs/promises";
9770
10037
  import { homedir as homedir11 } from "os";
9771
- import { join as join18 } from "path";
10038
+ import { join as join19 } from "path";
9772
10039
  function sessionsDir2() {
9773
- const xdg = process.env.XDG_DATA_HOME || join18(homedir11(), ".local", "share");
9774
- return join18(xdg, "kimiflare", "sessions");
10040
+ const xdg = process.env.XDG_DATA_HOME || join19(homedir11(), ".local", "share");
10041
+ return join19(xdg, "kimiflare", "sessions");
9775
10042
  }
9776
10043
  function sanitize(text) {
9777
10044
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
@@ -9791,7 +10058,7 @@ function makeSessionId(firstPrompt) {
9791
10058
  async function saveSession(file) {
9792
10059
  const dir = sessionsDir2();
9793
10060
  await mkdir9(dir, { recursive: true });
9794
- const path = join18(dir, `${file.id}.json`);
10061
+ const path = join19(dir, `${file.id}.json`);
9795
10062
  await writeFile9(path, JSON.stringify(file, null, 2), "utf8");
9796
10063
  return path;
9797
10064
  }
@@ -9804,14 +10071,14 @@ async function listSessions(limit = 30, cwd) {
9804
10071
  const dir = sessionsDir2();
9805
10072
  let entries;
9806
10073
  try {
9807
- entries = await readdir3(dir);
10074
+ entries = await readdir4(dir);
9808
10075
  } catch {
9809
10076
  return [];
9810
10077
  }
9811
10078
  const summaries = [];
9812
10079
  for (const name of entries) {
9813
10080
  if (!name.endsWith(".json")) continue;
9814
- const path = join18(dir, name);
10081
+ const path = join19(dir, name);
9815
10082
  try {
9816
10083
  const [s, raw] = await Promise.all([stat4(path), readFile12(path, "utf8")]);
9817
10084
  const parsed = JSON.parse(raw);
@@ -9902,18 +10169,18 @@ var init_pricing = __esm({
9902
10169
  // src/usage-tracker.ts
9903
10170
  import { readFile as readFile13, writeFile as writeFile10, mkdir as mkdir10 } from "fs/promises";
9904
10171
  import { homedir as homedir12 } from "os";
9905
- import { join as join19 } from "path";
10172
+ import { join as join20 } from "path";
9906
10173
  import { EventEmitter as EventEmitter2 } from "events";
9907
10174
  import { randomUUID } from "crypto";
9908
10175
  function usageDir2() {
9909
- const xdg = process.env.XDG_DATA_HOME || join19(homedir12(), ".local", "share");
9910
- return join19(xdg, "kimiflare");
10176
+ const xdg = process.env.XDG_DATA_HOME || join20(homedir12(), ".local", "share");
10177
+ return join20(xdg, "kimiflare");
9911
10178
  }
9912
10179
  function usagePath2() {
9913
- return join19(usageDir2(), "usage.json");
10180
+ return join20(usageDir2(), "usage.json");
9914
10181
  }
9915
10182
  function historyPath() {
9916
- return join19(usageDir2(), "history.jsonl");
10183
+ return join20(usageDir2(), "history.jsonl");
9917
10184
  }
9918
10185
  function today2() {
9919
10186
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -10365,14 +10632,14 @@ var init_types2 = __esm({
10365
10632
  // src/hooks/settings.ts
10366
10633
  import { existsSync as existsSync2, readFileSync as readFileSync3, mkdirSync as mkdirSync3, writeFileSync } from "fs";
10367
10634
  import { homedir as homedir13 } from "os";
10368
- import { join as join20, dirname as dirname9 } from "path";
10635
+ import { join as join21, dirname as dirname9 } from "path";
10369
10636
  import { createHash as createHash2 } from "crypto";
10370
10637
  function globalSettingsPath() {
10371
- const xdg = process.env.XDG_CONFIG_HOME || join20(homedir13(), ".config");
10372
- return join20(xdg, "kimiflare", "settings.json");
10638
+ const xdg = process.env.XDG_CONFIG_HOME || join21(homedir13(), ".config");
10639
+ return join21(xdg, "kimiflare", "settings.json");
10373
10640
  }
10374
10641
  function projectSettingsPath(cwd) {
10375
- return join20(cwd, ".kimiflare", "settings.json");
10642
+ return join21(cwd, ".kimiflare", "settings.json");
10376
10643
  }
10377
10644
  function readSettingsFile(path) {
10378
10645
  if (!existsSync2(path)) return null;
@@ -10607,7 +10874,7 @@ var init_runner = __esm({
10607
10874
  init_logger();
10608
10875
  DEFAULT_TIMEOUT_MS = 3e4;
10609
10876
  STREAM_CAP_BYTES = 4 * 1024;
10610
- defaultSpawn = (command, payloadJson, env2, cwd, timeoutMs, signal) => new Promise((resolve3) => {
10877
+ defaultSpawn = (command, payloadJson, env2, cwd, timeoutMs, signal) => new Promise((resolve4) => {
10611
10878
  const child = spawn3(command, {
10612
10879
  shell: true,
10613
10880
  cwd,
@@ -10622,7 +10889,7 @@ var init_runner = __esm({
10622
10889
  settled = true;
10623
10890
  clearTimeout(timer2);
10624
10891
  signal?.removeEventListener("abort", onAbort);
10625
- resolve3({ exitCode, stdout, stderr, timedOut });
10892
+ resolve4({ exitCode, stdout, stderr, timedOut });
10626
10893
  };
10627
10894
  const onAbort = () => {
10628
10895
  child.kill("SIGTERM");
@@ -10695,13 +10962,13 @@ var init_manager3 = __esm({
10695
10962
  });
10696
10963
 
10697
10964
  // src/sdk/session.ts
10698
- import { resolve as resolve2 } from "path";
10965
+ import { resolve as resolve3 } from "path";
10699
10966
  import { homedir as homedir14 } from "os";
10700
- import { join as join21 } from "path";
10967
+ import { join as join22 } from "path";
10701
10968
  import { existsSync as existsSync3 } from "fs";
10702
10969
  async function createAgentSession(opts2) {
10703
10970
  const config2 = await resolveSdkConfig(opts2);
10704
- const cwd = resolve2(opts2.cwd ?? process.cwd());
10971
+ const cwd = resolve3(opts2.cwd ?? process.cwd());
10705
10972
  const tools = opts2.tools ?? ALL_TOOLS;
10706
10973
  let hooks;
10707
10974
  if (opts2.enableHooks) {
@@ -10712,7 +10979,7 @@ async function createAgentSession(opts2) {
10712
10979
  let memoryManager = null;
10713
10980
  const memoryEnabled = opts2.memoryEnabled ?? config2.memoryEnabled ?? false;
10714
10981
  if (memoryEnabled) {
10715
- const dbPath = config2.memoryDbPath ?? join21(homedir14(), ".local", "share", "kimiflare", "memory.db");
10982
+ const dbPath = config2.memoryDbPath ?? join22(homedir14(), ".local", "share", "kimiflare", "memory.db");
10716
10983
  memoryManager = new MemoryManager({
10717
10984
  dbPath,
10718
10985
  accountId: config2.accountId,
@@ -10743,7 +11010,7 @@ async function createAgentSession(opts2) {
10743
11010
  }
10744
11011
  let sessionFile;
10745
11012
  if (opts2.sessionId) {
10746
- const filePath = join21(sessionsDir2(), `${opts2.sessionId}.json`);
11013
+ const filePath = join22(sessionsDir2(), `${opts2.sessionId}.json`);
10747
11014
  try {
10748
11015
  sessionFile = await loadSession(filePath);
10749
11016
  } catch {
@@ -11095,12 +11362,12 @@ var init_session = __esm({
11095
11362
  toolName: req.tool.name,
11096
11363
  args: req.args
11097
11364
  });
11098
- const decision = await new Promise((resolve3) => {
11099
- this.permissionResolvers.set(requestId, resolve3);
11365
+ const decision = await new Promise((resolve4) => {
11366
+ this.permissionResolvers.set(requestId, resolve4);
11100
11367
  setTimeout(() => {
11101
11368
  if (this.permissionResolvers.has(requestId)) {
11102
11369
  this.permissionResolvers.delete(requestId);
11103
- resolve3("deny");
11370
+ resolve4("deny");
11104
11371
  }
11105
11372
  }, 3e5);
11106
11373
  });
@@ -11156,7 +11423,7 @@ var init_session = __esm({
11156
11423
  }
11157
11424
  }
11158
11425
  });
11159
- if (existsSync3(join21(this.cwd, "KIMI.md"))) {
11426
+ if (existsSync3(join22(this.cwd, "KIMI.md"))) {
11160
11427
  this.messages[0] = {
11161
11428
  role: "system",
11162
11429
  content: buildSystemPrompt({
@@ -11638,6 +11905,302 @@ var init_abort_scope = __esm({
11638
11905
  }
11639
11906
  });
11640
11907
 
11908
+ // src/util/diff.ts
11909
+ function tokenize(value, options = {}) {
11910
+ if (options.stripTrailingCr) {
11911
+ value = value.replace(/\r\n/g, "\n");
11912
+ }
11913
+ const retLines = [];
11914
+ const linesAndNewlines = value.split(/(\n|\r\n)/);
11915
+ if (!linesAndNewlines[linesAndNewlines.length - 1]) {
11916
+ linesAndNewlines.pop();
11917
+ }
11918
+ for (let i = 0; i < linesAndNewlines.length; i++) {
11919
+ const line = linesAndNewlines[i];
11920
+ if (i % 2 && !options.newlineIsToken) {
11921
+ retLines[retLines.length - 1] += line;
11922
+ } else {
11923
+ retLines.push(line);
11924
+ }
11925
+ }
11926
+ return retLines;
11927
+ }
11928
+ function removeEmpty(array) {
11929
+ const ret = [];
11930
+ for (let i = 0; i < array.length; i++) {
11931
+ if (array[i]) {
11932
+ ret.push(array[i]);
11933
+ }
11934
+ }
11935
+ return ret;
11936
+ }
11937
+ function diffLines(oldStr, newStr, options = {}) {
11938
+ const oldTokens = removeEmpty(tokenize(oldStr));
11939
+ const newTokens = removeEmpty(tokenize(newStr));
11940
+ const newLen = newTokens.length;
11941
+ const oldLen = oldTokens.length;
11942
+ let editLength = 1;
11943
+ let maxEditLength = newLen + oldLen;
11944
+ if (options.maxEditLength != null) {
11945
+ maxEditLength = Math.min(maxEditLength, options.maxEditLength);
11946
+ }
11947
+ const maxExecutionTime = options.timeout ?? Infinity;
11948
+ const abortAfterTimestamp = Date.now() + maxExecutionTime;
11949
+ const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
11950
+ let newPos = extractCommon(bestPath[0], newTokens, oldTokens, 0);
11951
+ if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
11952
+ return buildValues(bestPath[0].lastComponent, newTokens, oldTokens);
11953
+ }
11954
+ let minDiagonalToConsider = -Infinity;
11955
+ let maxDiagonalToConsider = Infinity;
11956
+ while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
11957
+ for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
11958
+ let basePath;
11959
+ const removePath = bestPath[diagonalPath - 1];
11960
+ const addPath = bestPath[diagonalPath + 1];
11961
+ if (removePath) {
11962
+ bestPath[diagonalPath - 1] = void 0;
11963
+ }
11964
+ let canAdd = false;
11965
+ if (addPath) {
11966
+ const addPathNewPos = addPath.oldPos - diagonalPath;
11967
+ canAdd = 0 <= addPathNewPos && addPathNewPos < newLen;
11968
+ }
11969
+ const canRemove = removePath && removePath.oldPos + 1 < oldLen;
11970
+ if (!canAdd && !canRemove) {
11971
+ bestPath[diagonalPath] = void 0;
11972
+ continue;
11973
+ }
11974
+ if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
11975
+ basePath = addToPath(addPath, true, false, 0);
11976
+ } else {
11977
+ basePath = addToPath(removePath, false, true, 1);
11978
+ }
11979
+ newPos = extractCommon(basePath, newTokens, oldTokens, diagonalPath);
11980
+ if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
11981
+ return buildValues(basePath.lastComponent, newTokens, oldTokens);
11982
+ }
11983
+ bestPath[diagonalPath] = basePath;
11984
+ if (basePath.oldPos + 1 >= oldLen) {
11985
+ maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
11986
+ }
11987
+ if (newPos + 1 >= newLen) {
11988
+ minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
11989
+ }
11990
+ }
11991
+ editLength++;
11992
+ }
11993
+ return [];
11994
+ }
11995
+ function addToPath(path, added, removed, oldPosInc) {
11996
+ const last = path.lastComponent;
11997
+ if (last && last.added === added && last.removed === removed) {
11998
+ return {
11999
+ oldPos: path.oldPos + oldPosInc,
12000
+ lastComponent: {
12001
+ count: last.count + 1,
12002
+ added,
12003
+ removed,
12004
+ previousComponent: last.previousComponent
12005
+ }
12006
+ };
12007
+ } else {
12008
+ return {
12009
+ oldPos: path.oldPos + oldPosInc,
12010
+ lastComponent: {
12011
+ count: 1,
12012
+ added,
12013
+ removed,
12014
+ previousComponent: last
12015
+ }
12016
+ };
12017
+ }
12018
+ }
12019
+ function extractCommon(basePath, newTokens, oldTokens, diagonalPath) {
12020
+ const newLen = newTokens.length;
12021
+ const oldLen = oldTokens.length;
12022
+ let oldPos = basePath.oldPos;
12023
+ let newPos = oldPos - diagonalPath;
12024
+ let commonCount = 0;
12025
+ while (newPos + 1 < newLen && oldPos + 1 < oldLen && oldTokens[oldPos + 1] === newTokens[newPos + 1]) {
12026
+ newPos++;
12027
+ oldPos++;
12028
+ commonCount++;
12029
+ }
12030
+ if (commonCount) {
12031
+ basePath.lastComponent = {
12032
+ count: commonCount,
12033
+ previousComponent: basePath.lastComponent,
12034
+ added: false,
12035
+ removed: false
12036
+ };
12037
+ }
12038
+ basePath.oldPos = oldPos;
12039
+ return newPos;
12040
+ }
12041
+ function buildValues(lastComponent, newTokens, oldTokens) {
12042
+ const components = [];
12043
+ let nextComponent;
12044
+ while (lastComponent) {
12045
+ components.push(lastComponent);
12046
+ nextComponent = lastComponent.previousComponent;
12047
+ delete lastComponent.previousComponent;
12048
+ lastComponent = nextComponent;
12049
+ }
12050
+ components.reverse();
12051
+ const result = [];
12052
+ let newPos = 0;
12053
+ let oldPos = 0;
12054
+ for (const component of components) {
12055
+ if (!component.removed) {
12056
+ component.value = newTokens.slice(newPos, newPos + component.count).join("");
12057
+ newPos += component.count;
12058
+ if (!component.added) {
12059
+ oldPos += component.count;
12060
+ }
12061
+ } else {
12062
+ component.value = oldTokens.slice(oldPos, oldPos + component.count).join("");
12063
+ oldPos += component.count;
12064
+ }
12065
+ result.push({ value: component.value, added: component.added, removed: component.removed });
12066
+ }
12067
+ return result;
12068
+ }
12069
+ function splitLines(text) {
12070
+ const hasTrailingNl = text.endsWith("\n");
12071
+ const result = text.split("\n").map((line) => line + "\n");
12072
+ if (hasTrailingNl) {
12073
+ result.pop();
12074
+ } else {
12075
+ const last = result.pop();
12076
+ if (last !== void 0) {
12077
+ result.push(last.slice(0, -1));
12078
+ }
12079
+ }
12080
+ return result;
12081
+ }
12082
+ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
12083
+ const optionsObj = options ?? {};
12084
+ if (typeof optionsObj.context === "undefined") {
12085
+ optionsObj.context = 4;
12086
+ }
12087
+ const context = optionsObj.context;
12088
+ const diff = diffLines(oldStr, newStr);
12089
+ return diffLinesResultToPatch(diff);
12090
+ function diffLinesResultToPatch(diffResult) {
12091
+ if (!diffResult) {
12092
+ return void 0;
12093
+ }
12094
+ diffResult.push({ value: "", lines: [] });
12095
+ function contextLines(lines) {
12096
+ return lines.map((entry) => " " + entry);
12097
+ }
12098
+ const hunks = [];
12099
+ let oldRangeStart = 0;
12100
+ let newRangeStart = 0;
12101
+ let curRange = [];
12102
+ let oldLine = 1;
12103
+ let newLine = 1;
12104
+ for (let i = 0; i < diffResult.length; i++) {
12105
+ const current = diffResult[i];
12106
+ const lines = current.lines || splitLines(current.value);
12107
+ current.lines = lines;
12108
+ if (current.added || current.removed) {
12109
+ if (!oldRangeStart) {
12110
+ const prev = diffResult[i - 1];
12111
+ oldRangeStart = oldLine;
12112
+ newRangeStart = newLine;
12113
+ if (prev) {
12114
+ curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
12115
+ oldRangeStart -= curRange.length;
12116
+ newRangeStart -= curRange.length;
12117
+ }
12118
+ }
12119
+ for (const line of lines) {
12120
+ curRange.push((current.added ? "+" : "-") + line);
12121
+ }
12122
+ if (current.added) {
12123
+ newLine += lines.length;
12124
+ } else {
12125
+ oldLine += lines.length;
12126
+ }
12127
+ } else {
12128
+ if (oldRangeStart) {
12129
+ if (lines.length <= context * 2 && i < diffResult.length - 2) {
12130
+ for (const line of contextLines(lines)) {
12131
+ curRange.push(line);
12132
+ }
12133
+ } else {
12134
+ const contextSize = Math.min(lines.length, context);
12135
+ for (const line of contextLines(lines.slice(0, contextSize))) {
12136
+ curRange.push(line);
12137
+ }
12138
+ const hunk = {
12139
+ oldStart: oldRangeStart,
12140
+ oldLines: oldLine - oldRangeStart + contextSize,
12141
+ newStart: newRangeStart,
12142
+ newLines: newLine - newRangeStart + contextSize,
12143
+ lines: curRange
12144
+ };
12145
+ hunks.push(hunk);
12146
+ oldRangeStart = 0;
12147
+ newRangeStart = 0;
12148
+ curRange = [];
12149
+ }
12150
+ }
12151
+ oldLine += lines.length;
12152
+ newLine += lines.length;
12153
+ }
12154
+ }
12155
+ for (const hunk of hunks) {
12156
+ for (let i = 0; i < hunk.lines.length; i++) {
12157
+ if (hunk.lines[i].endsWith("\n")) {
12158
+ hunk.lines[i] = hunk.lines[i].slice(0, -1);
12159
+ } else {
12160
+ hunk.lines.splice(i + 1, 0, "\");
12161
+ i++;
12162
+ }
12163
+ }
12164
+ }
12165
+ return {
12166
+ oldFileName,
12167
+ newFileName,
12168
+ oldHeader,
12169
+ newHeader,
12170
+ hunks
12171
+ };
12172
+ }
12173
+ }
12174
+ function formatPatch(patch) {
12175
+ const ret = [];
12176
+ ret.push("Index: " + patch.oldFileName);
12177
+ ret.push("===================================================================");
12178
+ ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
12179
+ ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
12180
+ for (let i = 0; i < patch.hunks.length; i++) {
12181
+ const hunk = patch.hunks[i];
12182
+ const oldStart = hunk.oldLines === 0 ? hunk.oldStart - 1 : hunk.oldStart;
12183
+ const newStart = hunk.newLines === 0 ? hunk.newStart - 1 : hunk.newStart;
12184
+ ret.push("@@ -" + oldStart + "," + hunk.oldLines + " +" + newStart + "," + hunk.newLines + " @@");
12185
+ for (const line of hunk.lines) {
12186
+ ret.push(line);
12187
+ }
12188
+ }
12189
+ return ret.join("\n") + "\n";
12190
+ }
12191
+ function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
12192
+ const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
12193
+ if (!patchObj) {
12194
+ return "";
12195
+ }
12196
+ return formatPatch(patchObj);
12197
+ }
12198
+ var init_diff = __esm({
12199
+ "src/util/diff.ts"() {
12200
+ "use strict";
12201
+ }
12202
+ });
12203
+
11641
12204
  // src/ui/theme-context.tsx
11642
12205
  import { createContext, useContext } from "react";
11643
12206
  import { jsx } from "react/jsx-runtime";
@@ -11662,7 +12225,6 @@ var init_theme_context = __esm({
11662
12225
 
11663
12226
  // src/ui/diff-view.tsx
11664
12227
  import { Box, Text } from "ink";
11665
- import { createTwoFilesPatch } from "diff";
11666
12228
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
11667
12229
  function DiffView({ path, before, after, maxLines = 40 }) {
11668
12230
  const theme = useTheme();
@@ -11709,6 +12271,7 @@ function DiffLine({ line }) {
11709
12271
  var init_diff_view = __esm({
11710
12272
  "src/ui/diff-view.tsx"() {
11711
12273
  "use strict";
12274
+ init_diff();
11712
12275
  init_theme_context();
11713
12276
  }
11714
12277
  });
@@ -13734,19 +14297,19 @@ function usePermissionController(getMode, onPlanModeBlocked) {
13734
14297
  const onPlanModeBlockedRef = useRef2(onPlanModeBlocked);
13735
14298
  onPlanModeBlockedRef.current = onPlanModeBlocked;
13736
14299
  const askPermission = useCallback2(
13737
- (req, askOpts) => new Promise((resolve3) => {
14300
+ (req, askOpts) => new Promise((resolve4) => {
13738
14301
  const outcome = decidePermission(req, getModeRef.current(), askOpts);
13739
14302
  if (outcome.kind === "resolve") {
13740
- resolve3(outcome.decision);
14303
+ resolve4(outcome.decision);
13741
14304
  return;
13742
14305
  }
13743
14306
  if (outcome.kind === "plan_blocked") {
13744
14307
  onPlanModeBlockedRef.current(outcome.toolName);
13745
- resolve3(AUTO_DENY);
14308
+ resolve4(AUTO_DENY);
13746
14309
  return;
13747
14310
  }
13748
- resolveRef.current = resolve3;
13749
- setPending({ tool: req.tool, args: req.args, resolve: resolve3 });
14311
+ resolveRef.current = resolve4;
14312
+ setPending({ tool: req.tool, args: req.args, resolve: resolve4 });
13750
14313
  }),
13751
14314
  []
13752
14315
  );
@@ -14811,16 +15374,15 @@ var init_frontmatter = __esm({
14811
15374
  });
14812
15375
 
14813
15376
  // src/commands/loader.ts
14814
- import { open, realpath } from "fs/promises";
15377
+ import { open, realpath as realpath2 } from "fs/promises";
14815
15378
  import { homedir as homedir15 } from "os";
14816
- import { join as join22, relative as relative4, sep as sep2 } from "path";
14817
- import fg3 from "fast-glob";
15379
+ import { join as join23, relative as relative5, sep as sep2 } from "path";
14818
15380
  function projectCommandsDir(cwd = process.cwd()) {
14819
- return join22(cwd, ".kimiflare", "commands");
15381
+ return join23(cwd, ".kimiflare", "commands");
14820
15382
  }
14821
15383
  function globalCommandsDir() {
14822
- const xdg = process.env.XDG_CONFIG_HOME || join22(homedir15(), ".config");
14823
- return join22(xdg, "kimiflare", "commands");
15384
+ const xdg = process.env.XDG_CONFIG_HOME || join23(homedir15(), ".config");
15385
+ return join23(xdg, "kimiflare", "commands");
14824
15386
  }
14825
15387
  async function loadCustomCommands(cwd = process.cwd()) {
14826
15388
  const warnings = [];
@@ -14833,11 +15395,10 @@ async function loadCustomCommands(cwd = process.cwd()) {
14833
15395
  sources.map(async ({ dir, source }) => {
14834
15396
  const safeDir = await resolveSafeDir(dir, source, cwd, warnings);
14835
15397
  if (safeDir === null) return [];
14836
- const files = await fg3("**/*.md", {
15398
+ const files = await glob("**/*.md", {
14837
15399
  cwd: safeDir,
14838
15400
  absolute: true,
14839
15401
  onlyFiles: true,
14840
- followSymbolicLinks: false,
14841
15402
  suppressErrors: true
14842
15403
  });
14843
15404
  return Promise.all(files.map((file) => loadOne(file, safeDir, source, warnings)));
@@ -14860,7 +15421,7 @@ async function loadCustomCommands(cwd = process.cwd()) {
14860
15421
  async function resolveSafeDir(dir, source, cwd, warnings) {
14861
15422
  let realDir;
14862
15423
  try {
14863
- realDir = await realpath(dir);
15424
+ realDir = await realpath2(dir);
14864
15425
  } catch (err) {
14865
15426
  const code = err.code;
14866
15427
  if (code !== "ENOENT" && code !== "ENOTDIR") {
@@ -14871,11 +15432,11 @@ async function resolveSafeDir(dir, source, cwd, warnings) {
14871
15432
  if (source === "project") {
14872
15433
  let realCwd;
14873
15434
  try {
14874
- realCwd = await realpath(cwd);
15435
+ realCwd = await realpath2(cwd);
14875
15436
  } catch {
14876
15437
  return null;
14877
15438
  }
14878
- const rel = relative4(realCwd, realDir);
15439
+ const rel = relative5(realCwd, realDir);
14879
15440
  if (rel !== "" && isPathOutside(rel)) {
14880
15441
  warnings.push(`commands dir ${dir} escapes workspace via symlink \u2014 skipped`);
14881
15442
  return null;
@@ -14950,7 +15511,7 @@ async function loadOne(file, rootDir, source, warnings) {
14950
15511
  return cmd;
14951
15512
  }
14952
15513
  function filenameToCommandName(file, rootDir) {
14953
- const rel = relative4(rootDir, file);
15514
+ const rel = relative5(rootDir, file);
14954
15515
  if (!rel || isPathOutside(rel)) return null;
14955
15516
  const noExt = rel.replace(/\.md$/i, "");
14956
15517
  const parts = noExt.split(sep2).filter((p) => p.length > 0);
@@ -14963,6 +15524,7 @@ var init_loader = __esm({
14963
15524
  "src/commands/loader.ts"() {
14964
15525
  "use strict";
14965
15526
  init_mode();
15527
+ init_glob();
14966
15528
  init_config();
14967
15529
  init_paths();
14968
15530
  init_frontmatter();
@@ -14972,8 +15534,8 @@ var init_loader = __esm({
14972
15534
 
14973
15535
  // src/commands/renderer.ts
14974
15536
  import { exec } from "child_process";
14975
- import { open as open2, realpath as realpath2 } from "fs/promises";
14976
- import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolvePathJoin, basename as pathBasename } from "path";
15537
+ import { open as open2, realpath as realpath3 } from "fs/promises";
15538
+ import { isAbsolute as isAbsolute2, relative as relative6, resolve as resolvePathJoin, basename as pathBasename } from "path";
14977
15539
  import { promisify as promisify2 } from "util";
14978
15540
  function tokenizeArgs(s) {
14979
15541
  return [...s.matchAll(ARG_TOKEN_RE)].map((match) => {
@@ -15064,7 +15626,7 @@ async function replaceFiles(prompt, warnings, cmd, cwd, maxFileBytes) {
15064
15626
  return "" + trailing;
15065
15627
  });
15066
15628
  }
15067
- const realCwd = await realpath2(cwd).catch(() => cwd);
15629
+ const realCwd = await realpath3(cwd).catch(() => cwd);
15068
15630
  const replacements = await Promise.all(
15069
15631
  matches.map(async (match) => {
15070
15632
  const rawPath = match[1] ?? "";
@@ -15078,18 +15640,18 @@ async function replaceFiles(prompt, warnings, cmd, cwd, maxFileBytes) {
15078
15640
  return "";
15079
15641
  }
15080
15642
  const resolved = resolvePathJoin(cwd, rawPath);
15081
- if (isPathOutside(relative5(cwd, resolved))) {
15643
+ if (isPathOutside(relative6(cwd, resolved))) {
15082
15644
  warnings.push(`file inclusion skipped: @${rawPath} \u2014 outside workspace`);
15083
15645
  return "";
15084
15646
  }
15085
15647
  let real;
15086
15648
  try {
15087
- real = await realpath2(resolved);
15649
+ real = await realpath3(resolved);
15088
15650
  } catch (error) {
15089
15651
  warnings.push(`file inclusion failed: @${rawPath} \u2014 ${message(error)}`);
15090
15652
  return "";
15091
15653
  }
15092
- if (isPathOutside(relative5(realCwd, real))) {
15654
+ if (isPathOutside(relative6(realCwd, real))) {
15093
15655
  warnings.push(`file inclusion skipped: @${rawPath} \u2014 symlink escapes workspace`);
15094
15656
  return "";
15095
15657
  }
@@ -16072,11 +16634,11 @@ var init_wcag = __esm({
16072
16634
  });
16073
16635
 
16074
16636
  // src/ui/theme-loader.ts
16075
- import { readFile as readFile15, readdir as readdir4 } from "fs/promises";
16076
- import { join as join23 } from "path";
16637
+ import { readFile as readFile15, readdir as readdir5 } from "fs/promises";
16638
+ import { join as join24 } from "path";
16077
16639
  import { homedir as homedir16 } from "os";
16078
16640
  function projectThemesDir(cwd = process.cwd()) {
16079
- return join23(cwd, ".kimiflare", "themes");
16641
+ return join24(cwd, ".kimiflare", "themes");
16080
16642
  }
16081
16643
  function isHexColor(c) {
16082
16644
  return /^#[0-9a-fA-F]{6}$/.test(c);
@@ -16160,12 +16722,12 @@ async function loadThemesFromDir(dir, source) {
16160
16722
  const errors = [];
16161
16723
  let files;
16162
16724
  try {
16163
- files = await readdir4(dir);
16725
+ files = await readdir5(dir);
16164
16726
  } catch {
16165
16727
  return { themes, errors };
16166
16728
  }
16167
16729
  for (const file of files.filter((f) => f.endsWith(".json"))) {
16168
- const path = join23(dir, file);
16730
+ const path = join24(dir, file);
16169
16731
  let raw;
16170
16732
  try {
16171
16733
  raw = await readFile15(path, "utf-8");
@@ -16314,8 +16876,8 @@ var init_theme_loader = __esm({
16314
16876
  "use strict";
16315
16877
  init_wcag();
16316
16878
  init_theme();
16317
- USER_THEMES_DIR = join23(
16318
- process.env.XDG_CONFIG_HOME || join23(homedir16(), ".config"),
16879
+ USER_THEMES_DIR = join24(
16880
+ process.env.XDG_CONFIG_HOME || join24(homedir16(), ".config"),
16319
16881
  "kimiflare",
16320
16882
  "themes"
16321
16883
  );
@@ -19837,8 +20399,8 @@ var init_frontmatter2 = __esm({
19837
20399
  });
19838
20400
 
19839
20401
  // src/skills/loader.ts
19840
- import { readFile as readFile16, readdir as readdir5, stat as stat5 } from "fs/promises";
19841
- import { join as join24, extname } from "path";
20402
+ import { readFile as readFile16, readdir as readdir6, stat as stat5 } from "fs/promises";
20403
+ import { join as join25, extname } from "path";
19842
20404
  function normalizeManifest(raw, filePath) {
19843
20405
  const name = typeof raw.name === "string" ? raw.name : "";
19844
20406
  const description = typeof raw.description === "string" ? raw.description : "";
@@ -19871,10 +20433,10 @@ async function loadSkillFile(filePath) {
19871
20433
  }
19872
20434
  async function loadSkillsFromDir(dirPath) {
19873
20435
  try {
19874
- const entries = await readdir5(dirPath);
20436
+ const entries = await readdir6(dirPath);
19875
20437
  const files = [];
19876
20438
  for (const entry of entries) {
19877
- const full = join24(dirPath, entry);
20439
+ const full = join25(dirPath, entry);
19878
20440
  const s = await stat5(full);
19879
20441
  if (s.isFile() && extname(entry) === ".md") {
19880
20442
  files.push(full);
@@ -19903,11 +20465,11 @@ var init_loader2 = __esm({
19903
20465
 
19904
20466
  // src/skills/manager.ts
19905
20467
  import { mkdir as mkdir11, writeFile as writeFile11, unlink as unlink2, readFile as readFile17 } from "fs/promises";
19906
- import { join as join25 } from "path";
20468
+ import { join as join26 } from "path";
19907
20469
  function getSkillDirs(cwd) {
19908
20470
  return {
19909
- projectDir: join25(cwd, ".kimiflare", "skills"),
19910
- globalDir: join25(process.env.HOME ?? "", ".config", "kimiflare", "skills")
20471
+ projectDir: join26(cwd, ".kimiflare", "skills"),
20472
+ globalDir: join26(process.env.HOME ?? "", ".config", "kimiflare", "skills")
19911
20473
  };
19912
20474
  }
19913
20475
  async function listAllSkills(cwd) {
@@ -19921,7 +20483,7 @@ async function listAllSkills(cwd) {
19921
20483
  async function createSkill(opts2) {
19922
20484
  const dirs = getSkillDirs(opts2.cwd);
19923
20485
  const dir = opts2.scope === "project" ? dirs.projectDir : dirs.globalDir;
19924
- const filepath = join25(dir, `${opts2.name}.md`);
20486
+ const filepath = join26(dir, `${opts2.name}.md`);
19925
20487
  const frontmatter = {
19926
20488
  name: opts2.name,
19927
20489
  enabled: true,
@@ -20043,7 +20605,7 @@ var init_report2 = __esm({
20043
20605
  // src/ui/app-helpers.ts
20044
20606
  import { execSync as execSync2, spawn as spawn5 } from "child_process";
20045
20607
  import { existsSync as existsSync4, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
20046
- import { join as join26 } from "path";
20608
+ import { join as join27 } from "path";
20047
20609
  import { platform as platform5 } from "os";
20048
20610
  function buildFilePickerIgnoreList(cwd) {
20049
20611
  const hardcoded = [
@@ -20115,7 +20677,7 @@ function buildFilePickerIgnoreList(cwd) {
20115
20677
  ];
20116
20678
  const gitignorePatterns = [];
20117
20679
  try {
20118
- const gitignorePath = join26(cwd, ".gitignore");
20680
+ const gitignorePath = join27(cwd, ".gitignore");
20119
20681
  const stats = statSync4(gitignorePath);
20120
20682
  if (stats.size > MAX_GITIGNORE_SIZE) {
20121
20683
  return hardcoded;
@@ -20288,14 +20850,14 @@ __export(tui_report_exports, {
20288
20850
  getCategoryReportText: () => getCategoryReportText
20289
20851
  });
20290
20852
  import { readFile as readFile18 } from "fs/promises";
20291
- import { join as join27 } from "path";
20853
+ import { join as join28 } from "path";
20292
20854
  import { homedir as homedir17 } from "os";
20293
20855
  function usageDir3() {
20294
- const xdg = process.env.XDG_DATA_HOME || join27(homedir17(), ".local", "share");
20295
- return join27(xdg, "kimiflare");
20856
+ const xdg = process.env.XDG_DATA_HOME || join28(homedir17(), ".local", "share");
20857
+ return join28(xdg, "kimiflare");
20296
20858
  }
20297
20859
  function usagePath3() {
20298
- return join27(usageDir3(), "usage.json");
20860
+ return join28(usageDir3(), "usage.json");
20299
20861
  }
20300
20862
  function today3() {
20301
20863
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -20364,7 +20926,7 @@ var init_tui_report = __esm({
20364
20926
  });
20365
20927
 
20366
20928
  // src/ui/slash-commands.ts
20367
- import { join as join28 } from "path";
20929
+ import { join as join29 } from "path";
20368
20930
  import { unlink as unlink3 } from "fs/promises";
20369
20931
  import QRCode from "qrcode";
20370
20932
  function dispatchSlashCommand(ctx, cmd) {
@@ -20932,7 +21494,7 @@ ${lines.join("\n")}` }]);
20932
21494
  try {
20933
21495
  ctx.ensureSessionId();
20934
21496
  const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
20935
- const filePath = join28(sessionsDir3(), `${ctx.sessionIdRef.current}.json`);
21497
+ const filePath = join29(sessionsDir3(), `${ctx.sessionIdRef.current}.json`);
20936
21498
  await addCheckpoint(filePath, cp);
20937
21499
  setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: `checkpoint saved: "${label}"` }]);
20938
21500
  } catch (e) {
@@ -20954,7 +21516,7 @@ ${lines.join("\n")}` }]);
20954
21516
  void (async () => {
20955
21517
  try {
20956
21518
  const { sessionsDir: sessionsDir3 } = await Promise.resolve().then(() => (init_sessions(), sessions_exports));
20957
- const file = await loadSession(join28(sessionsDir3(), `${currentId}.json`));
21519
+ const file = await loadSession(join29(sessionsDir3(), `${currentId}.json`));
20958
21520
  const cps = file.checkpoints ?? [];
20959
21521
  if (cps.length === 0) {
20960
21522
  setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: "no checkpoints in this session" }]);
@@ -21531,12 +22093,12 @@ project: ${projectSettingsPath(cwd)}`
21531
22093
 
21532
22094
  // src/init/context-generator.ts
21533
22095
  import { existsSync as existsSync5, statSync as statSync5 } from "fs";
21534
- import { join as join29 } from "path";
22096
+ import { join as join30 } from "path";
21535
22097
  function detectFlavor(cwd) {
21536
22098
  for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
21537
22099
  if (flavor === "generic") continue;
21538
22100
  for (const sig of signatures) {
21539
- const path = join29(cwd, sig);
22101
+ const path = join30(cwd, sig);
21540
22102
  if (sig.includes("*")) {
21541
22103
  try {
21542
22104
  const parts = sig.split("*");
@@ -21557,14 +22119,14 @@ function detectFlavor(cwd) {
21557
22119
  }
21558
22120
  function findFile(cwd, candidates) {
21559
22121
  for (const c of candidates) {
21560
- if (existsSync5(join29(cwd, c))) return c;
22122
+ if (existsSync5(join30(cwd, c))) return c;
21561
22123
  }
21562
22124
  return null;
21563
22125
  }
21564
22126
  function findSourceRoots(cwd) {
21565
22127
  const roots = [];
21566
22128
  for (const r of SOURCE_ROOT_CANDIDATES) {
21567
- const p = join29(cwd, r);
22129
+ const p = join30(cwd, r);
21568
22130
  try {
21569
22131
  const s = statSync5(p);
21570
22132
  if (s.isDirectory()) roots.push(r);
@@ -21575,9 +22137,9 @@ function findSourceRoots(cwd) {
21575
22137
  }
21576
22138
  function findCiConfig(cwd) {
21577
22139
  for (const c of CI_PATHS) {
21578
- if (existsSync5(join29(cwd, c))) {
22140
+ if (existsSync5(join30(cwd, c))) {
21579
22141
  try {
21580
- const s = statSync5(join29(cwd, c));
22142
+ const s = statSync5(join30(cwd, c));
21581
22143
  return s.isDirectory() ? c : c;
21582
22144
  } catch {
21583
22145
  }
@@ -21714,7 +22276,7 @@ function analyzeProject(cwd) {
21714
22276
  ciConfig: findCiConfig(cwd),
21715
22277
  readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
21716
22278
  sourceRoots: findSourceRoots(cwd),
21717
- hasGit: existsSync5(join29(cwd, ".git"))
22279
+ hasGit: existsSync5(join30(cwd, ".git"))
21718
22280
  };
21719
22281
  }
21720
22282
  function bashDiscoveryCommands(profile) {
@@ -21879,7 +22441,7 @@ Aim for 100\u2013200 lines total. Use markdown tables where they save space.
21879
22441
  }
21880
22442
  function buildInitPrompt(cwd) {
21881
22443
  const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
21882
- (n) => existsSync5(join29(cwd, n))
22444
+ (n) => existsSync5(join30(cwd, n))
21883
22445
  );
21884
22446
  const isRefresh = existingName !== void 0;
21885
22447
  const targetFilename = existingName ?? "KIMI.md";
@@ -21963,7 +22525,7 @@ var init_context_generator = __esm({
21963
22525
 
21964
22526
  // src/init/run-init.ts
21965
22527
  import { existsSync as existsSync6 } from "fs";
21966
- import { join as join30 } from "path";
22528
+ import { join as join31 } from "path";
21967
22529
  async function runInit(deps) {
21968
22530
  const {
21969
22531
  cfg,
@@ -22190,7 +22752,7 @@ async function runInit(deps) {
22190
22752
  }
22191
22753
  }
22192
22754
  });
22193
- if (existsSync6(join30(cwd, "KIMI.md"))) {
22755
+ if (existsSync6(join31(cwd, "KIMI.md"))) {
22194
22756
  if (cacheStableRef.current) {
22195
22757
  messagesRef.current[1] = {
22196
22758
  role: "system",
@@ -22320,8 +22882,8 @@ var init_run_init = __esm({
22320
22882
  });
22321
22883
 
22322
22884
  // src/skills/discovery.ts
22323
- import { readdir as readdir6, stat as stat6, readFile as readFile19 } from "fs/promises";
22324
- import { join as join31, extname as extname2 } from "path";
22885
+ import { readdir as readdir7, stat as stat6, readFile as readFile19 } from "fs/promises";
22886
+ import { join as join32, extname as extname2 } from "path";
22325
22887
  async function dirExists(path) {
22326
22888
  try {
22327
22889
  const s = await stat6(path);
@@ -22340,20 +22902,20 @@ async function fileExists(path) {
22340
22902
  }
22341
22903
  async function scanSkillDir(dirPath, source) {
22342
22904
  if (!await dirExists(dirPath)) return [];
22343
- const entries = await readdir6(dirPath, { withFileTypes: true });
22905
+ const entries = await readdir7(dirPath, { withFileTypes: true });
22344
22906
  const files = [];
22345
22907
  for (const entry of entries) {
22346
22908
  if (!entry.isFile()) continue;
22347
22909
  if (!SKILL_EXTENSIONS.has(extname2(entry.name))) continue;
22348
- files.push({ filePath: join31(dirPath, entry.name), source });
22910
+ files.push({ filePath: join32(dirPath, entry.name), source });
22349
22911
  }
22350
22912
  return files;
22351
22913
  }
22352
22914
  async function discoverSkills(cwd) {
22353
- const agentsSkills = await scanSkillDir(join31(cwd, ".agents", "skills"), "agents");
22354
- const agentsMd = await fileExists(join31(cwd, "AGENTS.md")) ? [{ filePath: join31(cwd, "AGENTS.md"), source: "agents-md" }] : [];
22355
- const githubSkills = await scanSkillDir(join31(cwd, ".github", "skills"), "github");
22356
- const kimiflareSkills = await scanSkillDir(join31(cwd, ".kimiflare", "skills"), "kimiflare");
22915
+ const agentsSkills = await scanSkillDir(join32(cwd, ".agents", "skills"), "agents");
22916
+ const agentsMd = await fileExists(join32(cwd, "AGENTS.md")) ? [{ filePath: join32(cwd, "AGENTS.md"), source: "agents-md" }] : [];
22917
+ const githubSkills = await scanSkillDir(join32(cwd, ".github", "skills"), "github");
22918
+ const kimiflareSkills = await scanSkillDir(join32(cwd, ".kimiflare", "skills"), "kimiflare");
22357
22919
  const ordered = [...agentsSkills, ...agentsMd, ...githubSkills, ...kimiflareSkills];
22358
22920
  return ordered;
22359
22921
  }
@@ -22568,10 +23130,10 @@ var init_skills = __esm({
22568
23130
  // src/util/state.ts
22569
23131
  import { readFile as readFile20, writeFile as writeFile12, mkdir as mkdir12 } from "fs/promises";
22570
23132
  import { homedir as homedir18 } from "os";
22571
- import { join as join32 } from "path";
23133
+ import { join as join33 } from "path";
22572
23134
  function statePath() {
22573
- const xdg = process.env.XDG_CONFIG_HOME || join32(homedir18(), ".config");
22574
- return join32(xdg, "kimiflare", "state.json");
23135
+ const xdg = process.env.XDG_CONFIG_HOME || join33(homedir18(), ".config");
23136
+ return join33(xdg, "kimiflare", "state.json");
22575
23137
  }
22576
23138
  async function readState() {
22577
23139
  try {
@@ -22583,7 +23145,7 @@ async function readState() {
22583
23145
  }
22584
23146
  async function writeState(state) {
22585
23147
  const path = statePath();
22586
- await mkdir12(join32(path, ".."), { recursive: true });
23148
+ await mkdir12(join33(path, ".."), { recursive: true });
22587
23149
  await writeFile12(path, JSON.stringify(state, null, 2) + "\n", "utf8");
22588
23150
  }
22589
23151
  async function markCreatorMessageSeen(version) {
@@ -22603,7 +23165,7 @@ var init_state = __esm({
22603
23165
 
22604
23166
  // src/ui/run-startup-tasks.ts
22605
23167
  import { existsSync as existsSync7 } from "fs";
22606
- import { join as join33 } from "path";
23168
+ import { join as join34 } from "path";
22607
23169
  function runStartupTasks(deps) {
22608
23170
  const {
22609
23171
  cfg,
@@ -22658,7 +23220,7 @@ function runStartupTasks(deps) {
22658
23220
  }
22659
23221
  });
22660
23222
  if (cfg.memoryEnabled) {
22661
- const dbPath = cfg.memoryDbPath ?? join33(process.cwd(), ".kimiflare", "memory.db");
23223
+ const dbPath = cfg.memoryDbPath ?? join34(process.cwd(), ".kimiflare", "memory.db");
22662
23224
  const manager = new MemoryManager({
22663
23225
  dbPath,
22664
23226
  accountId: cfg.accountId,
@@ -22692,7 +23254,7 @@ function runStartupTasks(deps) {
22692
23254
  });
22693
23255
  const cwd = process.cwd();
22694
23256
  sessionStartRecallRef.current = manager.recall({ text: cwd, repoPath: cwd, limit: 5 });
22695
- if (existsSync7(join33(cwd, "KIMI.md"))) {
23257
+ if (existsSync7(join34(cwd, "KIMI.md"))) {
22696
23258
  const lastRefresh = manager.getLastKimiMdRefreshTime(cwd);
22697
23259
  const driftCount = manager.countHighSignalMemoriesSince(cwd, lastRefresh);
22698
23260
  if (driftCount >= 5) {
@@ -22703,7 +23265,7 @@ function runStartupTasks(deps) {
22703
23265
  memoryManagerRef.current?.close();
22704
23266
  memoryManagerRef.current = null;
22705
23267
  }
22706
- const skillDbPath = cfg.memoryDbPath ?? join33(process.cwd(), ".kimiflare", "memory.db");
23268
+ const skillDbPath = cfg.memoryDbPath ?? join34(process.cwd(), ".kimiflare", "memory.db");
22707
23269
  const skillDb = getMemoryDb() ?? openMemoryDb(skillDbPath);
22708
23270
  initSkillsSchema(skillDb);
22709
23271
  void indexSkills({
@@ -23202,8 +23764,7 @@ __export(app_exports, {
23202
23764
  import React19, { useState as useState20, useRef as useRef7, useEffect as useEffect8, useCallback as useCallback8 } from "react";
23203
23765
  import { Box as Box28, Text as Text29, useApp, useInput as useInput12, render } from "ink";
23204
23766
  import { existsSync as existsSync8 } from "fs";
23205
- import { join as join34 } from "path";
23206
- import fg4 from "fast-glob";
23767
+ import { join as join35 } from "path";
23207
23768
  import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
23208
23769
  function App({
23209
23770
  initialCfg,
@@ -23503,7 +24064,7 @@ ${wcagWarnings.join("\n")}` }
23503
24064
  const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || checkpointSession !== null || perm !== null || limitModal !== null || loopModal !== null || showInboxModal;
23504
24065
  const loadFilePickerItems = useCallback8(async () => {
23505
24066
  const cwd = process.cwd();
23506
- const entries = await fg4("**/*", {
24067
+ const entries = await glob("**/*", {
23507
24068
  cwd,
23508
24069
  ignore: buildFilePickerIgnoreList(cwd),
23509
24070
  dot: false,
@@ -24303,7 +24864,7 @@ ${wcagWarnings.join("\n")}` }
24303
24864
  }
24304
24865
  }
24305
24866
  turnCounterRef.current += 1;
24306
- if (turnCounterRef.current % 15 === 0 && existsSync8(join34(process.cwd(), "KIMI.md")) && !kimiMdStale) {
24867
+ if (turnCounterRef.current % 15 === 0 && existsSync8(join35(process.cwd(), "KIMI.md")) && !kimiMdStale) {
24307
24868
  setEvents((e) => [
24308
24869
  ...e,
24309
24870
  { kind: "info", key: mkKey(), text: "Tip: Rerunning /init occasionally helps KimiFlare stay accurate as your project evolves." }
@@ -24443,13 +25004,13 @@ ${wcagWarnings.join("\n")}` }
24443
25004
  }
24444
25005
  },
24445
25006
  askPermission: askForPermission,
24446
- onToolLimitReached: () => new Promise((resolve3) => {
24447
- limitResolveRef.current = resolve3;
24448
- setLimitModal({ limit: 50, resolve: resolve3 });
25007
+ onToolLimitReached: () => new Promise((resolve4) => {
25008
+ limitResolveRef.current = resolve4;
25009
+ setLimitModal({ limit: 50, resolve: resolve4 });
24449
25010
  }),
24450
- onLoopDetected: () => new Promise((resolve3) => {
24451
- loopResolveRef.current = resolve3;
24452
- setLoopModal({ resolve: resolve3 });
25011
+ onLoopDetected: () => new Promise((resolve4) => {
25012
+ loopResolveRef.current = resolve4;
25013
+ setLoopModal({ resolve: resolve4 });
24453
25014
  }),
24454
25015
  onKimiMdStale: () => {
24455
25016
  if (!kimiMdStaleNudgedRef.current) {
@@ -24808,7 +25369,7 @@ ${wcagWarnings.join("\n")}` }
24808
25369
  onCommandDelete: handleCommandDelete2,
24809
25370
  lspServers: cfg?.lspServers ?? {},
24810
25371
  lspScope,
24811
- hasProjectDir: existsSync8(join34(process.cwd(), ".kimiflare")),
25372
+ hasProjectDir: existsSync8(join35(process.cwd(), ".kimiflare")),
24812
25373
  onLspSave: handleLspSave2,
24813
25374
  themes: themeList(),
24814
25375
  onPickTheme: handleThemePick,
@@ -25032,6 +25593,7 @@ var init_app = __esm({
25032
25593
  init_theme();
25033
25594
  init_theme_loader();
25034
25595
  init_lsp_nudge();
25596
+ init_glob();
25035
25597
  init_file_picker();
25036
25598
  init_slash_picker();
25037
25599
  init_use_picker_controller();