@kenkaiiii/gg-boss 4.11.2 → 4.12.1

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.
@@ -3225,8 +3225,8 @@ var require_utils = __commonJS({
3225
3225
  }
3226
3226
  return ind;
3227
3227
  }
3228
- function removeDotSegments(path46) {
3229
- let input = path46;
3228
+ function removeDotSegments(path48) {
3229
+ let input = path48;
3230
3230
  const output = [];
3231
3231
  let nextSlash = -1;
3232
3232
  let len = 0;
@@ -3426,8 +3426,8 @@ var require_schemes = __commonJS({
3426
3426
  wsComponent.secure = void 0;
3427
3427
  }
3428
3428
  if (wsComponent.resourceName) {
3429
- const [path46, query] = wsComponent.resourceName.split("?");
3430
- wsComponent.path = path46 && path46 !== "/" ? path46 : void 0;
3429
+ const [path48, query] = wsComponent.resourceName.split("?");
3430
+ wsComponent.path = path48 && path48 !== "/" ? path48 : void 0;
3431
3431
  wsComponent.query = query;
3432
3432
  wsComponent.resourceName = void 0;
3433
3433
  }
@@ -3486,7 +3486,7 @@ var require_schemes = __commonJS({
3486
3486
  urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
3487
3487
  return urnComponent;
3488
3488
  }
3489
- var http = (
3489
+ var http2 = (
3490
3490
  /** @type {SchemeHandler} */
3491
3491
  {
3492
3492
  scheme: "http",
@@ -3499,7 +3499,7 @@ var require_schemes = __commonJS({
3499
3499
  /** @type {SchemeHandler} */
3500
3500
  {
3501
3501
  scheme: "https",
3502
- domainHost: http.domainHost,
3502
+ domainHost: http2.domainHost,
3503
3503
  parse: httpParse,
3504
3504
  serialize: httpSerialize
3505
3505
  }
@@ -3543,7 +3543,7 @@ var require_schemes = __commonJS({
3543
3543
  var SCHEMES = (
3544
3544
  /** @type {Record<SchemeName, SchemeHandler>} */
3545
3545
  {
3546
- http,
3546
+ http: http2,
3547
3547
  https,
3548
3548
  ws,
3549
3549
  wss,
@@ -6835,12 +6835,12 @@ var require_dist = __commonJS({
6835
6835
  throw new Error(`Unknown format "${name}"`);
6836
6836
  return f;
6837
6837
  };
6838
- function addFormats(ajv, list, fs39, exportName) {
6838
+ function addFormats(ajv, list, fs40, exportName) {
6839
6839
  var _a6;
6840
6840
  var _b;
6841
6841
  (_a6 = (_b = ajv.opts.code).formats) !== null && _a6 !== void 0 ? _a6 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6842
6842
  for (const f of list)
6843
- ajv.addFormat(f, fs39[f]);
6843
+ ajv.addFormat(f, fs40[f]);
6844
6844
  }
6845
6845
  module.exports = exports = formatsPlugin;
6846
6846
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -6855,8 +6855,8 @@ var require_windows = __commonJS({
6855
6855
  init_esm_shims();
6856
6856
  module.exports = isexe;
6857
6857
  isexe.sync = sync;
6858
- var fs39 = __require("fs");
6859
- function checkPathExt(path46, options) {
6858
+ var fs40 = __require("fs");
6859
+ function checkPathExt(path48, options) {
6860
6860
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
6861
6861
  if (!pathext) {
6862
6862
  return true;
@@ -6867,25 +6867,25 @@ var require_windows = __commonJS({
6867
6867
  }
6868
6868
  for (var i = 0; i < pathext.length; i++) {
6869
6869
  var p = pathext[i].toLowerCase();
6870
- if (p && path46.substr(-p.length).toLowerCase() === p) {
6870
+ if (p && path48.substr(-p.length).toLowerCase() === p) {
6871
6871
  return true;
6872
6872
  }
6873
6873
  }
6874
6874
  return false;
6875
6875
  }
6876
- function checkStat(stat, path46, options) {
6876
+ function checkStat(stat, path48, options) {
6877
6877
  if (!stat.isSymbolicLink() && !stat.isFile()) {
6878
6878
  return false;
6879
6879
  }
6880
- return checkPathExt(path46, options);
6880
+ return checkPathExt(path48, options);
6881
6881
  }
6882
- function isexe(path46, options, cb) {
6883
- fs39.stat(path46, function(er, stat) {
6884
- cb(er, er ? false : checkStat(stat, path46, options));
6882
+ function isexe(path48, options, cb) {
6883
+ fs40.stat(path48, function(er, stat) {
6884
+ cb(er, er ? false : checkStat(stat, path48, options));
6885
6885
  });
6886
6886
  }
6887
- function sync(path46, options) {
6888
- return checkStat(fs39.statSync(path46), path46, options);
6887
+ function sync(path48, options) {
6888
+ return checkStat(fs40.statSync(path48), path48, options);
6889
6889
  }
6890
6890
  }
6891
6891
  });
@@ -6897,14 +6897,14 @@ var require_mode = __commonJS({
6897
6897
  init_esm_shims();
6898
6898
  module.exports = isexe;
6899
6899
  isexe.sync = sync;
6900
- var fs39 = __require("fs");
6901
- function isexe(path46, options, cb) {
6902
- fs39.stat(path46, function(er, stat) {
6900
+ var fs40 = __require("fs");
6901
+ function isexe(path48, options, cb) {
6902
+ fs40.stat(path48, function(er, stat) {
6903
6903
  cb(er, er ? false : checkStat(stat, options));
6904
6904
  });
6905
6905
  }
6906
- function sync(path46, options) {
6907
- return checkStat(fs39.statSync(path46), options);
6906
+ function sync(path48, options) {
6907
+ return checkStat(fs40.statSync(path48), options);
6908
6908
  }
6909
6909
  function checkStat(stat, options) {
6910
6910
  return stat.isFile() && checkMode(stat, options);
@@ -6930,7 +6930,7 @@ var require_isexe = __commonJS({
6930
6930
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
6931
6931
  "use strict";
6932
6932
  init_esm_shims();
6933
- var fs39 = __require("fs");
6933
+ var fs40 = __require("fs");
6934
6934
  var core;
6935
6935
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
6936
6936
  core = require_windows();
@@ -6939,7 +6939,7 @@ var require_isexe = __commonJS({
6939
6939
  }
6940
6940
  module.exports = isexe;
6941
6941
  isexe.sync = sync;
6942
- function isexe(path46, options, cb) {
6942
+ function isexe(path48, options, cb) {
6943
6943
  if (typeof options === "function") {
6944
6944
  cb = options;
6945
6945
  options = {};
@@ -6949,7 +6949,7 @@ var require_isexe = __commonJS({
6949
6949
  throw new TypeError("callback not provided");
6950
6950
  }
6951
6951
  return new Promise(function(resolve2, reject) {
6952
- isexe(path46, options || {}, function(er, is) {
6952
+ isexe(path48, options || {}, function(er, is) {
6953
6953
  if (er) {
6954
6954
  reject(er);
6955
6955
  } else {
@@ -6958,7 +6958,7 @@ var require_isexe = __commonJS({
6958
6958
  });
6959
6959
  });
6960
6960
  }
6961
- core(path46, options || {}, function(er, is) {
6961
+ core(path48, options || {}, function(er, is) {
6962
6962
  if (er) {
6963
6963
  if (er.code === "EACCES" || options && options.ignoreErrors) {
6964
6964
  er = null;
@@ -6968,9 +6968,9 @@ var require_isexe = __commonJS({
6968
6968
  cb(er, is);
6969
6969
  });
6970
6970
  }
6971
- function sync(path46, options) {
6971
+ function sync(path48, options) {
6972
6972
  try {
6973
- return core.sync(path46, options || {});
6973
+ return core.sync(path48, options || {});
6974
6974
  } catch (er) {
6975
6975
  if (options && options.ignoreErrors || er.code === "EACCES") {
6976
6976
  return false;
@@ -6988,7 +6988,7 @@ var require_which = __commonJS({
6988
6988
  "use strict";
6989
6989
  init_esm_shims();
6990
6990
  var isWindows3 = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
6991
- var path46 = __require("path");
6991
+ var path48 = __require("path");
6992
6992
  var COLON = isWindows3 ? ";" : ":";
6993
6993
  var isexe = require_isexe();
6994
6994
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -7026,7 +7026,7 @@ var require_which = __commonJS({
7026
7026
  return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
7027
7027
  const ppRaw = pathEnv[i];
7028
7028
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
7029
- const pCmd = path46.join(pathPart, cmd);
7029
+ const pCmd = path48.join(pathPart, cmd);
7030
7030
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
7031
7031
  resolve2(subStep(p, i, 0));
7032
7032
  });
@@ -7053,7 +7053,7 @@ var require_which = __commonJS({
7053
7053
  for (let i = 0; i < pathEnv.length; i++) {
7054
7054
  const ppRaw = pathEnv[i];
7055
7055
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
7056
- const pCmd = path46.join(pathPart, cmd);
7056
+ const pCmd = path48.join(pathPart, cmd);
7057
7057
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
7058
7058
  for (let j = 0; j < pathExt.length; j++) {
7059
7059
  const cur = p + pathExt[j];
@@ -7103,7 +7103,7 @@ var require_resolveCommand = __commonJS({
7103
7103
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
7104
7104
  "use strict";
7105
7105
  init_esm_shims();
7106
- var path46 = __require("path");
7106
+ var path48 = __require("path");
7107
7107
  var which = require_which();
7108
7108
  var getPathKey = require_path_key();
7109
7109
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -7121,7 +7121,7 @@ var require_resolveCommand = __commonJS({
7121
7121
  try {
7122
7122
  resolved = which.sync(parsed.command, {
7123
7123
  path: env2[getPathKey({ env: env2 })],
7124
- pathExt: withoutPathExt ? path46.delimiter : void 0
7124
+ pathExt: withoutPathExt ? path48.delimiter : void 0
7125
7125
  });
7126
7126
  } catch (e) {
7127
7127
  } finally {
@@ -7130,7 +7130,7 @@ var require_resolveCommand = __commonJS({
7130
7130
  }
7131
7131
  }
7132
7132
  if (resolved) {
7133
- resolved = path46.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
7133
+ resolved = path48.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
7134
7134
  }
7135
7135
  return resolved;
7136
7136
  }
@@ -7187,8 +7187,8 @@ var require_shebang_command = __commonJS({
7187
7187
  if (!match) {
7188
7188
  return null;
7189
7189
  }
7190
- const [path46, argument] = match[0].replace(/#! ?/, "").split(" ");
7191
- const binary = path46.split("/").pop();
7190
+ const [path48, argument] = match[0].replace(/#! ?/, "").split(" ");
7191
+ const binary = path48.split("/").pop();
7192
7192
  if (binary === "env") {
7193
7193
  return argument;
7194
7194
  }
@@ -7202,16 +7202,16 @@ var require_readShebang = __commonJS({
7202
7202
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
7203
7203
  "use strict";
7204
7204
  init_esm_shims();
7205
- var fs39 = __require("fs");
7205
+ var fs40 = __require("fs");
7206
7206
  var shebangCommand = require_shebang_command();
7207
7207
  function readShebang(command) {
7208
7208
  const size = 150;
7209
7209
  const buffer = Buffer.alloc(size);
7210
7210
  let fd2;
7211
7211
  try {
7212
- fd2 = fs39.openSync(command, "r");
7213
- fs39.readSync(fd2, buffer, 0, size, 0);
7214
- fs39.closeSync(fd2);
7212
+ fd2 = fs40.openSync(command, "r");
7213
+ fs40.readSync(fd2, buffer, 0, size, 0);
7214
+ fs40.closeSync(fd2);
7215
7215
  } catch (e) {
7216
7216
  }
7217
7217
  return shebangCommand(buffer.toString());
@@ -7225,7 +7225,7 @@ var require_parse = __commonJS({
7225
7225
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
7226
7226
  "use strict";
7227
7227
  init_esm_shims();
7228
- var path46 = __require("path");
7228
+ var path48 = __require("path");
7229
7229
  var resolveCommand = require_resolveCommand();
7230
7230
  var escape4 = require_escape();
7231
7231
  var readShebang = require_readShebang();
@@ -7250,7 +7250,7 @@ var require_parse = __commonJS({
7250
7250
  const needsShell = !isExecutableRegExp.test(commandFile);
7251
7251
  if (parsed.options.forceShell || needsShell) {
7252
7252
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
7253
- parsed.command = path46.normalize(parsed.command);
7253
+ parsed.command = path48.normalize(parsed.command);
7254
7254
  parsed.command = escape4.command(parsed.command);
7255
7255
  parsed.args = parsed.args.map((arg) => escape4.argument(arg, needsDoubleEscapeMetaChars));
7256
7256
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -17765,10 +17765,10 @@ var require_react_reconciler_development = __commonJS({
17765
17765
  fiber = fiber.next, id2--;
17766
17766
  return fiber;
17767
17767
  }
17768
- function copyWithSetImpl(obj, path46, index, value) {
17769
- if (index >= path46.length) return value;
17770
- var key = path46[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
17771
- updated[key] = copyWithSetImpl(obj[key], path46, index + 1, value);
17768
+ function copyWithSetImpl(obj, path48, index, value) {
17769
+ if (index >= path48.length) return value;
17770
+ var key = path48[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
17771
+ updated[key] = copyWithSetImpl(obj[key], path48, index + 1, value);
17772
17772
  return updated;
17773
17773
  }
17774
17774
  function copyWithRename(obj, oldPath, newPath) {
@@ -17795,11 +17795,11 @@ var require_react_reconciler_development = __commonJS({
17795
17795
  );
17796
17796
  return updated;
17797
17797
  }
17798
- function copyWithDeleteImpl(obj, path46, index) {
17799
- var key = path46[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
17800
- if (index + 1 === path46.length)
17798
+ function copyWithDeleteImpl(obj, path48, index) {
17799
+ var key = path48[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
17800
+ if (index + 1 === path48.length)
17801
17801
  return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
17802
- updated[key] = copyWithDeleteImpl(obj[key], path46, index + 1);
17802
+ updated[key] = copyWithDeleteImpl(obj[key], path48, index + 1);
17803
17803
  return updated;
17804
17804
  }
17805
17805
  function shouldSuspendImpl() {
@@ -31076,29 +31076,29 @@ var require_react_reconciler_development = __commonJS({
31076
31076
  var didWarnAboutNestedUpdates = false;
31077
31077
  var didWarnAboutFindNodeInStrictMode = {};
31078
31078
  var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
31079
- overrideHookState = function(fiber, id2, path46, value) {
31079
+ overrideHookState = function(fiber, id2, path48, value) {
31080
31080
  id2 = findHook(fiber, id2);
31081
- null !== id2 && (path46 = copyWithSetImpl(id2.memoizedState, path46, 0, value), id2.memoizedState = path46, id2.baseState = path46, fiber.memoizedProps = assign({}, fiber.memoizedProps), path46 = enqueueConcurrentRenderForLane(fiber, 2), null !== path46 && scheduleUpdateOnFiber(path46, fiber, 2));
31081
+ null !== id2 && (path48 = copyWithSetImpl(id2.memoizedState, path48, 0, value), id2.memoizedState = path48, id2.baseState = path48, fiber.memoizedProps = assign({}, fiber.memoizedProps), path48 = enqueueConcurrentRenderForLane(fiber, 2), null !== path48 && scheduleUpdateOnFiber(path48, fiber, 2));
31082
31082
  };
31083
- overrideHookStateDeletePath = function(fiber, id2, path46) {
31083
+ overrideHookStateDeletePath = function(fiber, id2, path48) {
31084
31084
  id2 = findHook(fiber, id2);
31085
- null !== id2 && (path46 = copyWithDeleteImpl(id2.memoizedState, path46, 0), id2.memoizedState = path46, id2.baseState = path46, fiber.memoizedProps = assign({}, fiber.memoizedProps), path46 = enqueueConcurrentRenderForLane(fiber, 2), null !== path46 && scheduleUpdateOnFiber(path46, fiber, 2));
31085
+ null !== id2 && (path48 = copyWithDeleteImpl(id2.memoizedState, path48, 0), id2.memoizedState = path48, id2.baseState = path48, fiber.memoizedProps = assign({}, fiber.memoizedProps), path48 = enqueueConcurrentRenderForLane(fiber, 2), null !== path48 && scheduleUpdateOnFiber(path48, fiber, 2));
31086
31086
  };
31087
31087
  overrideHookStateRenamePath = function(fiber, id2, oldPath, newPath) {
31088
31088
  id2 = findHook(fiber, id2);
31089
31089
  null !== id2 && (oldPath = copyWithRename(id2.memoizedState, oldPath, newPath), id2.memoizedState = oldPath, id2.baseState = oldPath, fiber.memoizedProps = assign({}, fiber.memoizedProps), oldPath = enqueueConcurrentRenderForLane(fiber, 2), null !== oldPath && scheduleUpdateOnFiber(oldPath, fiber, 2));
31090
31090
  };
31091
- overrideProps = function(fiber, path46, value) {
31092
- fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path46, 0, value);
31091
+ overrideProps = function(fiber, path48, value) {
31092
+ fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path48, 0, value);
31093
31093
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
31094
- path46 = enqueueConcurrentRenderForLane(fiber, 2);
31095
- null !== path46 && scheduleUpdateOnFiber(path46, fiber, 2);
31094
+ path48 = enqueueConcurrentRenderForLane(fiber, 2);
31095
+ null !== path48 && scheduleUpdateOnFiber(path48, fiber, 2);
31096
31096
  };
31097
- overridePropsDeletePath = function(fiber, path46) {
31098
- fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path46, 0);
31097
+ overridePropsDeletePath = function(fiber, path48) {
31098
+ fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path48, 0);
31099
31099
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
31100
- path46 = enqueueConcurrentRenderForLane(fiber, 2);
31101
- null !== path46 && scheduleUpdateOnFiber(path46, fiber, 2);
31100
+ path48 = enqueueConcurrentRenderForLane(fiber, 2);
31101
+ null !== path48 && scheduleUpdateOnFiber(path48, fiber, 2);
31102
31102
  };
31103
31103
  overridePropsRenamePath = function(fiber, oldPath, newPath) {
31104
31104
  fiber.pendingProps = copyWithRename(
@@ -33840,13 +33840,13 @@ function __classPrivateFieldGet(receiver, state3, kind, f) {
33840
33840
  // ../../node_modules/.pnpm/@anthropic-ai+sdk@0.94.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/internal/utils/uuid.mjs
33841
33841
  init_esm_shims();
33842
33842
  var uuid4 = function() {
33843
- const { crypto: crypto12 } = globalThis;
33844
- if (crypto12?.randomUUID) {
33845
- uuid4 = crypto12.randomUUID.bind(crypto12);
33846
- return crypto12.randomUUID();
33843
+ const { crypto: crypto13 } = globalThis;
33844
+ if (crypto13?.randomUUID) {
33845
+ uuid4 = crypto13.randomUUID.bind(crypto13);
33846
+ return crypto13.randomUUID();
33847
33847
  }
33848
33848
  const u8 = new Uint8Array(1);
33849
- const randomByte = crypto12 ? () => crypto12.getRandomValues(u8)[0] : () => Math.random() * 255 & 255;
33849
+ const randomByte = crypto13 ? () => crypto13.getRandomValues(u8)[0] : () => Math.random() * 255 & 255;
33850
33850
  return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c2) => (+c2 ^ randomByte() & 15 >> +c2 / 4).toString(16));
33851
33851
  };
33852
33852
 
@@ -34333,15 +34333,15 @@ function redactSensitive(body) {
34333
34333
  }
34334
34334
  return null;
34335
34335
  }
34336
- async function checkCredentialsFileSafety(path46, onWarn = (m) => console.warn(`anthropic-sdk: ${m}`)) {
34336
+ async function checkCredentialsFileSafety(path48, onWarn = (m) => console.warn(`anthropic-sdk: ${m}`)) {
34337
34337
  if (typeof process === "undefined" || process.platform === "win32")
34338
34338
  return;
34339
- const fs39 = await import("fs");
34340
- let resolved = path46;
34339
+ const fs40 = await import("fs");
34340
+ let resolved = path48;
34341
34341
  let st;
34342
34342
  try {
34343
- resolved = await fs39.promises.realpath(path46);
34344
- st = await fs39.promises.stat(resolved);
34343
+ resolved = await fs40.promises.realpath(path48);
34344
+ st = await fs40.promises.stat(resolved);
34345
34345
  } catch {
34346
34346
  return;
34347
34347
  }
@@ -34357,27 +34357,27 @@ async function checkCredentialsFileSafety(path46, onWarn = (m) => console.warn(`
34357
34357
  }
34358
34358
  }
34359
34359
  async function writeCredentialsFileAtomic(targetPath, data) {
34360
- const fs39 = await import("fs");
34361
- const path46 = await import("path");
34362
- const dir = path46.dirname(targetPath);
34363
- await fs39.promises.mkdir(dir, { recursive: true, mode: 448 });
34360
+ const fs40 = await import("fs");
34361
+ const path48 = await import("path");
34362
+ const dir = path48.dirname(targetPath);
34363
+ await fs40.promises.mkdir(dir, { recursive: true, mode: 448 });
34364
34364
  const tmpPath = `${targetPath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
34365
34365
  try {
34366
- const fh = await fs39.promises.open(tmpPath, "w", 384);
34366
+ const fh = await fs40.promises.open(tmpPath, "w", 384);
34367
34367
  try {
34368
34368
  await fh.writeFile(JSON.stringify(data, null, 2));
34369
34369
  await fh.sync();
34370
34370
  } finally {
34371
34371
  await fh.close();
34372
34372
  }
34373
- await fs39.promises.rename(tmpPath, targetPath);
34373
+ await fs40.promises.rename(tmpPath, targetPath);
34374
34374
  } catch (err) {
34375
- await fs39.promises.unlink(tmpPath).catch(() => {
34375
+ await fs40.promises.unlink(tmpPath).catch(() => {
34376
34376
  });
34377
34377
  throw err;
34378
34378
  }
34379
34379
  try {
34380
- const dirFh = await fs39.promises.open(dir, "r");
34380
+ const dirFh = await fs40.promises.open(dir, "r");
34381
34381
  try {
34382
34382
  await dirFh.sync();
34383
34383
  } finally {
@@ -34679,12 +34679,12 @@ var loadConfigWithSource = async (profile) => {
34679
34679
  return null;
34680
34680
  }
34681
34681
  validateProfileName(profileName);
34682
- const fs39 = await import("fs");
34683
- const path46 = await import("path");
34684
- const configPath = path46.join(rootConfigPath, "configs", `${profileName}.json`);
34682
+ const fs40 = await import("fs");
34683
+ const path48 = await import("path");
34684
+ const configPath = path48.join(rootConfigPath, "configs", `${profileName}.json`);
34685
34685
  let configRaw;
34686
34686
  try {
34687
- configRaw = await fs39.promises.readFile(configPath, "utf-8");
34687
+ configRaw = await fs40.promises.readFile(configPath, "utf-8");
34688
34688
  } catch (err) {
34689
34689
  if (err?.code !== "ENOENT") {
34690
34690
  throw new Error(`failed to read config file ${configPath}: ${err}`);
@@ -34765,14 +34765,14 @@ var getCredentialsPath = async (config2, profile) => {
34765
34765
  return null;
34766
34766
  }
34767
34767
  validateProfileName(profileName);
34768
- const path46 = await import("path");
34769
- return path46.join(rootConfigPath, "credentials", `${profileName}.json`);
34768
+ const path48 = await import("path");
34769
+ return path48.join(rootConfigPath, "credentials", `${profileName}.json`);
34770
34770
  };
34771
34771
  var getRootConfigPath = async () => {
34772
34772
  if (!supportsLocalConfigFiles()) {
34773
34773
  return null;
34774
34774
  }
34775
- const path46 = await import("path");
34775
+ const path48 = await import("path");
34776
34776
  const configDir = readEnv("ANTHROPIC_CONFIG_DIR");
34777
34777
  if (configDir) {
34778
34778
  return configDir;
@@ -34781,21 +34781,21 @@ var getRootConfigPath = async () => {
34781
34781
  if (os13 === "Windows") {
34782
34782
  const appData = readEnv("APPDATA");
34783
34783
  if (appData) {
34784
- return path46.join(appData, "Anthropic");
34784
+ return path48.join(appData, "Anthropic");
34785
34785
  }
34786
34786
  const userProfile = readEnv("USERPROFILE");
34787
34787
  if (userProfile) {
34788
- return path46.join(userProfile, "AppData", "Roaming", "Anthropic");
34788
+ return path48.join(userProfile, "AppData", "Roaming", "Anthropic");
34789
34789
  }
34790
34790
  return null;
34791
34791
  }
34792
34792
  const xdgConfigHome = readEnv("XDG_CONFIG_HOME");
34793
34793
  if (xdgConfigHome) {
34794
- return path46.join(xdgConfigHome, "anthropic");
34794
+ return path48.join(xdgConfigHome, "anthropic");
34795
34795
  }
34796
34796
  const home = readEnv("HOME");
34797
34797
  if (home) {
34798
- return path46.join(home, ".config", "anthropic");
34798
+ return path48.join(home, ".config", "anthropic");
34799
34799
  }
34800
34800
  return null;
34801
34801
  };
@@ -34812,11 +34812,11 @@ var getActiveProfileName = async () => {
34812
34812
  if (profileName) {
34813
34813
  return profileName;
34814
34814
  }
34815
- const fs39 = await import("fs");
34816
- const path46 = await import("path");
34817
- const filePath = path46.join(rootConfigPath, "active_config");
34815
+ const fs40 = await import("fs");
34816
+ const path48 = await import("path");
34817
+ const filePath = path48.join(rootConfigPath, "active_config");
34818
34818
  try {
34819
- return (await fs39.promises.readFile(filePath, "utf-8")).trim() || "default";
34819
+ return (await fs40.promises.readFile(filePath, "utf-8")).trim() || "default";
34820
34820
  } catch (err) {
34821
34821
  if (err?.code !== "ENOENT") {
34822
34822
  throw new Error(`failed to read ${filePath}: ${err}`);
@@ -34827,21 +34827,21 @@ var getActiveProfileName = async () => {
34827
34827
 
34828
34828
  // ../../node_modules/.pnpm/@anthropic-ai+sdk@0.94.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/identity-token.mjs
34829
34829
  init_esm_shims();
34830
- function identityTokenFromFile(path46) {
34831
- if (!path46) {
34830
+ function identityTokenFromFile(path48) {
34831
+ if (!path48) {
34832
34832
  throw new AnthropicError("Identity token file path is empty");
34833
34833
  }
34834
34834
  return async () => {
34835
- const fs39 = await import("fs");
34835
+ const fs40 = await import("fs");
34836
34836
  let content;
34837
34837
  try {
34838
- content = await fs39.promises.readFile(path46, "utf-8");
34838
+ content = await fs40.promises.readFile(path48, "utf-8");
34839
34839
  } catch (err) {
34840
- throw new AnthropicError(`Failed to read identity token file at ${path46}: ${err}`);
34840
+ throw new AnthropicError(`Failed to read identity token file at ${path48}: ${err}`);
34841
34841
  }
34842
34842
  const token = content.trim();
34843
34843
  if (!token) {
34844
- throw new AnthropicError(`Identity token file at ${path46} is empty`);
34844
+ throw new AnthropicError(`Identity token file at ${path48} is empty`);
34845
34845
  }
34846
34846
  return token;
34847
34847
  };
@@ -34916,11 +34916,11 @@ function oidcFederationProvider(config2) {
34916
34916
  init_esm_shims();
34917
34917
  function userOAuthProvider(config2) {
34918
34918
  return async (opts) => {
34919
- const fs39 = await import("fs");
34919
+ const fs40 = await import("fs");
34920
34920
  await checkCredentialsFileSafety(config2.credentialsPath, config2.onSafetyWarning);
34921
34921
  let raw;
34922
34922
  try {
34923
- raw = await fs39.promises.readFile(config2.credentialsPath, "utf-8");
34923
+ raw = await fs40.promises.readFile(config2.credentialsPath, "utf-8");
34924
34924
  } catch (err) {
34925
34925
  throw new WorkloadIdentityError(`Credentials file not found at ${config2.credentialsPath}: ${err}`);
34926
34926
  }
@@ -35084,11 +35084,11 @@ function resolveIdentityTokenProvider(auth2) {
35084
35084
  }
35085
35085
  function cachedExchangeProvider(exchange, credentialsPath, onCacheWriteError, onSafetyWarning) {
35086
35086
  return async (opts) => {
35087
- const fs39 = await import("fs");
35087
+ const fs40 = await import("fs");
35088
35088
  await checkCredentialsFileSafety(credentialsPath, onSafetyWarning);
35089
35089
  let existing;
35090
35090
  try {
35091
- const raw = await fs39.promises.readFile(credentialsPath, "utf-8");
35091
+ const raw = await fs40.promises.readFile(credentialsPath, "utf-8");
35092
35092
  existing = JSON.parse(raw);
35093
35093
  const token = existing?.["access_token"];
35094
35094
  if (token && !opts?.forceRefresh) {
@@ -35927,12 +35927,12 @@ function encodeURIPath(str2) {
35927
35927
  return str2.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
35928
35928
  }
35929
35929
  var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
35930
- var createPathTagFunction = (pathEncoder = encodeURIPath) => function path46(statics, ...params) {
35930
+ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path48(statics, ...params) {
35931
35931
  if (statics.length === 1)
35932
35932
  return statics[0];
35933
35933
  let postPath = false;
35934
35934
  const invalidSegments = [];
35935
- const path47 = statics.reduce((previousValue, currentValue, index) => {
35935
+ const path49 = statics.reduce((previousValue, currentValue, index) => {
35936
35936
  if (/[?#]/.test(currentValue)) {
35937
35937
  postPath = true;
35938
35938
  }
@@ -35949,7 +35949,7 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path46(sta
35949
35949
  }
35950
35950
  return previousValue + currentValue + (index === params.length ? "" : encoded);
35951
35951
  }, "");
35952
- const pathOnly = path47.split(/[?#]/, 1)[0];
35952
+ const pathOnly = path49.split(/[?#]/, 1)[0];
35953
35953
  const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
35954
35954
  let match;
35955
35955
  while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
@@ -35970,10 +35970,10 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path46(sta
35970
35970
  }, "");
35971
35971
  throw new AnthropicError(`Path parameters result in path with invalid segments:
35972
35972
  ${invalidSegments.map((e) => e.error).join("\n")}
35973
- ${path47}
35973
+ ${path49}
35974
35974
  ${underline}`);
35975
35975
  }
35976
- return path47;
35976
+ return path49;
35977
35977
  };
35978
35978
  var path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
35979
35979
 
@@ -40734,9 +40734,9 @@ var BaseAnthropic = class {
40734
40734
  makeStatusError(status, error51, message, headers) {
40735
40735
  return APIError.generate(status, error51, message, headers);
40736
40736
  }
40737
- buildURL(path46, query, defaultBaseURL) {
40737
+ buildURL(path48, query, defaultBaseURL) {
40738
40738
  const baseURL = !__classPrivateFieldGet(this, _BaseAnthropic_instances, "m", _BaseAnthropic_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
40739
- const url2 = isAbsoluteURL(path46) ? new URL(path46) : new URL(baseURL + (baseURL.endsWith("/") && path46.startsWith("/") ? path46.slice(1) : path46));
40739
+ const url2 = isAbsoluteURL(path48) ? new URL(path48) : new URL(baseURL + (baseURL.endsWith("/") && path48.startsWith("/") ? path48.slice(1) : path48));
40740
40740
  const defaultQuery = this.defaultQuery();
40741
40741
  const pathQuery = Object.fromEntries(url2.searchParams);
40742
40742
  if (!isEmptyObj(defaultQuery) || !isEmptyObj(pathQuery)) {
@@ -40780,24 +40780,24 @@ var BaseAnthropic = class {
40780
40780
  request.headers = headers;
40781
40781
  }
40782
40782
  }
40783
- get(path46, opts) {
40784
- return this.methodRequest("get", path46, opts);
40783
+ get(path48, opts) {
40784
+ return this.methodRequest("get", path48, opts);
40785
40785
  }
40786
- post(path46, opts) {
40787
- return this.methodRequest("post", path46, opts);
40786
+ post(path48, opts) {
40787
+ return this.methodRequest("post", path48, opts);
40788
40788
  }
40789
- patch(path46, opts) {
40790
- return this.methodRequest("patch", path46, opts);
40789
+ patch(path48, opts) {
40790
+ return this.methodRequest("patch", path48, opts);
40791
40791
  }
40792
- put(path46, opts) {
40793
- return this.methodRequest("put", path46, opts);
40792
+ put(path48, opts) {
40793
+ return this.methodRequest("put", path48, opts);
40794
40794
  }
40795
- delete(path46, opts) {
40796
- return this.methodRequest("delete", path46, opts);
40795
+ delete(path48, opts) {
40796
+ return this.methodRequest("delete", path48, opts);
40797
40797
  }
40798
- methodRequest(method, path46, opts) {
40798
+ methodRequest(method, path48, opts) {
40799
40799
  return this.request(Promise.resolve(opts).then((opts2) => {
40800
- return { method, path: path46, ...opts2 };
40800
+ return { method, path: path48, ...opts2 };
40801
40801
  }));
40802
40802
  }
40803
40803
  request(options, remainingRetries = null) {
@@ -40902,8 +40902,8 @@ var BaseAnthropic = class {
40902
40902
  }));
40903
40903
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
40904
40904
  }
40905
- getAPIList(path46, Page3, opts) {
40906
- return this.requestAPIList(Page3, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path46, ...opts2 })) : { method: "get", path: path46, ...opts });
40905
+ getAPIList(path48, Page3, opts) {
40906
+ return this.requestAPIList(Page3, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path48, ...opts2 })) : { method: "get", path: path48, ...opts });
40907
40907
  }
40908
40908
  requestAPIList(Page3, options) {
40909
40909
  const request = this.makeRequest(options, null, void 0);
@@ -40997,14 +40997,14 @@ var BaseAnthropic = class {
40997
40997
  }
40998
40998
  async buildRequest(inputOptions, { retryCount = 0 } = {}) {
40999
40999
  const options = { ...inputOptions };
41000
- const { method, path: path46, query, defaultBaseURL } = options;
41000
+ const { method, path: path48, query, defaultBaseURL } = options;
41001
41001
  if (this._authState.resolution) {
41002
41002
  await this._authState.resolution;
41003
41003
  }
41004
41004
  if (!this._baseURLIsExplicit && this._authState.baseURL && this.baseURL !== this._authState.baseURL) {
41005
41005
  this.baseURL = this._authState.baseURL;
41006
41006
  }
41007
- const url2 = this.buildURL(path46, query, defaultBaseURL);
41007
+ const url2 = this.buildURL(path48, query, defaultBaseURL);
41008
41008
  if ("timeout" in options)
41009
41009
  validatePositiveInteger("timeout", options.timeout);
41010
41010
  options.timeout = options.timeout ?? this.timeout;
@@ -41891,10 +41891,10 @@ function mergeDefs(...defs) {
41891
41891
  function cloneDef(schema) {
41892
41892
  return mergeDefs(schema._zod.def);
41893
41893
  }
41894
- function getElementAtPath(obj, path46) {
41895
- if (!path46)
41894
+ function getElementAtPath(obj, path48) {
41895
+ if (!path48)
41896
41896
  return obj;
41897
- return path46.reduce((acc, key) => acc?.[key], obj);
41897
+ return path48.reduce((acc, key) => acc?.[key], obj);
41898
41898
  }
41899
41899
  function promiseAllObject(promisesObj) {
41900
41900
  const keys = Object.keys(promisesObj);
@@ -42303,11 +42303,11 @@ function explicitlyAborted(x, startIndex = 0) {
42303
42303
  }
42304
42304
  return false;
42305
42305
  }
42306
- function prefixIssues(path46, issues) {
42306
+ function prefixIssues(path48, issues) {
42307
42307
  return issues.map((iss) => {
42308
42308
  var _a6;
42309
42309
  (_a6 = iss).path ?? (_a6.path = []);
42310
- iss.path.unshift(path46);
42310
+ iss.path.unshift(path48);
42311
42311
  return iss;
42312
42312
  });
42313
42313
  }
@@ -42454,16 +42454,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
42454
42454
  }
42455
42455
  function formatError(error51, mapper = (issue2) => issue2.message) {
42456
42456
  const fieldErrors = { _errors: [] };
42457
- const processError = (error52, path46 = []) => {
42457
+ const processError = (error52, path48 = []) => {
42458
42458
  for (const issue2 of error52.issues) {
42459
42459
  if (issue2.code === "invalid_union" && issue2.errors.length) {
42460
- issue2.errors.map((issues) => processError({ issues }, [...path46, ...issue2.path]));
42460
+ issue2.errors.map((issues) => processError({ issues }, [...path48, ...issue2.path]));
42461
42461
  } else if (issue2.code === "invalid_key") {
42462
- processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
42462
+ processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
42463
42463
  } else if (issue2.code === "invalid_element") {
42464
- processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
42464
+ processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
42465
42465
  } else {
42466
- const fullpath = [...path46, ...issue2.path];
42466
+ const fullpath = [...path48, ...issue2.path];
42467
42467
  if (fullpath.length === 0) {
42468
42468
  fieldErrors._errors.push(mapper(issue2));
42469
42469
  } else {
@@ -42490,17 +42490,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
42490
42490
  }
42491
42491
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
42492
42492
  const result = { errors: [] };
42493
- const processError = (error52, path46 = []) => {
42493
+ const processError = (error52, path48 = []) => {
42494
42494
  var _a6, _b;
42495
42495
  for (const issue2 of error52.issues) {
42496
42496
  if (issue2.code === "invalid_union" && issue2.errors.length) {
42497
- issue2.errors.map((issues) => processError({ issues }, [...path46, ...issue2.path]));
42497
+ issue2.errors.map((issues) => processError({ issues }, [...path48, ...issue2.path]));
42498
42498
  } else if (issue2.code === "invalid_key") {
42499
- processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
42499
+ processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
42500
42500
  } else if (issue2.code === "invalid_element") {
42501
- processError({ issues: issue2.issues }, [...path46, ...issue2.path]);
42501
+ processError({ issues: issue2.issues }, [...path48, ...issue2.path]);
42502
42502
  } else {
42503
- const fullpath = [...path46, ...issue2.path];
42503
+ const fullpath = [...path48, ...issue2.path];
42504
42504
  if (fullpath.length === 0) {
42505
42505
  result.errors.push(mapper(issue2));
42506
42506
  continue;
@@ -42532,8 +42532,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
42532
42532
  }
42533
42533
  function toDotPath(_path) {
42534
42534
  const segs = [];
42535
- const path46 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
42536
- for (const seg of path46) {
42535
+ const path48 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
42536
+ for (const seg of path48) {
42537
42537
  if (typeof seg === "number")
42538
42538
  segs.push(`[${seg}]`);
42539
42539
  else if (typeof seg === "symbol")
@@ -55306,13 +55306,13 @@ function resolveRef(ref, ctx) {
55306
55306
  if (!ref.startsWith("#")) {
55307
55307
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
55308
55308
  }
55309
- const path46 = ref.slice(1).split("/").filter(Boolean);
55310
- if (path46.length === 0) {
55309
+ const path48 = ref.slice(1).split("/").filter(Boolean);
55310
+ if (path48.length === 0) {
55311
55311
  return ctx.rootSchema;
55312
55312
  }
55313
55313
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
55314
- if (path46[0] === defsKey) {
55315
- const key = path46[1];
55314
+ if (path48[0] === defsKey) {
55315
+ const key = path48[1];
55316
55316
  if (!key || !ctx.defs[key]) {
55317
55317
  throw new Error(`Reference not found: ${ref}`);
55318
55318
  }
@@ -55749,13 +55749,13 @@ function __classPrivateFieldGet2(receiver, state3, kind, f) {
55749
55749
  // ../../node_modules/.pnpm/openai@6.34.0_ws@8.20.0_zod@4.4.3/node_modules/openai/internal/utils/uuid.mjs
55750
55750
  init_esm_shims();
55751
55751
  var uuid43 = function() {
55752
- const { crypto: crypto12 } = globalThis;
55753
- if (crypto12?.randomUUID) {
55754
- uuid43 = crypto12.randomUUID.bind(crypto12);
55755
- return crypto12.randomUUID();
55752
+ const { crypto: crypto13 } = globalThis;
55753
+ if (crypto13?.randomUUID) {
55754
+ uuid43 = crypto13.randomUUID.bind(crypto13);
55755
+ return crypto13.randomUUID();
55756
55756
  }
55757
55757
  const u8 = new Uint8Array(1);
55758
- const randomByte = crypto12 ? () => crypto12.getRandomValues(u8)[0] : () => Math.random() * 255 & 255;
55758
+ const randomByte = crypto13 ? () => crypto13.getRandomValues(u8)[0] : () => Math.random() * 255 & 255;
55759
55759
  return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c2) => (+c2 ^ randomByte() & 15 >> +c2 / 4).toString(16));
55760
55760
  };
55761
55761
 
@@ -57541,12 +57541,12 @@ function encodeURIPath2(str2) {
57541
57541
  return str2.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
57542
57542
  }
57543
57543
  var EMPTY2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
57544
- var createPathTagFunction2 = (pathEncoder = encodeURIPath2) => function path46(statics, ...params) {
57544
+ var createPathTagFunction2 = (pathEncoder = encodeURIPath2) => function path48(statics, ...params) {
57545
57545
  if (statics.length === 1)
57546
57546
  return statics[0];
57547
57547
  let postPath = false;
57548
57548
  const invalidSegments = [];
57549
- const path47 = statics.reduce((previousValue, currentValue, index) => {
57549
+ const path49 = statics.reduce((previousValue, currentValue, index) => {
57550
57550
  if (/[?#]/.test(currentValue)) {
57551
57551
  postPath = true;
57552
57552
  }
@@ -57563,7 +57563,7 @@ var createPathTagFunction2 = (pathEncoder = encodeURIPath2) => function path46(s
57563
57563
  }
57564
57564
  return previousValue + currentValue + (index === params.length ? "" : encoded);
57565
57565
  }, "");
57566
- const pathOnly = path47.split(/[?#]/, 1)[0];
57566
+ const pathOnly = path49.split(/[?#]/, 1)[0];
57567
57567
  const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
57568
57568
  let match;
57569
57569
  while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
@@ -57584,10 +57584,10 @@ var createPathTagFunction2 = (pathEncoder = encodeURIPath2) => function path46(s
57584
57584
  }, "");
57585
57585
  throw new OpenAIError(`Path parameters result in path with invalid segments:
57586
57586
  ${invalidSegments.map((e) => e.error).join("\n")}
57587
- ${path47}
57587
+ ${path49}
57588
57588
  ${underline}`);
57589
57589
  }
57590
- return path47;
57590
+ return path49;
57591
57591
  };
57592
57592
  var path2 = /* @__PURE__ */ createPathTagFunction2(encodeURIPath2);
57593
57593
 
@@ -62713,9 +62713,9 @@ var OpenAI = class {
62713
62713
  this.apiKey = token;
62714
62714
  return true;
62715
62715
  }
62716
- buildURL(path46, query, defaultBaseURL) {
62716
+ buildURL(path48, query, defaultBaseURL) {
62717
62717
  const baseURL = !__classPrivateFieldGet2(this, _OpenAI_instances, "m", _OpenAI_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
62718
- const url2 = isAbsoluteURL2(path46) ? new URL(path46) : new URL(baseURL + (baseURL.endsWith("/") && path46.startsWith("/") ? path46.slice(1) : path46));
62718
+ const url2 = isAbsoluteURL2(path48) ? new URL(path48) : new URL(baseURL + (baseURL.endsWith("/") && path48.startsWith("/") ? path48.slice(1) : path48));
62719
62719
  const defaultQuery = this.defaultQuery();
62720
62720
  const pathQuery = Object.fromEntries(url2.searchParams);
62721
62721
  if (!isEmptyObj2(defaultQuery) || !isEmptyObj2(pathQuery)) {
@@ -62740,24 +62740,24 @@ var OpenAI = class {
62740
62740
  */
62741
62741
  async prepareRequest(request, { url: url2, options }) {
62742
62742
  }
62743
- get(path46, opts) {
62744
- return this.methodRequest("get", path46, opts);
62743
+ get(path48, opts) {
62744
+ return this.methodRequest("get", path48, opts);
62745
62745
  }
62746
- post(path46, opts) {
62747
- return this.methodRequest("post", path46, opts);
62746
+ post(path48, opts) {
62747
+ return this.methodRequest("post", path48, opts);
62748
62748
  }
62749
- patch(path46, opts) {
62750
- return this.methodRequest("patch", path46, opts);
62749
+ patch(path48, opts) {
62750
+ return this.methodRequest("patch", path48, opts);
62751
62751
  }
62752
- put(path46, opts) {
62753
- return this.methodRequest("put", path46, opts);
62752
+ put(path48, opts) {
62753
+ return this.methodRequest("put", path48, opts);
62754
62754
  }
62755
- delete(path46, opts) {
62756
- return this.methodRequest("delete", path46, opts);
62755
+ delete(path48, opts) {
62756
+ return this.methodRequest("delete", path48, opts);
62757
62757
  }
62758
- methodRequest(method, path46, opts) {
62758
+ methodRequest(method, path48, opts) {
62759
62759
  return this.request(Promise.resolve(opts).then((opts2) => {
62760
- return { method, path: path46, ...opts2 };
62760
+ return { method, path: path48, ...opts2 };
62761
62761
  }));
62762
62762
  }
62763
62763
  request(options, remainingRetries = null) {
@@ -62875,8 +62875,8 @@ var OpenAI = class {
62875
62875
  }));
62876
62876
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
62877
62877
  }
62878
- getAPIList(path46, Page3, opts) {
62879
- return this.requestAPIList(Page3, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path46, ...opts2 })) : { method: "get", path: path46, ...opts });
62878
+ getAPIList(path48, Page3, opts) {
62879
+ return this.requestAPIList(Page3, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path48, ...opts2 })) : { method: "get", path: path48, ...opts });
62880
62880
  }
62881
62881
  requestAPIList(Page3, options) {
62882
62882
  const request = this.makeRequest(options, null, void 0);
@@ -62967,8 +62967,8 @@ var OpenAI = class {
62967
62967
  }
62968
62968
  async buildRequest(inputOptions, { retryCount = 0 } = {}) {
62969
62969
  const options = { ...inputOptions };
62970
- const { method, path: path46, query, defaultBaseURL } = options;
62971
- const url2 = this.buildURL(path46, query, defaultBaseURL);
62970
+ const { method, path: path48, query, defaultBaseURL } = options;
62971
+ const url2 = this.buildURL(path48, query, defaultBaseURL);
62972
62972
  if ("timeout" in options)
62973
62973
  validatePositiveInteger2("timeout", options.timeout);
62974
62974
  options.timeout = options.timeout ?? this.timeout;
@@ -63372,7 +63372,7 @@ var EventStream2 = class {
63372
63372
  }
63373
63373
  }
63374
63374
  };
63375
- var StreamResult = class {
63375
+ var StreamResult = class _StreamResult {
63376
63376
  response;
63377
63377
  buffer = [];
63378
63378
  done = false;
@@ -63380,6 +63380,18 @@ var StreamResult = class {
63380
63380
  resolveResponse;
63381
63381
  rejectResponse;
63382
63382
  resolveWait = null;
63383
+ /**
63384
+ * High-water mark: when the buffer exceeds this many unconsumed events,
63385
+ * the pump pauses until the consumer drains below the low-water mark.
63386
+ * Prevents unbounded memory growth when a consumer is slow.
63387
+ * Only active when someone IS iterating — if nobody iterates (the `then()`
63388
+ * path), backpressure is skipped so the pump can complete and resolve.
63389
+ */
63390
+ static HIGH_WATER = 5e3;
63391
+ static LOW_WATER = 1e3;
63392
+ iterating = false;
63393
+ paused = false;
63394
+ resolveDrain = null;
63383
63395
  constructor(generator, signal) {
63384
63396
  this.response = new Promise((resolve2, reject) => {
63385
63397
  this.resolveResponse = resolve2;
@@ -63394,6 +63406,13 @@ var StreamResult = class {
63394
63406
  this.buffer.push(next.value);
63395
63407
  this.resolveWait?.();
63396
63408
  this.resolveWait = null;
63409
+ if (this.iterating && this.buffer.length > _StreamResult.HIGH_WATER) {
63410
+ this.paused = true;
63411
+ await new Promise((r2) => {
63412
+ this.resolveDrain = r2;
63413
+ });
63414
+ this.paused = false;
63415
+ }
63397
63416
  next = await this._nextWithAbort(generator, signal);
63398
63417
  }
63399
63418
  this.done = true;
@@ -63432,11 +63451,20 @@ var StreamResult = class {
63432
63451
  }
63433
63452
  }
63434
63453
  async *[Symbol.asyncIterator]() {
63454
+ this.iterating = true;
63435
63455
  let index = 0;
63436
63456
  while (true) {
63437
63457
  while (index < this.buffer.length) {
63438
63458
  yield this.buffer[index++];
63439
63459
  }
63460
+ if (this.paused && index > _StreamResult.LOW_WATER) {
63461
+ this.resolveDrain?.();
63462
+ this.resolveDrain = null;
63463
+ }
63464
+ if (index > 0 && !this.paused) {
63465
+ this.buffer.splice(0, index);
63466
+ index = 0;
63467
+ }
63440
63468
  if (this.error) throw this.error;
63441
63469
  if (this.done) return;
63442
63470
  await new Promise((r2) => {
@@ -63449,13 +63477,23 @@ var StreamResult = class {
63449
63477
  }
63450
63478
  }
63451
63479
  then(onfulfilled, onrejected) {
63480
+ if (this.paused) {
63481
+ this.paused = false;
63482
+ this.resolveDrain?.();
63483
+ this.resolveDrain = null;
63484
+ }
63452
63485
  return this.response.then(onfulfilled, onrejected);
63453
63486
  }
63454
63487
  };
63488
+ var schemaCache = /* @__PURE__ */ new WeakMap();
63455
63489
  function zodToJsonSchema(schema) {
63490
+ const cached4 = schemaCache.get(schema);
63491
+ if (cached4) return cached4;
63456
63492
  const jsonSchema = external_exports.toJSONSchema(schema);
63457
63493
  const { $schema: _schema, ...rest } = jsonSchema;
63458
- return normalizeRootForAnthropic(rest);
63494
+ const normalized = normalizeRootForAnthropic(rest);
63495
+ schemaCache.set(schema, normalized);
63496
+ return normalized;
63459
63497
  }
63460
63498
  function resolveToolSchema(tool) {
63461
63499
  return tool.rawInputSchema ?? zodToJsonSchema(tool.parameters);
@@ -63845,16 +63883,17 @@ function toAnthropicThinking(level, maxTokens, model) {
63845
63883
  outputConfig: { effort }
63846
63884
  };
63847
63885
  }
63886
+ const VISIBLE_FLOOR = 1024;
63848
63887
  const effectiveLevel = level === "xhigh" || level === "max" ? "high" : level;
63849
63888
  const budgetMap = {
63850
- low: Math.max(1024, Math.floor(maxTokens * 0.25)),
63851
- medium: Math.max(2048, Math.floor(maxTokens * 0.5)),
63852
- high: Math.max(4096, maxTokens)
63889
+ low: Math.max(1024, Math.floor(maxTokens * 0.2)),
63890
+ medium: Math.max(2048, Math.floor(maxTokens * 0.45)),
63891
+ high: Math.max(4096, Math.floor(maxTokens * 0.8))
63853
63892
  };
63854
- const budget = budgetMap[effectiveLevel];
63893
+ const budget = Math.max(0, Math.min(budgetMap[effectiveLevel], maxTokens - VISIBLE_FLOOR));
63855
63894
  return {
63856
63895
  thinking: { type: "enabled", budget_tokens: budget },
63857
- maxTokens: maxTokens + budget
63896
+ maxTokens
63858
63897
  };
63859
63898
  }
63860
63899
  function remapToolCallId(id2, idMap) {
@@ -64056,26 +64095,83 @@ function parseToolArguments(argsJson) {
64056
64095
  return {};
64057
64096
  }
64058
64097
  }
64098
+ var anthropicClientCache = /* @__PURE__ */ new Map();
64059
64099
  function createClient(options) {
64060
64100
  const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
64061
- return new Anthropic({
64101
+ const userAgent = isOAuth ? options.userAgent ?? "claude-cli/2.1.75 (external, cli)" : "";
64102
+ const cacheKey = `${options.apiKey ?? ""}|${options.baseUrl ?? ""}|${userAgent}`;
64103
+ if (!options.fetch) {
64104
+ const cached4 = anthropicClientCache.get(cacheKey);
64105
+ if (cached4) return cached4;
64106
+ }
64107
+ const client = new Anthropic({
64062
64108
  ...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
64063
64109
  ...options.baseUrl ? { baseURL: options.baseUrl } : {},
64064
64110
  ...options.fetch ? { fetch: options.fetch } : {},
64065
- // Disable SDK retries — the agent loop has its own stall/overload retry
64066
- // logic that surfaces errors properly. SDK retries on 429s can cause
64067
- // multi-minute hangs when the provider stops responding mid-retry.
64068
64111
  maxRetries: 0,
64069
64112
  ...isOAuth ? {
64070
64113
  defaultHeaders: {
64071
- // Anthropic's OAuth edge validates the claude-cli version. Callers
64072
- // (ggcoder) resolve the live version at runtime; the literal here
64073
- // is the offline fallback for direct gg-ai consumers.
64074
- "user-agent": options.userAgent ?? "claude-cli/2.1.75 (external, cli)",
64114
+ "user-agent": userAgent,
64075
64115
  "x-app": "cli"
64076
64116
  }
64077
64117
  } : {}
64078
64118
  });
64119
+ if (!options.fetch) {
64120
+ if (anthropicClientCache.size >= 8) {
64121
+ const oldest = anthropicClientCache.keys().next().value;
64122
+ if (oldest) anthropicClientCache.delete(oldest);
64123
+ }
64124
+ anthropicClientCache.set(cacheKey, client);
64125
+ }
64126
+ return client;
64127
+ }
64128
+ async function prewarmAnthropicCache(options) {
64129
+ try {
64130
+ const client = createClient({
64131
+ apiKey: options.apiKey,
64132
+ baseUrl: options.baseUrl,
64133
+ userAgent: options.userAgent
64134
+ });
64135
+ const cacheControl = toAnthropicCacheControl(options.cacheRetention ?? "long", options.baseUrl);
64136
+ const { system, messages } = toAnthropicMessages(
64137
+ [
64138
+ { role: "system", content: options.system },
64139
+ { role: "user", content: "." }
64140
+ ],
64141
+ cacheControl
64142
+ );
64143
+ const isOAuth = options.apiKey.startsWith("sk-ant-oat");
64144
+ const fullSystem = isOAuth ? [
64145
+ {
64146
+ type: "text",
64147
+ text: "You are Claude Code, Anthropic's official CLI for Claude."
64148
+ },
64149
+ ...system ?? []
64150
+ ] : system;
64151
+ const tools = options.tools?.length ? toAnthropicTools(options.tools, {
64152
+ cacheControl,
64153
+ enableFineGrainedToolStreaming: true
64154
+ }) : void 0;
64155
+ await client.messages.create(
64156
+ {
64157
+ model: options.model,
64158
+ max_tokens: 1,
64159
+ messages,
64160
+ ...fullSystem ? { system: fullSystem } : {},
64161
+ ...tools ? {
64162
+ tools: [
64163
+ ...tools,
64164
+ ...options.serverTools ?? []
64165
+ ]
64166
+ } : {}
64167
+ },
64168
+ {
64169
+ signal: options.signal ?? void 0,
64170
+ ...isOAuth ? { headers: { "anthropic-beta": "claude-code-20250219,oauth-2025-04-20" } } : {}
64171
+ }
64172
+ );
64173
+ } catch {
64174
+ }
64079
64175
  }
64080
64176
  function streamAnthropic(options) {
64081
64177
  return new StreamResult(runStream(options), options.signal);
@@ -64639,13 +64735,27 @@ function extractOpenAIUsage(usage) {
64639
64735
  cacheRead
64640
64736
  };
64641
64737
  }
64738
+ var openaiClientCache = /* @__PURE__ */ new Map();
64642
64739
  function createClient2(options) {
64643
- return new OpenAI({
64740
+ const cacheKey = `${options.apiKey ?? ""}|${options.baseUrl ?? ""}|${JSON.stringify(options.defaultHeaders ?? {})}`;
64741
+ if (!options.fetch) {
64742
+ const cached4 = openaiClientCache.get(cacheKey);
64743
+ if (cached4) return cached4;
64744
+ }
64745
+ const client = new OpenAI({
64644
64746
  apiKey: options.apiKey,
64645
64747
  ...options.baseUrl ? { baseURL: options.baseUrl } : {},
64646
64748
  ...options.fetch ? { fetch: options.fetch } : {},
64647
64749
  ...options.defaultHeaders ? { defaultHeaders: options.defaultHeaders } : {}
64648
64750
  });
64751
+ if (!options.fetch) {
64752
+ if (openaiClientCache.size >= 8) {
64753
+ const oldest = openaiClientCache.keys().next().value;
64754
+ if (oldest) openaiClientCache.delete(oldest);
64755
+ }
64756
+ openaiClientCache.set(cacheKey, client);
64757
+ }
64758
+ return client;
64649
64759
  }
64650
64760
  function streamOpenAI(options) {
64651
64761
  return new StreamResult(runStream2(options), options.signal);
@@ -64703,11 +64813,11 @@ async function* runStream2(options) {
64703
64813
  }
64704
64814
  }
64705
64815
  if (getEnvironment()?.GGAI_DUMP_REQUEST) {
64706
- const fs39 = await import("fs");
64816
+ const fs40 = await import("fs");
64707
64817
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
64708
64818
  const dumpPath = `/tmp/ggai-request-${ts}.json`;
64709
- fs39.writeFileSync(dumpPath, JSON.stringify(params, null, 2));
64710
- fs39.appendFileSync(
64819
+ fs40.writeFileSync(dumpPath, JSON.stringify(params, null, 2));
64820
+ fs40.appendFileSync(
64711
64821
  "/tmp/ggai-requests.log",
64712
64822
  `[${ts}] ${dumpPath} messages=${params.messages.length}
64713
64823
  `
@@ -65051,9 +65161,6 @@ async function* runStream3(options) {
65051
65161
  body.tools = toCodexTools(options.tools);
65052
65162
  }
65053
65163
  body.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ggcoder");
65054
- if (options.cacheRetention === "long") {
65055
- body.prompt_cache_retention = "24h";
65056
- }
65057
65164
  if (options.temperature != null && !options.thinking) {
65058
65165
  body.temperature = options.temperature;
65059
65166
  }
@@ -66406,23 +66513,25 @@ async function* agentLoop(messages, options) {
66406
66513
  while (turn < maxTurns) {
66407
66514
  options.signal?.throwIfAborted();
66408
66515
  turn++;
66409
- let msgChars = 0;
66410
- for (const m of messages) {
66411
- if (typeof m.content === "string") msgChars += m.content.length;
66412
- else if (Array.isArray(m.content)) {
66413
- for (const p of m.content) {
66414
- if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
66415
- if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
66516
+ if (_diagFn2) {
66517
+ let msgChars = 0;
66518
+ for (const m of messages) {
66519
+ if (typeof m.content === "string") msgChars += m.content.length;
66520
+ else if (Array.isArray(m.content)) {
66521
+ for (const p of m.content) {
66522
+ if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
66523
+ if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
66524
+ }
66416
66525
  }
66417
66526
  }
66527
+ diag("turn_start", {
66528
+ turn,
66529
+ messages: messages.length,
66530
+ chars: msgChars,
66531
+ provider: options.provider,
66532
+ model: options.model
66533
+ });
66418
66534
  }
66419
- diag("turn_start", {
66420
- turn,
66421
- messages: messages.length,
66422
- chars: msgChars,
66423
- provider: options.provider,
66424
- model: options.model
66425
- });
66426
66535
  if (firstTurn && options.getSteeringMessages) {
66427
66536
  const steering = await options.getSteeringMessages();
66428
66537
  if (steering && steering.length > 0) {
@@ -66958,7 +67067,7 @@ async function* agentLoop(messages, options) {
66958
67067
  const hasSequentialToolCall = toolCalls.some(
66959
67068
  (toolCall) => toolMap.get(toolCall.name)?.executionMode === "sequential"
66960
67069
  );
66961
- const executionResult = hasSequentialToolCall ? yield* executeToolCallsSequential(toolCalls, toolResults, executionOptions) : yield* executeToolCallsParallel(toolCalls, toolResults, executionOptions);
67070
+ const executionResult = hasSequentialToolCall ? yield* executeToolCallsMixed(toolCalls, toolResults, executionOptions) : yield* executeToolCallsParallel(toolCalls, toolResults, executionOptions);
66962
67071
  messages.push({ role: "tool", content: executionResult.toolResults });
66963
67072
  const toolsAborted = executionResult.aborted;
66964
67073
  if (fatalToolArgumentError) {
@@ -67018,8 +67127,10 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
67018
67127
  } else {
67019
67128
  try {
67020
67129
  const parsed = tool.parameters.parse(toolCall.args);
67130
+ const callerSignal = options.signal;
67131
+ const toolTimeout = AbortSignal.timeout(3e5);
67021
67132
  const ctx = {
67022
- signal: options.signal ?? AbortSignal.timeout(3e5),
67133
+ signal: callerSignal ? AbortSignal.any([callerSignal, toolTimeout]) : toolTimeout,
67023
67134
  toolCallId: toolCall.id,
67024
67135
  onUpdate: (update) => {
67025
67136
  pushEvent({
@@ -67068,22 +67179,59 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
67068
67179
  });
67069
67180
  return { toolCallId: toolCall.id, content: resultContent, isError };
67070
67181
  }
67071
- async function* executeToolCallsSequential(toolCalls, initialToolResults, options) {
67182
+ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
67072
67183
  const eventStream = new EventStream2();
67073
67184
  const state3 = { finalized: false };
67074
67185
  const resultsById = /* @__PURE__ */ new Map();
67075
67186
  const abortHandler = () => eventStream.abort(new Error("aborted"));
67076
67187
  options.signal?.addEventListener("abort", abortHandler, { once: true });
67188
+ const phases = [];
67189
+ let currentParallel = [];
67190
+ for (const toolCall of toolCalls) {
67191
+ const isSequential = options.toolMap.get(toolCall.name)?.executionMode === "sequential";
67192
+ if (isSequential) {
67193
+ if (currentParallel.length > 0) {
67194
+ phases.push({ parallel: currentParallel, sequential: null });
67195
+ currentParallel = [];
67196
+ }
67197
+ phases.push({ parallel: [], sequential: toolCall });
67198
+ } else {
67199
+ currentParallel.push(toolCall);
67200
+ }
67201
+ }
67202
+ if (currentParallel.length > 0) {
67203
+ phases.push({ parallel: currentParallel, sequential: null });
67204
+ }
67077
67205
  void (async () => {
67078
67206
  try {
67079
- for (const toolCall of toolCalls) {
67207
+ for (const phase of phases) {
67080
67208
  if (options.signal?.aborted) break;
67081
- const record2 = await executeSingleToolCall(
67082
- toolCall,
67083
- options,
67084
- (event) => pushToolEvent(eventStream, state3, event)
67085
- );
67086
- resultsById.set(record2.toolCallId, record2);
67209
+ if (phase.sequential) {
67210
+ const record2 = await executeSingleToolCall(
67211
+ phase.sequential,
67212
+ options,
67213
+ (event) => pushToolEvent(eventStream, state3, event)
67214
+ );
67215
+ resultsById.set(record2.toolCallId, record2);
67216
+ } else if (phase.parallel.length === 1) {
67217
+ const record2 = await executeSingleToolCall(
67218
+ phase.parallel[0],
67219
+ options,
67220
+ (event) => pushToolEvent(eventStream, state3, event)
67221
+ );
67222
+ resultsById.set(record2.toolCallId, record2);
67223
+ } else {
67224
+ await Promise.all(
67225
+ phase.parallel.map(async (toolCall) => {
67226
+ const record2 = await executeSingleToolCall(
67227
+ toolCall,
67228
+ options,
67229
+ (event) => pushToolEvent(eventStream, state3, event)
67230
+ );
67231
+ resultsById.set(record2.toolCallId, record2);
67232
+ })
67233
+ );
67234
+ }
67087
67235
  }
67088
67236
  if (!state3.finalized) eventStream.close();
67089
67237
  } catch (err) {
@@ -67798,7 +67946,7 @@ function getSummaryModel(provider, currentModelId) {
67798
67946
  // ../gg-core/dist/index.js
67799
67947
  init_esm_shims();
67800
67948
 
67801
- // ../gg-core/dist/chunk-TZNVRILI.js
67949
+ // ../gg-core/dist/chunk-KQJNZC6A.js
67802
67950
  init_esm_shims();
67803
67951
  import path3 from "path";
67804
67952
  import os2 from "os";
@@ -67812,6 +67960,7 @@ function getAppPaths() {
67812
67960
  telegramFile: path3.join(agentDir, "telegram.json"),
67813
67961
  agentHomeFile: path3.join(agentDir, "agent-home.json"),
67814
67962
  mcpFile: path3.join(agentDir, "mcp.json"),
67963
+ mcpAuthFile: path3.join(agentDir, "mcp-auth.json"),
67815
67964
  logFile: path3.join(agentDir, "debug.log"),
67816
67965
  skillsDir: path3.join(agentDir, "skills"),
67817
67966
  extensionsDir: path3.join(agentDir, "extensions"),
@@ -69084,7 +69233,7 @@ init_esm_shims();
69084
69233
  import { spawn as spawn2, spawnSync } from "child_process";
69085
69234
  import fs6 from "fs";
69086
69235
  import fsp from "fs/promises";
69087
- import path6 from "path";
69236
+ import path7 from "path";
69088
69237
  import os3 from "os";
69089
69238
  import crypto2 from "crypto";
69090
69239
 
@@ -69142,7 +69291,34 @@ var ENV_ALLOWLIST = /* @__PURE__ */ new Set([
69142
69291
  "ANDROID_SDK_ROOT",
69143
69292
  "RUBY_VERSION",
69144
69293
  "GEM_HOME",
69145
- "RBENV_ROOT"
69294
+ "RBENV_ROOT",
69295
+ // Windows essentials. Without these, child processes (cmd.exe, Git Bash,
69296
+ // node, npm, MCP stdio servers) misbehave or fail to spawn: SystemRoot +
69297
+ // PATHEXT are required by the Windows loader/resolver, ComSpec is the
69298
+ // cmd.exe path, and the USERPROFILE/APPDATA/TEMP family is where toolchains
69299
+ // read and write. Stripping them was a silent cause of broken shell calls.
69300
+ "SystemRoot",
69301
+ "SystemDrive",
69302
+ "windir",
69303
+ "PATHEXT",
69304
+ "ComSpec",
69305
+ "COMSPEC",
69306
+ "USERPROFILE",
69307
+ "HOMEDRIVE",
69308
+ "HOMEPATH",
69309
+ "APPDATA",
69310
+ "LOCALAPPDATA",
69311
+ "PROGRAMDATA",
69312
+ "ProgramData",
69313
+ "ProgramFiles",
69314
+ "ProgramFiles(x86)",
69315
+ "ProgramW6432",
69316
+ "TEMP",
69317
+ "TMP",
69318
+ "NUMBER_OF_PROCESSORS",
69319
+ "PROCESSOR_ARCHITECTURE",
69320
+ // Git Bash override for the agent shell (see core/shell.ts).
69321
+ "GG_BASH"
69146
69322
  ]);
69147
69323
  function getSafeToolEnv(sourceEnv = process.env) {
69148
69324
  const env2 = { TERM: "dumb", GG_CODER: "true" };
@@ -69154,8 +69330,68 @@ function getSafeToolEnv(sourceEnv = process.env) {
69154
69330
  return env2;
69155
69331
  }
69156
69332
 
69333
+ // ../ggcoder/dist/core/shell.js
69334
+ init_esm_shims();
69335
+ import { existsSync as existsSync2 } from "fs";
69336
+ import path6 from "path";
69337
+ function gitBashFixedCandidates(env2) {
69338
+ const programFiles = env2.ProgramFiles ?? "C:\\Program Files";
69339
+ const programFilesX86 = env2["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
69340
+ const localAppData = env2.LOCALAPPDATA;
69341
+ const candidates = [
69342
+ path6.win32.join(programFiles, "Git", "bin", "bash.exe"),
69343
+ path6.win32.join(programFilesX86, "Git", "bin", "bash.exe")
69344
+ ];
69345
+ if (localAppData) {
69346
+ candidates.push(path6.win32.join(localAppData, "Programs", "Git", "bin", "bash.exe"));
69347
+ }
69348
+ return candidates;
69349
+ }
69350
+ function gitBashFromPath(env2, exists) {
69351
+ const rawPath = env2.PATH ?? env2.Path ?? "";
69352
+ if (!rawPath)
69353
+ return null;
69354
+ for (const dir of rawPath.split(";")) {
69355
+ if (!dir)
69356
+ continue;
69357
+ const gitExe = path6.win32.join(dir, "git.exe");
69358
+ if (!exists(gitExe))
69359
+ continue;
69360
+ const gitRoot = path6.win32.dirname(path6.win32.dirname(gitExe));
69361
+ const bash2 = path6.win32.join(gitRoot, "bin", "bash.exe");
69362
+ if (exists(bash2))
69363
+ return bash2;
69364
+ }
69365
+ return null;
69366
+ }
69367
+ function findGitBash(env2, exists) {
69368
+ for (const candidate of gitBashFixedCandidates(env2)) {
69369
+ if (exists(candidate))
69370
+ return candidate;
69371
+ }
69372
+ return gitBashFromPath(env2, exists);
69373
+ }
69374
+ function resolveShell(command, opts = {}) {
69375
+ const platform2 = opts.platform ?? process.platform;
69376
+ const env2 = opts.env ?? process.env;
69377
+ const exists = opts.exists ?? existsSync2;
69378
+ const override = env2.GG_BASH?.trim();
69379
+ if (override) {
69380
+ return { file: override, args: ["-c", command], isCmdFallback: false };
69381
+ }
69382
+ if (platform2 !== "win32") {
69383
+ return { file: "bash", args: ["-c", command], isCmdFallback: false };
69384
+ }
69385
+ const gitBash = findGitBash(env2, exists);
69386
+ if (gitBash) {
69387
+ return { file: gitBash, args: ["-c", command], isCmdFallback: false };
69388
+ }
69389
+ const comspec = env2.ComSpec ?? env2.COMSPEC ?? "C:\\Windows\\System32\\cmd.exe";
69390
+ return { file: comspec, args: ["/d", "/s", "/c", command], isCmdFallback: true };
69391
+ }
69392
+
69157
69393
  // ../ggcoder/dist/core/process-manager.js
69158
- var BG_DIR = path6.join(os3.homedir(), ".gg", "bg");
69394
+ var BG_DIR = path7.join(os3.homedir(), ".gg", "bg");
69159
69395
  function stopProcessTree(pid, ops = {}) {
69160
69396
  if ((ops.platform ?? process.platform) === "win32") {
69161
69397
  (ops.spawnSync ?? spawnSync)("taskkill", ["/pid", String(pid), "/T", "/F"], {
@@ -69175,9 +69411,10 @@ var ProcessManager = class {
69175
69411
  async start(command, cwd2) {
69176
69412
  await fsp.mkdir(BG_DIR, { recursive: true });
69177
69413
  const id2 = crypto2.randomUUID().slice(0, 8);
69178
- const logFile = path6.join(BG_DIR, `${id2}.log`);
69414
+ const logFile = path7.join(BG_DIR, `${id2}.log`);
69179
69415
  const fd2 = fs6.openSync(logFile, "w");
69180
- const child = spawn2("bash", ["-c", command], {
69416
+ const shell2 = resolveShell(command);
69417
+ const child = spawn2(shell2.file, shell2.args, {
69181
69418
  cwd: cwd2,
69182
69419
  detached: true,
69183
69420
  // stdin is a pipe so callers can drive interactive processes (REPLs,
@@ -69320,7 +69557,7 @@ var ProcessManager = class {
69320
69557
 
69321
69558
  // ../ggcoder/dist/core/lsp/manager.js
69322
69559
  init_esm_shims();
69323
- import path8 from "path";
69560
+ import path9 from "path";
69324
69561
 
69325
69562
  // ../ggcoder/dist/core/logger.js
69326
69563
  init_esm_shims();
@@ -69689,7 +69926,7 @@ Diagnostics in ${relPath} (informational \u2014 may resolve after related edits)
69689
69926
  // ../ggcoder/dist/core/lsp/servers.js
69690
69927
  init_esm_shims();
69691
69928
  import fs7 from "fs";
69692
- import path7 from "path";
69929
+ import path8 from "path";
69693
69930
  import { fileURLToPath } from "url";
69694
69931
  var WINDOWS_SUFFIXES = [".cmd", ".exe", ".bat"];
69695
69932
  function isExecutableFile(candidate) {
@@ -69705,13 +69942,13 @@ function candidateNames(name) {
69705
69942
  return [name];
69706
69943
  return [name, ...WINDOWS_SUFFIXES.map((suffix) => `${name}${suffix}`)];
69707
69944
  }
69708
- var MODULE_DIR = path7.dirname(fileURLToPath(import.meta.url));
69945
+ var MODULE_DIR = path8.dirname(fileURLToPath(import.meta.url));
69709
69946
  function binDirsUpFrom(start) {
69710
69947
  const dirs = [];
69711
69948
  let dir = start;
69712
69949
  for (; ; ) {
69713
- dirs.push(path7.join(dir, "node_modules", ".bin"));
69714
- const parent = path7.dirname(dir);
69950
+ dirs.push(path8.join(dir, "node_modules", ".bin"));
69951
+ const parent = path8.dirname(dir);
69715
69952
  if (parent === dir)
69716
69953
  break;
69717
69954
  dir = parent;
@@ -69723,17 +69960,17 @@ function findExecutable(name, projectRoot) {
69723
69960
  const binDirs = [...binDirsUpFrom(projectRoot), ...binDirsUpFrom(MODULE_DIR)];
69724
69961
  for (const binDir of binDirs) {
69725
69962
  for (const candidate of names) {
69726
- const binPath = path7.join(binDir, candidate);
69963
+ const binPath = path8.join(binDir, candidate);
69727
69964
  if (isExecutableFile(binPath))
69728
69965
  return binPath;
69729
69966
  }
69730
69967
  }
69731
69968
  const pathEnv = process.env.PATH ?? "";
69732
- for (const pathDir of pathEnv.split(path7.delimiter)) {
69969
+ for (const pathDir of pathEnv.split(path8.delimiter)) {
69733
69970
  if (!pathDir)
69734
69971
  continue;
69735
69972
  for (const candidate of names) {
69736
- const binPath = path7.join(pathDir, candidate);
69973
+ const binPath = path8.join(pathDir, candidate);
69737
69974
  if (isExecutableFile(binPath))
69738
69975
  return binPath;
69739
69976
  }
@@ -69743,17 +69980,17 @@ function findExecutable(name, projectRoot) {
69743
69980
  function findInNodeModulesUp(relPath, start) {
69744
69981
  let dir = start;
69745
69982
  for (; ; ) {
69746
- const candidate = path7.join(dir, "node_modules", relPath);
69983
+ const candidate = path8.join(dir, "node_modules", relPath);
69747
69984
  if (fs7.existsSync(candidate))
69748
69985
  return candidate;
69749
- const parent = path7.dirname(dir);
69986
+ const parent = path8.dirname(dir);
69750
69987
  if (parent === dir)
69751
69988
  return null;
69752
69989
  dir = parent;
69753
69990
  }
69754
69991
  }
69755
69992
  function findPackageBinScript(pkgName, binName, start) {
69756
- const pkgJsonPath = findInNodeModulesUp(path7.join(pkgName, "package.json"), start);
69993
+ const pkgJsonPath = findInNodeModulesUp(path8.join(pkgName, "package.json"), start);
69757
69994
  if (!pkgJsonPath)
69758
69995
  return null;
69759
69996
  try {
@@ -69761,7 +69998,7 @@ function findPackageBinScript(pkgName, binName, start) {
69761
69998
  const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.[binName];
69762
69999
  if (!bin)
69763
70000
  return null;
69764
- const script = path7.join(path7.dirname(pkgJsonPath), bin);
70001
+ const script = path8.join(path8.dirname(pkgJsonPath), bin);
69765
70002
  return fs7.existsSync(script) ? script : null;
69766
70003
  } catch {
69767
70004
  return null;
@@ -69774,7 +70011,7 @@ function resolveNodeServer(pkgName, binName, projectRoot, args) {
69774
70011
  const bin = findExecutable(binName, projectRoot);
69775
70012
  return bin ? { command: bin, args } : null;
69776
70013
  }
69777
- var TSSERVER_REL_PATH = path7.join("typescript", "lib", "tsserver.js");
70014
+ var TSSERVER_REL_PATH = path8.join("typescript", "lib", "tsserver.js");
69778
70015
  function projectTsserverPath(projectRoot) {
69779
70016
  return findInNodeModulesUp(TSSERVER_REL_PATH, projectRoot);
69780
70017
  }
@@ -69864,27 +70101,27 @@ var LSP_SERVER_CATALOG = [
69864
70101
  }
69865
70102
  ];
69866
70103
  function serverForFile(filePath, catalog = LSP_SERVER_CATALOG) {
69867
- const extension = path7.extname(filePath).toLowerCase();
70104
+ const extension = path8.extname(filePath).toLowerCase();
69868
70105
  if (!extension)
69869
70106
  return null;
69870
70107
  return catalog.find((spec) => spec.extensions.includes(extension)) ?? null;
69871
70108
  }
69872
70109
  function findProjectRoot(filePath, markers, ceiling) {
69873
- const fileDir = path7.dirname(path7.resolve(filePath));
69874
- const cap = path7.resolve(ceiling);
69875
- const underCeiling = fileDir === cap || fileDir.startsWith(cap + path7.sep);
70110
+ const fileDir = path8.dirname(path8.resolve(filePath));
70111
+ const cap = path8.resolve(ceiling);
70112
+ const underCeiling = fileDir === cap || fileDir.startsWith(cap + path8.sep);
69876
70113
  let dir = fileDir;
69877
70114
  for (; ; ) {
69878
70115
  for (const marker of markers) {
69879
70116
  try {
69880
- fs7.statSync(path7.join(dir, marker));
70117
+ fs7.statSync(path8.join(dir, marker));
69881
70118
  return dir;
69882
70119
  } catch {
69883
70120
  }
69884
70121
  }
69885
70122
  if (underCeiling && dir === cap)
69886
70123
  break;
69887
- const parent = path7.dirname(dir);
70124
+ const parent = path8.dirname(dir);
69888
70125
  if (parent === dir)
69889
70126
  break;
69890
70127
  dir = parent;
@@ -69955,12 +70192,12 @@ var LspManager = class {
69955
70192
  log("WARN", "lsp", `${spec.id} server died`, { root });
69956
70193
  return "";
69957
70194
  }
69958
- const uri = client.syncDocument(path8.resolve(this.cwd, filePath), content);
70195
+ const uri = client.syncDocument(path9.resolve(this.cwd, filePath), content);
69959
70196
  const diagnostics = await client.collectDiagnostics(uri, budgetMs);
69960
70197
  this.warmKeys.add(key);
69961
70198
  if (diagnostics === null)
69962
70199
  return "";
69963
- const relPath = path8.relative(this.cwd, path8.resolve(this.cwd, filePath));
70200
+ const relPath = path9.relative(this.cwd, path9.resolve(this.cwd, filePath));
69964
70201
  return formatDiagnostics(relPath, diagnostics);
69965
70202
  }
69966
70203
  ensureClient(key, spec, root) {
@@ -70011,18 +70248,18 @@ function withBudget(work, budgetMs) {
70011
70248
  // ../ggcoder/dist/tools/read.js
70012
70249
  init_esm_shims();
70013
70250
  import fs12 from "fs/promises";
70014
- import path12 from "path";
70251
+ import path13 from "path";
70015
70252
 
70016
70253
  // ../ggcoder/dist/tools/path-utils.js
70017
70254
  init_esm_shims();
70018
70255
  import fs8 from "fs/promises";
70019
- import path9 from "path";
70256
+ import path10 from "path";
70020
70257
  import os4 from "os";
70021
70258
  function resolvePath(cwd2, filePath) {
70022
70259
  if (filePath.startsWith("~")) {
70023
- filePath = path9.join(os4.homedir(), filePath.slice(1));
70260
+ filePath = path10.join(os4.homedir(), filePath.slice(1));
70024
70261
  }
70025
- return path9.resolve(cwd2, filePath);
70262
+ return path10.resolve(cwd2, filePath);
70026
70263
  }
70027
70264
  async function rejectSymlink(resolved) {
70028
70265
  try {
@@ -70089,9 +70326,9 @@ function truncateTail(content, maxLines = MAX_LINES, maxBytes = MAX_BYTES2) {
70089
70326
  init_esm_shims();
70090
70327
  import fs9 from "fs/promises";
70091
70328
  import os5 from "os";
70092
- import path10 from "path";
70329
+ import path11 from "path";
70093
70330
  async function writeOverflow(content, prefix) {
70094
- const filePath = path10.join(os5.tmpdir(), `gg-${prefix}-${Date.now()}.txt`);
70331
+ const filePath = path11.join(os5.tmpdir(), `gg-${prefix}-${Date.now()}.txt`);
70095
70332
  await fs9.writeFile(filePath, content, { encoding: "utf-8", mode: 384 });
70096
70333
  return filePath;
70097
70334
  }
@@ -70102,18 +70339,18 @@ import fs10 from "fs/promises";
70102
70339
  import { spawn as spawn4 } from "child_process";
70103
70340
  import { createReadStream } from "fs";
70104
70341
  var localOperations = {
70105
- readFile: (path46) => fs10.readFile(path46, "utf-8"),
70106
- writeFile: async (path46, content) => {
70342
+ readFile: (path48) => fs10.readFile(path48, "utf-8"),
70343
+ writeFile: async (path48, content) => {
70107
70344
  const { dirname: dirname3 } = await import("path");
70108
- await fs10.mkdir(dirname3(path46), { recursive: true });
70109
- await fs10.writeFile(path46, content, "utf-8");
70345
+ await fs10.mkdir(dirname3(path48), { recursive: true });
70346
+ await fs10.writeFile(path48, content, "utf-8");
70110
70347
  },
70111
- stat: (path46) => fs10.stat(path46),
70112
- lstat: (path46) => fs10.lstat(path46),
70113
- readdir: (path46, options) => fs10.readdir(path46, options),
70114
- mkdir: (path46) => fs10.mkdir(path46, { recursive: true }).then(() => {
70348
+ stat: (path48) => fs10.stat(path48),
70349
+ lstat: (path48) => fs10.lstat(path48),
70350
+ readdir: (path48, options) => fs10.readdir(path48, options),
70351
+ mkdir: (path48) => fs10.mkdir(path48, { recursive: true }).then(() => {
70115
70352
  }),
70116
- createReadStream: (path46, encoding) => createReadStream(path46, { encoding }),
70353
+ createReadStream: (path48, encoding) => createReadStream(path48, { encoding }),
70117
70354
  spawn: (command, args, options) => spawn4(command, args, {
70118
70355
  cwd: options.cwd,
70119
70356
  env: options.env,
@@ -70159,7 +70396,7 @@ async function assertFresh(tracker, resolvedPath, ops) {
70159
70396
  init_esm_shims();
70160
70397
  import fs11 from "fs/promises";
70161
70398
  import os6 from "os";
70162
- import path11 from "path";
70399
+ import path12 from "path";
70163
70400
  import { execFile } from "child_process";
70164
70401
  import { promisify } from "util";
70165
70402
  var execFileAsync = promisify(execFile);
@@ -70207,7 +70444,7 @@ async function compressVideoToFit(inputPath, targetBytes = COMPRESS_TARGET_BYTES
70207
70444
  }
70208
70445
  const totalKbps = Math.floor(targetBytes * 8 / durationSec / 1e3 * 0.9);
70209
70446
  const videoKbps = Math.max(COMPRESS_MIN_VIDEO_KBPS, totalKbps - COMPRESS_AUDIO_KBPS);
70210
- const outPath = path11.join(os6.tmpdir(), `ggcoder-compressed-${Date.now()}.mp4`);
70447
+ const outPath = path12.join(os6.tmpdir(), `ggcoder-compressed-${Date.now()}.mp4`);
70211
70448
  try {
70212
70449
  await execFileAsync("ffmpeg", [
70213
70450
  "-y",
@@ -70279,7 +70516,7 @@ var VIDEO_MEDIA_TYPES = {
70279
70516
  };
70280
70517
  var MEDIA_TYPES = IMAGE_MEDIA_TYPES;
70281
70518
  function isAttachablePath(filePath) {
70282
- const ext = path11.extname(filePath).toLowerCase();
70519
+ const ext = path12.extname(filePath).toLowerCase();
70283
70520
  return ATTACHABLE_EXTENSIONS.has(ext);
70284
70521
  }
70285
70522
  function resolvePath2(filePath, cwd2) {
@@ -70292,9 +70529,9 @@ function resolvePath2(filePath, cwd2) {
70292
70529
  }
70293
70530
  resolved = resolved.replace(/\\(.)/g, "$1");
70294
70531
  if (resolved.startsWith("~/")) {
70295
- resolved = path11.join(process.env.HOME ?? "/", resolved.slice(2));
70296
- } else if (!path11.isAbsolute(resolved)) {
70297
- resolved = path11.join(cwd2, resolved);
70532
+ resolved = path12.join(process.env.HOME ?? "/", resolved.slice(2));
70533
+ } else if (!path12.isAbsolute(resolved)) {
70534
+ resolved = path12.join(cwd2, resolved);
70298
70535
  }
70299
70536
  return resolved;
70300
70537
  }
@@ -70407,8 +70644,8 @@ async function downscaleForPreview(buffer) {
70407
70644
  }
70408
70645
  }
70409
70646
  async function readImageFile(filePath) {
70410
- const ext = path11.extname(filePath).toLowerCase();
70411
- const fileName = path11.basename(filePath);
70647
+ const ext = path12.extname(filePath).toLowerCase();
70648
+ const fileName = path12.basename(filePath);
70412
70649
  if (VIDEO_EXTENSIONS.has(ext)) {
70413
70650
  try {
70414
70651
  const mediaType = VIDEO_MEDIA_TYPES[ext] ?? "video/mp4";
@@ -70573,7 +70810,7 @@ function createReadTool(cwd2, readFiles, ops = localOperations, onFileRead, vide
70573
70810
  async execute({ file_path, offset, limit: limit2 }, context) {
70574
70811
  const resolved = resolvePath(cwd2, file_path);
70575
70812
  await rejectSymlink(resolved);
70576
- const ext = path12.extname(resolved).toLowerCase();
70813
+ const ext = path13.extname(resolved).toLowerCase();
70577
70814
  if (IMAGE_EXTENSIONS.has(ext)) {
70578
70815
  try {
70579
70816
  const rawBuffer = await fs12.readFile(resolved);
@@ -70700,7 +70937,7 @@ init_esm_shims();
70700
70937
  // ../ggcoder/dist/tools/write.js
70701
70938
  init_esm_shims();
70702
70939
  import fs13 from "fs/promises";
70703
- import path13 from "path";
70940
+ import path14 from "path";
70704
70941
 
70705
70942
  // ../ggcoder/dist/core/runtime-mode.js
70706
70943
  init_esm_shims();
@@ -70734,9 +70971,9 @@ function createWriteTool(cwd2, readFiles, ops = localOperations, planModeRefOrOn
70734
70971
  const resolved = resolvePath(cwd2, file_path);
70735
70972
  await rejectSymlink(resolved);
70736
70973
  if (isPlanModeActive(planModeRef)) {
70737
- const plansDir = path13.join(cwd2, ".gg", "plans");
70738
- const relative = path13.relative(plansDir, resolved);
70739
- if (relative.startsWith("..") || path13.isAbsolute(relative)) {
70974
+ const plansDir = path14.join(cwd2, ".gg", "plans");
70975
+ const relative = path14.relative(plansDir, resolved);
70976
+ if (relative.startsWith("..") || path14.isAbsolute(relative)) {
70740
70977
  return `Error: write is restricted in plan mode. You can only write to .gg/plans/. Got: ${file_path}`;
70741
70978
  }
70742
70979
  await fs13.mkdir(plansDir, { recursive: true });
@@ -70766,7 +71003,7 @@ function createWriteTool(cwd2, readFiles, ops = localOperations, planModeRefOrOn
70766
71003
 
70767
71004
  // ../ggcoder/dist/tools/edit.js
70768
71005
  init_esm_shims();
70769
- import path14 from "path";
71006
+ import path15 from "path";
70770
71007
 
70771
71008
  // ../ggcoder/dist/tools/edit-diff.js
70772
71009
  init_esm_shims();
@@ -70875,16 +71112,16 @@ var Diff = class {
70875
71112
  }
70876
71113
  }
70877
71114
  }
70878
- addToPath(path46, added, removed, oldPosInc, options) {
70879
- const last = path46.lastComponent;
71115
+ addToPath(path48, added, removed, oldPosInc, options) {
71116
+ const last = path48.lastComponent;
70880
71117
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
70881
71118
  return {
70882
- oldPos: path46.oldPos + oldPosInc,
71119
+ oldPos: path48.oldPos + oldPosInc,
70883
71120
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
70884
71121
  };
70885
71122
  } else {
70886
71123
  return {
70887
- oldPos: path46.oldPos + oldPosInc,
71124
+ oldPos: path48.oldPos + oldPosInc,
70888
71125
  lastComponent: { count: 1, added, removed, previousComponent: last }
70889
71126
  };
70890
71127
  }
@@ -71450,16 +71687,22 @@ function fuzzyFindText(content, oldText) {
71450
71687
  }
71451
71688
  const oldLines = oldText.split("\n");
71452
71689
  const contentLines = content.split("\n");
71453
- const normalizedOldLines = oldLines.map(normalizeForFuzzyMatch);
71690
+ const normalizedOldJoined = oldLines.map(normalizeForFuzzyMatch).join("\n");
71691
+ const normalizedCache = new Array(contentLines.length);
71454
71692
  for (let startLine = 0; startLine + oldLines.length <= contentLines.length; startLine++) {
71455
- const candidateLines = contentLines.slice(startLine, startLine + oldLines.length);
71456
- const normalizedCandidate = candidateLines.map(normalizeForFuzzyMatch);
71457
- if (normalizedCandidate.join("\n") !== normalizedOldLines.join("\n"))
71693
+ let normalizedCandidate = "";
71694
+ for (let j = startLine; j < startLine + oldLines.length; j++) {
71695
+ normalizedCandidate += normalizedCache[j] ??= normalizeForFuzzyMatch(contentLines[j]);
71696
+ if (j < startLine + oldLines.length - 1)
71697
+ normalizedCandidate += "\n";
71698
+ }
71699
+ if (normalizedCandidate !== normalizedOldJoined)
71458
71700
  continue;
71459
71701
  let actualIndex = 0;
71460
71702
  for (let i = 0; i < startLine; i++) {
71461
71703
  actualIndex += contentLines[i].length + 1;
71462
71704
  }
71705
+ const candidateLines = contentLines.slice(startLine, startLine + oldLines.length);
71463
71706
  return {
71464
71707
  found: true,
71465
71708
  index: actualIndex,
@@ -71490,8 +71733,14 @@ function countOccurrences(content, oldText) {
71490
71733
  }
71491
71734
  const oldLines = oldText.split("\n");
71492
71735
  const contentLines = content.split("\n");
71736
+ const normalizedCache = new Array(contentLines.length);
71493
71737
  for (let startLine = 0; startLine + oldLines.length <= contentLines.length; startLine++) {
71494
- const normalizedCandidate = contentLines.slice(startLine, startLine + oldLines.length).map(normalizeForFuzzyMatch).join("\n");
71738
+ let normalizedCandidate = "";
71739
+ for (let j = startLine; j < startLine + oldLines.length; j++) {
71740
+ normalizedCandidate += normalizedCache[j] ??= normalizeForFuzzyMatch(contentLines[j]);
71741
+ if (j < startLine + oldLines.length - 1)
71742
+ normalizedCandidate += "\n";
71743
+ }
71495
71744
  if (normalizedCandidate === normalizedOld)
71496
71745
  count++;
71497
71746
  }
@@ -71651,7 +71900,7 @@ function createEditTool(cwd2, readFiles, ops = localOperations, planModeRefOrOnF
71651
71900
  const hasCRLF = original.includes("\r\n");
71652
71901
  const originalNormalized = hasCRLF ? original.replace(/\r\n/g, "\n") : original;
71653
71902
  let working = originalNormalized;
71654
- const fileName = path14.basename(resolved);
71903
+ const fileName = path15.basename(resolved);
71655
71904
  const outcomes = new Array(edits.length);
71656
71905
  for (let i = 0; i < edits.length; i++) {
71657
71906
  const { old_text, new_text, replace_all } = edits[i];
@@ -71753,7 +72002,7 @@ ${f.closestSnippet}`;
71753
72002
  ` : "";
71754
72003
  throw new Error(header + formatFailures());
71755
72004
  }
71756
- const relPath = path14.relative(cwd2, resolved);
72005
+ const relPath = path15.relative(cwd2, resolved);
71757
72006
  const diff3 = generateDiff(originalNormalized, working, relPath);
71758
72007
  const changed = working !== originalNormalized;
71759
72008
  let diagnosticsNote = "";
@@ -71950,7 +72199,8 @@ Use task_output with id="${result.id}" to read output, task_send to type input/a
71950
72199
  }
71951
72200
  const effectiveTimeout = timeoutMs ?? DEFAULT_TIMEOUT;
71952
72201
  return new Promise((resolve2) => {
71953
- const child = ops.spawn("bash", ["-c", command], {
72202
+ const shell2 = resolveShell(command);
72203
+ const child = ops.spawn(shell2.file, shell2.args, {
71954
72204
  cwd: cwd2,
71955
72205
  detached: true,
71956
72206
  stdio: ["ignore", "pipe", "pipe"],
@@ -72008,6 +72258,9 @@ ${output}`;
72008
72258
  output = `[Truncated: showing last ${result.keptLines} of ${result.totalLines} lines.${overflowNotice}]
72009
72259
  ${output}`;
72010
72260
  }
72261
+ if (shell2.isCmdFallback) {
72262
+ output = "[Ran under Windows cmd.exe \u2014 bash is unavailable. Use cmd syntax (dir, findstr, type); POSIX commands and quoting will fail. Install Git for Windows to get bash.]\n" + output;
72263
+ }
72011
72264
  const exitCode = timedOut ? `TIMEOUT (${effectiveTimeout}ms)` : killed ? "KILLED" : String(code ?? 1);
72012
72265
  resolve2(`Exit code: ${exitCode}
72013
72266
  ${output}`);
@@ -72026,7 +72279,7 @@ Failed to spawn: ${err.message}`);
72026
72279
  // ../ggcoder/dist/tools/find.js
72027
72280
  init_esm_shims();
72028
72281
  import fs14 from "fs/promises";
72029
- import path15 from "path";
72282
+ import path16 from "path";
72030
72283
  var FindParams = external_exports.object({
72031
72284
  pattern: external_exports.string().describe("Glob pattern to match files (e.g. '**/*.ts', 'src/**/*.tsx')"),
72032
72285
  path: external_exports.string().optional().describe("Directory to search in (defaults to cwd)")
@@ -72072,7 +72325,7 @@ ${filtered.length} file(s) found`;
72072
72325
  }
72073
72326
  async function loadGitignore(dir) {
72074
72327
  try {
72075
- const content = await fs14.readFile(path15.join(dir, ".gitignore"), "utf-8");
72328
+ const content = await fs14.readFile(path16.join(dir, ".gitignore"), "utf-8");
72076
72329
  return content.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
72077
72330
  } catch {
72078
72331
  return [];
@@ -72082,7 +72335,7 @@ async function loadGitignore(dir) {
72082
72335
  // ../ggcoder/dist/tools/grep.js
72083
72336
  init_esm_shims();
72084
72337
  import readline from "readline";
72085
- import path16 from "path";
72338
+ import path17 from "path";
72086
72339
  var GrepParams = external_exports.object({
72087
72340
  pattern: external_exports.string().describe("Search pattern (regex supported)"),
72088
72341
  path: external_exports.string().optional().describe("File or directory to search (defaults to cwd)"),
@@ -72138,10 +72391,10 @@ function createGrepTool(cwd2, ops = localOperations) {
72138
72391
  }
72139
72392
  scannedCandidates += 1;
72140
72393
  const entry = typeof item === "string" ? item : item.path;
72141
- const ext = path16.extname(entry).toLowerCase();
72394
+ const ext = path17.extname(entry).toLowerCase();
72142
72395
  if (BINARY_EXTENSIONS.has(ext))
72143
72396
  continue;
72144
- const filePath = path16.join(dir, entry);
72397
+ const filePath = path17.join(dir, entry);
72145
72398
  const fileResults = await searchFile(filePath, regex2, cwd2, maxResults - results.length, ops);
72146
72399
  results.push(...fileResults);
72147
72400
  }
@@ -72151,7 +72404,7 @@ function createGrepTool(cwd2, ops = localOperations) {
72151
72404
  }
72152
72405
  async function searchFile(filePath, regex2, cwd2, maxResults, ops) {
72153
72406
  const results = [];
72154
- const relPath = path16.relative(cwd2, filePath);
72407
+ const relPath = path17.relative(cwd2, filePath);
72155
72408
  try {
72156
72409
  const fileStat = await ops.stat(filePath);
72157
72410
  if (fileStat.size > MAX_FILE_SIZE)
@@ -72213,7 +72466,7 @@ ${results.length} match(es) found`;
72213
72466
 
72214
72467
  // ../ggcoder/dist/tools/ls.js
72215
72468
  init_esm_shims();
72216
- import path17 from "path";
72469
+ import path18 from "path";
72217
72470
  var LsParams = external_exports.object({
72218
72471
  path: external_exports.string().optional().describe("Directory path (defaults to cwd)"),
72219
72472
  all: external_exports.boolean().optional().describe("Show hidden files (default: false)")
@@ -72233,16 +72486,17 @@ function createLsTool(cwd2, ops = localOperations) {
72233
72486
  for (const dir of dirs) {
72234
72487
  lines.push(`d - ${dir.name}/`);
72235
72488
  }
72236
- for (const file2 of files) {
72489
+ const fileLines = await Promise.all(files.map(async (file2) => {
72237
72490
  try {
72238
- const stat = await ops.stat(path17.join(resolved, file2.name));
72491
+ const stat = await ops.stat(path18.join(resolved, file2.name));
72239
72492
  const size = formatSize(stat.size);
72240
72493
  const type2 = file2.isSymbolicLink() ? "l" : "f";
72241
- lines.push(`${type2} ${size.padStart(8)} ${file2.name}`);
72494
+ return `${type2} ${size.padStart(8)} ${file2.name}`;
72242
72495
  } catch {
72243
- lines.push(`? - ${file2.name}`);
72496
+ return `? - ${file2.name}`;
72244
72497
  }
72245
- }
72498
+ }));
72499
+ lines.push(...fileLines);
72246
72500
  if (lines.length === 0)
72247
72501
  return "Empty directory.";
72248
72502
  return lines.join("\n");
@@ -72263,7 +72517,7 @@ function formatSize(bytes) {
72263
72517
  init_esm_shims();
72264
72518
  import { spawn as spawn5 } from "child_process";
72265
72519
  import { createInterface } from "readline";
72266
- import { existsSync as existsSync2 } from "fs";
72520
+ import { existsSync as existsSync3 } from "fs";
72267
72521
  import { fileURLToPath as fileURLToPath2 } from "url";
72268
72522
  var SUB_AGENT_MAX_TURNS = 10;
72269
72523
  var SUB_AGENT_MAX_OUTPUT_CHARS = 1e5;
@@ -72272,7 +72526,7 @@ var SUB_AGENT_MAX_STDERR_CHARS = 1e4;
72272
72526
  var SUB_AGENT_TIMEOUT_MS = 10 * 60 * 1e3;
72273
72527
  function resolveCliEntry() {
72274
72528
  const cliPath = fileURLToPath2(new URL("../cli.js", import.meta.url));
72275
- return existsSync2(cliPath) ? cliPath : process.argv[1];
72529
+ return existsSync3(cliPath) ? cliPath : process.argv[1];
72276
72530
  }
72277
72531
  var SubAgentParams = external_exports.object({
72278
72532
  task: external_exports.string().describe("The task to delegate to the sub-agent"),
@@ -73721,7 +73975,7 @@ function createWebSearchTool() {
73721
73975
  // ../ggcoder/dist/tools/source-path.js
73722
73976
  init_esm_shims();
73723
73977
  import { spawn as spawn6 } from "child_process";
73724
- import path18 from "path";
73978
+ import path19 from "path";
73725
73979
  import { fileURLToPath as fileURLToPath3 } from "url";
73726
73980
  var SOURCE_PATH_TIMEOUT_MS = 12e4;
73727
73981
  var MAX_STDERR_CHARS = 1e4;
@@ -73821,8 +74075,8 @@ function getBundledOpenSrcBinPath() {
73821
74075
  const override = process.env[OPENSRC_BIN_ENV]?.trim();
73822
74076
  if (override)
73823
74077
  return override;
73824
- const currentDir = path18.dirname(fileURLToPath3(import.meta.url));
73825
- return path18.resolve(currentDir, "../../node_modules/opensrc/bin/opensrc.js");
74078
+ const currentDir = path19.dirname(fileURLToPath3(import.meta.url));
74079
+ return path19.resolve(currentDir, "../../node_modules/opensrc/bin/opensrc.js");
73826
74080
  }
73827
74081
  function getOpenSrcEnv() {
73828
74082
  return {
@@ -74070,7 +74324,7 @@ ${list}`;
74070
74324
 
74071
74325
  // ../ggcoder/dist/tools/screenshot.js
74072
74326
  init_esm_shims();
74073
- import path19 from "path";
74327
+ import path20 from "path";
74074
74328
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
74075
74329
  var INSTALL_HINT = "Browser engine not installed. Add the optional dependency and download Chromium:\n pnpm add -w playwright && npx playwright install chromium\nThen retry the screenshot.";
74076
74330
  var ActionInput = external_exports.object({
@@ -74108,7 +74362,7 @@ function isBrowserBinaryMissing(err) {
74108
74362
  }
74109
74363
  function defaultOutPath(cwd2) {
74110
74364
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
74111
- return path19.join(cwd2, ".gg", "screenshots", `${stamp}.png`);
74365
+ return path20.join(cwd2, ".gg", "screenshots", `${stamp}.png`);
74112
74366
  }
74113
74367
  async function runActions(page, actions) {
74114
74368
  for (const action of actions ?? []) {
@@ -74159,7 +74413,7 @@ function createScreenshotTool(cwd2) {
74159
74413
  await runActions(page, args.actions);
74160
74414
  const raw = await page.screenshot({ fullPage: args.full_page ?? false });
74161
74415
  context.signal.removeEventListener("abort", onAbort);
74162
- await mkdir2(path19.dirname(outPath), { recursive: true });
74416
+ await mkdir2(path20.dirname(outPath), { recursive: true });
74163
74417
  await writeFile2(outPath, raw);
74164
74418
  const { buffer, mediaType } = await shrinkToFit(raw, "image/png");
74165
74419
  const previewBuffer = await downscaleForPreview(buffer);
@@ -74191,6 +74445,215 @@ function createScreenshotTool(cwd2) {
74191
74445
  };
74192
74446
  }
74193
74447
 
74448
+ // ../ggcoder/dist/tools/generate-image.js
74449
+ init_esm_shims();
74450
+ import path21 from "path";
74451
+ import { mkdir as mkdir3, writeFile as writeFile3, readFile as readFile2 } from "fs/promises";
74452
+ var CODEX_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
74453
+ var IMAGE_GEN_MODEL = "gpt-5.5";
74454
+ var GenerateImageParams = external_exports.object({
74455
+ prompt: external_exports.string().describe("Text description of the image to generate or the edit to apply"),
74456
+ image: external_exports.string().optional().describe("Path to an existing image file to edit (use the path returned by a previous generate_image call, or a user-attached image path). When omitted, a new image is generated from scratch."),
74457
+ size: external_exports.string().optional().describe("Output resolution. gpt-image-2 accepts any size where both edges are multiples of 16px, max edge \u22643840px, long:short ratio \u22643:1, total pixels 655,360\u20138,294,400. Popular: 1024x1024, 1536x1024, 1024x1536, 2048x2048. Default: auto."),
74458
+ quality: external_exports.enum(["low", "medium", "high", "auto"]).optional().describe("Rendering quality. Use 'low' for fast drafts, 'high' for final assets. Default: auto."),
74459
+ n: external_exports.number().int().min(1).max(4).optional().describe("Number of images to generate (1\u20134, default 1)"),
74460
+ out_path: external_exports.string().optional().describe("Where to save the generated image (relative to cwd or absolute). Defaults to .gg/generated/<timestamp>.png"),
74461
+ output_format: external_exports.enum(["png", "jpeg", "webp"]).optional().describe("Output file format (default png)"),
74462
+ background: external_exports.enum(["opaque", "auto"]).optional().describe("Background type (default auto; gpt-image-2 does not support transparent)")
74463
+ });
74464
+ function defaultOutPath2(cwd2, format) {
74465
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
74466
+ const ext = format === "png" ? "png" : format === "jpeg" ? "jpg" : "webp";
74467
+ return path21.join(cwd2, ".gg", "generated", `${stamp}.${ext}`);
74468
+ }
74469
+ function mediaTypeFor(format) {
74470
+ if (format === "jpeg")
74471
+ return "image/jpeg";
74472
+ if (format === "webp")
74473
+ return "image/webp";
74474
+ return "image/png";
74475
+ }
74476
+ function createGenerateImageTool(cwd2, auth2) {
74477
+ return {
74478
+ name: "generate_image",
74479
+ description: "Generate or edit images using OpenAI's gpt-image-2 model. Works even when a different chat provider is active \u2014 only requires OpenAI to be connected. Only use this tool when the user explicitly asks to create, generate, or edit an image. Pass `image` with a file path to edit an existing image (e.g. a previously generated one or a user attachment). Use `out_path` to save to a specific location (defaults to .gg/generated/).",
74480
+ parameters: GenerateImageParams,
74481
+ async execute(args, context) {
74482
+ if (context.signal.aborted)
74483
+ return "Image generation aborted before start.";
74484
+ let token;
74485
+ let accountId;
74486
+ try {
74487
+ const creds = await auth2.resolveCredentials("openai");
74488
+ token = creds.accessToken;
74489
+ accountId = creds.accountId;
74490
+ } catch {
74491
+ return "OpenAI is not connected. The user needs to connect their OpenAI account to use image generation.";
74492
+ }
74493
+ const outputFormat = args.output_format ?? "png";
74494
+ const mediaType = mediaTypeFor(outputFormat);
74495
+ const outPath = args.out_path ? resolvePath(cwd2, args.out_path) : defaultOutPath2(cwd2, outputFormat);
74496
+ try {
74497
+ const imageTool = {
74498
+ type: "image_generation",
74499
+ output_format: outputFormat
74500
+ };
74501
+ if (args.size)
74502
+ imageTool.size = args.size;
74503
+ if (args.quality)
74504
+ imageTool.quality = args.quality;
74505
+ if (args.n)
74506
+ imageTool.n = args.n;
74507
+ if (args.background)
74508
+ imageTool.background = args.background;
74509
+ const inputContent = [
74510
+ { type: "input_text", text: args.prompt }
74511
+ ];
74512
+ if (args.image) {
74513
+ const imagePath = resolvePath(cwd2, args.image);
74514
+ let fileBuffer;
74515
+ try {
74516
+ fileBuffer = await readFile2(imagePath);
74517
+ } catch {
74518
+ return `Could not read the image at ${args.image}. Check the path is correct.`;
74519
+ }
74520
+ const refMediaType = imagePath.toLowerCase().endsWith(".jpg") || imagePath.toLowerCase().endsWith(".jpeg") ? "image/jpeg" : imagePath.toLowerCase().endsWith(".webp") ? "image/webp" : "image/png";
74521
+ inputContent.push({
74522
+ type: "input_image",
74523
+ image_url: `data:${refMediaType};base64,${fileBuffer.toString("base64")}`
74524
+ });
74525
+ imageTool.action = "edit";
74526
+ } else {
74527
+ imageTool.action = "generate";
74528
+ }
74529
+ const imageBuffers = await callImageGeneration(inputContent, imageTool, token, accountId, context.signal);
74530
+ if (imageBuffers.length === 0) {
74531
+ return "Image generation returned no results. The prompt may have been blocked by content moderation.";
74532
+ }
74533
+ const savedPaths = [];
74534
+ for (let i = 0; i < imageBuffers.length; i++) {
74535
+ const buf = imageBuffers[i];
74536
+ const savePath = imageBuffers.length === 1 ? outPath : insertIndex(outPath, i);
74537
+ await mkdir3(path21.dirname(savePath), { recursive: true });
74538
+ await writeFile3(savePath, buf);
74539
+ savedPaths.push(savePath);
74540
+ }
74541
+ const primary = imageBuffers[0];
74542
+ const primaryPath = savedPaths[0];
74543
+ const { buffer: shrunk, mediaType: detectedType } = await shrinkToFit(primary, mediaType);
74544
+ const previewBuffer = await downscaleForPreview(shrunk);
74545
+ const imagePreviews = [
74546
+ {
74547
+ base64: previewBuffer.toString("base64"),
74548
+ mediaType: detectedType,
74549
+ path: primaryPath
74550
+ }
74551
+ ];
74552
+ for (let i = 1; i < imageBuffers.length; i++) {
74553
+ const extraBuf = imageBuffers[i];
74554
+ const extraPath = savedPaths[i];
74555
+ const extraShrunk = await shrinkToFit(extraBuf, mediaType);
74556
+ const extraPreview = await downscaleForPreview(extraShrunk.buffer);
74557
+ imagePreviews.push({
74558
+ base64: extraPreview.toString("base64"),
74559
+ mediaType: extraShrunk.mediaType,
74560
+ path: extraPath
74561
+ });
74562
+ }
74563
+ const summary = savedPaths.length === 1 ? `Generated image \u2192 ${primaryPath}` : `Generated ${savedPaths.length} images \u2192 ${savedPaths.join(", ")}`;
74564
+ const allContent = [
74565
+ { type: "text", text: summary },
74566
+ {
74567
+ type: "image",
74568
+ mediaType: detectedType,
74569
+ data: shrunk.toString("base64")
74570
+ }
74571
+ ];
74572
+ return {
74573
+ content: allContent,
74574
+ details: { imagePreviews }
74575
+ };
74576
+ } catch (err) {
74577
+ if (context.signal.aborted)
74578
+ return "Image generation aborted.";
74579
+ const reason = err instanceof Error ? err.message : String(err);
74580
+ return `Image generation failed: ${reason}`;
74581
+ }
74582
+ }
74583
+ };
74584
+ }
74585
+ function insertIndex(filePath, index) {
74586
+ const ext = path21.extname(filePath);
74587
+ const base = filePath.slice(0, filePath.length - ext.length);
74588
+ return `${base}_${index}${ext}`;
74589
+ }
74590
+ async function callImageGeneration(inputContent, imageTool, token, accountId, signal) {
74591
+ const body = {
74592
+ model: IMAGE_GEN_MODEL,
74593
+ store: false,
74594
+ stream: true,
74595
+ instructions: "Generate the image the user requested.",
74596
+ input: [{ role: "user", content: inputContent }],
74597
+ tools: [imageTool],
74598
+ tool_choice: "auto",
74599
+ reasoning: { effort: "low" }
74600
+ };
74601
+ const response = await fetch(CODEX_ENDPOINT, {
74602
+ method: "POST",
74603
+ headers: {
74604
+ "Content-Type": "application/json",
74605
+ Authorization: `Bearer ${token}`,
74606
+ ...accountId ? { "chatgpt-account-id": accountId } : {},
74607
+ originator: "ggcoder"
74608
+ },
74609
+ body: JSON.stringify(body),
74610
+ signal
74611
+ });
74612
+ if (!response.ok) {
74613
+ const text = await response.text();
74614
+ let detail = text;
74615
+ try {
74616
+ const parsed = JSON.parse(text);
74617
+ if (parsed.detail)
74618
+ detail = parsed.detail;
74619
+ else if (parsed.error?.message)
74620
+ detail = parsed.error.message;
74621
+ } catch {
74622
+ }
74623
+ throw new Error(`OpenAI Image API (${response.status}): ${detail}`);
74624
+ }
74625
+ if (!response.body) {
74626
+ throw new Error("OpenAI Image API returned no response body.");
74627
+ }
74628
+ const reader = response.body.getReader();
74629
+ const decoder = new TextDecoder();
74630
+ let buffer = "";
74631
+ const imageBuffers = [];
74632
+ while (true) {
74633
+ const { done, value } = await reader.read();
74634
+ if (done)
74635
+ break;
74636
+ buffer += decoder.decode(value, { stream: true });
74637
+ const lines = buffer.split("\n");
74638
+ buffer = lines.pop() ?? "";
74639
+ for (const line of lines) {
74640
+ if (!line.startsWith("data: "))
74641
+ continue;
74642
+ const data = line.slice(6);
74643
+ if (data === "[DONE]")
74644
+ continue;
74645
+ try {
74646
+ const evt = JSON.parse(data);
74647
+ if (evt.type === "response.output_item.done" && evt.item?.type === "image_generation_call" && evt.item.result) {
74648
+ imageBuffers.push(Buffer.from(evt.item.result, "base64"));
74649
+ }
74650
+ } catch {
74651
+ }
74652
+ }
74653
+ }
74654
+ return imageBuffers;
74655
+ }
74656
+
74194
74657
  // ../ggcoder/dist/tools/enter-plan.js
74195
74658
  init_esm_shims();
74196
74659
  var EnterPlanParams = external_exports.object({
@@ -74212,7 +74675,7 @@ function createEnterPlanTool(onEnterPlan) {
74212
74675
  // ../ggcoder/dist/tools/exit-plan.js
74213
74676
  init_esm_shims();
74214
74677
  import fs15 from "fs/promises";
74215
- import path20 from "path";
74678
+ import path23 from "path";
74216
74679
  var ExitPlanParams = external_exports.object({
74217
74680
  plan_path: external_exports.string().describe("Path to the plan markdown file; must be under .gg/plans/")
74218
74681
  });
@@ -74224,9 +74687,9 @@ function createExitPlanTool(cwd2, onExitPlan) {
74224
74687
  executionMode: "sequential",
74225
74688
  async execute({ plan_path }) {
74226
74689
  const resolved = resolvePath(cwd2, plan_path);
74227
- const plansDir = path20.join(cwd2, ".gg", "plans");
74228
- const relative = path20.relative(plansDir, resolved);
74229
- if (relative.startsWith("..") || path20.isAbsolute(relative)) {
74690
+ const plansDir = path23.join(cwd2, ".gg", "plans");
74691
+ const relative = path23.relative(plansDir, resolved);
74692
+ if (relative.startsWith("..") || path23.isAbsolute(relative)) {
74230
74693
  return `Error: plan_path must be under .gg/plans/. Got: ${plan_path}`;
74231
74694
  }
74232
74695
  try {
@@ -74243,7 +74706,7 @@ function createExitPlanTool(cwd2, onExitPlan) {
74243
74706
  }
74244
74707
 
74245
74708
  // ../ggcoder/dist/tools/index.js
74246
- function createTools(cwd2, opts) {
74709
+ async function createTools(cwd2, opts) {
74247
74710
  const readFiles = /* @__PURE__ */ new Map();
74248
74711
  const processManager = new ProcessManager();
74249
74712
  const ops = opts?.operations ?? localOperations;
@@ -74283,6 +74746,14 @@ function createTools(cwd2, opts) {
74283
74746
  if (opts?.onExitPlan) {
74284
74747
  tools.push(createExitPlanTool(cwd2, opts.onExitPlan));
74285
74748
  }
74749
+ if (opts?.authStorage) {
74750
+ try {
74751
+ if (await opts.authStorage.hasProviderAuth("openai")) {
74752
+ tools.push(createGenerateImageTool(cwd2, opts.authStorage));
74753
+ }
74754
+ } catch {
74755
+ }
74756
+ }
74286
74757
  const rebuildReadTool = (model) => createReadTool(cwd2, readFiles, ops, opts?.onFileRead, getVideoByteLimit(model));
74287
74758
  return { tools, processManager, rebuildReadTool, lspManager };
74288
74759
  }
@@ -74290,18 +74761,18 @@ function createTools(cwd2, opts) {
74290
74761
  // ../ggcoder/dist/system-prompt.js
74291
74762
  init_esm_shims();
74292
74763
  import fs20 from "fs/promises";
74293
- import path26 from "path";
74764
+ import path28 from "path";
74294
74765
 
74295
74766
  // ../ggcoder/dist/core/skills.js
74296
74767
  init_esm_shims();
74297
74768
  import fs16 from "fs/promises";
74298
- import path21 from "path";
74769
+ import path24 from "path";
74299
74770
  async function discoverSkills(options) {
74300
74771
  const skills = [];
74301
74772
  const globalSkills = await loadSkillsFromDir(options.globalSkillsDir, "global");
74302
74773
  skills.push(...globalSkills);
74303
74774
  if (options.projectDir) {
74304
- const projectSkillsDir = path21.join(options.projectDir, ".gg", "skills");
74775
+ const projectSkillsDir = path24.join(options.projectDir, ".gg", "skills");
74305
74776
  const projectSkills = await loadSkillsFromDir(projectSkillsDir, "project");
74306
74777
  skills.push(...projectSkills);
74307
74778
  }
@@ -74316,20 +74787,20 @@ async function loadSkillsFromDir(dir, source2) {
74316
74787
  return skills;
74317
74788
  }
74318
74789
  for (const entry of dirents) {
74319
- const entryPath = path21.join(dir, entry.name);
74790
+ const entryPath = path24.join(dir, entry.name);
74320
74791
  if (entry.isFile() && entry.name.endsWith(".md")) {
74321
74792
  try {
74322
74793
  const content = await fs16.readFile(entryPath, "utf-8");
74323
74794
  const skill = parseSkillFile(content, source2);
74324
74795
  if (!skill.name)
74325
- skill.name = path21.basename(entry.name, ".md");
74796
+ skill.name = path24.basename(entry.name, ".md");
74326
74797
  skills.push(skill);
74327
74798
  } catch {
74328
74799
  }
74329
74800
  continue;
74330
74801
  }
74331
74802
  if (entry.isDirectory()) {
74332
- const skillFile = path21.join(entryPath, "SKILL.md");
74803
+ const skillFile = path24.join(entryPath, "SKILL.md");
74333
74804
  try {
74334
74805
  const content = await fs16.readFile(skillFile, "utf-8");
74335
74806
  const skill = parseSkillFile(content, source2);
@@ -74390,6 +74861,7 @@ var TOOL_PROMPT_HINTS = {
74390
74861
  exit_plan: "Submit a .gg/plans/ markdown plan for user approval and leave plan mode.",
74391
74862
  subagent: "Delegate focused, isolated subtasks (research, parallel exploration).",
74392
74863
  skill: "Invoke a named skill for specialized instructions.",
74864
+ generate_image: "Generate or edit images using OpenAI's gpt-image-2 model. Only use when the user explicitly asks to create or edit an image \u2014 never generate images proactively. Requires OpenAI to be connected. Pass `image` with a file path to edit an existing image. Save with `out_path`.",
74393
74865
  "mcp__kencode-search__referenceSources": "Get curated, categorized reference repos for examples, inspiration, architecture, UI, agents, SaaS, workflows, and domain patterns. Repo-only starting points; fetch docs/source, then verify code with searchCode.",
74394
74866
  "mcp__kencode-search__discoverRepos": "Search GitHub repos live by keyword/language/topic/stars/recency. Use for current/top repos or long-tail discovery; returns metadata, not snippets. Follow with docs/source and searchCode.",
74395
74867
  "mcp__kencode-search__searchCode": "Verify public GitHub code by literal text or RE2 regex; NOT semantic. Put code/import/API tokens in `query`; `path` is a literal file-path substring, not a concept. Start broad/peek, then narrow by repo/path. RE2 multi-line needs `(?s)`."
@@ -74424,6 +74896,7 @@ var DEFAULT_TOOL_NAMES = [
74424
74896
  "exit_plan",
74425
74897
  "subagent",
74426
74898
  "skill",
74899
+ "generate_image",
74427
74900
  "mcp__kencode-search__referenceSources",
74428
74901
  "mcp__kencode-search__discoverRepos",
74429
74902
  "mcp__kencode-search__searchCode"
@@ -74432,12 +74905,12 @@ var DEFAULT_TOOL_NAMES = [
74432
74905
  // ../ggcoder/dist/core/style-packs/index.js
74433
74906
  init_esm_shims();
74434
74907
  import fs18 from "fs";
74435
- import path24 from "path";
74908
+ import path26 from "path";
74436
74909
 
74437
74910
  // ../ggcoder/dist/core/language-detector.js
74438
74911
  init_esm_shims();
74439
74912
  import fs17 from "fs";
74440
- import path23 from "path";
74913
+ import path25 from "path";
74441
74914
  var MARKERS = {
74442
74915
  typescript: { manifests: ["tsconfig.json"], extensions: [".ts", ".tsx", ".mts", ".cts"] },
74443
74916
  // JS is only flagged when there's a package.json AND no tsconfig — pure JS projects.
@@ -74725,7 +75198,7 @@ var PACKS = {
74725
75198
 
74726
75199
  // ../ggcoder/dist/core/style-packs/index.js
74727
75200
  function loadPack(id2, cwd2) {
74728
- const overridePath = path24.join(cwd2, ".gg", "styles", `${id2}.md`);
75201
+ const overridePath = path26.join(cwd2, ".gg", "styles", `${id2}.md`);
74729
75202
  try {
74730
75203
  const stat = fs18.statSync(overridePath);
74731
75204
  if (stat.isFile()) {
@@ -74769,7 +75242,7 @@ Universal rules for agent-written code:
74769
75242
  // ../ggcoder/dist/core/verify-commands.js
74770
75243
  init_esm_shims();
74771
75244
  import fs19 from "fs";
74772
- import path25 from "path";
75245
+ import path27 from "path";
74773
75246
  function detectVerifyCommands(cwd2, active) {
74774
75247
  const cmds = [];
74775
75248
  if (active.has("typescript") || active.has("javascript")) {
@@ -74796,12 +75269,12 @@ function detectVerifyCommands(cwd2, active) {
74796
75269
  const testScript = pick2("test", "test:unit");
74797
75270
  if (testScript)
74798
75271
  cmds.push({ label: "test", command: `${runner} ${testScript}`, language: lang });
74799
- } else if (active.has("typescript") && fileExists2(path25.join(cwd2, "tsconfig.json"))) {
75272
+ } else if (active.has("typescript") && fileExists2(path27.join(cwd2, "tsconfig.json"))) {
74800
75273
  cmds.push({ label: "typecheck", command: "tsc --noEmit", language: "typescript" });
74801
75274
  }
74802
75275
  }
74803
75276
  if (active.has("python")) {
74804
- const pyproject = readFileSafe(path25.join(cwd2, "pyproject.toml"));
75277
+ const pyproject = readFileSafe(path27.join(cwd2, "pyproject.toml"));
74805
75278
  if (pyproject) {
74806
75279
  if (/\[tool\.ruff/.test(pyproject)) {
74807
75280
  cmds.push({ label: "lint", command: "ruff check .", language: "python" });
@@ -74833,10 +75306,10 @@ function detectVerifyCommands(cwd2, active) {
74833
75306
  }
74834
75307
  if (active.has("java") || active.has("kotlin")) {
74835
75308
  const lang = active.has("kotlin") ? "kotlin" : "java";
74836
- if (fileExists2(path25.join(cwd2, "gradlew"))) {
75309
+ if (fileExists2(path27.join(cwd2, "gradlew"))) {
74837
75310
  cmds.push({ label: "build", command: "./gradlew build", language: lang });
74838
75311
  cmds.push({ label: "test", command: "./gradlew test", language: lang });
74839
- } else if (fileExists2(path25.join(cwd2, "pom.xml"))) {
75312
+ } else if (fileExists2(path27.join(cwd2, "pom.xml"))) {
74840
75313
  cmds.push({ label: "verify", command: "mvn verify", language: lang });
74841
75314
  }
74842
75315
  }
@@ -74850,7 +75323,7 @@ function detectVerifyCommands(cwd2, active) {
74850
75323
  cmds.push({ label: "test", command: "dotnet test", language: "csharp" });
74851
75324
  }
74852
75325
  if (active.has("ruby")) {
74853
- if (fileExists2(path25.join(cwd2, "Gemfile"))) {
75326
+ if (fileExists2(path27.join(cwd2, "Gemfile"))) {
74854
75327
  cmds.push({ label: "lint", command: "bundle exec rubocop", language: "ruby" });
74855
75328
  cmds.push({ label: "test", command: "bundle exec rspec", language: "ruby" });
74856
75329
  }
@@ -74860,7 +75333,7 @@ function detectVerifyCommands(cwd2, active) {
74860
75333
  cmds.push({ label: "test", command: "mix test", language: "elixir" });
74861
75334
  }
74862
75335
  if (active.has("php")) {
74863
- if (fileExists2(path25.join(cwd2, "composer.json"))) {
75336
+ if (fileExists2(path27.join(cwd2, "composer.json"))) {
74864
75337
  cmds.push({ label: "test", command: "composer test", language: "php" });
74865
75338
  }
74866
75339
  }
@@ -74892,7 +75365,7 @@ function readFileSafe(p) {
74892
75365
  }
74893
75366
  }
74894
75367
  function readPackageJsonScripts(cwd2) {
74895
- const raw = readFileSafe(path25.join(cwd2, "package.json"));
75368
+ const raw = readFileSafe(path27.join(cwd2, "package.json"));
74896
75369
  if (!raw)
74897
75370
  return null;
74898
75371
  try {
@@ -74903,11 +75376,11 @@ function readPackageJsonScripts(cwd2) {
74903
75376
  }
74904
75377
  }
74905
75378
  function detectNodeRunner(cwd2) {
74906
- if (fileExists2(path25.join(cwd2, "pnpm-lock.yaml")))
75379
+ if (fileExists2(path27.join(cwd2, "pnpm-lock.yaml")))
74907
75380
  return "pnpm";
74908
- if (fileExists2(path25.join(cwd2, "yarn.lock")))
75381
+ if (fileExists2(path27.join(cwd2, "yarn.lock")))
74909
75382
  return "yarn";
74910
- if (fileExists2(path25.join(cwd2, "bun.lockb")))
75383
+ if (fileExists2(path27.join(cwd2, "bun.lockb")))
74911
75384
  return "bun";
74912
75385
  return "npm run";
74913
75386
  }
@@ -75067,17 +75540,17 @@ async function collectProjectContext(cwd2) {
75067
75540
  while (!visited.has(dir)) {
75068
75541
  visited.add(dir);
75069
75542
  for (const name of CONTEXT_FILES) {
75070
- const filePath = path26.join(dir, name);
75543
+ const filePath = path28.join(dir, name);
75071
75544
  try {
75072
75545
  const content = await fs20.readFile(filePath, "utf-8");
75073
- const relPath = path26.relative(cwd2, filePath) || name;
75546
+ const relPath = path28.relative(cwd2, filePath) || name;
75074
75547
  contextParts.push(`### ${relPath}
75075
75548
 
75076
75549
  ${content.trim()}`);
75077
75550
  } catch {
75078
75551
  }
75079
75552
  }
75080
- const parent = path26.dirname(dir);
75553
+ const parent = path28.dirname(dir);
75081
75554
  if (parent === dir)
75082
75555
  break;
75083
75556
  dir = parent;
@@ -75144,10 +75617,10 @@ async function buildSystemPrompt(cwd2, skills, planMode, approvedPlanPath, toolN
75144
75617
  // ../ggcoder/dist/session.js
75145
75618
  init_esm_shims();
75146
75619
  import fs21 from "fs/promises";
75147
- import path27 from "path";
75620
+ import path29 from "path";
75148
75621
  import os7 from "os";
75149
75622
  import crypto4 from "crypto";
75150
- var SESSION_DIR = path27.join(os7.homedir(), ".gg", "sessions");
75623
+ var SESSION_DIR = path29.join(os7.homedir(), ".gg", "sessions");
75151
75624
 
75152
75625
  // ../ggcoder/dist/core/index.js
75153
75626
  init_esm_shims();
@@ -75265,7 +75738,7 @@ import fs23 from "fs/promises";
75265
75738
 
75266
75739
  // ../ggcoder/dist/config.js
75267
75740
  init_esm_shims();
75268
- import path28 from "path";
75741
+ import path30 from "path";
75269
75742
  import fs22 from "fs/promises";
75270
75743
  import fsSync from "fs";
75271
75744
  async function ensureAppDirs() {
@@ -75331,7 +75804,7 @@ Rules:
75331
75804
  `
75332
75805
  };
75333
75806
  for (const [filename, content] of Object.entries(defaults2)) {
75334
- const filePath = path28.join(agentsDir, filename);
75807
+ const filePath = path30.join(agentsDir, filename);
75335
75808
  try {
75336
75809
  await fs22.access(filePath);
75337
75810
  } catch {
@@ -75344,7 +75817,7 @@ async function seedDefaultSkills(skillsDir) {
75344
75817
  "find-skills.md": FIND_SKILLS_MD
75345
75818
  };
75346
75819
  for (const [filename, content] of Object.entries(defaults2)) {
75347
- const filePath = path28.join(skillsDir, filename);
75820
+ const filePath = path30.join(skillsDir, filename);
75348
75821
  try {
75349
75822
  await fs22.access(filePath);
75350
75823
  } catch {
@@ -75471,7 +75944,11 @@ var SettingsSchema = external_exports.object({
75471
75944
  lspDiagnostics: external_exports.boolean().default(true),
75472
75945
  enabledTools: external_exports.array(external_exports.string()).optional(),
75473
75946
  /** Delete session transcripts older than this many days at startup. 0 disables pruning. */
75474
- sessionRetentionDays: external_exports.number().int().min(0).default(30)
75947
+ sessionRetentionDays: external_exports.number().int().min(0).default(30),
75948
+ /** Speed optimization profile.
75949
+ * - "baseline": 5-min cache TTL, no pre-warm
75950
+ * - "optimized": 1-h cache TTL, cache pre-warming on first prompt (default) */
75951
+ speedProfile: external_exports.enum(["baseline", "optimized"]).default("optimized")
75475
75952
  });
75476
75953
  var DEFAULT_SETTINGS = {
75477
75954
  autoCompact: true,
@@ -75483,7 +75960,8 @@ var DEFAULT_SETTINGS = {
75483
75960
  showTokenUsage: true,
75484
75961
  idealReviewEnabled: true,
75485
75962
  lspDiagnostics: true,
75486
- sessionRetentionDays: 30
75963
+ sessionRetentionDays: 30,
75964
+ speedProfile: "optimized"
75487
75965
  };
75488
75966
  var SettingsManager = class {
75489
75967
  settings = { ...DEFAULT_SETTINGS };
@@ -75524,7 +76002,7 @@ init_esm_shims();
75524
76002
  import fs24 from "fs/promises";
75525
76003
  import { createReadStream as createReadStream2 } from "fs";
75526
76004
  import { createInterface as createInterface2 } from "readline";
75527
- import path29 from "path";
76005
+ import path31 from "path";
75528
76006
  import crypto6 from "crypto";
75529
76007
  var DISPLAY_ITEM_CUSTOM_KIND = "display_item";
75530
76008
  function isCompletedItemLike(value) {
@@ -75559,7 +76037,7 @@ var SessionManager = class _SessionManager {
75559
76037
  this.onPersistError?.(err);
75560
76038
  }
75561
76039
  dirForCwd(cwd2) {
75562
- return path29.join(this.sessionsDir, encodeCwd(cwd2));
76040
+ return path31.join(this.sessionsDir, encodeCwd(cwd2));
75563
76041
  }
75564
76042
  async create(cwd2, provider, model) {
75565
76043
  const id2 = crypto6.randomUUID();
@@ -75567,7 +76045,7 @@ var SessionManager = class _SessionManager {
75567
76045
  const dir = this.dirForCwd(cwd2);
75568
76046
  await fs24.mkdir(dir, { recursive: true });
75569
76047
  const fileName = `${timestamp.replace(/[:.]/g, "-")}_${id2.slice(0, 8)}.jsonl`;
75570
- const filePath = path29.join(dir, fileName);
76048
+ const filePath = path31.join(dir, fileName);
75571
76049
  const header = {
75572
76050
  type: "session",
75573
76051
  version: 2,
@@ -75639,7 +76117,7 @@ var SessionManager = class _SessionManager {
75639
76117
  for (const file2 of files) {
75640
76118
  if (!file2.endsWith(".jsonl"))
75641
76119
  continue;
75642
- const filePath = path29.join(dir, file2);
76120
+ const filePath = path31.join(dir, file2);
75643
76121
  try {
75644
76122
  const rl = createInterface2({
75645
76123
  input: createReadStream2(filePath, { encoding: "utf-8" }),
@@ -75702,7 +76180,7 @@ var SessionManager = class _SessionManager {
75702
76180
  if (options.maxAgeDays <= 0)
75703
76181
  return result;
75704
76182
  const cutoffMs = Date.now() - options.maxAgeDays * 864e5;
75705
- const keep = new Set((options.keepPaths ?? []).map((p) => path29.resolve(p)));
76183
+ const keep = new Set((options.keepPaths ?? []).map((p) => path31.resolve(p)));
75706
76184
  let cwdDirs;
75707
76185
  try {
75708
76186
  cwdDirs = await fs24.readdir(this.sessionsDir);
@@ -75710,7 +76188,7 @@ var SessionManager = class _SessionManager {
75710
76188
  return result;
75711
76189
  }
75712
76190
  for (const dirName of cwdDirs) {
75713
- const dir = path29.join(this.sessionsDir, dirName);
76191
+ const dir = path31.join(this.sessionsDir, dirName);
75714
76192
  let files;
75715
76193
  try {
75716
76194
  const stat = await fs24.stat(dir);
@@ -75724,8 +76202,8 @@ var SessionManager = class _SessionManager {
75724
76202
  for (const file2 of files) {
75725
76203
  if (!file2.endsWith(".jsonl"))
75726
76204
  continue;
75727
- const filePath = path29.join(dir, file2);
75728
- if (keep.has(path29.resolve(filePath)))
76205
+ const filePath = path31.join(dir, file2);
76206
+ if (keep.has(path31.resolve(filePath)))
75729
76207
  continue;
75730
76208
  try {
75731
76209
  const stat = await fs24.stat(filePath);
@@ -76725,9 +77203,9 @@ function getPromptCommand(name) {
76725
77203
  // ../ggcoder/dist/core/custom-commands.js
76726
77204
  init_esm_shims();
76727
77205
  import fs25 from "fs/promises";
76728
- import path30 from "path";
77206
+ import path33 from "path";
76729
77207
  async function loadCustomCommands(cwd2) {
76730
- const commandsDir = path30.join(cwd2, ".gg", "commands");
77208
+ const commandsDir = path33.join(cwd2, ".gg", "commands");
76731
77209
  const commands = [];
76732
77210
  let files;
76733
77211
  try {
@@ -76738,11 +77216,11 @@ async function loadCustomCommands(cwd2) {
76738
77216
  for (const file2 of files) {
76739
77217
  if (!file2.endsWith(".md"))
76740
77218
  continue;
76741
- const filePath = path30.join(commandsDir, file2);
77219
+ const filePath = path33.join(commandsDir, file2);
76742
77220
  try {
76743
77221
  const raw = await fs25.readFile(filePath, "utf-8");
76744
77222
  const parsed = parseSkillFile(raw, "project");
76745
- const name = parsed.name || path30.basename(file2, ".md");
77223
+ const name = parsed.name || path33.basename(file2, ".md");
76746
77224
  commands.push({
76747
77225
  name,
76748
77226
  description: parsed.description || `Custom command from .gg/commands/${file2}`,
@@ -76764,7 +77242,7 @@ init_esm_shims();
76764
77242
  // ../ggcoder/dist/core/extensions/loader.js
76765
77243
  init_esm_shims();
76766
77244
  import fs26 from "fs/promises";
76767
- import path31 from "path";
77245
+ import path34 from "path";
76768
77246
  var ExtensionLoader = class {
76769
77247
  loaded = [];
76770
77248
  async loadAll(extensionsDir, context) {
@@ -76777,7 +77255,7 @@ var ExtensionLoader = class {
76777
77255
  for (const file2 of files) {
76778
77256
  if (!file2.endsWith(".js"))
76779
77257
  continue;
76780
- const filePath = path31.join(extensionsDir, file2);
77258
+ const filePath = path34.join(extensionsDir, file2);
76781
77259
  try {
76782
77260
  const mod = await import(filePath);
76783
77261
  const factory = typeof mod.default === "function" ? mod.default : mod.createExtension;
@@ -83011,7 +83489,171 @@ var StdioClientTransport = class {
83011
83489
  };
83012
83490
 
83013
83491
  // ../ggcoder/dist/core/mcp/client.js
83492
+ import http from "http";
83014
83493
  import os8 from "os";
83494
+
83495
+ // ../ggcoder/dist/core/mcp/oauth-provider.js
83496
+ init_esm_shims();
83497
+ import crypto8 from "crypto";
83498
+
83499
+ // ../ggcoder/dist/core/mcp/oauth-store.js
83500
+ init_esm_shims();
83501
+ import fs27 from "fs/promises";
83502
+ var McpOAuthStore = class {
83503
+ filePath;
83504
+ constructor(filePath = getAppPaths().mcpAuthFile) {
83505
+ this.filePath = filePath;
83506
+ }
83507
+ async readAll() {
83508
+ try {
83509
+ const raw = await fs27.readFile(this.filePath, "utf-8");
83510
+ const parsed = JSON.parse(raw);
83511
+ return { version: 1, servers: parsed.servers ?? {} };
83512
+ } catch {
83513
+ return { version: 1, servers: {} };
83514
+ }
83515
+ }
83516
+ async writeAll(data) {
83517
+ try {
83518
+ await fs27.writeFile(this.filePath, JSON.stringify(data, null, 2), {
83519
+ encoding: "utf-8",
83520
+ mode: 384
83521
+ });
83522
+ } catch (err) {
83523
+ log("WARN", "mcp", "failed to persist MCP OAuth store", {
83524
+ message: err instanceof Error ? err.message : String(err)
83525
+ });
83526
+ }
83527
+ }
83528
+ async get(name) {
83529
+ const all = await this.readAll();
83530
+ return all.servers[name] ?? {};
83531
+ }
83532
+ /** Merge a partial entry into the server's record (read-modify-write). */
83533
+ async patch(name, patch) {
83534
+ const all = await this.readAll();
83535
+ all.servers[name] = { ...all.servers[name] ?? {}, ...patch };
83536
+ await this.writeAll(all);
83537
+ }
83538
+ /** Drop a server's whole OAuth record (used on logout / removal). */
83539
+ async clear(name) {
83540
+ const all = await this.readAll();
83541
+ if (all.servers[name]) {
83542
+ delete all.servers[name];
83543
+ await this.writeAll(all);
83544
+ }
83545
+ }
83546
+ /** Whether this server has saved tokens (i.e. has completed login at least once). */
83547
+ async hasTokens(name) {
83548
+ const entry = await this.get(name);
83549
+ return !!entry.tokens?.access_token;
83550
+ }
83551
+ };
83552
+
83553
+ // ../ggcoder/dist/core/mcp/oauth-provider.js
83554
+ var MCP_OAUTH_CALLBACK_PORT = 41999;
83555
+ var MCP_OAUTH_CALLBACK_PATH = "/oauth/callback";
83556
+ function mcpOAuthRedirectUrl() {
83557
+ return `http://localhost:${MCP_OAUTH_CALLBACK_PORT}${MCP_OAUTH_CALLBACK_PATH}`;
83558
+ }
83559
+ var McpOAuthProvider = class {
83560
+ store;
83561
+ serverName;
83562
+ onRedirect;
83563
+ scope;
83564
+ constructor(opts) {
83565
+ this.serverName = opts.serverName;
83566
+ this.store = opts.store ?? new McpOAuthStore();
83567
+ this.onRedirect = opts.onRedirect;
83568
+ this.scope = opts.scope;
83569
+ }
83570
+ get redirectUrl() {
83571
+ return mcpOAuthRedirectUrl();
83572
+ }
83573
+ get clientMetadata() {
83574
+ return {
83575
+ client_name: "GG Coder",
83576
+ client_uri: "https://github.com/kenkaiii/gg-coder",
83577
+ redirect_uris: [this.redirectUrl],
83578
+ grant_types: ["authorization_code", "refresh_token"],
83579
+ response_types: ["code"],
83580
+ token_endpoint_auth_method: "none",
83581
+ ...this.scope ? { scope: this.scope } : {}
83582
+ };
83583
+ }
83584
+ async state() {
83585
+ const entry = await this.store.get(this.serverName);
83586
+ if (entry.state)
83587
+ return entry.state;
83588
+ const fresh = crypto8.randomBytes(16).toString("hex");
83589
+ await this.store.patch(this.serverName, { state: fresh });
83590
+ return fresh;
83591
+ }
83592
+ async clientInformation() {
83593
+ const entry = await this.store.get(this.serverName);
83594
+ return entry.clientInformation;
83595
+ }
83596
+ async saveClientInformation(info) {
83597
+ await this.store.patch(this.serverName, {
83598
+ clientInformation: info
83599
+ });
83600
+ }
83601
+ async tokens() {
83602
+ const entry = await this.store.get(this.serverName);
83603
+ return entry.tokens;
83604
+ }
83605
+ async saveTokens(tokens2) {
83606
+ await this.store.patch(this.serverName, { tokens: tokens2 });
83607
+ }
83608
+ redirectToAuthorization(authorizationUrl) {
83609
+ this.onRedirect?.(authorizationUrl);
83610
+ }
83611
+ async saveCodeVerifier(codeVerifier) {
83612
+ await this.store.patch(this.serverName, { codeVerifier });
83613
+ }
83614
+ async codeVerifier() {
83615
+ const entry = await this.store.get(this.serverName);
83616
+ if (!entry.codeVerifier) {
83617
+ throw new Error("No PKCE code verifier saved for this MCP server.");
83618
+ }
83619
+ return entry.codeVerifier;
83620
+ }
83621
+ };
83622
+
83623
+ // ../ggcoder/dist/core/mcp/loopback.js
83624
+ init_esm_shims();
83625
+ function isLocalhost(url2) {
83626
+ const h = normalizeHost(url2.hostname);
83627
+ return h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "0.0.0.0";
83628
+ }
83629
+ function alternateLoopback(hostname4) {
83630
+ const h = normalizeHost(hostname4);
83631
+ if (h === "localhost")
83632
+ return "127.0.0.1";
83633
+ if (h === "127.0.0.1")
83634
+ return "localhost";
83635
+ if (h === "::1")
83636
+ return "127.0.0.1";
83637
+ if (h === "0.0.0.0")
83638
+ return "127.0.0.1";
83639
+ return void 0;
83640
+ }
83641
+ function normalizeHost(hostname4) {
83642
+ let h = hostname4.toLowerCase();
83643
+ if (h.startsWith("[") && h.endsWith("]"))
83644
+ h = h.slice(1, -1);
83645
+ return h;
83646
+ }
83647
+ function isNetworkError(err) {
83648
+ if (err == null)
83649
+ return false;
83650
+ const msg = err instanceof Error ? err.message : String(err);
83651
+ const cause = err.cause;
83652
+ const text = `${msg} ${cause?.message ?? ""} ${cause?.code ?? ""}`.toLowerCase();
83653
+ return text.includes("econnrefused") || text.includes("econnreset") || text.includes("enotfound") || text.includes("eai_again") || text.includes("fetch failed") || text.includes("failed to fetch") || text.includes("connection refused") || text.includes("network request failed") || text.includes("sse error");
83654
+ }
83655
+
83656
+ // ../ggcoder/dist/core/mcp/client.js
83015
83657
  var MCPClientManager = class {
83016
83658
  servers = [];
83017
83659
  async connectAll(configs) {
@@ -83033,9 +83675,10 @@ var MCPClientManager = class {
83033
83675
  if (result.status === "fulfilled") {
83034
83676
  return { name, ok: true, toolCount: result.value.length, tools: result.value };
83035
83677
  }
83036
- const error51 = formatConnectError(result.reason);
83678
+ const requiresAuth = isUnauthorized(result.reason);
83679
+ const error51 = requiresAuth ? "Requires login." : formatConnectError(result.reason);
83037
83680
  log("WARN", "mcp", `Failed to connect to MCP server "${name}"`, { error: error51 });
83038
- return { name, ok: false, toolCount: 0, tools: [], error: error51 };
83681
+ return { name, ok: false, toolCount: 0, tools: [], error: error51, requiresAuth };
83039
83682
  });
83040
83683
  const connected = results.filter((r2) => r2.ok).length;
83041
83684
  const toolCount = results.reduce((sum, r2) => sum + r2.toolCount, 0);
@@ -83060,8 +83703,120 @@ var MCPClientManager = class {
83060
83703
  }
83061
83704
  return { name: config2.name, ok: true, toolCount: tools.length, tools };
83062
83705
  } catch (err) {
83063
- const error51 = formatConnectError(err);
83064
- return { name: config2.name, ok: false, toolCount: 0, tools: [], error: error51 };
83706
+ const requiresAuth = isUnauthorized(err);
83707
+ const error51 = requiresAuth ? "Requires login." : formatConnectError(err);
83708
+ return { name: config2.name, ok: false, toolCount: 0, tools: [], error: error51, requiresAuth };
83709
+ }
83710
+ }
83711
+ /**
83712
+ * Run the interactive OAuth login for one remote MCP server end-to-end:
83713
+ * start a loopback callback server, let the SDK open the browser via
83714
+ * `onAuthorizationUrl`, capture the redirect, exchange the code, then verify
83715
+ * the authorized connection by listing tools. Tokens are persisted by the
83716
+ * provider so later (non-interactive) connects succeed silently.
83717
+ *
83718
+ * `onAuthorizationUrl` is invoked with the authorize URL so the host can open
83719
+ * it (the gg-app broadcasts it to the webview, which opens the system
83720
+ * browser; the CLI prints it). Never throws — returns `{ ok:false, error }`.
83721
+ */
83722
+ async login(config2, onAuthorizationUrl, timeoutMs = 18e4) {
83723
+ if (!config2.url) {
83724
+ return { ok: false, toolCount: 0, error: "Login is only supported for HTTP MCP servers." };
83725
+ }
83726
+ const url2 = new URL(config2.url);
83727
+ const store2 = new McpOAuthStore();
83728
+ await store2.patch(config2.name, { codeVerifier: void 0, state: void 0 });
83729
+ let codeResolve;
83730
+ let codeReject;
83731
+ const codePromise = new Promise((resolve2, reject) => {
83732
+ codeResolve = resolve2;
83733
+ codeReject = reject;
83734
+ });
83735
+ const provider = new McpOAuthProvider({
83736
+ serverName: config2.name,
83737
+ store: store2,
83738
+ onRedirect: (authUrl) => onAuthorizationUrl(authUrl.toString())
83739
+ });
83740
+ const expectedState = await provider.state();
83741
+ const server = http.createServer((req, res) => {
83742
+ const reqUrl = new URL(req.url || "", `http://localhost:${MCP_OAUTH_CALLBACK_PORT}`);
83743
+ if (reqUrl.pathname !== MCP_OAUTH_CALLBACK_PATH) {
83744
+ res.statusCode = 404;
83745
+ res.end("Not found");
83746
+ return;
83747
+ }
83748
+ const err = reqUrl.searchParams.get("error");
83749
+ const code = reqUrl.searchParams.get("code");
83750
+ const state3 = reqUrl.searchParams.get("state");
83751
+ res.writeHead(200, { "Content-Type": "text/html" });
83752
+ if (err) {
83753
+ res.end(`<html><body><h1>Login failed</h1><p>${escapeHtml(err)}</p></body></html>`);
83754
+ codeReject?.(new Error(`Authorization failed: ${err}`));
83755
+ return;
83756
+ }
83757
+ if (!code) {
83758
+ res.end("<html><body><h1>Login failed</h1><p>No authorization code.</p></body></html>");
83759
+ codeReject?.(new Error("No authorization code in callback."));
83760
+ return;
83761
+ }
83762
+ if (state3 !== expectedState) {
83763
+ res.end("<html><body><h1>Login failed</h1><p>State mismatch.</p></body></html>");
83764
+ codeReject?.(new Error("OAuth state mismatch."));
83765
+ return;
83766
+ }
83767
+ res.end("<html><body><h1>Login successful!</h1><p>You can close this tab and return to GG Coder.</p></body></html>");
83768
+ codeResolve?.(code);
83769
+ });
83770
+ try {
83771
+ await new Promise((resolve2, reject) => {
83772
+ server.once("error", reject);
83773
+ server.listen(MCP_OAUTH_CALLBACK_PORT, "127.0.0.1", () => resolve2());
83774
+ });
83775
+ } catch (err) {
83776
+ const msg = err instanceof Error ? err.message : String(err);
83777
+ const hint = msg.includes("EADDRINUSE") || msg.includes("in use") ? `Port ${MCP_OAUTH_CALLBACK_PORT} is in use \u2014 close whatever is using it and retry.` : msg;
83778
+ return { ok: false, toolCount: 0, error: `Could not start login callback server: ${hint}` };
83779
+ }
83780
+ const overallTimeout = setTimeout(() => {
83781
+ codeReject?.(new Error("Login timed out waiting for the browser callback."));
83782
+ }, timeoutMs);
83783
+ overallTimeout.unref();
83784
+ try {
83785
+ const loginTransport = new StreamableHTTPClientTransport(url2, {
83786
+ requestInit: config2.headers ? { headers: config2.headers } : void 0,
83787
+ authProvider: provider
83788
+ });
83789
+ const loginClient = new Client({ name: "ggcoder", version: "1.0.0" });
83790
+ try {
83791
+ await loginClient.connect(loginTransport);
83792
+ const { tools: tools2 } = await loginClient.listTools();
83793
+ await loginClient.close().catch(() => {
83794
+ });
83795
+ return { ok: true, toolCount: tools2.length };
83796
+ } catch (err) {
83797
+ if (!isUnauthorized(err))
83798
+ throw err;
83799
+ }
83800
+ const code = await codePromise;
83801
+ await loginTransport.finishAuth(code);
83802
+ await loginClient.close().catch(() => {
83803
+ });
83804
+ const verifyTransport = new StreamableHTTPClientTransport(url2, {
83805
+ requestInit: config2.headers ? { headers: config2.headers } : void 0,
83806
+ authProvider: provider
83807
+ });
83808
+ const verifyClient = new Client({ name: "ggcoder", version: "1.0.0" });
83809
+ await verifyClient.connect(verifyTransport);
83810
+ const { tools } = await verifyClient.listTools();
83811
+ await verifyClient.close().catch(() => {
83812
+ });
83813
+ return { ok: true, toolCount: tools.length };
83814
+ } catch (err) {
83815
+ return { ok: false, toolCount: 0, error: formatConnectError(err) };
83816
+ } finally {
83817
+ clearTimeout(overallTimeout);
83818
+ server.close();
83819
+ await store2.patch(config2.name, { codeVerifier: void 0, state: void 0 });
83065
83820
  }
83066
83821
  }
83067
83822
  async connectServer(config2) {
@@ -83092,23 +83847,23 @@ var MCPClientManager = class {
83092
83847
  }
83093
83848
  } else {
83094
83849
  const url2 = new URL(config2.url);
83095
- const reqInit = config2.headers ? { headers: config2.headers } : void 0;
83850
+ const isLocal = isLocalhost(url2);
83096
83851
  try {
83097
- transport = new StreamableHTTPClientTransport(url2, {
83098
- requestInit: reqInit
83099
- });
83100
- client = new Client({ name: "ggcoder", version: "1.0.0" });
83101
- await client.connect(transport, { timeout });
83102
- } catch (streamableErr) {
83103
- log("INFO", "mcp", `StreamableHTTP failed for "${config2.name}", trying SSE fallback`, {
83104
- error: String(streamableErr)
83105
- });
83106
- transport = new SSEClientTransport(url2, {
83107
- eventSourceInit: config2.headers ? { fetch: createHeaderFetch(config2.headers) } : void 0,
83108
- requestInit: reqInit
83852
+ const r2 = await this.connectHttp(url2, config2, isLocal, timeout);
83853
+ client = r2.client;
83854
+ transport = r2.transport;
83855
+ } catch (err) {
83856
+ const alt = isLocal ? alternateLoopback(url2.hostname) : void 0;
83857
+ if (!alt || !isNetworkError(err))
83858
+ throw err;
83859
+ log("INFO", "mcp", `localhost connect failed for "${config2.name}", retrying as ${alt}`, {
83860
+ error: String(err)
83109
83861
  });
83110
- client = new Client({ name: "ggcoder", version: "1.0.0" });
83111
- await client.connect(transport, { timeout });
83862
+ const altUrl = new URL(url2);
83863
+ altUrl.hostname = alt;
83864
+ const r2 = await this.connectHttp(altUrl, config2, isLocal, timeout);
83865
+ client = r2.client;
83866
+ transport = r2.transport;
83112
83867
  }
83113
83868
  }
83114
83869
  this.servers.push({ name: config2.name, client, transport, lastCallTime: 0 });
@@ -83153,6 +83908,50 @@ var MCPClientManager = class {
83153
83908
  };
83154
83909
  });
83155
83910
  }
83911
+ /**
83912
+ * Connect a single HTTP (Streamable HTTP or SSE) server and return the live
83913
+ * client + transport. Transport selection:
83914
+ * - `transport === "sse"` → legacy SSE directly (Playwright MCP `--port`).
83915
+ * - otherwise → Streamable HTTP first, SSE fallback for older servers.
83916
+ *
83917
+ * An OAuth provider is attached only for REMOTE servers — localhost never
83918
+ * needs OAuth and attaching it there is dead weight that can misdiagnose a
83919
+ * protocol mismatch as a login requirement.
83920
+ */
83921
+ async connectHttp(url2, config2, isLocal, timeout) {
83922
+ const reqInit = config2.headers ? { headers: config2.headers } : void 0;
83923
+ const authProvider = isLocal ? void 0 : new McpOAuthProvider({ serverName: config2.name });
83924
+ const sseTransport = () => new SSEClientTransport(url2, {
83925
+ eventSourceInit: config2.headers ? { fetch: createHeaderFetch(config2.headers) } : void 0,
83926
+ requestInit: reqInit,
83927
+ authProvider
83928
+ });
83929
+ if (config2.transport === "sse") {
83930
+ const transport = sseTransport();
83931
+ const client = new Client({ name: "ggcoder", version: "1.0.0" });
83932
+ await client.connect(transport, { timeout });
83933
+ return { client, transport };
83934
+ }
83935
+ try {
83936
+ const transport = new StreamableHTTPClientTransport(url2, {
83937
+ requestInit: reqInit,
83938
+ authProvider
83939
+ });
83940
+ const client = new Client({ name: "ggcoder", version: "1.0.0" });
83941
+ await client.connect(transport, { timeout });
83942
+ return { client, transport };
83943
+ } catch (streamableErr) {
83944
+ if (!isLocal && isUnauthorized(streamableErr))
83945
+ throw streamableErr;
83946
+ log("INFO", "mcp", `StreamableHTTP failed for "${config2.name}", trying SSE fallback`, {
83947
+ error: String(streamableErr)
83948
+ });
83949
+ const transport = sseTransport();
83950
+ const client = new Client({ name: "ggcoder", version: "1.0.0" });
83951
+ await client.connect(transport, { timeout });
83952
+ return { client, transport };
83953
+ }
83954
+ }
83156
83955
  async dispose() {
83157
83956
  for (const server of this.servers) {
83158
83957
  try {
@@ -83170,6 +83969,15 @@ function formatConnectError(reason) {
83170
83969
  }
83171
83970
  return msg;
83172
83971
  }
83972
+ function isUnauthorized(reason) {
83973
+ if (reason instanceof UnauthorizedError)
83974
+ return true;
83975
+ const msg = reason instanceof Error ? reason.message : String(reason);
83976
+ return msg.includes("Unauthorized") || msg.includes("401") || msg.toLowerCase().includes("invalid_token");
83977
+ }
83978
+ function escapeHtml(value) {
83979
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
83980
+ }
83173
83981
  function createHeaderFetch(extraHeaders) {
83174
83982
  return (url2, init) => {
83175
83983
  const existing = init?.headers ?? {};
@@ -83182,8 +83990,8 @@ init_esm_shims();
83182
83990
 
83183
83991
  // ../ggcoder/dist/core/mcp/store.js
83184
83992
  init_esm_shims();
83185
- import path33 from "path";
83186
- import fs27 from "fs/promises";
83993
+ import path35 from "path";
83994
+ import fs28 from "fs/promises";
83187
83995
  var StoredServerEntrySchema = external_exports.object({
83188
83996
  type: external_exports.enum(["stdio", "http", "streamable-http", "sse"]).optional(),
83189
83997
  url: external_exports.string().optional(),
@@ -83201,12 +84009,12 @@ function globalMcpPath() {
83201
84009
  return getAppPaths().mcpFile;
83202
84010
  }
83203
84011
  function projectMcpPath(cwd2) {
83204
- return path33.join(cwd2, ".gg", "mcp.json");
84012
+ return path35.join(cwd2, ".gg", "mcp.json");
83205
84013
  }
83206
84014
  async function readMcpFile(filePath) {
83207
84015
  let content;
83208
84016
  try {
83209
- content = await fs27.readFile(filePath, "utf-8");
84017
+ content = await fs28.readFile(filePath, "utf-8");
83210
84018
  } catch {
83211
84019
  return { mcpServers: {} };
83212
84020
  }
@@ -83226,6 +84034,10 @@ function fromStoredEntry(name, entry) {
83226
84034
  config2.url = entry.url;
83227
84035
  if (entry.headers)
83228
84036
  config2.headers = entry.headers;
84037
+ if (entry.type === "sse")
84038
+ config2.transport = "sse";
84039
+ else if (entry.type === "http" || entry.type === "streamable-http")
84040
+ config2.transport = "http";
83229
84041
  } else if (entry.command) {
83230
84042
  config2.command = entry.command;
83231
84043
  if (entry.args)
@@ -83309,12 +84121,12 @@ init_esm_shims();
83309
84121
 
83310
84122
  // ../ggcoder/dist/core/agents.js
83311
84123
  init_esm_shims();
83312
- import fs28 from "fs/promises";
83313
- import path34 from "path";
84124
+ import fs29 from "fs/promises";
84125
+ import path36 from "path";
83314
84126
  async function discoverAgents(options) {
83315
84127
  const agents = [];
83316
84128
  if (options.projectDir) {
83317
- const projectAgentsDir = path34.join(options.projectDir, ".gg", "agents");
84129
+ const projectAgentsDir = path36.join(options.projectDir, ".gg", "agents");
83318
84130
  const projectAgents = await loadAgentsFromDir(projectAgentsDir, "project");
83319
84131
  agents.push(...projectAgents);
83320
84132
  }
@@ -83332,19 +84144,19 @@ async function loadAgentsFromDir(dir, source2) {
83332
84144
  const agents = [];
83333
84145
  let files;
83334
84146
  try {
83335
- files = await fs28.readdir(dir);
84147
+ files = await fs29.readdir(dir);
83336
84148
  } catch {
83337
84149
  return agents;
83338
84150
  }
83339
84151
  for (const file2 of files) {
83340
84152
  if (!file2.endsWith(".md"))
83341
84153
  continue;
83342
- const filePath = path34.join(dir, file2);
84154
+ const filePath = path36.join(dir, file2);
83343
84155
  try {
83344
- const content = await fs28.readFile(filePath, "utf-8");
84156
+ const content = await fs29.readFile(filePath, "utf-8");
83345
84157
  const agent = parseAgentFile(content, source2);
83346
84158
  if (!agent.name) {
83347
- agent.name = path34.basename(file2, ".md");
84159
+ agent.name = path36.basename(file2, ".md");
83348
84160
  }
83349
84161
  agents.push(agent);
83350
84162
  } catch {
@@ -83663,9 +84475,9 @@ The user's original request was:
83663
84475
  }
83664
84476
 
83665
84477
  // ../ggcoder/dist/core/agent-session.js
83666
- import crypto8 from "crypto";
83667
- import fs29 from "fs/promises";
83668
- import path35 from "path";
84478
+ import crypto9 from "crypto";
84479
+ import fs30 from "fs/promises";
84480
+ import path37 from "path";
83669
84481
  var AgentSession = class {
83670
84482
  eventBus = new EventBus();
83671
84483
  slashCommands = new SlashCommandRegistry();
@@ -83675,6 +84487,10 @@ var AgentSession = class {
83675
84487
  extensionLoader = new ExtensionLoader();
83676
84488
  messages = [];
83677
84489
  tools = [];
84490
+ /** Rebuilds the read tool for a new model (video byte cap is baked in at
84491
+ * creation). Called from switchModel so video-capable models get the
84492
+ * read-tool's native-video path after a mid-session model change. */
84493
+ rebuildReadTool;
83678
84494
  skills = [];
83679
84495
  cacheKeyLogged = false;
83680
84496
  // ── Self-correction hook state (mirrors the TUI's useAgentLoop refs) ──
@@ -83701,9 +84517,13 @@ var AgentSession = class {
83701
84517
  regroundingInjected = false;
83702
84518
  compactionOccurred = false;
83703
84519
  originalRequest = "";
84520
+ /** True after the cache has been pre-warmed for this session. Ensures we only
84521
+ * fire the warm-up call once (before the first real turn). */
84522
+ cachePrewarmed = false;
83704
84523
  // Messages queued by the user while a run is in flight. Drained at the
83705
84524
  // mid-loop steering boundary (user steering wins over the hooks), mirroring
83706
- // the TUI's getSteeringMessages.
84525
+ // the TUI's getSteeringMessages. Each entry carries its own attachments so a
84526
+ // user can queue media (images/video/files) mid-run, not just plain text.
83707
84527
  userQueue = [];
83708
84528
  processManager;
83709
84529
  lspManager;
@@ -83733,10 +84553,25 @@ var AgentSession = class {
83733
84553
  this.model = options.model;
83734
84554
  this.cwd = options.cwd;
83735
84555
  this.baseUrl = options.baseUrl;
83736
- this.maxTokens = options.maxTokens ?? getModel(options.model)?.maxOutputTokens ?? 16384;
84556
+ this.maxTokens = this.resolveMaxTokens(options.model);
83737
84557
  this.thinkingLevel = options.thinkingLevel;
83738
84558
  this.customSystemPrompt = options.systemPrompt;
83739
84559
  }
84560
+ /**
84561
+ * Derive the output-token cap for a model. Follows the active model's
84562
+ * `maxOutputTokens` so a session booted on a large-output model (e.g. Kimi's
84563
+ * 256K) doesn't carry that cap to a smaller one (e.g. Opus's 128K) after a
84564
+ * model switch — that mismatch surfaces from the provider as
84565
+ * `max_tokens: 262144 > 128000, which is the maximum allowed …`. An explicit
84566
+ * `maxTokens` override is honored but clamped to the model's ceiling.
84567
+ */
84568
+ resolveMaxTokens(modelId) {
84569
+ const modelInfo = getModel(modelId);
84570
+ if (this.opts.maxTokens) {
84571
+ return modelInfo ? Math.min(this.opts.maxTokens, modelInfo.maxOutputTokens) : this.opts.maxTokens;
84572
+ }
84573
+ return modelInfo?.maxOutputTokens ?? 16384;
84574
+ }
83740
84575
  async initialize() {
83741
84576
  setEstimatorModel(this.model);
83742
84577
  const paths = await ensureAppDirs();
@@ -83745,10 +84580,10 @@ var AgentSession = class {
83745
84580
  this.authStorage = new AuthStorage(paths.authFile);
83746
84581
  await this.authStorage.load();
83747
84582
  this.sessionManager = new SessionManager(paths.sessionsDir);
83748
- const localGGDir = path35.join(this.cwd, ".gg");
83749
- await fs29.mkdir(path35.join(localGGDir, "skills"), { recursive: true });
83750
- await fs29.mkdir(path35.join(localGGDir, "commands"), { recursive: true });
83751
- await fs29.mkdir(path35.join(localGGDir, "agents"), { recursive: true });
84583
+ const localGGDir = path37.join(this.cwd, ".gg");
84584
+ await fs30.mkdir(path37.join(localGGDir, "skills"), { recursive: true });
84585
+ await fs30.mkdir(path37.join(localGGDir, "commands"), { recursive: true });
84586
+ await fs30.mkdir(path37.join(localGGDir, "agents"), { recursive: true });
83752
84587
  this.skills = await discoverSkills({
83753
84588
  globalSkillsDir: paths.skillsDir,
83754
84589
  projectDir: this.cwd
@@ -83757,12 +84592,13 @@ var AgentSession = class {
83757
84592
  globalAgentsDir: paths.agentsDir,
83758
84593
  projectDir: this.cwd
83759
84594
  });
83760
- const { tools, processManager, lspManager } = createTools(this.cwd, {
84595
+ const { tools, processManager, rebuildReadTool, lspManager } = await createTools(this.cwd, {
83761
84596
  agents,
83762
84597
  skills: this.skills,
83763
84598
  provider: this.provider,
83764
84599
  model: this.model,
83765
84600
  lspDiagnostics: this.settingsManager.get("lspDiagnostics"),
84601
+ authStorage: this.authStorage,
83766
84602
  // Lazy — sessionId/model/provider can change after createTools() runs, so
83767
84603
  // sub-agent spawns read the current parent state at execution time.
83768
84604
  getProvider: () => this.provider,
@@ -83777,22 +84613,14 @@ var AgentSession = class {
83777
84613
  } : {}
83778
84614
  });
83779
84615
  this.tools = tools;
84616
+ this.rebuildReadTool = rebuildReadTool;
83780
84617
  this.processManager = processManager;
83781
84618
  this.lspManager = lspManager;
83782
84619
  this.mcpManager = new MCPClientManager();
83783
- try {
83784
- let apiKey;
83785
- if (this.provider === "glm") {
83786
- try {
83787
- const glmCreds = await this.authStorage.resolveCredentials("glm");
83788
- apiKey = glmCreds.accessToken;
83789
- } catch {
83790
- }
83791
- }
83792
- const mcpTools = await this.mcpManager.connectAll(getMCPServers(this.provider, apiKey));
83793
- this.tools.push(...mcpTools);
83794
- } catch (err) {
83795
- log("WARN", "mcp", `MCP initialization failed: ${err instanceof Error ? err.message : String(err)}`);
84620
+ if (this.opts.backgroundMcpConnect) {
84621
+ void this.connectMcpServers();
84622
+ } else {
84623
+ await this.connectMcpServers();
83796
84624
  }
83797
84625
  const basePrompt = this.customSystemPrompt ?? await buildSystemPrompt(this.cwd, this.skills, false, void 0, this.tools.map((tool) => tool.name), void 0, this.provider);
83798
84626
  this.messages = [{ role: "system", content: basePrompt }];
@@ -83849,6 +84677,36 @@ var AgentSession = class {
83849
84677
  await this.extensionLoader.loadAll(paths.extensionsDir, extContext);
83850
84678
  this.eventBus.emit("session_start", { sessionId: this.sessionId });
83851
84679
  }
84680
+ /**
84681
+ * Connect all configured MCP servers and append their tools to `this.tools`.
84682
+ * Resolves the GLM api key first (Z.AI's bundled servers need it). Never
84683
+ * throws — a failed connect is logged and skipped — so it is safe to either
84684
+ * `await` (CLI: tools ready before the first turn) or fire-and-forget
84685
+ * (sidecar: `backgroundMcpConnect`, so a slow stdio server can't stall
84686
+ * startup). Tools are pushed onto the live array the agent loop reads each
84687
+ * turn, so background-connected servers become available on the next prompt.
84688
+ */
84689
+ async connectMcpServers() {
84690
+ if (!this.mcpManager)
84691
+ return;
84692
+ try {
84693
+ let apiKey;
84694
+ if (this.provider === "glm") {
84695
+ try {
84696
+ const glmCreds = await this.authStorage.resolveCredentials("glm");
84697
+ apiKey = glmCreds.accessToken;
84698
+ } catch {
84699
+ }
84700
+ }
84701
+ const mcpTools = await this.mcpManager.connectAll(await getAllMcpServers(this.provider, apiKey, this.cwd));
84702
+ this.tools.push(...mcpTools);
84703
+ if (this.opts.backgroundMcpConnect && mcpTools.length > 0) {
84704
+ await this.rebuildSystemPromptInPlace();
84705
+ }
84706
+ } catch (err) {
84707
+ log("WARN", "mcp", `MCP initialization failed: ${err instanceof Error ? err.message : String(err)}`);
84708
+ }
84709
+ }
83852
84710
  /**
83853
84711
  * Process user input. Handles slash commands or runs agent loop.
83854
84712
  */
@@ -83893,13 +84751,47 @@ ${parsed.args}` : promptText;
83893
84751
  * attachments are always a direct conversational turn.
83894
84752
  */
83895
84753
  async promptWithAttachments(text, attachments) {
84754
+ const parts = this.buildAttachmentParts(text, attachments);
84755
+ if (parts.length === 0)
84756
+ return;
84757
+ const userMessage = { role: "user", content: parts };
84758
+ this.messages.push(userMessage);
84759
+ await this.persistMessage(userMessage);
84760
+ this.lastPersistedIndex = this.messages.length;
84761
+ await this.runLoop();
84762
+ }
84763
+ /**
84764
+ * Build the native content blocks (text + image/video notes + file notes) for
84765
+ * a user message with attachments. Shared by {@link promptWithAttachments} and
84766
+ * the mid-run steering drain so queued media is delivered identically.
84767
+ */
84768
+ buildAttachmentParts(text, attachments) {
83896
84769
  const parts = [];
83897
84770
  const fileNotes = [];
84771
+ const modelSupportsVideo = getModel(this.model)?.supportsVideo ?? false;
83898
84772
  for (const a of attachments) {
83899
84773
  if (a.kind === "image") {
83900
84774
  parts.push({ type: "image", mediaType: a.mediaType, data: a.data });
84775
+ if (a.path) {
84776
+ parts.push({ type: "text", text: `[Image saved at ${a.path}]` });
84777
+ }
83901
84778
  } else if (a.kind === "video") {
83902
- parts.push({ type: "video", mediaType: a.mediaType, data: a.data });
84779
+ if (modelSupportsVideo && a.path) {
84780
+ parts.push({
84781
+ type: "text",
84782
+ text: `The user attached a video at ${a.path}. You CAN watch it: call the read tool on this exact path now, then answer based on what you see. Do not say you cannot watch video \u2014 reading the file lets you analyze it.`
84783
+ });
84784
+ } else if (a.path) {
84785
+ parts.push({
84786
+ type: "text",
84787
+ text: `[User attached a video file at ${a.path}. You cannot watch video directly; if needed, use ffmpeg to extract frames or audio.]`
84788
+ });
84789
+ } else {
84790
+ parts.push({
84791
+ type: "text",
84792
+ text: `[User attached a video file but it could not be saved for analysis.]`
84793
+ });
84794
+ }
83903
84795
  } else if (a.path) {
83904
84796
  fileNotes.push(`- ${a.name} (saved at ${a.path})`);
83905
84797
  }
@@ -83913,13 +84805,7 @@ ${fileNotes.join("\n")}`);
83913
84805
  }
83914
84806
  if (textParts.length > 0)
83915
84807
  parts.unshift({ type: "text", text: textParts.join("\n\n") });
83916
- if (parts.length === 0)
83917
- return;
83918
- const userMessage = { role: "user", content: parts };
83919
- this.messages.push(userMessage);
83920
- await this.persistMessage(userMessage);
83921
- this.lastPersistedIndex = this.messages.length;
83922
- await this.runLoop();
84808
+ return parts;
83923
84809
  }
83924
84810
  /**
83925
84811
  * Reset per-run self-correction hook state. Mirrors the TUI's run_start
@@ -84011,8 +84897,15 @@ ${fileNotes.join("\n")}`);
84011
84897
  */
84012
84898
  getHookSteeringMessages() {
84013
84899
  if (this.userQueue.length > 0) {
84014
- const merged = this.userQueue.splice(0).join("\n\n");
84015
- return [{ role: "user", content: merged }];
84900
+ const queued = this.userQueue.splice(0);
84901
+ if (queued.every((m) => m.attachments.length === 0)) {
84902
+ const merged = queued.map((m) => m.text).join("\n\n");
84903
+ return [{ role: "user", content: merged }];
84904
+ }
84905
+ const parts = [];
84906
+ for (const m of queued)
84907
+ parts.push(...this.buildAttachmentParts(m.text, m.attachments));
84908
+ return [{ role: "user", content: parts }];
84016
84909
  }
84017
84910
  if (!this.settingsManager.get("idealReviewEnabled"))
84018
84911
  return null;
@@ -84098,7 +84991,9 @@ ${fileNotes.join("\n")}`);
84098
84991
  // Kimi For Coding gates the managed endpoint on coding-agent identity
84099
84992
  // headers; attach them only when the Kimi OAuth token is in use.
84100
84993
  defaultHeaders: this.provider === "moonshot" && isKimiCodingEndpoint(effectiveBaseUrl) ? kimiCodingHeaders() : void 0,
84101
- cacheRetention: "short",
84994
+ // speedProfile "optimized": 1-h cache TTL (survives turns >5 min apart)
84995
+ // + pre-warm before the first turn. "baseline": current 5-min default.
84996
+ cacheRetention: this.isSpeedOptimized() ? "long" : "short",
84102
84997
  promptCacheKey: this.getPromptCacheKey(),
84103
84998
  supportsImages: modelInfo?.supportsImages,
84104
84999
  supportsVideo: modelInfo?.supportsVideo,
@@ -84117,6 +85012,7 @@ ${fileNotes.join("\n")}`);
84117
85012
  }
84118
85013
  };
84119
85014
  try {
85015
+ await this.maybePrewarmCache(creds);
84120
85016
  await runAgentLoop(creds.accessToken, creds.accountId, creds.projectId);
84121
85017
  } catch (err) {
84122
85018
  if (isAbortError4(err) || this.opts.signal?.aborted) {
@@ -84147,7 +85043,16 @@ ${fileNotes.join("\n")}`);
84147
85043
  this.provider = provider;
84148
85044
  this.model = model;
84149
85045
  setEstimatorModel(model);
84150
- this.eventBus.emit("model_change", { provider: this.provider, model: this.model });
85046
+ this.maxTokens = this.resolveMaxTokens(model);
85047
+ this.eventBus.emit("model_change", {
85048
+ provider: this.provider,
85049
+ model: this.model,
85050
+ supportsVideo: getModel(this.model)?.supportsVideo ?? false
85051
+ });
85052
+ if (this.rebuildReadTool) {
85053
+ const newReadTool = this.rebuildReadTool(model);
85054
+ this.tools = this.tools.map((t) => t.name === "read" ? newReadTool : t);
85055
+ }
84151
85056
  if (provider && provider !== prevProvider) {
84152
85057
  const hasWebSearch = this.tools.some((t) => t.name === "web_search");
84153
85058
  if (this.provider === "anthropic" && hasWebSearch) {
@@ -84273,19 +85178,21 @@ ${fileNotes.join("\n")}`);
84273
85178
  getPlanMode() {
84274
85179
  return this.planModeRef.current;
84275
85180
  }
84276
- /** Queue a user message to be injected mid-run as steering. Returns the new
84277
- * queue length. No-op semantics are the caller's concern. */
84278
- queueMessage(text) {
84279
- this.userQueue.push(text);
85181
+ /** Queue a user message (optionally with attachments) to be injected mid-run
85182
+ * as steering. Returns the new queue length. No-op semantics are the caller's
85183
+ * concern. */
85184
+ queueMessage(text, attachments = []) {
85185
+ this.userQueue.push({ text, attachments });
84280
85186
  return this.userQueue.length;
84281
85187
  }
84282
85188
  /** Number of messages currently queued. */
84283
85189
  getQueuedCount() {
84284
85190
  return this.userQueue.length;
84285
85191
  }
84286
- /** Clear the queue, returning the combined text (to restore to the composer). */
85192
+ /** Clear the queue, returning the combined text (to restore to the composer).
85193
+ * Queued attachments are dropped on cancel — the composer only restores text. */
84287
85194
  drainQueue() {
84288
- return this.userQueue.splice(0).join("\n\n");
85195
+ return this.userQueue.splice(0).map((m) => m.text).join("\n\n");
84289
85196
  }
84290
85197
  /** Snapshot of background processes (bash run_in_background), newest-state. */
84291
85198
  listBackgroundProcesses() {
@@ -84373,6 +85280,42 @@ ${fileNotes.join("\n")}`);
84373
85280
  setSignal(signal) {
84374
85281
  this.opts = { ...this.opts, signal };
84375
85282
  }
85283
+ /** True when speedProfile is "optimized" (1-h cache TTL + pre-warm). */
85284
+ isSpeedOptimized() {
85285
+ return this.settingsManager?.get("speedProfile") === "optimized";
85286
+ }
85287
+ /** Fire a cache pre-warm request for Anthropic so the first real turn is a
85288
+ * cache read instead of a cold write. No-op for other providers and when
85289
+ * speedProfile is not "optimized". Entirely best-effort — any failure is
85290
+ * swallowed so prewarm never blocks or aborts the real prompt. */
85291
+ async maybePrewarmCache(creds) {
85292
+ if (this.cachePrewarmed || !this.isSpeedOptimized() || this.provider !== "anthropic") {
85293
+ return;
85294
+ }
85295
+ this.cachePrewarmed = true;
85296
+ try {
85297
+ const userAgent = await getClaudeCliUserAgent();
85298
+ const systemText = typeof this.messages[0]?.content === "string" ? this.messages[0].content : "";
85299
+ if (!systemText)
85300
+ return;
85301
+ await prewarmAnthropicCache({
85302
+ apiKey: creds.accessToken,
85303
+ model: this.model,
85304
+ system: systemText,
85305
+ tools: this.tools.map((t) => ({
85306
+ name: t.name,
85307
+ description: t.description,
85308
+ parameters: t.parameters,
85309
+ ...t.rawInputSchema ? { rawInputSchema: t.rawInputSchema } : {}
85310
+ })),
85311
+ baseUrl: this.baseUrl ?? creds.baseUrl,
85312
+ userAgent,
85313
+ cacheRetention: "long",
85314
+ signal: this.opts.signal
85315
+ });
85316
+ } catch {
85317
+ }
85318
+ }
84376
85319
  getPromptCacheKey() {
84377
85320
  if (this.opts.promptCacheKey)
84378
85321
  return this.opts.promptCacheKey;
@@ -84445,7 +85388,7 @@ ${fileNotes.join("\n")}`);
84445
85388
  async persistMessage(message) {
84446
85389
  if (!this.sessionPath)
84447
85390
  return;
84448
- const entryId = crypto8.randomUUID();
85391
+ const entryId = crypto9.randomUUID();
84449
85392
  const entry = {
84450
85393
  type: "message",
84451
85394
  id: entryId,
@@ -85261,7 +86204,7 @@ import process14 from "process";
85261
86204
  init_esm_shims();
85262
86205
  var import_react15 = __toESM(require_react(), 1);
85263
86206
  import process13 from "process";
85264
- import fs32 from "fs";
86207
+ import fs33 from "fs";
85265
86208
 
85266
86209
  // ../../node_modules/.pnpm/es-toolkit@1.46.1/node_modules/es-toolkit/dist/compat/index.mjs
85267
86210
  init_esm_shims();
@@ -87454,7 +88397,7 @@ function wrapAnsi2(string4, columns, options) {
87454
88397
  init_esm_shims();
87455
88398
  import process5 from "process";
87456
88399
  import { execFileSync as execFileSync2 } from "child_process";
87457
- import fs30 from "fs";
88400
+ import fs31 from "fs";
87458
88401
  import tty from "tty";
87459
88402
  var defaultColumns = 80;
87460
88403
  var defaultRows = 24;
@@ -87484,7 +88427,7 @@ var isForegroundProcess = () => {
87484
88427
  return true;
87485
88428
  }
87486
88429
  try {
87487
- const statContents = fs30.readFileSync("/proc/self/stat", "utf8");
88430
+ const statContents = fs31.readFileSync("/proc/self/stat", "utf8");
87488
88431
  const closingParenthesisIndex = statContents.lastIndexOf(") ");
87489
88432
  if (closingParenthesisIndex === -1) {
87490
88433
  return false;
@@ -87528,8 +88471,8 @@ function terminalSize() {
87528
88471
  }
87529
88472
  var devTty = () => {
87530
88473
  try {
87531
- const flags = process5.platform === "darwin" ? fs30.constants.O_EVTONLY | fs30.constants.O_NONBLOCK : fs30.constants.O_NONBLOCK;
87532
- const { columns, rows } = tty.WriteStream(fs30.openSync("/dev/tty", flags));
88474
+ const flags = process5.platform === "darwin" ? fs31.constants.O_EVTONLY | fs31.constants.O_NONBLOCK : fs31.constants.O_NONBLOCK;
88475
+ const { columns, rows } = tty.WriteStream(fs31.openSync("/dev/tty", flags));
87533
88476
  return { columns, rows };
87534
88477
  } catch {
87535
88478
  }
@@ -89469,8 +90412,8 @@ var cleanupYogaNode = (node) => {
89469
90412
  var currentUpdatePriority = import_constants3.NoEventPriority;
89470
90413
  var currentRootNode;
89471
90414
  async function loadPackageJson() {
89472
- const fs39 = await import("fs");
89473
- const content = fs39.readFileSync(new URL("../package.json", import.meta.url), "utf8");
90415
+ const fs40 = await import("fs");
90416
+ const content = fs40.readFileSync(new URL("../package.json", import.meta.url), "utf8");
89474
90417
  return JSON.parse(content);
89475
90418
  }
89476
90419
  var packageJson = isDev() ? await loadPackageJson() : { name: void 0, version: void 0 };
@@ -91032,7 +91975,7 @@ var import_react13 = __toESM(require_react(), 1);
91032
91975
  init_esm_shims();
91033
91976
  var import_react12 = __toESM(require_react(), 1);
91034
91977
  var import_stack_utils = __toESM(require_stack_utils(), 1);
91035
- import * as fs31 from "fs";
91978
+ import * as fs32 from "fs";
91036
91979
  import { cwd } from "process";
91037
91980
 
91038
91981
  // ../../node_modules/.pnpm/code-excerpt@4.0.0/node_modules/code-excerpt/dist/index.js
@@ -91160,8 +92103,8 @@ function Text({ color: color2, backgroundColor, dimColor = false, bold = false,
91160
92103
  }
91161
92104
 
91162
92105
  // ../../node_modules/.pnpm/@kenkaiiii+ink@6.8.0-gg.2_@types+react@19.2.14_react@19.2.5/node_modules/@kenkaiiii/ink/build/components/ErrorOverview.js
91163
- var cleanupPath = (path46) => {
91164
- return path46?.replace(`file://${cwd()}/`, "");
92106
+ var cleanupPath = (path48) => {
92107
+ return path48?.replace(`file://${cwd()}/`, "");
91165
92108
  };
91166
92109
  var stackUtils = new import_stack_utils.default({
91167
92110
  cwd: cwd(),
@@ -91173,8 +92116,8 @@ function ErrorOverview({ error: error51 }) {
91173
92116
  const filePath = cleanupPath(origin?.file);
91174
92117
  let excerpt;
91175
92118
  let lineWidth = 0;
91176
- if (filePath && origin?.line && fs31.existsSync(filePath)) {
91177
- const sourceCode = fs31.readFileSync(filePath, "utf8");
92119
+ if (filePath && origin?.line && fs32.existsSync(filePath)) {
92120
+ const sourceCode = fs32.readFileSync(filePath, "utf8");
91178
92121
  excerpt = dist_default3(sourceCode, origin.line);
91179
92122
  if (excerpt) {
91180
92123
  for (const { line } of excerpt) {
@@ -91993,7 +92936,7 @@ var Ink = class {
91993
92936
  }
91994
92937
  if (process13.env["GG_INK_DEBUG"] === "1" && (delta !== 0 || this.framePadDebt > 0)) {
91995
92938
  try {
91996
- fs32.appendFileSync("/tmp/gg-ink-debug.log", JSON.stringify({
92939
+ fs33.appendFileSync("/tmp/gg-ink-debug.log", JSON.stringify({
91997
92940
  t: Date.now() % 1e5,
91998
92941
  delta,
91999
92942
  ins: insertLineCount,
@@ -93715,7 +94658,7 @@ var import_react37 = __toESM(require_react(), 1);
93715
94658
 
93716
94659
  // ../ggcoder/dist/core/session-compaction.js
93717
94660
  init_esm_shims();
93718
- import crypto9 from "crypto";
94661
+ import crypto10 from "crypto";
93719
94662
 
93720
94663
  // ../ggcoder/dist/ui/hooks/useContextCompaction.js
93721
94664
  init_esm_shims();
@@ -94446,8 +95389,8 @@ function shortenValue(value, maxLength = MAX_DETAIL_LENGTH) {
94446
95389
  const tailLength = maxLength - 1 - headLength;
94447
95390
  return `${normalized.slice(0, headLength)}\u2026${normalized.slice(-tailLength)}`;
94448
95391
  }
94449
- function basename2(path46) {
94450
- const trimmed = path46.replace(/\/+$/u, "");
95392
+ function basename2(path48) {
95393
+ const trimmed = path48.replace(/\/+$/u, "");
94451
95394
  return trimmed.split("/").filter(Boolean).at(-1) ?? trimmed;
94452
95395
  }
94453
95396
  function uniqueValues(values) {
@@ -109430,7 +110373,7 @@ function collapseSubmittedUserText(text) {
109430
110373
  }
109431
110374
 
109432
110375
  // ../ggcoder/dist/ui/terminal-history.js
109433
- import path36 from "path";
110376
+ import path38 from "path";
109434
110377
  import { pathToFileURL as pathToFileURL2 } from "url";
109435
110378
 
109436
110379
  // ../ggcoder/dist/ui/utils/terminal-graphics.js
@@ -110458,7 +111401,7 @@ function TaskPickerMenu({ tasks, selectedIndex, width }) {
110458
111401
  // ../ggcoder/dist/ui/components/InputArea.js
110459
111402
  import { homedir as homedir2 } from "os";
110460
111403
  import { join as join2 } from "path";
110461
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync2, renameSync, unlinkSync, existsSync as existsSync4 } from "fs";
111404
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync2, renameSync, unlinkSync, existsSync as existsSync5 } from "fs";
110462
111405
  var MAX_VISIBLE_LINES = 12;
110463
111406
  var PROMPT = "> ";
110464
111407
  var PLACEHOLDER = " Type your message or / to run a command";
@@ -110598,7 +111541,7 @@ function compactHistory2() {
110598
111541
  lineCountEstimate = trimmed.length;
110599
111542
  } catch {
110600
111543
  try {
110601
- if (existsSync4(tempPath))
111544
+ if (existsSync5(tempPath))
110602
111545
  unlinkSync(tempPath);
110603
111546
  } catch {
110604
111547
  }
@@ -111710,7 +112653,7 @@ var import_react67 = __toESM(require_react(), 1);
111710
112653
 
111711
112654
  // ../ggcoder/dist/ui/pixel.js
111712
112655
  init_esm_shims();
111713
- import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
112656
+ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
111714
112657
  import { homedir as homedir3 } from "os";
111715
112658
  import { join as join4 } from "path";
111716
112659
 
@@ -111750,7 +112693,7 @@ function visualWidth2(str2) {
111750
112693
  }
111751
112694
 
111752
112695
  // ../ggcoder/dist/ui/components/PlanOverlay.js
111753
- import { readdir, readFile as readFile2, unlink } from "fs/promises";
112696
+ import { readdir, readFile as readFile3, unlink } from "fs/promises";
111754
112697
  import { join as join5 } from "path";
111755
112698
  var PLAN_LOGO = [
111756
112699
  " \u2584\u2580\u2580\u2580 \u2584\u2580\u2580\u2580",
@@ -111787,11 +112730,11 @@ import { execFile as execFile4 } from "child_process";
111787
112730
 
111788
112731
  // ../ggcoder/dist/core/auto-update.js
111789
112732
  init_esm_shims();
111790
- import path37 from "path";
112733
+ import path39 from "path";
111791
112734
  import os10 from "os";
111792
112735
  var updater = createAutoUpdater({
111793
112736
  packageName: "@kenkaiiii/ggcoder",
111794
- stateFilePath: () => path37.join(os10.homedir(), ".gg", "update-state.json")
112737
+ stateFilePath: () => path39.join(os10.homedir(), ".gg", "update-state.json")
111795
112738
  });
111796
112739
  var checkAndAutoUpdate = updater.checkAndAutoUpdate;
111797
112740
  var getPendingUpdate = updater.getPendingUpdate;
@@ -111800,10 +112743,10 @@ var stopPeriodicUpdateCheck = updater.stopPeriodicUpdateCheck;
111800
112743
 
111801
112744
  // ../ggcoder/dist/core/setup-history.js
111802
112745
  init_esm_shims();
111803
- import fs33 from "fs";
111804
- import path38 from "path";
112746
+ import fs34 from "fs";
112747
+ import path40 from "path";
111805
112748
  import os11 from "os";
111806
- var HISTORY_PATH = path38.join(os11.homedir(), ".gg", "setup-history.json");
112749
+ var HISTORY_PATH = path40.join(os11.homedir(), ".gg", "setup-history.json");
111807
112750
 
111808
112751
  // ../ggcoder/dist/ui/components/RewindOverlay.js
111809
112752
  init_esm_shims();
@@ -112047,7 +112990,7 @@ function MessageResponse({ children, height, accentColor }) {
112047
112990
 
112048
112991
  // ../ggcoder/dist/ui/utils/highlight.js
112049
112992
  init_esm_shims();
112050
- import path39 from "path";
112993
+ import path41 from "path";
112051
112994
  var EXT_TO_LANG = {
112052
112995
  ts: "typescript",
112053
112996
  tsx: "typescript",
@@ -112075,7 +113018,7 @@ var EXT_TO_LANG = {
112075
113018
  dockerfile: "dockerfile"
112076
113019
  };
112077
113020
  function langFromPath(filePath) {
112078
- const ext = path39.extname(filePath).replace(/^\./, "").toLowerCase();
113021
+ const ext = path41.extname(filePath).replace(/^\./, "").toLowerCase();
112079
113022
  return EXT_TO_LANG[ext];
112080
113023
  }
112081
113024
  var hlModule;
@@ -112923,11 +113866,11 @@ var VIEWPORT_CLEAR = DISABLE_MODIFY_OTHER_KEYS + "\x1B[2J\x1B[H";
112923
113866
 
112924
113867
  // ../ggcoder/dist/core/project-discovery.js
112925
113868
  init_esm_shims();
112926
- import fs34 from "fs/promises";
113869
+ import fs35 from "fs/promises";
112927
113870
  import { createReadStream as createReadStream3 } from "fs";
112928
113871
  import readline3 from "readline";
112929
113872
  import os12 from "os";
112930
- import path40 from "path";
113873
+ import path43 from "path";
112931
113874
  async function discoverProjects() {
112932
113875
  const [gg, cc, cx] = await Promise.all([
112933
113876
  discoverGgcoderProjects(),
@@ -112970,21 +113913,21 @@ async function discoverGgcoderProjects() {
112970
113913
  const sessionsDir = getAppPaths().sessionsDir;
112971
113914
  let entries;
112972
113915
  try {
112973
- entries = await fs34.readdir(sessionsDir);
113916
+ entries = await fs35.readdir(sessionsDir);
112974
113917
  } catch {
112975
113918
  return [];
112976
113919
  }
112977
113920
  const results = [];
112978
113921
  for (const entry of entries) {
112979
- const dir = path40.join(sessionsDir, entry);
113922
+ const dir = path43.join(sessionsDir, entry);
112980
113923
  const mtime = await maxJsonlMtime(dir);
112981
113924
  if (mtime === null)
112982
113925
  continue;
112983
- const decoded = path40.resolve("/" + entry.replace(/_/g, "/"));
113926
+ const decoded = path43.resolve("/" + entry.replace(/_/g, "/"));
112984
113927
  if (!await isDirectory(decoded))
112985
113928
  continue;
112986
113929
  results.push({
112987
- name: path40.basename(decoded),
113930
+ name: path43.basename(decoded),
112988
113931
  path: decoded,
112989
113932
  lastActiveMs: mtime,
112990
113933
  lastActiveDisplay: formatRelativeTime(mtime),
@@ -112994,15 +113937,15 @@ async function discoverGgcoderProjects() {
112994
113937
  return results;
112995
113938
  }
112996
113939
  async function discoverClaudeProjects() {
112997
- const projectsDir = path40.join(os12.homedir(), ".claude", "projects");
113940
+ const projectsDir = path43.join(os12.homedir(), ".claude", "projects");
112998
113941
  let entries;
112999
113942
  try {
113000
- entries = await fs34.readdir(projectsDir);
113943
+ entries = await fs35.readdir(projectsDir);
113001
113944
  } catch {
113002
113945
  return [];
113003
113946
  }
113004
113947
  const results = await Promise.all(entries.map(async (entry) => {
113005
- const dir = path40.join(projectsDir, entry);
113948
+ const dir = path43.join(projectsDir, entry);
113006
113949
  const mtime = await maxJsonlMtime(dir);
113007
113950
  if (mtime === null)
113008
113951
  return null;
@@ -113012,7 +113955,7 @@ async function discoverClaudeProjects() {
113012
113955
  if (!await isDirectory(cwd2))
113013
113956
  return null;
113014
113957
  return {
113015
- name: path40.basename(cwd2),
113958
+ name: path43.basename(cwd2),
113016
113959
  path: cwd2,
113017
113960
  lastActiveMs: mtime,
113018
113961
  lastActiveDisplay: formatRelativeTime(mtime),
@@ -113022,7 +113965,7 @@ async function discoverClaudeProjects() {
113022
113965
  return results.filter((p) => p !== null);
113023
113966
  }
113024
113967
  async function discoverCodexProjects() {
113025
- const sessionsDir = path40.join(os12.homedir(), ".codex", "sessions");
113968
+ const sessionsDir = path43.join(os12.homedir(), ".codex", "sessions");
113026
113969
  if (!await isDirectory(sessionsDir))
113027
113970
  return [];
113028
113971
  const files = await collectJsonlFiles(sessionsDir, 4);
@@ -113043,7 +113986,7 @@ async function discoverCodexProjects() {
113043
113986
  if (!await isDirectory(cwd2))
113044
113987
  continue;
113045
113988
  results.push({
113046
- name: path40.basename(cwd2),
113989
+ name: path43.basename(cwd2),
113047
113990
  path: cwd2,
113048
113991
  lastActiveMs: mtime,
113049
113992
  lastActiveDisplay: formatRelativeTime(mtime),
@@ -113054,7 +113997,7 @@ async function discoverCodexProjects() {
113054
113997
  }
113055
113998
  async function isDirectory(p) {
113056
113999
  try {
113057
- const s = await fs34.stat(p);
114000
+ const s = await fs35.stat(p);
113058
114001
  return s.isDirectory();
113059
114002
  } catch {
113060
114003
  return false;
@@ -113079,15 +114022,15 @@ async function collectJsonlFiles(dir, maxDepth) {
113079
114022
  async function walk(current, depth) {
113080
114023
  let entries;
113081
114024
  try {
113082
- entries = await fs34.readdir(current, { withFileTypes: true });
114025
+ entries = await fs35.readdir(current, { withFileTypes: true });
113083
114026
  } catch {
113084
114027
  return;
113085
114028
  }
113086
114029
  for (const e of entries) {
113087
- const full = path40.join(current, e.name);
114030
+ const full = path43.join(current, e.name);
113088
114031
  if (e.isFile() && e.name.endsWith(".jsonl")) {
113089
114032
  try {
113090
- const s = await fs34.stat(full);
114033
+ const s = await fs35.stat(full);
113091
114034
  out.push({ path: full, mtime: s.mtimeMs });
113092
114035
  } catch {
113093
114036
  }
@@ -114455,17 +115398,17 @@ var EventQueue = class {
114455
115398
 
114456
115399
  // src/settings.ts
114457
115400
  init_esm_shims();
114458
- import fs35 from "fs/promises";
114459
- import path41 from "path";
115401
+ import fs36 from "fs/promises";
115402
+ import path44 from "path";
114460
115403
  function settingsPath() {
114461
- return path41.join(getAppPaths().agentDir, "boss", "settings.json");
115404
+ return path44.join(getAppPaths().agentDir, "boss", "settings.json");
114462
115405
  }
114463
115406
  async function ensureDir() {
114464
- await fs35.mkdir(path41.dirname(settingsPath()), { recursive: true, mode: 448 });
115407
+ await fs36.mkdir(path44.dirname(settingsPath()), { recursive: true, mode: 448 });
114465
115408
  }
114466
115409
  async function loadSettings() {
114467
115410
  try {
114468
- const content = await fs35.readFile(settingsPath(), "utf-8");
115411
+ const content = await fs36.readFile(settingsPath(), "utf-8");
114469
115412
  const parsed = JSON.parse(content);
114470
115413
  if (!parsed || typeof parsed !== "object") return {};
114471
115414
  return parsed;
@@ -114480,8 +115423,8 @@ async function saveSettings(patch) {
114480
115423
  const merged = { ...current, ...patch };
114481
115424
  await ensureDir();
114482
115425
  const tmp = `${settingsPath()}.${process.pid}.tmp`;
114483
- await fs35.writeFile(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
114484
- await fs35.rename(tmp, settingsPath());
115426
+ await fs36.writeFile(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
115427
+ await fs36.rename(tmp, settingsPath());
114485
115428
  });
114486
115429
  writeChain = next.catch(() => void 0);
114487
115430
  await next;
@@ -114873,18 +115816,18 @@ init_esm_shims();
114873
115816
  // src/tasks-store.ts
114874
115817
  init_esm_shims();
114875
115818
  var import_react98 = __toESM(require_react(), 1);
114876
- import fs36 from "fs/promises";
114877
- import path43 from "path";
114878
- import crypto10 from "crypto";
115819
+ import fs37 from "fs/promises";
115820
+ import path45 from "path";
115821
+ import crypto11 from "crypto";
114879
115822
  function getPlanPath() {
114880
- return path43.join(getAppPaths().agentDir, "boss", "plan.json");
115823
+ return path45.join(getAppPaths().agentDir, "boss", "plan.json");
114881
115824
  }
114882
115825
  async function ensureDir2() {
114883
- await fs36.mkdir(path43.dirname(getPlanPath()), { recursive: true, mode: 448 });
115826
+ await fs37.mkdir(path45.dirname(getPlanPath()), { recursive: true, mode: 448 });
114884
115827
  }
114885
115828
  async function loadPlan() {
114886
115829
  try {
114887
- const content = await fs36.readFile(getPlanPath(), "utf-8");
115830
+ const content = await fs37.readFile(getPlanPath(), "utf-8");
114888
115831
  const parsed = JSON.parse(content);
114889
115832
  return Array.isArray(parsed.tasks) ? parsed.tasks : [];
114890
115833
  } catch {
@@ -114898,8 +115841,8 @@ async function persist(tasks) {
114898
115841
  await ensureDir2();
114899
115842
  const finalPath = getPlanPath();
114900
115843
  const tmpPath = `${finalPath}.${process.pid}.tmp`;
114901
- await fs36.writeFile(tmpPath, snapshot, "utf-8");
114902
- await fs36.rename(tmpPath, finalPath);
115844
+ await fs37.writeFile(tmpPath, snapshot, "utf-8");
115845
+ await fs37.rename(tmpPath, finalPath);
114903
115846
  });
114904
115847
  persistChain = next.catch(() => void 0);
114905
115848
  await next;
@@ -114922,7 +115865,7 @@ function useTasksState() {
114922
115865
  return (0, import_react98.useSyncExternalStore)(subscribe2, getSnapshot2, getSnapshot2);
114923
115866
  }
114924
115867
  function newId() {
114925
- return crypto10.randomBytes(6).toString("hex");
115868
+ return crypto11.randomBytes(6).toString("hex");
114926
115869
  }
114927
115870
  function now() {
114928
115871
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -115169,11 +116112,11 @@ function createTaskTools(deps) {
115169
116112
  init_esm_shims();
115170
116113
  import { spawn as spawn8, execFileSync as execFileSync4 } from "child_process";
115171
116114
  import { fileURLToPath as fileURLToPath6 } from "url";
115172
- import path44 from "path";
115173
- import fs37 from "fs";
116115
+ import path46 from "path";
116116
+ import fs38 from "fs";
115174
116117
  function readMp3DurationMs(file2) {
115175
116118
  try {
115176
- const buf = fs37.readFileSync(file2);
116119
+ const buf = fs38.readFileSync(file2);
115177
116120
  let i = 0;
115178
116121
  if (buf.length >= 10 && buf[0] === 73 && buf[1] === 68 && buf[2] === 51) {
115179
116122
  const tagSize = (buf[6] & 127) << 21 | (buf[7] & 127) << 14 | (buf[8] & 127) << 7 | buf[9] & 127;
@@ -115230,10 +116173,10 @@ function getSplashAudioDurationMs() {
115230
116173
  return ms && ms > 0 ? ms : 1500;
115231
116174
  }
115232
116175
  function assetPath(name) {
115233
- const here = path44.dirname(fileURLToPath6(import.meta.url));
115234
- const dist = path44.join(here, name);
115235
- if (fs37.existsSync(dist)) return dist;
115236
- return path44.join(here, "..", "assets", name);
116176
+ const here = path46.dirname(fileURLToPath6(import.meta.url));
116177
+ const dist = path46.join(here, name);
116178
+ if (fs38.existsSync(dist)) return dist;
116179
+ return path46.join(here, "..", "assets", name);
115237
116180
  }
115238
116181
  function splashAssetPath() {
115239
116182
  return assetPath("splash.mp3");
@@ -115273,15 +116216,15 @@ function trySpawn(cmd, args) {
115273
116216
  }
115274
116217
  function isWsl() {
115275
116218
  if (process.platform !== "linux") return false;
115276
- return !!process.env.WSL_DISTRO_NAME || fs37.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop");
116219
+ return !!process.env.WSL_DISTRO_NAME || fs38.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop");
115277
116220
  }
115278
116221
  async function tryPlayOnWindowsHost(file2) {
115279
116222
  try {
115280
- const here = path44.dirname(fileURLToPath6(import.meta.url));
115281
- const devAssets = path44.resolve(here, "..", "assets");
115282
- const resolved = path44.resolve(file2);
115283
- const inDist = resolved === here || resolved.startsWith(here + path44.sep);
115284
- const inAssets = resolved === devAssets || resolved.startsWith(devAssets + path44.sep);
116223
+ const here = path46.dirname(fileURLToPath6(import.meta.url));
116224
+ const devAssets = path46.resolve(here, "..", "assets");
116225
+ const resolved = path46.resolve(file2);
116226
+ const inDist = resolved === here || resolved.startsWith(here + path46.sep);
116227
+ const inAssets = resolved === devAssets || resolved.startsWith(devAssets + path46.sep);
115285
116228
  if (!inDist && !inAssets) {
115286
116229
  return false;
115287
116230
  }
@@ -115345,7 +116288,7 @@ async function tryPlayOnWindowsHost(file2) {
115345
116288
  }
115346
116289
  }
115347
116290
  async function playFile(file2) {
115348
- if (!fs37.existsSync(file2)) return;
116291
+ if (!fs38.existsSync(file2)) return;
115349
116292
  const platform2 = process.platform;
115350
116293
  if (platform2 === "darwin") {
115351
116294
  await trySpawn("afplay", [file2]);
@@ -115443,37 +116386,37 @@ function truncateOversizedToolResults2(messages, opts = {}) {
115443
116386
 
115444
116387
  // src/sessions.ts
115445
116388
  init_esm_shims();
115446
- import fs38 from "fs/promises";
115447
- import path45 from "path";
115448
- import crypto11 from "crypto";
116389
+ import fs39 from "fs/promises";
116390
+ import path47 from "path";
116391
+ import crypto12 from "crypto";
115449
116392
  var BOSS_SUBDIR = "boss";
115450
116393
  var SESSIONS_SUBDIR = "sessions";
115451
116394
  function getBossDir() {
115452
- return path45.join(getAppPaths().agentDir, BOSS_SUBDIR);
116395
+ return path47.join(getAppPaths().agentDir, BOSS_SUBDIR);
115453
116396
  }
115454
116397
  function getSessionsDir() {
115455
- return path45.join(getBossDir(), SESSIONS_SUBDIR);
116398
+ return path47.join(getBossDir(), SESSIONS_SUBDIR);
115456
116399
  }
115457
116400
  async function ensureSessionsDir() {
115458
116401
  const dir = getSessionsDir();
115459
- await fs38.mkdir(dir, { recursive: true, mode: 448 });
116402
+ await fs39.mkdir(dir, { recursive: true, mode: 448 });
115460
116403
  return dir;
115461
116404
  }
115462
116405
  async function createSession2() {
115463
116406
  await ensureSessionsDir();
115464
- const id2 = `${Date.now()}-${crypto11.randomBytes(4).toString("hex")}`;
115465
- const filePath = path45.join(getSessionsDir(), `${id2}.jsonl`);
115466
- await fs38.writeFile(filePath, "", "utf-8");
116407
+ const id2 = `${Date.now()}-${crypto12.randomBytes(4).toString("hex")}`;
116408
+ const filePath = path47.join(getSessionsDir(), `${id2}.jsonl`);
116409
+ await fs39.writeFile(filePath, "", "utf-8");
115467
116410
  return { id: id2, filePath };
115468
116411
  }
115469
116412
  async function appendMessages(filePath, msgs) {
115470
116413
  if (msgs.length === 0) return;
115471
116414
  const lines = msgs.map((m) => JSON.stringify(m)).join("\n") + "\n";
115472
- await fs38.appendFile(filePath, lines, "utf-8");
116415
+ await fs39.appendFile(filePath, lines, "utf-8");
115473
116416
  }
115474
116417
  async function loadSession2(filePath) {
115475
116418
  try {
115476
- const content = await fs38.readFile(filePath, "utf-8");
116419
+ const content = await fs39.readFile(filePath, "utf-8");
115477
116420
  const lines = content.split("\n").filter((l) => l.length > 0);
115478
116421
  const messages = [];
115479
116422
  for (const line of lines) {
@@ -115489,8 +116432,8 @@ async function loadSession2(filePath) {
115489
116432
  }
115490
116433
  async function inspectSession(filePath, id2) {
115491
116434
  try {
115492
- const stat = await fs38.stat(filePath);
115493
- const content = await fs38.readFile(filePath, "utf-8");
116435
+ const stat = await fs39.stat(filePath);
116436
+ const content = await fs39.readFile(filePath, "utf-8");
115494
116437
  const lines = content.split("\n").filter((l) => l.length > 0);
115495
116438
  let firstUserMessage;
115496
116439
  for (const line of lines) {
@@ -115523,7 +116466,7 @@ async function listSessions2() {
115523
116466
  await ensureSessionsDir();
115524
116467
  let entries;
115525
116468
  try {
115526
- entries = await fs38.readdir(getSessionsDir());
116469
+ entries = await fs39.readdir(getSessionsDir());
115527
116470
  } catch {
115528
116471
  return [];
115529
116472
  }
@@ -115531,7 +116474,7 @@ async function listSessions2() {
115531
116474
  for (const name of entries) {
115532
116475
  if (!name.endsWith(".jsonl")) continue;
115533
116476
  const id2 = name.replace(/\.jsonl$/, "");
115534
- const info = await inspectSession(path45.join(getSessionsDir(), name), id2);
116477
+ const info = await inspectSession(path47.join(getSessionsDir(), name), id2);
115535
116478
  if (info) infos.push(info);
115536
116479
  }
115537
116480
  infos.sort((a, b) => b.lastModified - a.lastModified);
@@ -115542,7 +116485,7 @@ async function getMostRecent() {
115542
116485
  return all[0] ?? null;
115543
116486
  }
115544
116487
  async function getSessionById(id2) {
115545
- const filePath = path45.join(getSessionsDir(), `${id2}.jsonl`);
116488
+ const filePath = path47.join(getSessionsDir(), `${id2}.jsonl`);
115546
116489
  return inspectSession(filePath, id2);
115547
116490
  }
115548
116491
 
@@ -116497,4 +117440,4 @@ react/cjs/react-jsx-runtime.development.js:
116497
117440
  * LICENSE file in the root directory of this source tree.
116498
117441
  *)
116499
117442
  */
116500
- //# sourceMappingURL=chunk-CR6V6KR3.js.map
117443
+ //# sourceMappingURL=chunk-JGJ4EKFB.js.map