@ridit/lens 0.3.7 → 0.3.8

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.mjs CHANGED
@@ -194362,14 +194362,14 @@ var require_gifutil = __commonJS((exports) => {
194362
194362
  jimpImage.bitmap.data = bitmapImageToShare.bitmap.data;
194363
194363
  return jimpImage;
194364
194364
  };
194365
- exports.write = function(path24, frames, spec, encoder) {
194365
+ exports.write = function(path23, frames, spec, encoder) {
194366
194366
  encoder = encoder || defaultCodec;
194367
- const matches2 = path24.match(/\.[a-zA-Z]+$/);
194367
+ const matches2 = path23.match(/\.[a-zA-Z]+$/);
194368
194368
  if (matches2 !== null && INVALID_SUFFIXES.includes(matches2[0].toLowerCase())) {
194369
- throw new Error(`GIF '${path24}' has an unexpected suffix`);
194369
+ throw new Error(`GIF '${path23}' has an unexpected suffix`);
194370
194370
  }
194371
194371
  return encoder.encodeGif(frames, spec).then((gif) => {
194372
- return _writeBinary(path24, gif.buffer).then(() => {
194372
+ return _writeBinary(path23, gif.buffer).then(() => {
194373
194373
  return gif;
194374
194374
  });
194375
194375
  });
@@ -194431,9 +194431,9 @@ var require_gifutil = __commonJS((exports) => {
194431
194431
  }
194432
194432
  }
194433
194433
  }
194434
- function _readBinary(path24) {
194434
+ function _readBinary(path23) {
194435
194435
  return new Promise((resolve2, reject3) => {
194436
- fs4.readFile(path24, (err, buffer) => {
194436
+ fs4.readFile(path23, (err, buffer) => {
194437
194437
  if (err) {
194438
194438
  return reject3(err);
194439
194439
  }
@@ -194441,9 +194441,9 @@ var require_gifutil = __commonJS((exports) => {
194441
194441
  });
194442
194442
  });
194443
194443
  }
194444
- function _writeBinary(path24, buffer) {
194444
+ function _writeBinary(path23, buffer) {
194445
194445
  return new Promise((resolve2, reject3) => {
194446
- fs4.writeFile(path24, buffer, (err) => {
194446
+ fs4.writeFile(path23, buffer, (err) => {
194447
194447
  if (err) {
194448
194448
  return reject3(err);
194449
194449
  }
@@ -196396,9 +196396,9 @@ var require_decoder = __commonJS((exports, module) => {
196396
196396
  return a < 0 ? 0 : a > 255 ? 255 : a;
196397
196397
  }
196398
196398
  constructor.prototype = {
196399
- load: function load(path24) {
196399
+ load: function load(path23) {
196400
196400
  var xhr = new XMLHttpRequest;
196401
- xhr.open("GET", path24, true);
196401
+ xhr.open("GET", path23, true);
196402
196402
  xhr.responseType = "arraybuffer";
196403
196403
  xhr.onload = function() {
196404
196404
  var data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer);
@@ -207197,8 +207197,8 @@ class ParseStatus {
207197
207197
  }
207198
207198
  }
207199
207199
  var makeIssue = (params) => {
207200
- const { data, path: path24, errorMaps, issueData } = params;
207201
- const fullPath = [...path24, ...issueData.path || []];
207200
+ const { data, path: path23, errorMaps, issueData } = params;
207201
+ const fullPath = [...path23, ...issueData.path || []];
207202
207202
  const fullIssue = {
207203
207203
  ...issueData,
207204
207204
  path: fullPath
@@ -207244,11 +207244,11 @@ var init_errorUtil = __esm(() => {
207244
207244
 
207245
207245
  // node_modules/zod/v3/types.js
207246
207246
  class ParseInputLazyPath {
207247
- constructor(parent, value, path24, key) {
207247
+ constructor(parent, value, path23, key) {
207248
207248
  this._cachedPath = [];
207249
207249
  this.parent = parent;
207250
207250
  this.data = value;
207251
- this._path = path24;
207251
+ this._path = path23;
207252
207252
  this._key = key;
207253
207253
  }
207254
207254
  get path() {
@@ -214366,7 +214366,7 @@ var require_await_to_js_umd = __commonJS((exports, module) => {
214366
214366
 
214367
214367
  // node_modules/@jimp/file-ops/dist/esm/index.js
214368
214368
  import { promises as fs4 } from "fs";
214369
- import { existsSync as existsSync19 } from "fs";
214369
+ import { existsSync as existsSync18 } from "fs";
214370
214370
  var readFile2, writeFile2;
214371
214371
  var init_esm13 = __esm(() => {
214372
214372
  readFile2 = fs4.readFile;
@@ -214407,11 +214407,11 @@ var require_Mime = __commonJS((exports, module) => {
214407
214407
  }
214408
214408
  }
214409
214409
  };
214410
- Mime.prototype.getType = function(path24) {
214411
- path24 = String(path24);
214412
- let last2 = path24.replace(/^.*[/\\]/, "").toLowerCase();
214410
+ Mime.prototype.getType = function(path23) {
214411
+ path23 = String(path23);
214412
+ let last2 = path23.replace(/^.*[/\\]/, "").toLowerCase();
214413
214413
  let ext = last2.replace(/^.*\./, "").toLowerCase();
214414
- let hasPath = last2.length < path24.length;
214414
+ let hasPath = last2.length < path23.length;
214415
214415
  let hasDot = ext.length < last2.length - 1;
214416
214416
  return (hasDot || !hasPath) && this._types[ext] || null;
214417
214417
  };
@@ -216062,7 +216062,7 @@ function createJimp({ plugins: pluginsArg, formats: formatsArg } = {}) {
216062
216062
  if (Buffer.isBuffer(url) || url instanceof ArrayBuffer) {
216063
216063
  return this.fromBuffer(url);
216064
216064
  }
216065
- if (existsSync19(url)) {
216065
+ if (existsSync18(url)) {
216066
216066
  return this.fromBuffer(await readFile2(url));
216067
216067
  }
216068
216068
  const [fetchErr, response] = await import_await_to_js.to(fetch(url));
@@ -216151,9 +216151,9 @@ function createJimp({ plugins: pluginsArg, formats: formatsArg } = {}) {
216151
216151
  const data = await this.getBuffer(mime2, options);
216152
216152
  return "data:" + mime2 + ";base64," + data.toString("base64");
216153
216153
  }
216154
- async write(path24, options) {
216155
- const mimeType = import_lite.default.getType(path24);
216156
- await writeFile2(path24, await this.getBuffer(mimeType, options));
216154
+ async write(path23, options) {
216155
+ const mimeType = import_lite.default.getType(path23);
216156
+ await writeFile2(path23, await this.getBuffer(mimeType, options));
216157
216157
  }
216158
216158
  clone() {
216159
216159
  return new CustomJimp({
@@ -226590,7 +226590,7 @@ var require_windows = __commonJS((exports, module) => {
226590
226590
  module.exports = isexe;
226591
226591
  isexe.sync = sync;
226592
226592
  var fs5 = __require("fs");
226593
- function checkPathExt(path24, options) {
226593
+ function checkPathExt(path23, options) {
226594
226594
  var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
226595
226595
  if (!pathext) {
226596
226596
  return true;
@@ -226601,25 +226601,25 @@ var require_windows = __commonJS((exports, module) => {
226601
226601
  }
226602
226602
  for (var i = 0;i < pathext.length; i++) {
226603
226603
  var p = pathext[i].toLowerCase();
226604
- if (p && path24.substr(-p.length).toLowerCase() === p) {
226604
+ if (p && path23.substr(-p.length).toLowerCase() === p) {
226605
226605
  return true;
226606
226606
  }
226607
226607
  }
226608
226608
  return false;
226609
226609
  }
226610
- function checkStat(stat, path24, options) {
226610
+ function checkStat(stat, path23, options) {
226611
226611
  if (!stat.isSymbolicLink() && !stat.isFile()) {
226612
226612
  return false;
226613
226613
  }
226614
- return checkPathExt(path24, options);
226614
+ return checkPathExt(path23, options);
226615
226615
  }
226616
- function isexe(path24, options, cb) {
226617
- fs5.stat(path24, function(er, stat) {
226618
- cb(er, er ? false : checkStat(stat, path24, options));
226616
+ function isexe(path23, options, cb) {
226617
+ fs5.stat(path23, function(er, stat) {
226618
+ cb(er, er ? false : checkStat(stat, path23, options));
226619
226619
  });
226620
226620
  }
226621
- function sync(path24, options) {
226622
- return checkStat(fs5.statSync(path24), path24, options);
226621
+ function sync(path23, options) {
226622
+ return checkStat(fs5.statSync(path23), path23, options);
226623
226623
  }
226624
226624
  });
226625
226625
 
@@ -226628,13 +226628,13 @@ var require_mode = __commonJS((exports, module) => {
226628
226628
  module.exports = isexe;
226629
226629
  isexe.sync = sync;
226630
226630
  var fs5 = __require("fs");
226631
- function isexe(path24, options, cb) {
226632
- fs5.stat(path24, function(er, stat) {
226631
+ function isexe(path23, options, cb) {
226632
+ fs5.stat(path23, function(er, stat) {
226633
226633
  cb(er, er ? false : checkStat(stat, options));
226634
226634
  });
226635
226635
  }
226636
- function sync(path24, options) {
226637
- return checkStat(fs5.statSync(path24), options);
226636
+ function sync(path23, options) {
226637
+ return checkStat(fs5.statSync(path23), options);
226638
226638
  }
226639
226639
  function checkStat(stat, options) {
226640
226640
  return stat.isFile() && checkMode(stat, options);
@@ -226665,7 +226665,7 @@ var require_isexe = __commonJS((exports, module) => {
226665
226665
  }
226666
226666
  module.exports = isexe;
226667
226667
  isexe.sync = sync;
226668
- function isexe(path24, options, cb) {
226668
+ function isexe(path23, options, cb) {
226669
226669
  if (typeof options === "function") {
226670
226670
  cb = options;
226671
226671
  options = {};
@@ -226675,7 +226675,7 @@ var require_isexe = __commonJS((exports, module) => {
226675
226675
  throw new TypeError("callback not provided");
226676
226676
  }
226677
226677
  return new Promise(function(resolve2, reject3) {
226678
- isexe(path24, options || {}, function(er, is) {
226678
+ isexe(path23, options || {}, function(er, is) {
226679
226679
  if (er) {
226680
226680
  reject3(er);
226681
226681
  } else {
@@ -226684,7 +226684,7 @@ var require_isexe = __commonJS((exports, module) => {
226684
226684
  });
226685
226685
  });
226686
226686
  }
226687
- core(path24, options || {}, function(er, is) {
226687
+ core(path23, options || {}, function(er, is) {
226688
226688
  if (er) {
226689
226689
  if (er.code === "EACCES" || options && options.ignoreErrors) {
226690
226690
  er = null;
@@ -226694,9 +226694,9 @@ var require_isexe = __commonJS((exports, module) => {
226694
226694
  cb(er, is);
226695
226695
  });
226696
226696
  }
226697
- function sync(path24, options) {
226697
+ function sync(path23, options) {
226698
226698
  try {
226699
- return core.sync(path24, options || {});
226699
+ return core.sync(path23, options || {});
226700
226700
  } catch (er) {
226701
226701
  if (options && options.ignoreErrors || er.code === "EACCES") {
226702
226702
  return false;
@@ -226710,7 +226710,7 @@ var require_isexe = __commonJS((exports, module) => {
226710
226710
  // node_modules/which/which.js
226711
226711
  var require_which = __commonJS((exports, module) => {
226712
226712
  var isWindows3 = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
226713
- var path24 = __require("path");
226713
+ var path23 = __require("path");
226714
226714
  var COLON = isWindows3 ? ";" : ":";
226715
226715
  var isexe = require_isexe();
226716
226716
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -226746,7 +226746,7 @@ var require_which = __commonJS((exports, module) => {
226746
226746
  return opt.all && found.length ? resolve2(found) : reject3(getNotFoundError(cmd));
226747
226747
  const ppRaw = pathEnv[i];
226748
226748
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
226749
- const pCmd = path24.join(pathPart, cmd);
226749
+ const pCmd = path23.join(pathPart, cmd);
226750
226750
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
226751
226751
  resolve2(subStep(p, i, 0));
226752
226752
  });
@@ -226773,7 +226773,7 @@ var require_which = __commonJS((exports, module) => {
226773
226773
  for (let i = 0;i < pathEnv.length; i++) {
226774
226774
  const ppRaw = pathEnv[i];
226775
226775
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
226776
- const pCmd = path24.join(pathPart, cmd);
226776
+ const pCmd = path23.join(pathPart, cmd);
226777
226777
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
226778
226778
  for (let j = 0;j < pathExt.length; j++) {
226779
226779
  const cur = p + pathExt[j];
@@ -226814,7 +226814,7 @@ var require_path_key = __commonJS((exports, module) => {
226814
226814
 
226815
226815
  // node_modules/cross-spawn/lib/util/resolveCommand.js
226816
226816
  var require_resolveCommand = __commonJS((exports, module) => {
226817
- var path24 = __require("path");
226817
+ var path23 = __require("path");
226818
226818
  var which = require_which();
226819
226819
  var getPathKey = require_path_key();
226820
226820
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -226831,7 +226831,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
226831
226831
  try {
226832
226832
  resolved = which.sync(parsed.command, {
226833
226833
  path: env3[getPathKey({ env: env3 })],
226834
- pathExt: withoutPathExt ? path24.delimiter : undefined
226834
+ pathExt: withoutPathExt ? path23.delimiter : undefined
226835
226835
  });
226836
226836
  } catch (e) {} finally {
226837
226837
  if (shouldSwitchCwd) {
@@ -226839,7 +226839,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
226839
226839
  }
226840
226840
  }
226841
226841
  if (resolved) {
226842
- resolved = path24.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
226842
+ resolved = path23.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
226843
226843
  }
226844
226844
  return resolved;
226845
226845
  }
@@ -226884,8 +226884,8 @@ var require_shebang_command = __commonJS((exports, module) => {
226884
226884
  if (!match) {
226885
226885
  return null;
226886
226886
  }
226887
- const [path24, argument] = match[0].replace(/#! ?/, "").split(" ");
226888
- const binary = path24.split("/").pop();
226887
+ const [path23, argument] = match[0].replace(/#! ?/, "").split(" ");
226888
+ const binary = path23.split("/").pop();
226889
226889
  if (binary === "env") {
226890
226890
  return argument;
226891
226891
  }
@@ -226913,7 +226913,7 @@ var require_readShebang = __commonJS((exports, module) => {
226913
226913
 
226914
226914
  // node_modules/cross-spawn/lib/parse.js
226915
226915
  var require_parse = __commonJS((exports, module) => {
226916
- var path24 = __require("path");
226916
+ var path23 = __require("path");
226917
226917
  var resolveCommand = require_resolveCommand();
226918
226918
  var escape4 = require_escape();
226919
226919
  var readShebang = require_readShebang();
@@ -226938,7 +226938,7 @@ var require_parse = __commonJS((exports, module) => {
226938
226938
  const needsShell = !isExecutableRegExp.test(commandFile);
226939
226939
  if (parsed.options.forceShell || needsShell) {
226940
226940
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
226941
- parsed.command = path24.normalize(parsed.command);
226941
+ parsed.command = path23.normalize(parsed.command);
226942
226942
  parsed.command = escape4.command(parsed.command);
226943
226943
  parsed.args = parsed.args.map((arg) => escape4.argument(arg, needsDoubleEscapeMetaChars));
226944
226944
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -227060,7 +227060,7 @@ var require_strip_final_newline = __commonJS((exports, module) => {
227060
227060
 
227061
227061
  // node_modules/npm-run-path/index.js
227062
227062
  var require_npm_run_path = __commonJS((exports, module) => {
227063
- var path24 = __require("path");
227063
+ var path23 = __require("path");
227064
227064
  var pathKey = require_path_key();
227065
227065
  var npmRunPath = (options) => {
227066
227066
  options = {
@@ -227070,16 +227070,16 @@ var require_npm_run_path = __commonJS((exports, module) => {
227070
227070
  ...options
227071
227071
  };
227072
227072
  let previous;
227073
- let cwdPath = path24.resolve(options.cwd);
227073
+ let cwdPath = path23.resolve(options.cwd);
227074
227074
  const result2 = [];
227075
227075
  while (previous !== cwdPath) {
227076
- result2.push(path24.join(cwdPath, "node_modules/.bin"));
227076
+ result2.push(path23.join(cwdPath, "node_modules/.bin"));
227077
227077
  previous = cwdPath;
227078
- cwdPath = path24.resolve(cwdPath, "..");
227078
+ cwdPath = path23.resolve(cwdPath, "..");
227079
227079
  }
227080
- const execPathDir = path24.resolve(options.cwd, options.execPath, "..");
227080
+ const execPathDir = path23.resolve(options.cwd, options.execPath, "..");
227081
227081
  result2.push(execPathDir);
227082
- return result2.concat(options.path).join(path24.delimiter);
227082
+ return result2.concat(options.path).join(path23.delimiter);
227083
227083
  };
227084
227084
  module.exports = npmRunPath;
227085
227085
  module.exports.default = npmRunPath;
@@ -227089,9 +227089,9 @@ var require_npm_run_path = __commonJS((exports, module) => {
227089
227089
  ...options
227090
227090
  };
227091
227091
  const env3 = { ...options.env };
227092
- const path25 = pathKey({ env: env3 });
227093
- options.path = env3[path25];
227094
- env3[path25] = module.exports(options);
227092
+ const path24 = pathKey({ env: env3 });
227093
+ options.path = env3[path24];
227094
+ env3[path24] = module.exports(options);
227095
227095
  return env3;
227096
227096
  };
227097
227097
  });
@@ -227980,7 +227980,7 @@ var require_command2 = __commonJS((exports, module) => {
227980
227980
 
227981
227981
  // node_modules/execa/index.js
227982
227982
  var require_execa = __commonJS((exports, module) => {
227983
- var path24 = __require("path");
227983
+ var path23 = __require("path");
227984
227984
  var childProcess = __require("child_process");
227985
227985
  var crossSpawn = require_cross_spawn();
227986
227986
  var stripFinalNewline = require_strip_final_newline();
@@ -228022,7 +228022,7 @@ var require_execa = __commonJS((exports, module) => {
228022
228022
  };
228023
228023
  options.env = getEnv(options);
228024
228024
  options.stdio = normalizeStdio(options);
228025
- if (process.platform === "win32" && path24.basename(file, ".exe") === "cmd") {
228025
+ if (process.platform === "win32" && path23.basename(file, ".exe") === "cmd") {
228026
228026
  args.unshift("/q");
228027
228027
  }
228028
228028
  return { file, args, options, parsed };
@@ -228201,7 +228201,7 @@ var require_execa = __commonJS((exports, module) => {
228201
228201
 
228202
228202
  // node_modules/app-path/index.js
228203
228203
  import { fileURLToPath } from "node:url";
228204
- import path24 from "node:path";
228204
+ import path23 from "node:path";
228205
228205
  async function appPath(appName) {
228206
228206
  if (process.platform !== "darwin") {
228207
228207
  throw new Error("macOS only");
@@ -228224,7 +228224,7 @@ var import_execa, dirname, improveError = (error) => {
228224
228224
  };
228225
228225
  var init_app_path = __esm(() => {
228226
228226
  import_execa = __toESM(require_execa(), 1);
228227
- dirname = path24.dirname(fileURLToPath(import.meta.url));
228227
+ dirname = path23.dirname(fileURLToPath(import.meta.url));
228228
228228
  appPath.sync = (appName) => {
228229
228229
  if (process.platform !== "darwin") {
228230
228230
  throw new Error("macOS only");
@@ -236391,7 +236391,7 @@ var require_plist = __commonJS((exports) => {
236391
236391
  });
236392
236392
 
236393
236393
  // node_modules/iterm2-version/index.js
236394
- import path25 from "node:path";
236394
+ import path24 from "node:path";
236395
236395
  import fs5 from "node:fs";
236396
236396
  function iterm2Version() {
236397
236397
  if (process.platform !== "darwin") {
@@ -236401,7 +236401,7 @@ function iterm2Version() {
236401
236401
  if (process.env.TERM_PROGRAM === "iTerm.app" && process.env.TERM_PROGRAM_VERSION) {
236402
236402
  version = process.env.TERM_PROGRAM_VERSION;
236403
236403
  } else {
236404
- const filePath = path25.join(appPath.sync("iTerm"), "Contents/Info.plist");
236404
+ const filePath = path24.join(appPath.sync("iTerm"), "Contents/Info.plist");
236405
236405
  version = import_plist.default.parse(fs5.readFileSync(filePath, "utf8")).CFBundleVersion;
236406
236406
  }
236407
236407
  }
@@ -237245,7 +237245,7 @@ var require_dist = __commonJS((exports) => {
237245
237245
 
237246
237246
  // node_modules/mkdirp/index.js
237247
237247
  var require_mkdirp = __commonJS((exports, module) => {
237248
- var path26 = __require("path");
237248
+ var path25 = __require("path");
237249
237249
  var fs7 = __require("fs");
237250
237250
  var _0777 = parseInt("0777", 8);
237251
237251
  module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
@@ -237264,7 +237264,7 @@ var require_mkdirp = __commonJS((exports, module) => {
237264
237264
  if (!made)
237265
237265
  made = null;
237266
237266
  var cb = f || function() {};
237267
- p = path26.resolve(p);
237267
+ p = path25.resolve(p);
237268
237268
  xfs.mkdir(p, mode, function(er) {
237269
237269
  if (!er) {
237270
237270
  made = made || p;
@@ -237272,9 +237272,9 @@ var require_mkdirp = __commonJS((exports, module) => {
237272
237272
  }
237273
237273
  switch (er.code) {
237274
237274
  case "ENOENT":
237275
- if (path26.dirname(p) === p)
237275
+ if (path25.dirname(p) === p)
237276
237276
  return cb(er);
237277
- mkdirP(path26.dirname(p), opts, function(er2, made2) {
237277
+ mkdirP(path25.dirname(p), opts, function(er2, made2) {
237278
237278
  if (er2)
237279
237279
  cb(er2, made2);
237280
237280
  else
@@ -237303,14 +237303,14 @@ var require_mkdirp = __commonJS((exports, module) => {
237303
237303
  }
237304
237304
  if (!made)
237305
237305
  made = null;
237306
- p = path26.resolve(p);
237306
+ p = path25.resolve(p);
237307
237307
  try {
237308
237308
  xfs.mkdirSync(p, mode);
237309
237309
  made = made || p;
237310
237310
  } catch (err0) {
237311
237311
  switch (err0.code) {
237312
237312
  case "ENOENT":
237313
- made = sync(path26.dirname(p), opts, made);
237313
+ made = sync(path25.dirname(p), opts, made);
237314
237314
  sync(p, opts, made);
237315
237315
  break;
237316
237316
  default:
@@ -239092,8 +239092,8 @@ var require_mime = __commonJS((exports) => {
239092
239092
  mimeTypes[mime2] = extensions;
239093
239093
  };
239094
239094
  exports.addType = addType;
239095
- var getType = function getType2(path26) {
239096
- var pathParts = path26.split("/").slice(-1);
239095
+ var getType = function getType2(path25) {
239096
+ var pathParts = path25.split("/").slice(-1);
239097
239097
  var extension = pathParts[pathParts.length - 1].split(".").pop();
239098
239098
  var type = findType(extension);
239099
239099
  return type[0];
@@ -239746,13 +239746,13 @@ var require_image_bitmap = __commonJS((exports) => {
239746
239746
  var constants6 = _interopRequireWildcard(require_constants5());
239747
239747
  var MIME = _interopRequireWildcard(require_mime());
239748
239748
  var _promisify = _interopRequireDefault(require_promisify());
239749
- function getMIMEFromBuffer(buffer, path26) {
239749
+ function getMIMEFromBuffer(buffer, path25) {
239750
239750
  var fileTypeFromBuffer = (0, _fileType["default"])(buffer);
239751
239751
  if (fileTypeFromBuffer) {
239752
239752
  return fileTypeFromBuffer.mime;
239753
239753
  }
239754
- if (path26) {
239755
- return MIME.getType(path26);
239754
+ if (path25) {
239755
+ return MIME.getType(path25);
239756
239756
  }
239757
239757
  return null;
239758
239758
  }
@@ -239823,10 +239823,10 @@ var require_image_bitmap = __commonJS((exports) => {
239823
239823
  var newHeight = swapDimensions ? img.bitmap.width : img.bitmap.height;
239824
239824
  transformBitmap2(img, newWidth, newHeight, transformation);
239825
239825
  }
239826
- function parseBitmap(data, path26, cb) {
239827
- var mime2 = getMIMEFromBuffer(data, path26);
239826
+ function parseBitmap(data, path25, cb) {
239827
+ var mime2 = getMIMEFromBuffer(data, path25);
239828
239828
  if (typeof mime2 !== "string") {
239829
- return cb(new Error("Could not find MIME for Buffer <" + path26 + ">"));
239829
+ return cb(new Error("Could not find MIME for Buffer <" + path25 + ">"));
239830
239830
  }
239831
239831
  this._originalMime = mime2.toLowerCase();
239832
239832
  try {
@@ -240003,8 +240003,8 @@ var require_dist2 = __commonJS((exports) => {
240003
240003
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_originalMime", Jimp3.MIME_PNG);
240004
240004
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_exif", null);
240005
240005
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rgba", true);
240006
- (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "writeAsync", function(path27) {
240007
- return (0, _promisify["default"])(_this.write, (0, _assertThisInitialized2["default"])(_this), path27);
240006
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "writeAsync", function(path26) {
240007
+ return (0, _promisify["default"])(_this.write, (0, _assertThisInitialized2["default"])(_this), path26);
240008
240008
  });
240009
240009
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getBase64Async", function(mime2) {
240010
240010
  return (0, _promisify["default"])(_this.getBase64, (0, _assertThisInitialized2["default"])(_this), mime2);
@@ -240107,7 +240107,7 @@ var require_dist2 = __commonJS((exports) => {
240107
240107
  };
240108
240108
  finish(null, (0, _assertThisInitialized2["default"])(_this));
240109
240109
  } else if (typeof args[0] === "string") {
240110
- var path26 = args[0];
240110
+ var path25 = args[0];
240111
240111
  cb = args[1];
240112
240112
  if (typeof cb === "undefined") {
240113
240113
  cb = noop3;
@@ -240115,11 +240115,11 @@ var require_dist2 = __commonJS((exports) => {
240115
240115
  if (typeof cb !== "function") {
240116
240116
  return (0, _possibleConstructorReturn2["default"])(_this, _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), "cb must be a function", finish));
240117
240117
  }
240118
- loadBufferFromPath(path26, function(err, data2) {
240118
+ loadBufferFromPath(path25, function(err, data2) {
240119
240119
  if (err) {
240120
240120
  return _utils.throwError.call((0, _assertThisInitialized2["default"])(_this), err, finish);
240121
240121
  }
240122
- _this.parseBitmap(data2, path26, finish);
240122
+ _this.parseBitmap(data2, path25, finish);
240123
240123
  });
240124
240124
  } else if ((0, _typeof2["default"])(args[0]) === "object" && Buffer.isBuffer(args[0])) {
240125
240125
  var data = args[0];
@@ -240154,7 +240154,7 @@ var require_dist2 = __commonJS((exports) => {
240154
240154
  }
240155
240155
  (0, _createClass2["default"])(Jimp3, [{
240156
240156
  key: "parseBitmap",
240157
- value: function parseBitmap(data, path26, finish) {
240157
+ value: function parseBitmap(data, path25, finish) {
240158
240158
  _imageBitmap.parseBitmap.call(this, data, null, finish);
240159
240159
  }
240160
240160
  }, {
@@ -240222,12 +240222,12 @@ var require_dist2 = __commonJS((exports) => {
240222
240222
  }
240223
240223
  }, {
240224
240224
  key: "write",
240225
- value: function write(path26, cb) {
240225
+ value: function write(path25, cb) {
240226
240226
  var _this2 = this;
240227
240227
  if (!_fs["default"] || !_fs["default"].createWriteStream) {
240228
240228
  throw new Error("Cant access the filesystem. You can use the getBase64 method.");
240229
240229
  }
240230
- if (typeof path26 !== "string") {
240230
+ if (typeof path25 !== "string") {
240231
240231
  return _utils.throwError.call(this, "path must be a string", cb);
240232
240232
  }
240233
240233
  if (typeof cb === "undefined") {
@@ -240236,8 +240236,8 @@ var require_dist2 = __commonJS((exports) => {
240236
240236
  if (typeof cb !== "function") {
240237
240237
  return _utils.throwError.call(this, "cb must be a function", cb);
240238
240238
  }
240239
- var mime2 = MIME.getType(path26) || this.getMIME();
240240
- var pathObj = _path["default"].parse(path26);
240239
+ var mime2 = MIME.getType(path25) || this.getMIME();
240240
+ var pathObj = _path["default"].parse(path25);
240241
240241
  if (pathObj.dir) {
240242
240242
  _mkdirp["default"].sync(pathObj.dir);
240243
240243
  }
@@ -240245,7 +240245,7 @@ var require_dist2 = __commonJS((exports) => {
240245
240245
  if (err) {
240246
240246
  return _utils.throwError.call(_this2, err, cb);
240247
240247
  }
240248
- var stream2 = _fs["default"].createWriteStream(path26);
240248
+ var stream2 = _fs["default"].createWriteStream(path25);
240249
240249
  stream2.on("open", function() {
240250
240250
  stream2.write(buffer);
240251
240251
  stream2.end();
@@ -240853,15 +240853,15 @@ var require_timm = __commonJS((exports) => {
240853
240853
  result2[idx] = newItem;
240854
240854
  return result2;
240855
240855
  }
240856
- function getIn(obj, path26) {
240857
- if (!Array.isArray(path26)) {
240856
+ function getIn(obj, path25) {
240857
+ if (!Array.isArray(path25)) {
240858
240858
  throwStr(IS_DEV ? "A path array should be provided when calling getIn()" : INVALID_ARGS);
240859
240859
  }
240860
240860
  if (obj == null)
240861
240861
  return;
240862
240862
  let ptr = obj;
240863
- for (let i = 0;i < path26.length; i++) {
240864
- const key = path26[i];
240863
+ for (let i = 0;i < path25.length; i++) {
240864
+ const key = path25[i];
240865
240865
  ptr = ptr != null ? ptr[key] : undefined;
240866
240866
  if (ptr === undefined)
240867
240867
  return ptr;
@@ -240878,19 +240878,19 @@ var require_timm = __commonJS((exports) => {
240878
240878
  obj2[key] = val;
240879
240879
  return obj2;
240880
240880
  }
240881
- function setIn(obj, path26, val) {
240882
- if (!path26.length)
240881
+ function setIn(obj, path25, val) {
240882
+ if (!path25.length)
240883
240883
  return val;
240884
- return doSetIn(obj, path26, val, 0);
240884
+ return doSetIn(obj, path25, val, 0);
240885
240885
  }
240886
- function doSetIn(obj, path26, val, idx) {
240886
+ function doSetIn(obj, path25, val, idx) {
240887
240887
  let newValue;
240888
- const key = path26[idx];
240889
- if (idx === path26.length - 1) {
240888
+ const key = path25[idx];
240889
+ if (idx === path25.length - 1) {
240890
240890
  newValue = val;
240891
240891
  } else {
240892
- const nestedObj = isObject2(obj) && isObject2(obj[key]) ? obj[key] : typeof path26[idx + 1] === "number" ? [] : {};
240893
- newValue = doSetIn(nestedObj, path26, val, idx + 1);
240892
+ const nestedObj = isObject2(obj) && isObject2(obj[key]) ? obj[key] : typeof path25[idx + 1] === "number" ? [] : {};
240893
+ newValue = doSetIn(nestedObj, path25, val, idx + 1);
240894
240894
  }
240895
240895
  return set2(obj, key, newValue);
240896
240896
  }
@@ -240899,10 +240899,10 @@ var require_timm = __commonJS((exports) => {
240899
240899
  const nextVal = fnUpdate(prevVal);
240900
240900
  return set2(obj, key, nextVal);
240901
240901
  }
240902
- function updateIn(obj, path26, fnUpdate) {
240903
- const prevVal = getIn(obj, path26);
240902
+ function updateIn(obj, path25, fnUpdate) {
240903
+ const prevVal = getIn(obj, path25);
240904
240904
  const nextVal = fnUpdate(prevVal);
240905
- return setIn(obj, path26, nextVal);
240905
+ return setIn(obj, path25, nextVal);
240906
240906
  }
240907
240907
  function merge2(a, b, c2, d, e, f, ...rest2) {
240908
240908
  return rest2.length ? doMerge.call(null, false, false, a, b, c2, d, e, f, ...rest2) : doMerge(false, false, a, b, c2, d, e, f);
@@ -240910,8 +240910,8 @@ var require_timm = __commonJS((exports) => {
240910
240910
  function mergeDeep(a, b, c2, d, e, f, ...rest2) {
240911
240911
  return rest2.length ? doMerge.call(null, false, true, a, b, c2, d, e, f, ...rest2) : doMerge(false, true, a, b, c2, d, e, f);
240912
240912
  }
240913
- function mergeIn(a, path26, b, c2, d, e, f, ...rest2) {
240914
- let prevVal = getIn(a, path26);
240913
+ function mergeIn(a, path25, b, c2, d, e, f, ...rest2) {
240914
+ let prevVal = getIn(a, path25);
240915
240915
  if (prevVal == null)
240916
240916
  prevVal = {};
240917
240917
  let nextVal;
@@ -240920,7 +240920,7 @@ var require_timm = __commonJS((exports) => {
240920
240920
  } else {
240921
240921
  nextVal = doMerge(false, false, prevVal, b, c2, d, e, f);
240922
240922
  }
240923
- return setIn(a, path26, nextVal);
240923
+ return setIn(a, path25, nextVal);
240924
240924
  }
240925
240925
  function omit2(obj, attrs) {
240926
240926
  const omitList = Array.isArray(attrs) ? attrs : [attrs];
@@ -250467,14 +250467,14 @@ var require_gifutil2 = __commonJS((exports) => {
250467
250467
  jimpImage.bitmap.data = bitmapImageToShare.bitmap.data;
250468
250468
  return jimpImage;
250469
250469
  };
250470
- exports.write = function(path26, frames, spec, encoder) {
250470
+ exports.write = function(path25, frames, spec, encoder) {
250471
250471
  encoder = encoder || defaultCodec;
250472
- const matches2 = path26.match(/\.[a-zA-Z]+$/);
250472
+ const matches2 = path25.match(/\.[a-zA-Z]+$/);
250473
250473
  if (matches2 !== null && INVALID_SUFFIXES.includes(matches2[0].toLowerCase())) {
250474
- throw new Error(`GIF '${path26}' has an unexpected suffix`);
250474
+ throw new Error(`GIF '${path25}' has an unexpected suffix`);
250475
250475
  }
250476
250476
  return encoder.encodeGif(frames, spec).then((gif2) => {
250477
- return _writeBinary(path26, gif2.buffer).then(() => {
250477
+ return _writeBinary(path25, gif2.buffer).then(() => {
250478
250478
  return gif2;
250479
250479
  });
250480
250480
  });
@@ -250536,9 +250536,9 @@ var require_gifutil2 = __commonJS((exports) => {
250536
250536
  }
250537
250537
  }
250538
250538
  }
250539
- function _readBinary(path26) {
250539
+ function _readBinary(path25) {
250540
250540
  return new Promise((resolve2, reject3) => {
250541
- fs7.readFile(path26, (err, buffer) => {
250541
+ fs7.readFile(path25, (err, buffer) => {
250542
250542
  if (err) {
250543
250543
  return reject3(err);
250544
250544
  }
@@ -250546,9 +250546,9 @@ var require_gifutil2 = __commonJS((exports) => {
250546
250546
  });
250547
250547
  });
250548
250548
  }
250549
- function _writeBinary(path26, buffer) {
250549
+ function _writeBinary(path25, buffer) {
250550
250550
  return new Promise((resolve2, reject3) => {
250551
- fs7.writeFile(path26, buffer, (err) => {
250551
+ fs7.writeFile(path25, buffer, (err) => {
250552
250552
  if (err) {
250553
250553
  return reject3(err);
250554
250554
  }
@@ -254809,7 +254809,7 @@ var require_CentraResponse = __commonJS((exports, module) => {
254809
254809
 
254810
254810
  // node_modules/centra/model/CentraRequest.js
254811
254811
  var require_CentraRequest = __commonJS((exports, module) => {
254812
- var path26 = __require("path");
254812
+ var path25 = __require("path");
254813
254813
  var http = __require("http");
254814
254814
  var https = __require("https");
254815
254815
  var followRedirects = require_follow_redirects();
@@ -254866,7 +254866,7 @@ var require_CentraRequest = __commonJS((exports, module) => {
254866
254866
  return this;
254867
254867
  }
254868
254868
  path(relativePath) {
254869
- this.url.pathname = path26.join(this.url.pathname, relativePath);
254869
+ this.url.pathname = path25.join(this.url.pathname, relativePath);
254870
254870
  return this;
254871
254871
  }
254872
254872
  body(data, sendAs) {
@@ -255071,7 +255071,7 @@ var require_types = __commonJS((exports, module) => {
255071
255071
 
255072
255072
  // node_modules/load-bmfont/node_modules/mime/mime.js
255073
255073
  var require_mime2 = __commonJS((exports, module) => {
255074
- var path26 = __require("path");
255074
+ var path25 = __require("path");
255075
255075
  var fs7 = __require("fs");
255076
255076
  function Mime() {
255077
255077
  this.types = Object.create(null);
@@ -255101,8 +255101,8 @@ var require_mime2 = __commonJS((exports, module) => {
255101
255101
  this.define(map2);
255102
255102
  this._loading = null;
255103
255103
  };
255104
- Mime.prototype.lookup = function(path27, fallback) {
255105
- var ext = path27.replace(/^.*[\.\/\\]/, "").toLowerCase();
255104
+ Mime.prototype.lookup = function(path26, fallback) {
255105
+ var ext = path26.replace(/^.*[\.\/\\]/, "").toLowerCase();
255106
255106
  return this.types[ext] || fallback || this.default_type;
255107
255107
  };
255108
255108
  Mime.prototype.extension = function(mimeType) {
@@ -255156,7 +255156,7 @@ var require_is_binary = __commonJS((exports, module) => {
255156
255156
  var require_load_bmfont = __commonJS((exports, module) => {
255157
255157
  var fs7 = __require("fs");
255158
255158
  var url = __require("url");
255159
- var path26 = __require("path");
255159
+ var path25 = __require("path");
255160
255160
  var request = require_phin();
255161
255161
  var parseASCII = require_parse_bmfont_ascii();
255162
255162
  var parseXML = require_lib4();
@@ -265816,6 +265816,23 @@ var CYAN = "#79C5D4";
265816
265816
 
265817
265817
  // src/utils/thinking.tsx
265818
265818
  var import_react30 = __toESM(require_react(), 1);
265819
+ var TIPS = [
265820
+ "use /auto to toggle auto-approve for safe tools",
265821
+ "ctrl+f to toggle force-all mode",
265822
+ "shift+enter for a new line in the input",
265823
+ "↑ / ↓ arrows navigate message history",
265824
+ "ctrl+w deletes the previous word",
265825
+ "ctrl+delete deletes the next word",
265826
+ "/timeline to browse commit history",
265827
+ "/review to analyze the current codebase",
265828
+ "/memory list to view stored memories",
265829
+ "/chat list to see saved conversations",
265830
+ "esc cancels a running response",
265831
+ "/clear history resets session memory",
265832
+ "tab autocompletes slash commands",
265833
+ "lens commit --auto for fast AI commits",
265834
+ 'lens run "bun dev" to watch and auto-fix errors'
265835
+ ];
265819
265836
  var PHRASES = {
265820
265837
  general: [
265821
265838
  "marinating on that... \uD83C\uDF56",
@@ -266128,6 +266145,50 @@ var PHRASES = {
266128
266145
  "the changelog said rent free... \uD83C\uDFE0"
266129
266146
  ]
266130
266147
  };
266148
+ function useThinkingTip(active, intervalMs = 8000) {
266149
+ const [index, setIndex] = import_react30.useState(() => Math.floor(Math.random() * TIPS.length));
266150
+ const usedRef = import_react30.useRef(new Set);
266151
+ import_react30.useEffect(() => {
266152
+ if (!active)
266153
+ return;
266154
+ const pickUnused = () => {
266155
+ if (usedRef.current.size >= TIPS.length)
266156
+ usedRef.current.clear();
266157
+ let next;
266158
+ do {
266159
+ next = Math.floor(Math.random() * TIPS.length);
266160
+ } while (usedRef.current.has(next));
266161
+ usedRef.current.add(next);
266162
+ return next;
266163
+ };
266164
+ setIndex(pickUnused());
266165
+ const id = setInterval(() => setIndex(pickUnused()), intervalMs);
266166
+ return () => clearInterval(id);
266167
+ }, [active, intervalMs]);
266168
+ return TIPS[index];
266169
+ }
266170
+ function useThinkingTimer(active) {
266171
+ const [seconds, setSeconds] = import_react30.useState(0);
266172
+ const startRef = import_react30.useRef(null);
266173
+ import_react30.useEffect(() => {
266174
+ if (active) {
266175
+ startRef.current = Date.now();
266176
+ setSeconds(0);
266177
+ const id = setInterval(() => {
266178
+ setSeconds(Math.floor((Date.now() - (startRef.current ?? Date.now())) / 1000));
266179
+ }, 1000);
266180
+ return () => clearInterval(id);
266181
+ } else {
266182
+ startRef.current = null;
266183
+ setSeconds(0);
266184
+ }
266185
+ }, [active]);
266186
+ if (!active || seconds === 0)
266187
+ return "";
266188
+ if (seconds < 60)
266189
+ return `${seconds}s`;
266190
+ return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
266191
+ }
266131
266192
  function useThinkingPhrase(active, kind = "general", intervalMs = 4321) {
266132
266193
  const list = PHRASES[kind];
266133
266194
  const [index, setIndex] = import_react30.useState(() => Math.floor(Math.random() * list.length));
@@ -268687,23 +268748,22 @@ Use memory-delete when the user asks you to forget something or a memory is outd
268687
268748
 
268688
268749
  1. ONE tool per response — emit the XML tag, then stop. Never chain tools in one response except when scaffolding (see below).
268689
268750
  2. NEVER call a tool more than once for the same path in a session. If write-file or shell returned a result, it succeeded. Move on immediately.
268690
- 3. NEVER write the same file twice in one session. One write per file, period. If you already wrote it, it is done.
268691
- 4. shell is ONLY for running code, installing packages, building, and testing. NEVER use shell to inspect the filesystem or read files — use read-file, read-folder, or grep instead.
268692
- 5. write-file content must be the COMPLETE file content, never a placeholder or partial.
268693
- 6. NEVER read a file you just wrote. The write output confirms success.
268694
- 7. NEVER apologize and redo a tool callone attempt is enough, trust the output.
268695
- 8. NEVER use shell to run git clone — use the clone tag instead.
268696
- 9. When the user asks you to CREATE a new file, write it immediately do NOT read first.
268697
- 10. When the user asks you to MODIFY or FIX an existing file, read it first, then write the complete updated version ONCE.
268698
- 11. When fixing multiple files, use read-files to read ALL of them first, then write each one ONCE sequentially never rewrite a file already written this session.
268699
- 12. If a read-folder or read-file returns not found, accept it and move on do NOT retry the same path.
268700
- 13. Every shell command runs from the repo root cd has no persistent effect. Use full paths or combine with && e.g. cd myapp && bun run index.ts
268701
- 14. write-file paths are relative to the repo rootuse full relative paths e.g. myapp/src/index.tsx not src/index.tsx
268702
- 15. When explaining how to use a tool in text, use [tag] bracket notation NEVER emit a real XML tool tag as part of an explanation.
268703
- 16. NEVER use markdown formatting in plain text responses no bold, no headings, no bullet points. Only use fenced code blocks when showing actual code.
268704
- 17. When scaffolding multiple files, emit ONE write-file tag per response and wait for the result before writing the next file.
268705
- 18. When you identify a bug or error, ALWAYS write the fix immediately using write-file or changes. Never describe the fix without writing it.
268706
- 19. NEVER use shell for filesystem inspection or searching — always use grep, read-file, or read-folder instead.
268751
+ 3. shell is ONLY for running code, installing packages, building, and testing. NEVER use shell to inspect the filesystem or read files — use read-file, read-folder, or grep instead.
268752
+ 4. NEVER use shell to run git clone — use the clone tag instead.
268753
+ 5. NEVER read a file you just wrote. The write output confirms success.
268754
+ 6. NEVER apologize and redo a tool call one attempt is enough, trust the output.
268755
+ 7. When the user asks you to CREATE a brand new file, use write-file immediately do NOT read first. write-file content must be the COMPLETE file content.
268756
+ 8. When the user asks you to MODIFY or FIX an existing file, read it first, then propose the edit using changes NEVER use write-file on an existing file.
268757
+ 9. When fixing multiple files, use read-files to read ALL of them first, then emit one changes tag with all patches together.
268758
+ 10. If a read-folder or read-file returns not found, accept it and move on do NOT retry the same path.
268759
+ 11. Every shell command runs from the repo root cd has no persistent effect. Use full paths or combine with && e.g. cd myapp && bun run index.ts
268760
+ 12. write-file paths are relative to the repo rootuse full relative paths e.g. myapp/src/index.tsx not src/index.tsx
268761
+ 13. When explaining how to use a tool in text, use [tag] bracket notation NEVER emit a real XML tool tag as part of an explanation.
268762
+ 14. NEVER use markdown formatting in plain text responsesno bold, no headings, no bullet points. Only use fenced code blocks when showing actual code.
268763
+ 15. When scaffolding multiple NEW files, emit ONE write-file per response and wait for the result before writing the next file.
268764
+ 16. When you identify a bug or error, ALWAYS propose the fix immediately using changes. Never describe the fix without proposing it.
268765
+ 17. NEVER use shell for filesystem inspection or searching always use grep, read-file, or read-folder instead.
268766
+ 18. changes patches must include the COMPLETE new file content for each path never partial content.
268707
268767
 
268708
268768
  ## ADDON FORMAT
268709
268769
 
@@ -269226,7 +269286,15 @@ function toCloneUrl(url) {
269226
269286
  }
269227
269287
  function buildApiMessages(messages) {
269228
269288
  const recent = messages.slice(-MAX_HISTORY);
269229
- return recent.map((m) => {
269289
+ const writtenFiles = [];
269290
+ for (const m of recent) {
269291
+ if (m.type === "tool" && m.toolName === "write-file" && m.approved) {
269292
+ const pathMatch = m.content.match(/^(.+?)\s*\(/);
269293
+ if (pathMatch?.[1])
269294
+ writtenFiles.push(pathMatch[1]);
269295
+ }
269296
+ }
269297
+ return recent.map((m, idx) => {
269230
269298
  if (m.type === "tool") {
269231
269299
  if (!m.approved) {
269232
269300
  return {
@@ -269234,9 +269302,28 @@ function buildApiMessages(messages) {
269234
269302
  content: "The tool call was denied by the user. Please respond without using that tool."
269235
269303
  };
269236
269304
  }
269305
+ if (m.toolName === "write-file") {
269306
+ const remaining = writtenFiles.slice(writtenFiles.indexOf(m.content.split(" (")[0]) + 1);
269307
+ const doneList = writtenFiles.slice(0, writtenFiles.indexOf(m.content.split(" (")[0]) + 1).map((f) => `- ${f}`).join(`
269308
+ `);
269309
+ return {
269310
+ role: "user",
269311
+ content: [
269312
+ `Tool result for write-file (${m.content}):`,
269313
+ "",
269314
+ m.result,
269315
+ "",
269316
+ `Files written so far:`,
269317
+ doneList || `- ${m.content.split(" (")[0]}`,
269318
+ "",
269319
+ remaining.length > 0 ? `Continue with the NEXT file. Do NOT rewrite any file already written above.` : `All files written. Summarize what was created.`
269320
+ ].join(`
269321
+ `)
269322
+ };
269323
+ }
269237
269324
  return {
269238
269325
  role: "user",
269239
- content: `Here is the output from the ${m.toolName} of ${m.content}:
269326
+ content: `Tool result for ${m.toolName} (${m.content}):
269240
269327
 
269241
269328
  ${m.result}
269242
269329
 
@@ -269281,7 +269368,7 @@ async function callChat(provider, systemPrompt, messages, abortSignal, retries =
269281
269368
  };
269282
269369
  }
269283
269370
  const controller = new AbortController;
269284
- const timer = setTimeout(() => controller.abort(), 60000);
269371
+ const timer = setTimeout(() => controller.abort(), 180000);
269285
269372
  abortSignal?.addEventListener("abort", () => controller.abort());
269286
269373
  try {
269287
269374
  const res = await fetch(url, {
@@ -269313,8 +269400,15 @@ async function callChat(provider, systemPrompt, messages, abortSignal, retries =
269313
269400
  }
269314
269401
  } catch (err) {
269315
269402
  clearTimeout(timer);
269316
- if (err instanceof Error && err.name === "AbortError")
269317
- throw err;
269403
+ if (err instanceof Error && err.name === "AbortError") {
269404
+ if (abortSignal?.aborted)
269405
+ throw err;
269406
+ if (retries > 0) {
269407
+ await new Promise((r) => setTimeout(r, 1500));
269408
+ return callChat(provider, systemPrompt, messages, abortSignal, retries - 1);
269409
+ }
269410
+ throw new Error("Request timed out. The model took too long to respond (>3 min).");
269411
+ }
269318
269412
  if (retries > 0) {
269319
269413
  await new Promise((r) => setTimeout(r, 1500));
269320
269414
  return callChat(provider, systemPrompt, messages, abortSignal, retries - 1);
@@ -269511,7 +269605,7 @@ function StaticMessage({ msg }) {
269511
269605
  flexDirection: "column",
269512
269606
  marginBottom: 1,
269513
269607
  children: [
269514
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
269608
+ msg.content ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
269515
269609
  gap: 1,
269516
269610
  children: [
269517
269611
  /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
@@ -269522,7 +269616,7 @@ function StaticMessage({ msg }) {
269522
269616
  content: msg.content
269523
269617
  }, undefined, false, undefined, this)
269524
269618
  ]
269525
- }, undefined, true, undefined, this),
269619
+ }, undefined, true, undefined, this) : null,
269526
269620
  /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
269527
269621
  marginLeft: 2,
269528
269622
  gap: 1,
@@ -269537,7 +269631,51 @@ function StaticMessage({ msg }) {
269537
269631
  children: msg.applied ? "changes applied" : "changes skipped"
269538
269632
  }, undefined, false, undefined, this)
269539
269633
  ]
269540
- }, undefined, true, undefined, this)
269634
+ }, undefined, true, undefined, this),
269635
+ msg.applied && msg.diffLines && msg.diffLines.length > 0 && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
269636
+ flexDirection: "column",
269637
+ marginLeft: 2,
269638
+ marginTop: 0,
269639
+ children: msg.patches.map((patch, fi) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
269640
+ flexDirection: "column",
269641
+ children: [
269642
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
269643
+ bold: true,
269644
+ color: fi % 2 === 0 ? "cyan" : "magenta",
269645
+ children: [
269646
+ figures_default.bullet,
269647
+ " ",
269648
+ patch.path,
269649
+ patch.isNew ? " (new)" : ""
269650
+ ]
269651
+ }, undefined, true, undefined, this),
269652
+ (msg.diffLines[fi] ?? []).map((line, li) => {
269653
+ const prefix = line.type === "added" ? "+" : line.type === "removed" ? "-" : " ";
269654
+ const color = line.type === "added" ? "green" : line.type === "removed" ? "red" : "gray";
269655
+ const lineNumStr = line.lineNum === -1 ? " " : String(line.lineNum).padStart(3, " ");
269656
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
269657
+ children: [
269658
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
269659
+ color: "gray",
269660
+ children: [
269661
+ lineNumStr,
269662
+ " "
269663
+ ]
269664
+ }, undefined, true, undefined, this),
269665
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
269666
+ color,
269667
+ children: [
269668
+ prefix,
269669
+ " ",
269670
+ line.content
269671
+ ]
269672
+ }, undefined, true, undefined, this)
269673
+ ]
269674
+ }, li, true, undefined, this);
269675
+ })
269676
+ ]
269677
+ }, patch.path, true, undefined, this))
269678
+ }, undefined, false, undefined, this)
269541
269679
  ]
269542
269680
  }, undefined, true, undefined, this);
269543
269681
  }
@@ -269610,11 +269748,12 @@ function TextArea({
269610
269748
  return;
269611
269749
  if (key.ctrl && input === "c")
269612
269750
  return;
269613
- if (key.return && !key.meta) {
269751
+ const isShiftEnter = key.return && key.shift || input === "\x1B[27;2;13~" || input === "\x1B[13;2u";
269752
+ if (key.return && !key.meta && !key.shift && !isShiftEnter) {
269614
269753
  onSubmit(value);
269615
269754
  return;
269616
269755
  }
269617
- if (key.return && key.meta || key.ctrl && input === "j") {
269756
+ if (isShiftEnter) {
269618
269757
  const next = value.slice(0, cursor) + `
269619
269758
  ` + value.slice(cursor);
269620
269759
  onChange(next);
@@ -269662,17 +269801,14 @@ function TextArea({
269662
269801
  onChange(value.slice(0, cursor) + (lineEnd === -1 ? "" : value.slice(lineEnd)));
269663
269802
  return;
269664
269803
  }
269665
- if (key.ctrl && input === "w") {
269804
+ if (key.ctrl && input === "f")
269805
+ return;
269806
+ if (key.ctrl && key.delete || input === "\x1B[3;5~") {
269666
269807
  const to = wordBoundaryLeft(value, cursor);
269667
269808
  onChange(value.slice(0, to) + value.slice(cursor));
269668
269809
  setCursor(to);
269669
269810
  return;
269670
269811
  }
269671
- if (key.ctrl && key.delete) {
269672
- const to = wordBoundaryRight(value, cursor);
269673
- onChange(value.slice(0, cursor) + value.slice(to));
269674
- return;
269675
- }
269676
269812
  if (key.backspace || key.delete) {
269677
269813
  if (cursor > 0) {
269678
269814
  onChange(value.slice(0, cursor - 1) + value.slice(cursor));
@@ -269844,7 +269980,14 @@ function InputBox({
269844
269980
  inputKey
269845
269981
  }) {
269846
269982
  const { stdout } = use_stdout_default();
269847
- const cols = stdout?.columns ?? 80;
269983
+ const [cols, setCols] = import_react36.useState(stdout?.columns ?? 80);
269984
+ import_react36.useEffect(() => {
269985
+ const handler = () => setCols(stdout?.columns ?? 80);
269986
+ stdout?.on("resize", handler);
269987
+ return () => {
269988
+ stdout?.off("resize", handler);
269989
+ };
269990
+ }, [stdout]);
269848
269991
  const rule = "─".repeat(Math.max(1, cols));
269849
269992
  return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
269850
269993
  flexDirection: "column",
@@ -269911,7 +270054,7 @@ function ShortcutBar({
269911
270054
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
269912
270055
  color: "gray",
269913
270056
  dimColor: true,
269914
- children: "enter send · alt+enter newline · ^w del word · ^c exit"
270057
+ children: "enter send · ctrl+enter newline · ctrl+del del word · ^f force · ^c exit"
269915
270058
  }, undefined, false, undefined, this),
269916
270059
  forceApprove ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
269917
270060
  color: RED,
@@ -269983,7 +270126,9 @@ function CloningView({
269983
270126
  children: [
269984
270127
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
269985
270128
  color: ACCENT,
269986
- children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(build_default, {}, undefined, false, undefined, this)
270129
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(build_default, {
270130
+ type: "line"
270131
+ }, undefined, false, undefined, this)
269987
270132
  }, undefined, false, undefined, this),
269988
270133
  /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
269989
270134
  color: "gray",
@@ -270308,7 +270453,9 @@ function AskingFilesStep() {
270308
270453
  children: [
270309
270454
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
270310
270455
  color: ACCENT,
270311
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(build_default, {}, undefined, false, undefined, this)
270456
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(build_default, {
270457
+ type: "moon"
270458
+ }, undefined, false, undefined, this)
270312
270459
  }, undefined, false, undefined, this),
270313
270460
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
270314
270461
  color: ACCENT,
@@ -270324,7 +270471,9 @@ function AnalyzingStep() {
270324
270471
  children: [
270325
270472
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
270326
270473
  color: ACCENT,
270327
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(build_default, {}, undefined, false, undefined, this)
270474
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(build_default, {
270475
+ type: "earth"
270476
+ }, undefined, false, undefined, this)
270328
270477
  }, undefined, false, undefined, this),
270329
270478
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
270330
270479
  color: ACCENT,
@@ -270562,7 +270711,9 @@ var RepoAnalysis = ({
270562
270711
  children: [
270563
270712
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
270564
270713
  color: ACCENT,
270565
- children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(build_default, {}, undefined, false, undefined, this)
270714
+ children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(build_default, {
270715
+ type: "arc"
270716
+ }, undefined, false, undefined, this)
270566
270717
  }, undefined, false, undefined, this),
270567
270718
  /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
270568
270719
  marginLeft: 1,
@@ -272375,7 +272526,9 @@ function ThinkingAboutStep({ prompt }) {
272375
272526
  children: [
272376
272527
  /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
272377
272528
  color: ACCENT,
272378
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(build_default, {}, undefined, false, undefined, this)
272529
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(build_default, {
272530
+ type: "triangle"
272531
+ }, undefined, false, undefined, this)
272379
272532
  }, undefined, false, undefined, this),
272380
272533
  /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
272381
272534
  color: ACCENT,
@@ -272556,7 +272709,9 @@ var PromptRunner = ({
272556
272709
  children: [
272557
272710
  /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
272558
272711
  color: ACCENT,
272559
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(build_default, {}, undefined, false, undefined, this)
272712
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(build_default, {
272713
+ type: "dots2"
272714
+ }, undefined, false, undefined, this)
272560
272715
  }, undefined, false, undefined, this),
272561
272716
  /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
272562
272717
  children: "Reading codebase..."
@@ -272652,7 +272807,9 @@ var PromptRunner = ({
272652
272807
  children: [
272653
272808
  /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
272654
272809
  color: ACCENT,
272655
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(build_default, {}, undefined, false, undefined, this)
272810
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(build_default, {
272811
+ type: "bouncingBar"
272812
+ }, undefined, false, undefined, this)
272656
272813
  }, undefined, false, undefined, this),
272657
272814
  /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
272658
272815
  children: "Applying changes..."
@@ -272810,10 +272967,6 @@ var TaskCommand = ({
272810
272967
  }, undefined, false, undefined, this);
272811
272968
  };
272812
272969
 
272813
- // src/commands/chat.tsx
272814
- import { existsSync as existsSync14 } from "fs";
272815
- import path19 from "path";
272816
-
272817
272970
  // src/components/chat/ChatRunner.tsx
272818
272971
  var import_react52 = __toESM(require_react(), 1);
272819
272972
  import path18 from "path";
@@ -275073,7 +275226,17 @@ function classifyIntent(userMessage) {
275073
275226
  }
275074
275227
 
275075
275228
  // src/components/chat/hooks/useChat.ts
275076
- function useChat(repoPath) {
275229
+ function hasUnclosedToolTag(text) {
275230
+ for (const tag of registry.names()) {
275231
+ if (text.includes(`<${tag}>`) && !text.includes(`</${tag}>`))
275232
+ return true;
275233
+ }
275234
+ const fences = text.match(/```/g);
275235
+ if (fences && fences.length % 2 !== 0)
275236
+ return true;
275237
+ return false;
275238
+ }
275239
+ function useChat(repoPath, autoForce = false) {
275077
275240
  const [stage, setStage] = import_react49.useState({ type: "picking-provider" });
275078
275241
  const [committed, setCommitted] = import_react49.useState([]);
275079
275242
  const [provider, setProvider] = import_react49.useState(null);
@@ -275083,8 +275246,8 @@ function useChat(repoPath) {
275083
275246
  const [clonedUrls, setClonedUrls] = import_react49.useState(new Set);
275084
275247
  const [showTimeline, setShowTimeline] = import_react49.useState(false);
275085
275248
  const [showReview, setShowReview] = import_react49.useState(false);
275086
- const [autoApprove, setAutoApprove] = import_react49.useState(false);
275087
- const [forceApprove, setForceApprove] = import_react49.useState(false);
275249
+ const [autoApprove, setAutoApprove] = import_react49.useState(autoForce);
275250
+ const [forceApprove, setForceApprove] = import_react49.useState(autoForce);
275088
275251
  const [showForceWarning, setShowForceWarning] = import_react49.useState(false);
275089
275252
  const [chatName, setChatName] = import_react49.useState(null);
275090
275253
  const [recentChats, setRecentChats] = import_react49.useState([]);
@@ -275094,6 +275257,7 @@ function useChat(repoPath) {
275094
275257
  const abortControllerRef = import_react49.useRef(null);
275095
275258
  const toolResultCache = import_react49.useRef(new Map);
275096
275259
  const batchApprovedRef = import_react49.useRef(false);
275260
+ const forceApproveRef = import_react49.useRef(autoForce);
275097
275261
  const updateChatName = (name) => {
275098
275262
  chatNameRef.current = name;
275099
275263
  setChatName(name);
@@ -275104,6 +275268,9 @@ function useChat(repoPath) {
275104
275268
  import_react50.default.useEffect(() => {
275105
275269
  systemPromptRef.current = systemPrompt;
275106
275270
  }, [systemPrompt]);
275271
+ import_react50.default.useEffect(() => {
275272
+ forceApproveRef.current = forceApprove;
275273
+ }, [forceApprove]);
275107
275274
  import_react50.default.useEffect(() => {
275108
275275
  const chats = listChats(repoPath);
275109
275276
  setRecentChats(chats.slice(0, 10).map((c) => c.name));
@@ -275113,6 +275280,12 @@ function useChat(repoPath) {
275113
275280
  saveChat(chatNameRef.current, repoPath, allMessages);
275114
275281
  }
275115
275282
  }, [allMessages]);
275283
+ const pushMsg = (msg, currentAll) => {
275284
+ const next = [...currentAll, msg];
275285
+ setAllMessages(next);
275286
+ setCommitted((prev) => [...prev, msg]);
275287
+ return next;
275288
+ };
275116
275289
  const handleError = (currentAll) => (err) => {
275117
275290
  batchApprovedRef.current = false;
275118
275291
  if (err instanceof Error && err.name === "AbortError") {
@@ -275124,92 +275297,133 @@ function useChat(repoPath) {
275124
275297
  content: `Error: ${err instanceof Error ? err.message : "Something went wrong"}`,
275125
275298
  type: "text"
275126
275299
  };
275127
- setAllMessages([...currentAll, errMsg]);
275128
- setCommitted((prev) => [...prev, errMsg]);
275300
+ pushMsg(errMsg, currentAll);
275129
275301
  setStage({ type: "idle" });
275130
275302
  };
275131
- const MAX_AUTO_CONTINUES = 3;
275132
- function isLikelyTruncated(text) {
275133
- for (const tag of registry.names()) {
275134
- if (text.includes(`<${tag}>`) && !text.includes(`</${tag}>`))
275135
- return true;
275303
+ const callNext = async (messages, signal, maxRetries = 3) => {
275304
+ const currentProvider = providerRef.current;
275305
+ const currentSystemPrompt = systemPromptRef.current;
275306
+ if (!currentProvider || signal.aborted)
275307
+ return { text: "", truncated: false };
275308
+ let currentMessages = messages;
275309
+ for (let attempt2 = 0;attempt2 <= maxRetries; attempt2++) {
275310
+ if (signal.aborted)
275311
+ return { text: "", truncated: false };
275312
+ const result2 = await callChat(currentProvider, currentSystemPrompt, currentMessages, signal);
275313
+ if (result2.text.trim())
275314
+ return result2;
275315
+ if (attempt2 < maxRetries) {
275316
+ const nudge = {
275317
+ role: "assistant",
275318
+ content: `(model stalled — retrying ${attempt2 + 1}/${maxRetries})`,
275319
+ type: "text"
275320
+ };
275321
+ setCommitted((prev) => [...prev, nudge]);
275322
+ currentMessages = [
275323
+ ...currentMessages,
275324
+ {
275325
+ role: "user",
275326
+ content: "Please continue your response.",
275327
+ type: "text"
275328
+ }
275329
+ ];
275330
+ }
275136
275331
  }
275137
- const fences = text.match(/```/g);
275138
- if (fences && fences.length % 2 !== 0)
275139
- return true;
275140
- return false;
275141
- }
275142
- const processResponse = (raw, currentAll, signal, truncated = false, continueCount = 0) => {
275332
+ return { text: "", truncated: false };
275333
+ };
275334
+ const MAX_CONTINUATIONS = 3;
275335
+ const handleTruncation = async (raw, currentAll, signal, depth) => {
275336
+ if (depth >= MAX_CONTINUATIONS)
275337
+ return null;
275338
+ const truncNotice = {
275339
+ role: "assistant",
275340
+ content: `(response cut off — continuing ${depth + 1}/${MAX_CONTINUATIONS}…)`,
275341
+ type: "text"
275342
+ };
275343
+ setCommitted((prev) => [...prev, truncNotice]);
275344
+ const partialMsg = {
275345
+ role: "assistant",
275346
+ content: raw,
275347
+ type: "text"
275348
+ };
275349
+ const nudgeMsg = {
275350
+ role: "user",
275351
+ content: "Your response was cut off. Please continue exactly from where you left off.",
275352
+ type: "text"
275353
+ };
275354
+ const withContext = [...currentAll, partialMsg, nudgeMsg];
275355
+ const result2 = await callNext(withContext, signal);
275356
+ return { text: result2.text ?? "", messages: withContext };
275357
+ };
275358
+ const processMemoryTags = (raw) => {
275359
+ const addMatches = [
275360
+ ...raw.matchAll(/<memory-add>([\s\S]*?)<\/memory-add>/g)
275361
+ ];
275362
+ const delMatches = [
275363
+ ...raw.matchAll(/<memory-delete>([\s\S]*?)<\/memory-delete>/g)
275364
+ ];
275365
+ for (const m of addMatches) {
275366
+ const content = m[1].trim();
275367
+ if (content)
275368
+ addMemory(content, repoPath);
275369
+ }
275370
+ for (const m of delMatches) {
275371
+ const id = m[1].trim();
275372
+ if (id)
275373
+ deleteMemory(id, repoPath);
275374
+ }
275375
+ return raw.replace(/<memory-add>[\s\S]*?<\/memory-add>/g, "").replace(/<memory-delete>[\s\S]*?<\/memory-delete>/g, "").trim();
275376
+ };
275377
+ const processResponse = async (raw, currentAll, signal, truncated = false, continuationDepth = 0) => {
275143
275378
  if (signal.aborted) {
275144
275379
  batchApprovedRef.current = false;
275145
275380
  setStage({ type: "idle" });
275146
275381
  return;
275147
275382
  }
275148
- if (truncated || isLikelyTruncated(raw)) {
275149
- if (continueCount >= MAX_AUTO_CONTINUES) {
275383
+ if (truncated || hasUnclosedToolTag(raw)) {
275384
+ const cont = await handleTruncation(raw, currentAll, signal, continuationDepth);
275385
+ if (!cont) {
275150
275386
  batchApprovedRef.current = false;
275151
275387
  const msg = {
275152
275388
  role: "assistant",
275153
275389
  content: raw.trim() || "(response was empty after multiple continuation attempts)",
275154
275390
  type: "text"
275155
275391
  };
275156
- setAllMessages([...currentAll, msg]);
275157
- setCommitted((prev) => [...prev, msg]);
275392
+ pushMsg(msg, currentAll);
275158
275393
  setStage({ type: "idle" });
275159
275394
  return;
275160
275395
  }
275161
- const partialMsg = {
275162
- role: "assistant",
275163
- content: raw,
275164
- type: "text"
275165
- };
275166
- const nudgeMsg = {
275167
- role: "user",
275168
- content: "Your response was cut off. Please continue exactly from where you left off.",
275169
- type: "text"
275170
- };
275171
- const withContext = [...currentAll, partialMsg, nudgeMsg];
275172
- const truncMsg = {
275396
+ return processResponse(cont.text, cont.messages, signal, false, continuationDepth + 1);
275397
+ }
275398
+ const cleanRaw = processMemoryTags(raw);
275399
+ const parsed = parseResponse(cleanRaw);
275400
+ if (parsed.kind === "text") {
275401
+ batchApprovedRef.current = false;
275402
+ if (!parsed.content.trim()) {
275403
+ const stallMsg = {
275404
+ role: "assistant",
275405
+ content: '(no response — try sending "continue" or start a new message)',
275406
+ type: "text"
275407
+ };
275408
+ pushMsg(stallMsg, currentAll);
275409
+ setStage({ type: "idle" });
275410
+ return;
275411
+ }
275412
+ const msg = {
275173
275413
  role: "assistant",
275174
- content: `(response cut off — auto-continuing ${continueCount + 1}/${MAX_AUTO_CONTINUES}…)`,
275414
+ content: parsed.content,
275175
275415
  type: "text"
275176
275416
  };
275177
- setAllMessages([...currentAll, truncMsg]);
275178
- setCommitted((prev) => [...prev, truncMsg]);
275179
- const currentProvider = providerRef.current;
275180
- const currentSystemPrompt = systemPromptRef.current;
275181
- if (!currentProvider) {
275417
+ const withMsg = pushMsg(msg, currentAll);
275418
+ const lastUserMsg = [...currentAll].reverse().find((m) => m.role === "user");
275419
+ const githubUrl = lastUserMsg ? extractGithubUrl(lastUserMsg.content) : null;
275420
+ if (githubUrl && !clonedUrls.has(githubUrl)) {
275421
+ setTimeout(() => setStage({ type: "clone-offer", repoUrl: githubUrl }), 80);
275422
+ } else {
275182
275423
  setStage({ type: "idle" });
275183
- return;
275184
275424
  }
275185
- const nextAbort = new AbortController;
275186
- abortControllerRef.current = nextAbort;
275187
- setStage({ type: "thinking" });
275188
- callChat(currentProvider, currentSystemPrompt, withContext, nextAbort.signal).then((result2) => {
275189
- if (nextAbort.signal.aborted)
275190
- return;
275191
- processResponse(result2.text ?? "", withContext, nextAbort.signal, result2.truncated, continueCount + 1);
275192
- }).catch(handleError(withContext));
275193
275425
  return;
275194
275426
  }
275195
- const memAddMatches = [
275196
- ...raw.matchAll(/<memory-add>([\s\S]*?)<\/memory-add>/g)
275197
- ];
275198
- const memDelMatches = [
275199
- ...raw.matchAll(/<memory-delete>([\s\S]*?)<\/memory-delete>/g)
275200
- ];
275201
- for (const match of memAddMatches) {
275202
- const content = match[1].trim();
275203
- if (content)
275204
- addMemory(content, repoPath);
275205
- }
275206
- for (const match of memDelMatches) {
275207
- const id = match[1].trim();
275208
- if (id)
275209
- deleteMemory(id, repoPath);
275210
- }
275211
- const cleanRaw = raw.replace(/<memory-add>[\s\S]*?<\/memory-add>/g, "").replace(/<memory-delete>[\s\S]*?<\/memory-delete>/g, "").trim();
275212
- const parsed = parseResponse(cleanRaw);
275213
275427
  if (parsed.kind === "changes") {
275214
275428
  batchApprovedRef.current = false;
275215
275429
  if (parsed.patches.length === 0) {
@@ -275218,22 +275432,42 @@ function useChat(repoPath) {
275218
275432
  content: parsed.content,
275219
275433
  type: "text"
275220
275434
  };
275221
- setAllMessages([...currentAll, msg]);
275222
- setCommitted((prev) => [...prev, msg]);
275435
+ pushMsg(msg, currentAll);
275223
275436
  setStage({ type: "idle" });
275224
275437
  return;
275225
275438
  }
275439
+ const diffLines = buildDiffs(repoPath, parsed.patches);
275440
+ if (forceApproveRef.current) {
275441
+ const assistantMsg2 = {
275442
+ role: "assistant",
275443
+ content: parsed.content,
275444
+ type: "plan",
275445
+ patches: parsed.patches,
275446
+ diffLines,
275447
+ applied: true
275448
+ };
275449
+ const withAssistant2 = [...currentAll, assistantMsg2];
275450
+ setAllMessages(withAssistant2);
275451
+ setCommitted((prev) => [...prev, assistantMsg2]);
275452
+ try {
275453
+ applyPatches2(repoPath, parsed.patches);
275454
+ logToolCall("changes", parsed.patches.map((p) => p.path).join(", "), `Applied changes to ${parsed.patches.length} file(s)`, repoPath);
275455
+ } catch {}
275456
+ continueAfterChanges(withAssistant2, parsed.content || "code changes");
275457
+ return;
275458
+ }
275226
275459
  const assistantMsg = {
275227
275460
  role: "assistant",
275228
275461
  content: parsed.content,
275229
275462
  type: "plan",
275230
275463
  patches: parsed.patches,
275464
+ diffLines,
275231
275465
  applied: false
275232
275466
  };
275233
275467
  const withAssistant = [...currentAll, assistantMsg];
275234
275468
  setAllMessages(withAssistant);
275469
+ setCommitted((prev) => [...prev, assistantMsg]);
275235
275470
  setPendingMsgIndex(withAssistant.length - 1);
275236
- const diffLines = buildDiffs(repoPath, parsed.patches);
275237
275471
  setStage({
275238
275472
  type: "preview",
275239
275473
  patches: parsed.patches,
@@ -275251,8 +275485,7 @@ function useChat(repoPath) {
275251
275485
  content: parsed.content,
275252
275486
  type: "text"
275253
275487
  };
275254
- setAllMessages([...currentAll, preambleMsg]);
275255
- setCommitted((prev) => [...prev, preambleMsg]);
275488
+ pushMsg(preambleMsg, currentAll);
275256
275489
  }
275257
275490
  setStage({
275258
275491
  type: "clone-offer",
@@ -275261,158 +275494,140 @@ function useChat(repoPath) {
275261
275494
  });
275262
275495
  return;
275263
275496
  }
275264
- if (parsed.kind === "text") {
275265
- batchApprovedRef.current = false;
275266
- if (!parsed.content.trim()) {
275267
- const stallMsg = {
275268
- role: "assistant",
275269
- content: '(no response — the model may have stalled. Try sending a short follow-up like "continue" or start a new message.)',
275270
- type: "text"
275271
- };
275272
- setAllMessages([...currentAll, stallMsg]);
275273
- setCommitted((prev) => [...prev, stallMsg]);
275274
- setStage({ type: "idle" });
275275
- return;
275276
- }
275277
- const msg = {
275278
- role: "assistant",
275279
- content: parsed.content,
275280
- type: "text"
275281
- };
275282
- const withMsg = [...currentAll, msg];
275283
- setAllMessages(withMsg);
275284
- setCommitted((prev) => [...prev, msg]);
275285
- const lastUserMsg = [...currentAll].reverse().find((m) => m.role === "user");
275286
- const githubUrl = lastUserMsg ? extractGithubUrl(lastUserMsg.content) : null;
275287
- if (githubUrl && !clonedUrls.has(githubUrl)) {
275288
- setTimeout(() => setStage({ type: "clone-offer", repoUrl: githubUrl }), 80);
275289
- } else {
275290
- setStage({ type: "idle" });
275291
- }
275292
- return;
275293
- }
275294
- const tool = registry.get(parsed.toolName);
275295
- if (!tool) {
275296
- batchApprovedRef.current = false;
275297
- setStage({ type: "idle" });
275298
- return;
275299
- }
275300
- if (parsed.content) {
275301
- const preambleMsg = {
275302
- role: "assistant",
275303
- content: parsed.content,
275304
- type: "text"
275305
- };
275306
- setAllMessages([...currentAll, preambleMsg]);
275307
- setCommitted((prev) => [...prev, preambleMsg]);
275308
- }
275309
- const remainder = parsed.remainder;
275310
- const isSafe = tool.safe ?? false;
275311
- const executeAndContinue = async (approved) => {
275312
- if (approved && remainder) {
275313
- batchApprovedRef.current = true;
275314
- }
275315
- const currentProvider = providerRef.current;
275316
- const currentSystemPrompt = systemPromptRef.current;
275317
- if (!currentProvider) {
275497
+ if (parsed.kind === "tool") {
275498
+ const tool = registry.get(parsed.toolName);
275499
+ if (!tool) {
275318
275500
  batchApprovedRef.current = false;
275319
275501
  setStage({ type: "idle" });
275320
275502
  return;
275321
275503
  }
275322
- let result2 = "(denied by user)";
275323
- if (approved) {
275324
- const cacheKey = isSafe ? `${parsed.toolName}:${parsed.rawInput}` : null;
275325
- if (cacheKey && toolResultCache.current.has(cacheKey)) {
275326
- result2 = toolResultCache.current.get(cacheKey) + `
275504
+ if (parsed.content) {
275505
+ const preambleMsg = {
275506
+ role: "assistant",
275507
+ content: parsed.content,
275508
+ type: "text"
275509
+ };
275510
+ pushMsg(preambleMsg, currentAll);
275511
+ }
275512
+ const isSafe = tool.safe ?? false;
275513
+ const remainder = parsed.remainder;
275514
+ const executeAndContinue = async (approved) => {
275515
+ if (approved && remainder)
275516
+ batchApprovedRef.current = true;
275517
+ const currentProvider = providerRef.current;
275518
+ const currentSystemPrompt = systemPromptRef.current;
275519
+ if (!currentProvider) {
275520
+ batchApprovedRef.current = false;
275521
+ setStage({ type: "idle" });
275522
+ return;
275523
+ }
275524
+ let result2 = "(denied by user)";
275525
+ if (approved) {
275526
+ const cacheKey = isSafe ? `${parsed.toolName}:${parsed.rawInput}` : null;
275527
+ if (cacheKey && toolResultCache.current.has(cacheKey)) {
275528
+ result2 = toolResultCache.current.get(cacheKey) + `
275327
275529
 
275328
275530
  [NOTE: This result was already retrieved earlier. Do not request it again.]`;
275329
- } else {
275330
- try {
275331
- setStage({ type: "thinking" });
275332
- const toolResult = await tool.execute(parsed.input, {
275333
- repoPath,
275334
- messages: currentAll
275335
- });
275336
- result2 = toolResult.value;
275337
- if (cacheKey && toolResult.kind === "text") {
275338
- toolResultCache.current.set(cacheKey, result2);
275531
+ } else {
275532
+ try {
275533
+ setStage({ type: "thinking" });
275534
+ const toolResult = await tool.execute(parsed.input, {
275535
+ repoPath,
275536
+ messages: currentAll
275537
+ });
275538
+ result2 = toolResult.value;
275539
+ if (cacheKey && toolResult.kind === "text") {
275540
+ toolResultCache.current.set(cacheKey, result2);
275541
+ }
275542
+ } catch (err) {
275543
+ result2 = `Error: ${err instanceof Error ? err.message : "failed"}`;
275339
275544
  }
275340
- } catch (err) {
275341
- result2 = `Error: ${err instanceof Error ? err.message : "failed"}`;
275342
275545
  }
275343
275546
  }
275344
- }
275345
- if (approved && !result2.startsWith("Error:")) {
275346
- logToolCall(parsed.toolName, tool.summariseInput ? String(tool.summariseInput(parsed.input)) : parsed.rawInput, result2, repoPath);
275347
- }
275348
- const displayContent = tool.summariseInput ? String(tool.summariseInput(parsed.input)) : parsed.rawInput;
275349
- const toolMsg = {
275350
- role: "assistant",
275351
- type: "tool",
275352
- toolName: parsed.toolName,
275353
- content: displayContent,
275354
- result: result2,
275355
- approved
275356
- };
275357
- const withTool = [...currentAll, toolMsg];
275358
- setAllMessages(withTool);
275359
- setCommitted((prev) => [...prev, toolMsg]);
275360
- if (approved && remainder && remainder.length > 0) {
275361
- processResponse(remainder, withTool, signal, truncated, continueCount);
275362
- return;
275363
- }
275364
- batchApprovedRef.current = false;
275365
- const nextAbort = new AbortController;
275366
- abortControllerRef.current = nextAbort;
275367
- setStage({ type: "thinking" });
275368
- const callWithAutoContinue = async (messages, maxRetries = 3) => {
275369
- let currentMessages = messages;
275370
- for (let i = 0;i < maxRetries; i++) {
275547
+ if (approved && !result2.startsWith("Error:")) {
275548
+ logToolCall(parsed.toolName, tool.summariseInput ? String(tool.summariseInput(parsed.input)) : parsed.rawInput, result2, repoPath);
275549
+ }
275550
+ const displayContent = tool.summariseInput ? String(tool.summariseInput(parsed.input)) : parsed.rawInput;
275551
+ const toolMsg = {
275552
+ role: "assistant",
275553
+ type: "tool",
275554
+ toolName: parsed.toolName,
275555
+ content: displayContent,
275556
+ result: result2,
275557
+ approved
275558
+ };
275559
+ const withTool = pushMsg(toolMsg, currentAll);
275560
+ if (approved && remainder && remainder.length > 0) {
275561
+ return processResponse(remainder, withTool, signal, false, continuationDepth);
275562
+ }
275563
+ batchApprovedRef.current = false;
275564
+ const nextAbort = new AbortController;
275565
+ abortControllerRef.current = nextAbort;
275566
+ setStage({ type: "thinking" });
275567
+ try {
275568
+ const nextResult = await callNext(withTool, nextAbort.signal);
275371
275569
  if (nextAbort.signal.aborted)
275372
- return { text: "", truncated: false };
275373
- const result3 = await callChat(currentProvider, currentSystemPrompt, currentMessages, nextAbort.signal);
275374
- if (result3.text.trim())
275375
- return result3;
275376
- const nudgeMsg = {
275377
- role: "assistant",
275378
- content: `(model stalled — auto-continuing, attempt ${i + 1}/${maxRetries})`,
275379
- type: "text"
275380
- };
275381
- setCommitted((prev) => [...prev, nudgeMsg]);
275382
- setAllMessages((prev) => [...prev, nudgeMsg]);
275383
- currentMessages = [
275384
- ...currentMessages,
275385
- {
275386
- role: "user",
275387
- content: "Please continue. Provide your response to the previous tool output.",
275570
+ return;
275571
+ if (!nextResult.text.trim()) {
275572
+ const stallMsg = {
275573
+ role: "assistant",
275574
+ content: '(model stopped responding — try sending "continue")',
275388
275575
  type: "text"
275389
- }
275390
- ];
275576
+ };
275577
+ pushMsg(stallMsg, withTool);
275578
+ setStage({ type: "idle" });
275579
+ return;
275580
+ }
275581
+ return processResponse(nextResult.text, withTool, nextAbort.signal, nextResult.truncated);
275582
+ } catch (err) {
275583
+ handleError(withTool)(err);
275391
275584
  }
275392
- return { text: "", truncated: false };
275393
275585
  };
275394
- callWithAutoContinue(withTool).then((result3) => {
275395
- if (nextAbort.signal.aborted)
275396
- return;
275397
- processResponse(result3.text ?? "", withTool, nextAbort.signal, result3.truncated);
275398
- }).catch(handleError(withTool));
275399
- };
275400
- if (forceApprove || isSafe || batchApprovedRef.current) {
275401
- executeAndContinue(true);
275586
+ if (forceApprove || isSafe || batchApprovedRef.current) {
275587
+ return executeAndContinue(true);
275588
+ }
275589
+ const permLabel = tool.permissionLabel ?? tool.name;
275590
+ const permValue = tool.summariseInput ? String(tool.summariseInput(parsed.input)) : parsed.rawInput;
275591
+ setStage({
275592
+ type: "permission",
275593
+ tool: {
275594
+ type: parsed.toolName,
275595
+ _display: permValue,
275596
+ _label: permLabel
275597
+ },
275598
+ pendingMessages: currentAll,
275599
+ resolve: executeAndContinue
275600
+ });
275601
+ }
275602
+ };
275603
+ const continueAfterChanges = (currentAll, summary) => {
275604
+ if (!providerRef.current) {
275605
+ setStage({ type: "idle" });
275402
275606
  return;
275403
275607
  }
275404
- const permLabel = tool.permissionLabel ?? tool.name;
275405
- const permValue = tool.summariseInput ? String(tool.summariseInput(parsed.input)) : parsed.rawInput;
275406
- setStage({
275407
- type: "permission",
275408
- tool: {
275409
- type: parsed.toolName,
275410
- _display: permValue,
275411
- _label: permLabel
275412
- },
275413
- pendingMessages: currentAll,
275414
- resolve: executeAndContinue
275415
- });
275608
+ const resultMsg = {
275609
+ role: "assistant",
275610
+ type: "tool",
275611
+ toolName: "changes",
275612
+ content: summary,
275613
+ result: "Changes applied successfully.",
275614
+ approved: true
275615
+ };
275616
+ const withResult = [...currentAll, resultMsg];
275617
+ setAllMessages(withResult);
275618
+ setCommitted((prev) => [...prev, resultMsg]);
275619
+ const abort = new AbortController;
275620
+ abortControllerRef.current = abort;
275621
+ setStage({ type: "thinking" });
275622
+ callNext(withResult, abort.signal).then((result2) => {
275623
+ if (abort.signal.aborted)
275624
+ return;
275625
+ if (!result2.text.trim()) {
275626
+ setStage({ type: "idle" });
275627
+ return;
275628
+ }
275629
+ return processResponse(result2.text, withResult, abort.signal, result2.truncated);
275630
+ }).catch(handleError(withResult));
275416
275631
  };
275417
275632
  const sendMessage = (text, currentProvider, currentSystemPrompt, currentAllMessages) => {
275418
275633
  const userMsg = { role: "user", content: text, type: "text" };
@@ -275531,6 +275746,7 @@ Tip: ⭐ Star Lens on GitHub — github.com/ridit-jangra/Lens`,
275531
275746
  handleProviderDone,
275532
275747
  abortThinking,
275533
275748
  applyPatchesAndContinue,
275749
+ continueAfterChanges,
275534
275750
  skipPatches,
275535
275751
  processResponse,
275536
275752
  handleError
@@ -275951,9 +276167,15 @@ function ForceAllWarning({
275951
276167
  ]
275952
276168
  }, undefined, true, undefined, this);
275953
276169
  }
275954
- var ChatRunner = ({ repoPath }) => {
275955
- const chat = useChat(repoPath);
275956
- const thinkingPhrase = useThinkingPhrase(chat.stage.type === "thinking");
276170
+ var ChatRunner = ({
276171
+ repoPath,
276172
+ autoForce = false
276173
+ }) => {
276174
+ const chat = useChat(repoPath, autoForce);
276175
+ const isThinking = chat.stage.type === "thinking";
276176
+ const thinkingPhrase = useThinkingPhrase(isThinking);
276177
+ const thinkingTip = useThinkingTip(isThinking);
276178
+ const thinkingTimer = useThinkingTimer(isThinking);
275957
276179
  const handleStageKey = (input, key) => {
275958
276180
  const { stage: stage2 } = chat;
275959
276181
  if (chat.showForceWarning && key.escape) {
@@ -276108,8 +276330,12 @@ Ask me anything about it — I can read files, explain how it works, or suggest
276108
276330
  if (msg?.type === "plan") {
276109
276331
  chat.applyPatchesAndContinue(msg.patches);
276110
276332
  const applied = { ...msg, applied: true };
276111
- chat.setAllMessages((prev) => prev.map((m, i) => i === chat.pendingMsgIndex ? applied : m));
276333
+ const updatedAll = chat.allMessages.map((m, i) => i === chat.pendingMsgIndex ? applied : m);
276334
+ chat.setAllMessages(updatedAll);
276112
276335
  chat.setCommitted((prev) => [...prev, applied]);
276336
+ chat.setPendingMsgIndex(null);
276337
+ chat.continueAfterChanges(updatedAll, msg.content || "code changes");
276338
+ return;
276113
276339
  }
276114
276340
  }
276115
276341
  chat.setPendingMsgIndex(null);
@@ -276135,6 +276361,23 @@ Ask me anything about it — I can read files, explain how it works, or suggest
276135
276361
  }
276136
276362
  }
276137
276363
  };
276364
+ use_input_default((input, key) => {
276365
+ if (!(key.ctrl && input === "f"))
276366
+ return;
276367
+ if (chat.forceApprove) {
276368
+ chat.setForceApprove(false);
276369
+ chat.setAutoApprove(false);
276370
+ const msg = {
276371
+ role: "assistant",
276372
+ content: "Force-all mode OFF — tools will ask for permission again.",
276373
+ type: "text"
276374
+ };
276375
+ chat.setCommitted((prev) => [...prev, msg]);
276376
+ chat.setAllMessages((prev) => [...prev, msg]);
276377
+ } else {
276378
+ chat.setShowForceWarning(true);
276379
+ }
276380
+ }, { isActive: chat.stage.type === "idle" });
276138
276381
  const chatInput = useChatInput(chat.stage, chat.showTimeline, chat.showForceWarning, chat.abortThinking, handleStageKey);
276139
276382
  const sendMessage = (text) => {
276140
276383
  if (!chat.provider)
@@ -276185,7 +276428,9 @@ Ask me anything about it — I can read files, explain how it works, or suggest
276185
276428
  }, undefined, false, undefined, this),
276186
276429
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276187
276430
  color: ACCENT,
276188
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(build_default, {}, undefined, false, undefined, this)
276431
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(build_default, {
276432
+ type: "arc"
276433
+ }, undefined, false, undefined, this)
276189
276434
  }, undefined, false, undefined, this),
276190
276435
  /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276191
276436
  color: "gray",
@@ -276273,19 +276518,38 @@ Ask me anything about it — I can read files, explain how it works, or suggest
276273
276518
  }
276274
276519
  }, undefined, false, undefined, this),
276275
276520
  !chat.showForceWarning && stage.type === "thinking" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
276276
- gap: 1,
276521
+ flexDirection: "column",
276277
276522
  children: [
276278
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276279
- color: ACCENT,
276280
- children: "●"
276281
- }, undefined, false, undefined, this),
276282
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TypewriterText, {
276283
- text: thinkingPhrase
276284
- }, undefined, false, undefined, this),
276285
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276286
- color: "gray",
276287
- dimColor: true,
276288
- children: esc cancel"
276523
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
276524
+ gap: 1,
276525
+ children: [
276526
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276527
+ color: ACCENT,
276528
+ children: "●"
276529
+ }, undefined, false, undefined, this),
276530
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TypewriterText, {
276531
+ text: thinkingPhrase
276532
+ }, undefined, false, undefined, this),
276533
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276534
+ color: "gray",
276535
+ dimColor: true,
276536
+ children: [
276537
+ thinkingTimer ? `· ${thinkingTimer} ` : "",
276538
+ "· esc cancel"
276539
+ ]
276540
+ }, undefined, true, undefined, this)
276541
+ ]
276542
+ }, undefined, true, undefined, this),
276543
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
276544
+ marginLeft: 2,
276545
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
276546
+ color: "gray",
276547
+ dimColor: true,
276548
+ children: [
276549
+ "tip: ",
276550
+ thinkingTip
276551
+ ]
276552
+ }, undefined, true, undefined, this)
276289
276553
  }, undefined, false, undefined, this)
276290
276554
  ]
276291
276555
  }, undefined, true, undefined, this),
@@ -276322,37 +276586,30 @@ Ask me anything about it — I can read files, explain how it works, or suggest
276322
276586
 
276323
276587
  // src/commands/chat.tsx
276324
276588
  var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
276325
- var ChatCommand = ({ path: inputPath }) => {
276326
- const resolvedPath = path19.resolve(inputPath);
276327
- if (!existsSync14(resolvedPath)) {
276328
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
276329
- marginTop: 1,
276330
- children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
276331
- color: "red",
276332
- children: [
276333
- figures_default.cross,
276334
- " Path not found: ",
276335
- resolvedPath
276336
- ]
276337
- }, undefined, true, undefined, this)
276338
- }, undefined, false, undefined, this);
276339
- }
276340
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ChatRunner, {
276341
- repoPath: resolvedPath
276589
+ function ChatCommand({
276590
+ path: path19,
276591
+ autoForce = false
276592
+ }) {
276593
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
276594
+ flexDirection: "column",
276595
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ChatRunner, {
276596
+ repoPath: path19,
276597
+ autoForce
276598
+ }, undefined, false, undefined, this)
276342
276599
  }, undefined, false, undefined, this);
276343
- };
276600
+ }
276344
276601
 
276345
276602
  // src/commands/run.tsx
276346
- import path21 from "path";
276347
- import { existsSync as existsSync16 } from "fs";
276603
+ import path20 from "path";
276604
+ import { existsSync as existsSync15 } from "fs";
276348
276605
 
276349
276606
  // src/components/watch/RunRunner.tsx
276350
276607
  var import_react53 = __toESM(require_react(), 1);
276351
276608
 
276352
276609
  // src/utils/watch.ts
276353
276610
  import { spawn as spawn2 } from "child_process";
276354
- import { readFileSync as readFileSync13, existsSync as existsSync15 } from "fs";
276355
- import path20 from "path";
276611
+ import { readFileSync as readFileSync13, existsSync as existsSync14 } from "fs";
276612
+ import path19 from "path";
276356
276613
  var ERROR_PATTERNS = [
276357
276614
  /error:/i,
276358
276615
  /TypeError/,
@@ -276512,8 +276769,8 @@ function spawnWatch(cmd, cwd2) {
276512
276769
  };
276513
276770
  }
276514
276771
  function readPackageJson(repoPath) {
276515
- const p = path20.join(repoPath, "package.json");
276516
- if (!existsSync15(p))
276772
+ const p = path19.join(repoPath, "package.json");
276773
+ if (!existsSync14(p))
276517
276774
  return "";
276518
276775
  try {
276519
276776
  const pkg = JSON.parse(readFileSync13(p, "utf-8"));
@@ -277565,7 +277822,7 @@ function RunCommand({
277565
277822
  autoRestart,
277566
277823
  prompt
277567
277824
  }) {
277568
- const repoPath = path21.resolve(inputPath);
277825
+ const repoPath = path20.resolve(inputPath);
277569
277826
  if (!cmd.trim()) {
277570
277827
  return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
277571
277828
  marginTop: 1,
@@ -277578,7 +277835,7 @@ function RunCommand({
277578
277835
  }, undefined, true, undefined, this)
277579
277836
  }, undefined, false, undefined, this);
277580
277837
  }
277581
- if (!existsSync16(repoPath)) {
277838
+ if (!existsSync15(repoPath)) {
277582
277839
  return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
277583
277840
  marginTop: 1,
277584
277841
  children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
@@ -277602,12 +277859,12 @@ function RunCommand({
277602
277859
  }
277603
277860
 
277604
277861
  // src/commands/timeline.tsx
277605
- import { existsSync as existsSync17 } from "fs";
277606
- import path22 from "path";
277862
+ import { existsSync as existsSync16 } from "fs";
277863
+ import path21 from "path";
277607
277864
  var jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
277608
277865
  var TimelineCommand = ({ path: inputPath }) => {
277609
- const resolvedPath = path22.resolve(inputPath);
277610
- if (!existsSync17(resolvedPath)) {
277866
+ const resolvedPath = path21.resolve(inputPath);
277867
+ if (!existsSync16(resolvedPath)) {
277611
277868
  return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
277612
277869
  marginTop: 1,
277613
277870
  children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
@@ -277628,8 +277885,8 @@ var TimelineCommand = ({ path: inputPath }) => {
277628
277885
  // src/commands/commit.tsx
277629
277886
  var import_react54 = __toESM(require_react(), 1);
277630
277887
  import { execSync as execSync5 } from "child_process";
277631
- import { existsSync as existsSync18 } from "fs";
277632
- import path23 from "path";
277888
+ import { existsSync as existsSync17 } from "fs";
277889
+ import path22 from "path";
277633
277890
  var jsx_dev_runtime28 = __toESM(require_jsx_dev_runtime(), 1);
277634
277891
  function gitRun3(cmd, cwd2) {
277635
277892
  try {
@@ -277699,9 +277956,9 @@ function validateFiles(files, cwd2) {
277699
277956
  const missing = [];
277700
277957
  const valid = [];
277701
277958
  for (const f of files) {
277702
- const abs = path23.isAbsolute(f) ? f : path23.join(cwd2, f);
277703
- if (existsSync18(abs)) {
277704
- valid.push(path23.relative(cwd2, abs).replace(/\\/g, "/"));
277959
+ const abs = path22.isAbsolute(f) ? f : path22.join(cwd2, f);
277960
+ if (existsSync17(abs)) {
277961
+ valid.push(path22.relative(cwd2, abs).replace(/\\/g, "/"));
277705
277962
  } else {
277706
277963
  missing.push(f);
277707
277964
  }
@@ -278350,9 +278607,9 @@ function CommitCommand({
278350
278607
  push,
278351
278608
  confirm
278352
278609
  }) {
278353
- const cwd2 = path23.resolve(inputPath);
278610
+ const cwd2 = path22.resolve(inputPath);
278354
278611
  const [provider, setProvider] = import_react54.useState(null);
278355
- if (!existsSync18(cwd2)) {
278612
+ if (!existsSync17(cwd2)) {
278356
278613
  return /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Box_default, {
278357
278614
  marginTop: 1,
278358
278615
  children: /* @__PURE__ */ jsx_dev_runtime28.jsxDEV(Text, {
@@ -278392,8 +278649,8 @@ var TOOL_TAGS = {
278392
278649
  find: "find"
278393
278650
  };
278394
278651
  // src/tools/view-image.ts
278395
- import path26 from "path";
278396
- import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
278652
+ import path25 from "path";
278653
+ import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
278397
278654
  import { execSync as execSync6 } from "child_process";
278398
278655
  function parseViewImageInput(body) {
278399
278656
  const trimmed = body.trim();
@@ -278419,8 +278676,8 @@ async function fetchBytes(src, repoPath) {
278419
278676
  throw new Error(`HTTP ${res.status}: ${res.statusText}`);
278420
278677
  return Buffer.from(await res.arrayBuffer());
278421
278678
  }
278422
- const resolved = path26.isAbsolute(src) ? src : path26.join(repoPath, src);
278423
- if (!existsSync20(resolved))
278679
+ const resolved = path25.isAbsolute(src) ? src : path25.join(repoPath, src);
278680
+ if (!existsSync19(resolved))
278424
278681
  throw new Error(`File not found: ${resolved}`);
278425
278682
  return readFileSync14(resolved);
278426
278683
  }
@@ -278493,7 +278750,7 @@ function renderKitty2(buf, width) {
278493
278750
  }
278494
278751
  function renderSixel(buf, src, repoPath, width) {
278495
278752
  const widthCols = typeof width === "number" ? width : width.endsWith("%") ? Math.floor((process.stdout.columns ?? 80) * (parseInt(width) / 100)) : parseInt(width);
278496
- const tmpPath = path26.join(process.env["TEMP"] ?? process.env["TMPDIR"] ?? "/tmp", `lens_img_${Date.now()}.bin`);
278753
+ const tmpPath = path25.join(process.env["TEMP"] ?? process.env["TMPDIR"] ?? "/tmp", `lens_img_${Date.now()}.bin`);
278497
278754
  const { writeFileSync: writeFileSync10, unlinkSync: unlinkSync2 } = __require("fs");
278498
278755
  writeFileSync10(tmpPath, buf);
278499
278756
  try {
@@ -278573,7 +278830,7 @@ var viewImageTool = {
278573
278830
  ].join(`
278574
278831
  `),
278575
278832
  parseInput: parseViewImageInput,
278576
- summariseInput: ({ src, width }) => `${path26.basename(src)} (${width ?? "80%"})`,
278833
+ summariseInput: ({ src, width }) => `${path25.basename(src)} (${width ?? "80%"})`,
278577
278834
  execute: async (input, ctx) => {
278578
278835
  try {
278579
278836
  const ansi = await renderImage(input, ctx.repoPath);
@@ -278736,8 +278993,8 @@ var chartDataTool = {
278736
278993
  }
278737
278994
  };
278738
278995
  // src/tools/convert-image.ts
278739
- import path27 from "path";
278740
- import { existsSync as existsSync21, mkdirSync as mkdirSync8 } from "fs";
278996
+ import path26 from "path";
278997
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8 } from "fs";
278741
278998
  import { execSync as execSync7 } from "child_process";
278742
278999
  function parseInput(body) {
278743
279000
  const trimmed = body.trim();
@@ -278761,11 +279018,11 @@ function ffmpegAvailable() {
278761
279018
  }
278762
279019
  }
278763
279020
  function resolve2(p, repoPath) {
278764
- return path27.isAbsolute(p) ? p : path27.join(repoPath, p);
279021
+ return path26.isAbsolute(p) ? p : path26.join(repoPath, p);
278765
279022
  }
278766
279023
  function ensureDir(filePath) {
278767
- const dir = path27.dirname(filePath);
278768
- if (!existsSync21(dir))
279024
+ const dir = path26.dirname(filePath);
279025
+ if (!existsSync20(dir))
278769
279026
  mkdirSync8(dir, { recursive: true });
278770
279027
  }
278771
279028
  function buildVfFilters(input) {
@@ -278837,7 +279094,7 @@ function buildArgs(input, resolvedInput, resolvedOutput, repoPath) {
278837
279094
  if (vf.length)
278838
279095
  args.push("-vf", vf.join(","));
278839
279096
  }
278840
- const ext = path27.extname(resolvedOutput).toLowerCase();
279097
+ const ext = path26.extname(resolvedOutput).toLowerCase();
278841
279098
  if (input.quality !== undefined) {
278842
279099
  if (ext === ".jpg" || ext === ".jpeg") {
278843
279100
  const q = Math.round(2 + (100 - input.quality) / 100 * 29);
@@ -278877,7 +279134,7 @@ function runConvert(input, repoPath) {
278877
279134
  ensureDir(resolvedOutput);
278878
279135
  const resolvedInput = Array.isArray(input.input) ? resolve2(input.input[0], repoPath) : resolve2(input.input, repoPath);
278879
279136
  if (!Array.isArray(input.input) && !input.input.startsWith("http")) {
278880
- if (!existsSync21(resolvedInput)) {
279137
+ if (!existsSync20(resolvedInput)) {
278881
279138
  return `Error: input file not found — ${resolvedInput}`;
278882
279139
  }
278883
279140
  }
@@ -278892,7 +279149,7 @@ function runConvert(input, repoPath) {
278892
279149
  const lines = (stderr || "").split(`
278893
279150
  `).filter((l) => l.includes("video:") || l.includes("frame=")).slice(-3).join(`
278894
279151
  `);
278895
- const inputLabel = Array.isArray(input.input) ? `${input.input.length} files` : path27.basename(input.input);
279152
+ const inputLabel = Array.isArray(input.input) ? `${input.input.length} files` : path26.basename(input.input);
278896
279153
  return (`✓ converted ${inputLabel} → ${input.output}
278897
279154
  ` + (lines ? `
278898
279155
  ${lines}` : "")).trim();
@@ -278941,8 +279198,8 @@ var convertImageTool = {
278941
279198
  `),
278942
279199
  parseInput,
278943
279200
  summariseInput: ({ input, output }) => {
278944
- const src = Array.isArray(input) ? `${input.length} files` : path27.basename(input);
278945
- return `${src} → ${path27.basename(output)}`;
279201
+ const src = Array.isArray(input) ? `${input.length} files` : path26.basename(input);
279202
+ return `${src} → ${path26.basename(output)}`;
278946
279203
  },
278947
279204
  execute: async (input, ctx) => {
278948
279205
  try {
@@ -279063,9 +279320,12 @@ var writeFileTool = {
279063
279320
  const tryParse = (s) => {
279064
279321
  try {
279065
279322
  const parsed = JSON.parse(s);
279066
- if (!parsed.path || parsed.content === undefined)
279323
+ if (typeof parsed.path !== "string" || typeof parsed.content !== "string")
279067
279324
  return null;
279068
- return { ...parsed, path: parsed.path.replace(/\\/g, "/") };
279325
+ return {
279326
+ path: parsed.path.replace(/\\/g, "/"),
279327
+ content: parsed.content
279328
+ };
279069
279329
  } catch {
279070
279330
  return null;
279071
279331
  }
@@ -279074,23 +279334,23 @@ var writeFileTool = {
279074
279334
  if (first)
279075
279335
  return first;
279076
279336
  try {
279077
- const sanitized = body.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
279337
+ const sanitized = body.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "").replace(/(?<!\\)\n/g, "\\n").replace(/(?<!\\)\r/g, "\\r").replace(/(?<!\\)\t/g, "\\t");
279078
279338
  const second = tryParse(sanitized);
279079
279339
  if (second)
279080
279340
  return second;
279081
279341
  } catch {}
279082
279342
  const pathMatch = body.match(/"path"\s*:\s*"([^"]+)"/);
279083
- const contentMatch = body.match(/"content"\s*:\s*"([\s\S]*)"\s*}?\s*$/);
279084
- if (pathMatch && contentMatch && contentMatch[1] !== undefined) {
279343
+ const contentMatch = body.match(/"content"\s*:\s*"([\s\S]*?)"\s*}?\s*$/);
279344
+ if (pathMatch?.[1] && contentMatch?.[1] !== undefined) {
279085
279345
  return {
279086
279346
  path: pathMatch[1].replace(/\\/g, "/"),
279087
279347
  content: contentMatch[1].replace(/\\n/g, `
279088
- `).replace(/\\t/g, "\t")
279348
+ `).replace(/\\r/g, "\r").replace(/\\t/g, "\t")
279089
279349
  };
279090
279350
  }
279091
279351
  return null;
279092
279352
  },
279093
- summariseInput: ({ path: path28, content }) => `${path28} (${content.length} bytes)`,
279353
+ summariseInput: (input) => input ? `${input.path} (${input.content.length} bytes)` : "unknown file",
279094
279354
  execute: ({ path: filePath, content }, ctx) => ({
279095
279355
  kind: "text",
279096
279356
  value: writeFile(filePath, content, ctx.repoPath)
@@ -279276,13 +279536,13 @@ function registerBuiltins() {
279276
279536
  }
279277
279537
 
279278
279538
  // src/utils/addons/loadAddons.ts
279279
- import path28 from "path";
279539
+ import path27 from "path";
279280
279540
  import os9 from "os";
279281
- import { existsSync as existsSync22, readdirSync as readdirSync5 } from "fs";
279541
+ import { existsSync as existsSync21, readdirSync as readdirSync5 } from "fs";
279282
279542
  import { pathToFileURL } from "url";
279283
- var ADDONS_DIR = path28.join(os9.homedir(), ".lens", "addons");
279543
+ var ADDONS_DIR = path27.join(os9.homedir(), ".lens", "addons");
279284
279544
  async function loadAddons() {
279285
- if (!existsSync22(ADDONS_DIR)) {
279545
+ if (!existsSync21(ADDONS_DIR)) {
279286
279546
  return;
279287
279547
  }
279288
279548
  const files = readdirSync5(ADDONS_DIR).filter((f) => f.endsWith(".js") && !f.startsWith("_"));
@@ -279290,7 +279550,7 @@ async function loadAddons() {
279290
279550
  const file = files[i];
279291
279551
  if (!file)
279292
279552
  return;
279293
- const fullPath = path28.join(ADDONS_DIR, file);
279553
+ const fullPath = path27.join(ADDONS_DIR, file);
279294
279554
  const fileUrl = pathToFileURL(fullPath).href;
279295
279555
  const isLast = i === files.length - 1;
279296
279556
  try {
@@ -279307,6 +279567,10 @@ async function loadAddons() {
279307
279567
  var jsx_dev_runtime29 = __toESM(require_jsx_dev_runtime(), 1);
279308
279568
  registerBuiltins();
279309
279569
  await loadAddons();
279570
+ if (process.stdout.isTTY) {
279571
+ process.stdout.write("\x1B[>4;1m");
279572
+ process.on("exit", () => process.stdout.write("\x1B[>4;0m"));
279573
+ }
279310
279574
  var program2 = new Command;
279311
279575
  program2.command("repo <url>").description("Analyze a remote repository").action((url) => {
279312
279576
  render_default(/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(RepoCommand, {
@@ -279327,9 +279591,10 @@ program2.command("task <text>").description("Apply a natural language change to
279327
279591
  path: opts.path
279328
279592
  }, undefined, false, undefined, this));
279329
279593
  });
279330
- program2.command("chat").description("Chat with your codebase — ask questions or make changes").option("-p, --path <path>", "Path to the repo", ".").action((opts) => {
279594
+ program2.command("chat").description("Chat with your codebase — ask questions or make changes").option("-p, --path <path>", "Path to the repo", ".").option("--auto-force", "Start with force-all mode enabled (auto-approves all tools)").action((opts) => {
279331
279595
  render_default(/* @__PURE__ */ jsx_dev_runtime29.jsxDEV(ChatCommand, {
279332
- path: opts.path
279596
+ path: opts.path,
279597
+ autoForce: opts.autoForce ?? false
279333
279598
  }, undefined, false, undefined, this));
279334
279599
  });
279335
279600
  program2.command("timeline").description("Explore your code history — see commits, changes, and evolution").option("-p, --path <path>", "Path to the repo", ".").action((opts) => {