@google/gemini-cli 0.67.0-preview.0 → 0.68.0-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +18 -24
  2. package/bundle/{chunk-4HG5TEPY.js → chunk-44PCK4QK.js} +1 -1
  3. package/bundle/{chunk-QVUC4J7B.js → chunk-6A5BTTNC.js} +9 -11
  4. package/bundle/{chunk-BFZQO5OI.js → chunk-B2FKXXUH.js} +327 -106
  5. package/bundle/{chunk-GTLUHCZL.js → chunk-BKVNBJ5C.js} +327 -106
  6. package/bundle/{chunk-IQFMOPBP.js → chunk-CXMHAFLN.js} +2 -2
  7. package/bundle/{chunk-76P7AV5J.js → chunk-G7EMTV2Q.js} +327 -106
  8. package/bundle/{chunk-VIWQUHCM.js → chunk-HRM7UWGB.js} +9 -11
  9. package/bundle/{chunk-WTMW35TZ.js → chunk-JMHCFAD6.js} +1 -1
  10. package/bundle/{chunk-WANMK7VA.js → chunk-KKKD4FID.js} +2 -2
  11. package/bundle/{chunk-5FYAQBC3.js → chunk-L57AYV6U.js} +1558 -996
  12. package/bundle/{chunk-6HF2HP2S.js → chunk-LQDISFTJ.js} +2 -2
  13. package/bundle/{chunk-R6BM7NWC.js → chunk-ODU7Z2RJ.js} +1 -1
  14. package/bundle/{chunk-THOV46FY.js → chunk-OZOUOK43.js} +1 -1
  15. package/bundle/{chunk-FPCAOQBY.js → chunk-Q76ZDILI.js} +3 -3
  16. package/bundle/{chunk-EAO5GUJT.js → chunk-RCF66HCI.js} +1625 -1006
  17. package/bundle/{chunk-FYX6LSG6.js → chunk-RD2EMHV2.js} +1 -1
  18. package/bundle/{chunk-QPO46AOD.js → chunk-VBHMFLBY.js} +1 -1
  19. package/bundle/{chunk-2BG2OMW3.js → chunk-VCO4TMD6.js} +9 -11
  20. package/bundle/{chunk-GI2BMP6K.js → chunk-WEP47ZZU.js} +1 -1
  21. package/bundle/{chunk-RNBD6XQX.js → chunk-XPTXBYQQ.js} +3 -3
  22. package/bundle/{chunk-SJ64DOGM.js → chunk-XVNEFQR3.js} +1 -1
  23. package/bundle/{chunk-JLA2J5MI.js → chunk-YPPJDFYP.js} +3 -3
  24. package/bundle/{chunk-SAQV5Q3G.js → chunk-ZEK4UYYW.js} +1 -1
  25. package/bundle/{chunk-HWPQINPO.js → chunk-ZZOOHVBL.js} +1627 -1008
  26. package/bundle/{cleanup-QXMGRCCJ.js → cleanup-CCR2EOHA.js} +2 -2
  27. package/bundle/{cleanup-R3QZGL6L.js → cleanup-OQV2G5Y3.js} +2 -2
  28. package/bundle/{cleanup-S6DWGSDA.js → cleanup-T24OFMOA.js} +2 -2
  29. package/bundle/{core-NQRYED5S.js → core-NQRKBS47.js} +3 -1
  30. package/bundle/{dist-XT4ZXTSC.js → core-UIPNZ5VU.js} +3 -1
  31. package/bundle/{devtoolsService-GPRO4RRU.js → devtoolsService-3G5ZA3JV.js} +2 -2
  32. package/bundle/{devtoolsService-WR3IFLZC.js → devtoolsService-EWNQDTC7.js} +2 -2
  33. package/bundle/{devtoolsService-ALST4BXH.js → devtoolsService-V3OEHE5V.js} +2 -2
  34. package/bundle/{core-3N7UGMI2.js → dist-OYZDNSTI.js} +3 -1
  35. package/bundle/docs/changelogs/index.md +24 -0
  36. package/bundle/docs/changelogs/latest.md +83 -90
  37. package/bundle/docs/changelogs/preview.md +89 -87
  38. package/bundle/docs/cli/sandbox.md +8 -2
  39. package/bundle/docs/cli/themes.md +6 -3
  40. package/bundle/docs/extensions/releasing.md +32 -0
  41. package/bundle/docs/reference/configuration.md +2 -10
  42. package/bundle/{gemini-K3EMSEQ5.js → gemini-2P73372G.js} +122 -24
  43. package/bundle/{gemini-MWKDIT7M.js → gemini-FSHMUCSM.js} +122 -24
  44. package/bundle/{gemini-5DCBUXWG.js → gemini-YFCTZ76S.js} +121 -23
  45. package/bundle/gemini.js +7 -7
  46. package/bundle/{interactiveCli-3B2SSFOJ.js → interactiveCli-F5RRE2VJ.js} +1350 -1145
  47. package/bundle/{interactiveCli-63JD5B2Z.js → interactiveCli-I75IWUIA.js} +1350 -1145
  48. package/bundle/{interactiveCli-QUIZ4FA2.js → interactiveCli-X54KN2EM.js} +1350 -1145
  49. package/bundle/{liteRtServerManager-M6NTFF5C.js → liteRtServerManager-FLPMMDNM.js} +4 -4
  50. package/bundle/{liteRtServerManager-QHOOPEJV.js → liteRtServerManager-JTOIS4KU.js} +4 -4
  51. package/bundle/{liteRtServerManager-AQUTLRTC.js → liteRtServerManager-UVQ2I6NL.js} +4 -4
  52. package/bundle/{oauth2-provider-3JCCMSND.js → oauth2-provider-AYO4BU7A.js} +1 -1
  53. package/bundle/{oauth2-provider-X55SWENY.js → oauth2-provider-NCQY7TJE.js} +1 -1
  54. package/bundle/{oauth2-provider-GCJTOYXK.js → oauth2-provider-VMBYZOC7.js} +1 -1
  55. package/bundle/{start-VKITAPOP.js → start-DFHM4HI4.js} +6 -6
  56. package/bundle/{start-X73XUSSH.js → start-IXQ2E7L6.js} +6 -6
  57. package/bundle/{start-4QIXXTMW.js → start-YEKGRZVH.js} +6 -6
  58. package/package.json +1 -1
@@ -2,7 +2,7 @@ const require = (await import('node:module')).createRequire(import.meta.url); co
2
2
  import {
3
3
  exitCli,
4
4
  require_source
5
- } from "./chunk-WTMW35TZ.js";
5
+ } from "./chunk-JMHCFAD6.js";
6
6
  import {
7
7
  AppEvent,
8
8
  appEvents
@@ -69,16 +69,16 @@ import {
69
69
  use_stdin_default,
70
70
  use_stdout_default,
71
71
  validateCustomTheme
72
- } from "./chunk-QVUC4J7B.js";
72
+ } from "./chunk-HRM7UWGB.js";
73
73
  import {
74
74
  isDevelopment,
75
75
  require_semver
76
- } from "./chunk-WANMK7VA.js";
76
+ } from "./chunk-CXMHAFLN.js";
77
77
  import {
78
78
  emptyIcon,
79
79
  mapCoreStatusToDisplayStatus,
80
80
  require_react
81
- } from "./chunk-SAQV5Q3G.js";
81
+ } from "./chunk-VBHMFLBY.js";
82
82
  import {
83
83
  ALL_EDITORS,
84
84
  ApprovalMode,
@@ -219,6 +219,7 @@ import {
219
219
  require_cross_spawn,
220
220
  require_is_stream,
221
221
  require_path_key,
222
+ require_proper_lockfile,
222
223
  require_pump,
223
224
  require_toml,
224
225
  resetBrowserSession,
@@ -239,7 +240,7 @@ import {
239
240
  uiTelemetryService,
240
241
  unescapePath,
241
242
  validateUrlDestination
242
- } from "./chunk-HWPQINPO.js";
243
+ } from "./chunk-RCF66HCI.js";
243
244
  import {
244
245
  require_src
245
246
  } from "./chunk-L6PII3GR.js";
@@ -6500,7 +6501,7 @@ var require_extract_zip = __commonJS({
6500
6501
  var stream = __require("stream");
6501
6502
  var yauzl = require_yauzl();
6502
6503
  var openZip = promisify5(yauzl.open);
6503
- var pipeline2 = promisify5(stream.pipeline);
6504
+ var pipeline3 = promisify5(stream.pipeline);
6504
6505
  var Extractor = class {
6505
6506
  constructor(zipPath, opts) {
6506
6507
  this.zipPath = zipPath;
@@ -6588,7 +6589,7 @@ var require_extract_zip = __commonJS({
6588
6589
  debug("creating symlink", link, dest);
6589
6590
  await fs33.symlink(link, dest);
6590
6591
  } else {
6591
- await pipeline2(readStream, createWriteStream5(dest, { mode: procMode }));
6592
+ await pipeline3(readStream, createWriteStream5(dest, { mode: procMode }));
6592
6593
  }
6593
6594
  }
6594
6595
  getExtractedMode(entryMode, isDir) {
@@ -15324,11 +15325,11 @@ var require_util4 = __commonJS({
15324
15325
  var { isUint8Array } = __require("node:util/types");
15325
15326
  var { webidl } = require_webidl();
15326
15327
  var supportedHashes = [];
15327
- var crypto3;
15328
+ var crypto4;
15328
15329
  try {
15329
- crypto3 = __require("node:crypto");
15330
+ crypto4 = __require("node:crypto");
15330
15331
  const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
15331
- supportedHashes = crypto3.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
15332
+ supportedHashes = crypto4.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
15332
15333
  } catch {
15333
15334
  }
15334
15335
  function responseURL(response) {
@@ -15631,7 +15632,7 @@ var require_util4 = __commonJS({
15631
15632
  return isOriginPotentiallyTrustworthy(url.origin);
15632
15633
  }
15633
15634
  function bytesMatch(bytes, metadataList) {
15634
- if (crypto3 === void 0) {
15635
+ if (crypto4 === void 0) {
15635
15636
  return true;
15636
15637
  }
15637
15638
  const parsedMetadata = parseMetadata(metadataList);
@@ -15646,7 +15647,7 @@ var require_util4 = __commonJS({
15646
15647
  for (const item of metadata) {
15647
15648
  const algorithm = item.algo;
15648
15649
  const expectedValue = item.hash;
15649
- let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64");
15650
+ let actualValue = crypto4.createHash(algorithm).update(bytes).digest("base64");
15650
15651
  if (actualValue[actualValue.length - 1] === "=") {
15651
15652
  if (actualValue[actualValue.length - 2] === "=") {
15652
15653
  actualValue = actualValue.slice(0, -2);
@@ -16664,8 +16665,8 @@ var require_body = __commonJS({
16664
16665
  var { multipartFormDataParser } = require_formdata_parser();
16665
16666
  var random;
16666
16667
  try {
16667
- const crypto3 = __require("node:crypto");
16668
- random = (max) => crypto3.randomInt(0, max);
16668
+ const crypto4 = __require("node:crypto");
16669
+ random = (max) => crypto4.randomInt(0, max);
16669
16670
  } catch {
16670
16671
  random = (max) => Math.floor(Math.random() * max);
16671
16672
  }
@@ -18116,7 +18117,7 @@ var require_client_h2 = __commonJS({
18116
18117
  "packages/cli/node_modules/undici/lib/dispatcher/client-h2.js"(exports, module) {
18117
18118
  "use strict";
18118
18119
  var assert = __require("node:assert");
18119
- var { pipeline: pipeline2 } = __require("node:stream");
18120
+ var { pipeline: pipeline3 } = __require("node:stream");
18120
18121
  var util2 = require_util3();
18121
18122
  var {
18122
18123
  RequestContentLengthMismatchError,
@@ -18611,7 +18612,7 @@ var require_client_h2 = __commonJS({
18611
18612
  }
18612
18613
  function writeStream(abort, socket, expectsPayload, h2stream, body, client, request, contentLength) {
18613
18614
  assert(contentLength !== 0 || client[kRunning] === 0, "stream body cannot be pipelined");
18614
- const pipe = pipeline2(
18615
+ const pipe = pipeline3(
18615
18616
  body,
18616
18617
  h2stream,
18617
18618
  (err) => {
@@ -21505,7 +21506,7 @@ var require_api_pipeline = __commonJS({
21505
21506
  util2.destroy(ret, err);
21506
21507
  }
21507
21508
  };
21508
- function pipeline2(opts, handler2) {
21509
+ function pipeline3(opts, handler2) {
21509
21510
  try {
21510
21511
  const pipelineHandler = new PipelineHandler(opts, handler2);
21511
21512
  this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler);
@@ -21514,7 +21515,7 @@ var require_api_pipeline = __commonJS({
21514
21515
  return new PassThrough().destroy(err);
21515
21516
  }
21516
21517
  }
21517
- module.exports = pipeline2;
21518
+ module.exports = pipeline3;
21518
21519
  }
21519
21520
  });
21520
21521
 
@@ -26930,7 +26931,7 @@ var require_fetch = __commonJS({
26930
26931
  subresourceSet
26931
26932
  } = require_constants3();
26932
26933
  var EE = __require("node:events");
26933
- var { Readable, pipeline: pipeline2, finished, isErrored, isReadable } = __require("node:stream");
26934
+ var { Readable, pipeline: pipeline3, finished, isErrored, isReadable } = __require("node:stream");
26934
26935
  var { addAbortListener, bufferToLowerCasedHeaderName } = require_util3();
26935
26936
  var { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require_data_url();
26936
26937
  var { getGlobalDispatcher } = require_global2();
@@ -27873,7 +27874,7 @@ var require_fetch = __commonJS({
27873
27874
  status,
27874
27875
  statusText,
27875
27876
  headersList,
27876
- body: decoders.length ? pipeline2(this.body, ...decoders, (err) => {
27877
+ body: decoders.length ? pipeline3(this.body, ...decoders, (err) => {
27877
27878
  if (err) {
27878
27879
  this.onError(err);
27879
27880
  }
@@ -29582,13 +29583,13 @@ var require_frame = __commonJS({
29582
29583
  "use strict";
29583
29584
  var { maxUnsigned16Bit, opcodes } = require_constants5();
29584
29585
  var BUFFER_SIZE = 8 * 1024;
29585
- var crypto3;
29586
+ var crypto4;
29586
29587
  var buffer = null;
29587
29588
  var bufIdx = BUFFER_SIZE;
29588
29589
  try {
29589
- crypto3 = __require("node:crypto");
29590
+ crypto4 = __require("node:crypto");
29590
29591
  } catch {
29591
- crypto3 = {
29592
+ crypto4 = {
29592
29593
  // not full compatibility, but minimum.
29593
29594
  randomFillSync: function randomFillSync(buffer2, _offset, _size) {
29594
29595
  for (let i = 0; i < buffer2.length; ++i) {
@@ -29601,7 +29602,7 @@ var require_frame = __commonJS({
29601
29602
  function generateMask() {
29602
29603
  if (bufIdx === BUFFER_SIZE) {
29603
29604
  bufIdx = 0;
29604
- crypto3.randomFillSync(buffer ??= Buffer.allocUnsafeSlow(BUFFER_SIZE), 0, BUFFER_SIZE);
29605
+ crypto4.randomFillSync(buffer ??= Buffer.allocUnsafeSlow(BUFFER_SIZE), 0, BUFFER_SIZE);
29605
29606
  }
29606
29607
  return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]];
29607
29608
  }
@@ -29699,9 +29700,9 @@ var require_connection = __commonJS({
29699
29700
  var { getDecodeSplit } = require_util4();
29700
29701
  var { WebsocketFrameSend } = require_frame();
29701
29702
  var assert = __require("node:assert");
29702
- var crypto3;
29703
+ var crypto4;
29703
29704
  try {
29704
- crypto3 = __require("node:crypto");
29705
+ crypto4 = __require("node:crypto");
29705
29706
  } catch {
29706
29707
  }
29707
29708
  function establishWebSocketConnection(url, protocols, client, handler2, options) {
@@ -29721,7 +29722,7 @@ var require_connection = __commonJS({
29721
29722
  const headersList = getHeadersList(new Headers(options.headers));
29722
29723
  request.headersList = headersList;
29723
29724
  }
29724
- const keyValue = crypto3.randomBytes(16).toString("base64");
29725
+ const keyValue = crypto4.randomBytes(16).toString("base64");
29725
29726
  request.headersList.append("sec-websocket-key", keyValue, true);
29726
29727
  request.headersList.append("sec-websocket-version", "13", true);
29727
29728
  for (const protocol of protocols) {
@@ -29754,7 +29755,7 @@ var require_connection = __commonJS({
29754
29755
  return;
29755
29756
  }
29756
29757
  const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
29757
- const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64");
29758
+ const digest = crypto4.createHash("sha1").update(keyValue + uid).digest("base64");
29758
29759
  if (secWSAccept !== digest) {
29759
29760
  failWebsocketConnection(handler2, 1002, "Incorrect hash received in Sec-WebSocket-Accept header.");
29760
29761
  return;
@@ -31366,7 +31367,7 @@ ${value}`;
31366
31367
  var require_eventsource = __commonJS({
31367
31368
  "packages/cli/node_modules/undici/lib/web/eventsource/eventsource.js"(exports, module) {
31368
31369
  "use strict";
31369
- var { pipeline: pipeline2 } = __require("node:stream");
31370
+ var { pipeline: pipeline3 } = __require("node:stream");
31370
31371
  var { fetching } = require_fetch();
31371
31372
  var { makeRequest } = require_request2();
31372
31373
  var { webidl } = require_webidl();
@@ -31527,7 +31528,7 @@ var require_eventsource = __commonJS({
31527
31528
  ));
31528
31529
  }
31529
31530
  });
31530
- pipeline2(
31531
+ pipeline3(
31531
31532
  response.body.stream,
31532
31533
  eventSourceStream,
31533
31534
  (error) => {
@@ -38661,6 +38662,7 @@ async function getMissingSettings(extensionConfig, extensionId, workspaceDir) {
38661
38662
 
38662
38663
  // packages/cli/src/config/extension-manager.ts
38663
38664
  var import_chalk2 = __toESM(require_source(), 1);
38665
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
38664
38666
  import * as fs12 from "node:fs";
38665
38667
  import * as path9 from "node:path";
38666
38668
  import { stat } from "node:fs/promises";
@@ -38832,7 +38834,7 @@ var ExtensionEnablementManager = class {
38832
38834
  };
38833
38835
 
38834
38836
  // packages/cli/src/config/extension-manager.ts
38835
- import { createHash as createHash2, randomUUID } from "node:crypto";
38837
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
38836
38838
 
38837
38839
  // packages/cli/src/config/extension.ts
38838
38840
  import * as fs8 from "node:fs";
@@ -38929,10 +38931,12 @@ function extensionUpdatesReducer(state, action) {
38929
38931
  }
38930
38932
 
38931
38933
  // packages/cli/src/config/extensions/github.ts
38934
+ import * as crypto2 from "node:crypto";
38932
38935
  import * as os3 from "node:os";
38933
38936
  import * as https2 from "node:https";
38934
38937
  import * as fs10 from "node:fs";
38935
38938
  import * as path8 from "node:path";
38939
+ import { pipeline } from "node:stream/promises";
38936
38940
 
38937
38941
  // packages/cli/node_modules/tar/dist/esm/index.min.js
38938
38942
  import Hr from "events";
@@ -41847,6 +41851,14 @@ import * as https from "node:https";
41847
41851
  function getGitHubToken() {
41848
41852
  return process.env["GITHUB_TOKEN"] || void 0;
41849
41853
  }
41854
+ function isTrustedGitHubUrl(url) {
41855
+ try {
41856
+ const parsedUrl = new URL(url);
41857
+ return parsedUrl.protocol === "https:" && (parsedUrl.hostname === "github.com" || parsedUrl.hostname.endsWith(".github.com"));
41858
+ } catch {
41859
+ return false;
41860
+ }
41861
+ }
41850
41862
  var lookupPublicAddress = (hostname, options, callback) => safeLookup(
41851
41863
  hostname,
41852
41864
  {
@@ -41856,6 +41868,7 @@ var lookupPublicAddress = (hostname, options, callback) => safeLookup(
41856
41868
  callback
41857
41869
  );
41858
41870
  var REDIRECT_STATUS_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
41871
+ var REQUEST_TIMEOUT_MS = 3e4;
41859
41872
  async function fetchJson(url, redirectCount = 0) {
41860
41873
  if (!await validateUrlDestination(url)) {
41861
41874
  throw new Error(`Access to blocked or private host ${url} is not allowed.`);
@@ -41864,14 +41877,8 @@ async function fetchJson(url, redirectCount = 0) {
41864
41877
  "User-Agent": "gemini-cli"
41865
41878
  };
41866
41879
  const token = getGitHubToken();
41867
- if (token) {
41868
- try {
41869
- const parsedUrl = new URL(url);
41870
- if (parsedUrl.protocol === "https:" && (parsedUrl.hostname === "github.com" || parsedUrl.hostname.endsWith(".github.com"))) {
41871
- headers.Authorization = `token ${token}`;
41872
- }
41873
- } catch {
41874
- }
41880
+ if (token && isTrustedGitHubUrl(url)) {
41881
+ headers.Authorization = `token ${token}`;
41875
41882
  }
41876
41883
  return new Promise((resolve9, reject) => {
41877
41884
  let settled = false;
@@ -41896,7 +41903,7 @@ async function fetchJson(url, redirectCount = 0) {
41896
41903
  const requestOptions = {
41897
41904
  headers,
41898
41905
  lookup: lookupPublicAddress,
41899
- timeout: 3e4
41906
+ timeout: REQUEST_TIMEOUT_MS
41900
41907
  };
41901
41908
  const req = https.get(url, requestOptions, (res) => {
41902
41909
  res.on(
@@ -41989,7 +41996,9 @@ async function fetchJson(url, redirectCount = 0) {
41989
41996
  });
41990
41997
  req.on("error", (error) => failUnlessRedirecting(() => error));
41991
41998
  req.on("timeout", () => {
41992
- failUnlessRedirecting(() => new Error("Request timed out after 30000ms"));
41999
+ failUnlessRedirecting(
42000
+ () => new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`)
42001
+ );
41993
42002
  req.destroy();
41994
42003
  });
41995
42004
  });
@@ -42059,7 +42068,7 @@ function tryParseGithubUrl(source2) {
42059
42068
  );
42060
42069
  }
42061
42070
  const owner = parts[0];
42062
- const repo = parts[1].replace(".git", "");
42071
+ const repo = parts[1].replace(/\.git$/i, "");
42063
42072
  return {
42064
42073
  owner,
42065
42074
  repo
@@ -42340,39 +42349,175 @@ function findReleaseAsset(assets) {
42340
42349
  return void 0;
42341
42350
  }
42342
42351
  async function downloadFile(url, dest, options, redirectCount = 0) {
42352
+ let parsedUrl;
42353
+ try {
42354
+ parsedUrl = new URL(url);
42355
+ } catch (error) {
42356
+ throw new Error(`Invalid download URL ${url}: ${getErrorMessage(error)}`, {
42357
+ cause: error
42358
+ });
42359
+ }
42360
+ if (parsedUrl.protocol !== "https:") {
42361
+ throw new Error(
42362
+ `Refusing to download from insecure protocol ${parsedUrl.protocol} for URL ${url}. Only HTTPS is supported.`
42363
+ );
42364
+ }
42365
+ const requestUrl = parsedUrl.toString();
42366
+ if (!await validateUrlDestination(requestUrl)) {
42367
+ throw new Error(
42368
+ `Access to blocked or private host ${requestUrl} is not allowed.`
42369
+ );
42370
+ }
42343
42371
  const headers = {
42344
42372
  "User-agent": "gemini-cli",
42345
42373
  Accept: "application/octet-stream",
42346
42374
  ...options?.headers
42347
42375
  };
42376
+ const trustedGitHubUrl = isTrustedGitHubUrl(requestUrl);
42377
+ if (!trustedGitHubUrl) {
42378
+ for (const key of Object.keys(headers)) {
42379
+ if (key.toLowerCase() === "authorization") {
42380
+ delete headers[key];
42381
+ }
42382
+ }
42383
+ }
42348
42384
  const token = getGitHubToken();
42349
- if (token) {
42385
+ if (token && trustedGitHubUrl) {
42350
42386
  headers["Authorization"] = `token ${token}`;
42351
42387
  }
42352
- return new Promise((resolve9, reject) => {
42353
- https2.get(url, { headers }, (res) => {
42354
- if (res.statusCode === 302 || res.statusCode === 301) {
42355
- if (redirectCount >= 10) {
42356
- return reject(new Error("Too many redirects"));
42388
+ let tempDest;
42389
+ let downloadPipeline;
42390
+ try {
42391
+ await new Promise((resolve9, reject) => {
42392
+ let settled = false;
42393
+ let isRedirecting = false;
42394
+ let responseStream;
42395
+ const settleResolve = () => {
42396
+ if (!settled) {
42397
+ settled = true;
42398
+ resolve9();
42357
42399
  }
42358
- if (!res.headers.location) {
42359
- return reject(
42360
- new Error("Redirect response missing Location header")
42400
+ };
42401
+ const settleReject = (error) => {
42402
+ if (!settled) {
42403
+ settled = true;
42404
+ reject(
42405
+ error instanceof Error ? error : new Error(getErrorMessage(error))
42361
42406
  );
42362
42407
  }
42363
- downloadFile(res.headers.location, dest, options, redirectCount + 1).then(resolve9).catch(reject);
42364
- return;
42408
+ };
42409
+ const requestOptions = {
42410
+ headers,
42411
+ lookup: lookupPublicAddress,
42412
+ timeout: REQUEST_TIMEOUT_MS
42413
+ };
42414
+ const req = https2.get(requestUrl, requestOptions, (res) => {
42415
+ res.on("error", (error) => {
42416
+ if (!isRedirecting) {
42417
+ settleReject(error);
42418
+ }
42419
+ });
42420
+ if (res.statusCode && REDIRECT_STATUS_CODES.has(res.statusCode)) {
42421
+ if (redirectCount >= 10) {
42422
+ res.resume?.();
42423
+ settleReject(new Error("Too many redirects"));
42424
+ return;
42425
+ }
42426
+ if (!res.headers.location) {
42427
+ res.resume?.();
42428
+ settleReject(
42429
+ new Error("Redirect response missing Location header")
42430
+ );
42431
+ return;
42432
+ }
42433
+ let redirectUrl;
42434
+ try {
42435
+ redirectUrl = new URL(res.headers.location, requestUrl).toString();
42436
+ } catch (error) {
42437
+ res.resume?.();
42438
+ settleReject(
42439
+ new Error(
42440
+ `Invalid redirect URL from ${requestUrl} (status ${res.statusCode}): ${getErrorMessage(error)}`,
42441
+ { cause: error }
42442
+ )
42443
+ );
42444
+ return;
42445
+ }
42446
+ isRedirecting = true;
42447
+ res.resume?.();
42448
+ void downloadFile(redirectUrl, dest, options, redirectCount + 1).then(
42449
+ settleResolve,
42450
+ settleReject
42451
+ );
42452
+ return;
42453
+ }
42454
+ if (res.statusCode !== 200) {
42455
+ res.resume?.();
42456
+ settleReject(
42457
+ new Error(`Request failed with status code ${res.statusCode}`)
42458
+ );
42459
+ return;
42460
+ }
42461
+ responseStream = res;
42462
+ const currentTempDest = `${dest}.${crypto2.randomUUID()}.tmp`;
42463
+ tempDest = currentTempDest;
42464
+ let file;
42465
+ try {
42466
+ file = fs10.createWriteStream(currentTempDest);
42467
+ } catch (error) {
42468
+ res.destroy?.();
42469
+ settleReject(error);
42470
+ return;
42471
+ }
42472
+ file.on("error", settleReject);
42473
+ downloadPipeline = pipeline(res, file);
42474
+ void downloadPipeline.then(() => {
42475
+ if (res.complete === false) {
42476
+ settleReject(
42477
+ new Error(
42478
+ `Response ended prematurely while downloading ${requestUrl}`
42479
+ )
42480
+ );
42481
+ return;
42482
+ }
42483
+ settleResolve();
42484
+ }, settleReject);
42485
+ });
42486
+ req.on("error", (error) => {
42487
+ if (isRedirecting) {
42488
+ return;
42489
+ }
42490
+ settleReject(error);
42491
+ responseStream?.destroy?.();
42492
+ });
42493
+ req.on("timeout", () => {
42494
+ if (!isRedirecting) {
42495
+ settleReject(
42496
+ new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`)
42497
+ );
42498
+ responseStream?.destroy?.();
42499
+ }
42500
+ req.destroy?.();
42501
+ });
42502
+ });
42503
+ if (tempDest) {
42504
+ await fs10.promises.rename(tempDest, dest);
42505
+ }
42506
+ } catch (error) {
42507
+ if (downloadPipeline) {
42508
+ try {
42509
+ await downloadPipeline;
42510
+ } catch {
42365
42511
  }
42366
- if (res.statusCode !== 200) {
42367
- return reject(
42368
- new Error(`Request failed with status code ${res.statusCode}`)
42369
- );
42512
+ }
42513
+ if (tempDest) {
42514
+ try {
42515
+ await fs10.promises.unlink(tempDest);
42516
+ } catch {
42370
42517
  }
42371
- const file = fs10.createWriteStream(dest);
42372
- res.pipe(file);
42373
- file.on("finish", () => file.close(resolve9));
42374
- }).on("error", reject);
42375
- });
42518
+ }
42519
+ throw error;
42520
+ }
42376
42521
  }
42377
42522
  async function extractFile(file, dest) {
42378
42523
  if (file.endsWith(".tar.gz")) {
@@ -42600,6 +42745,9 @@ async function removeDirectoryWithRetry(path37, options = {}) {
42600
42745
  }
42601
42746
 
42602
42747
  // packages/cli/src/config/extension-manager.ts
42748
+ var INSTALL_LOCK_SUFFIX = ".lock";
42749
+ var INSTALL_LOCK_STALE_MS = 15e3;
42750
+ var INSTALL_LOCK_RETRIES = { retries: 15, minTimeout: 200, maxTimeout: 500 };
42603
42751
  var ExtensionManager = class extends ExtensionLoader {
42604
42752
  extensionEnablementManager;
42605
42753
  integrityManager;
@@ -42620,7 +42768,7 @@ var ExtensionManager = class extends ExtensionLoader {
42620
42768
  this.telemetryConfig = new Config({
42621
42769
  telemetry: options.settings.telemetry,
42622
42770
  interactive: false,
42623
- sessionId: randomUUID(),
42771
+ sessionId: randomUUID2(),
42624
42772
  clientVersion: options.clientVersion ?? "unknown",
42625
42773
  targetDir: options.workspaceDir,
42626
42774
  cwd: options.workspaceDir,
@@ -42744,6 +42892,7 @@ Would you like to attempt to install via "git clone" instead?`
42744
42892
  } else {
42745
42893
  throw new Error(`Unsupported install type: ${installMetadata.type}`);
42746
42894
  }
42895
+ let releaseLock;
42747
42896
  try {
42748
42897
  newExtensionConfig = await this.loadExtensionConfig(localSourcePath);
42749
42898
  const newExtensionName = newExtensionConfig.name;
@@ -42792,11 +42941,19 @@ Would you like to attempt to install via "git clone" instead?`
42792
42941
  const destinationPath = new ExtensionStorage(
42793
42942
  newExtensionName
42794
42943
  ).getExtensionDir();
42795
- if ((!isUpdate || newExtensionName !== previousName) && fs12.existsSync(destinationPath)) {
42796
- throw new Error(
42797
- `Cannot install extension "${newExtensionName}" because a directory with that name already exists. Please remove it manually.`
42798
- );
42799
- }
42944
+ const assertDestinationIsAvailable = () => {
42945
+ if ((!isUpdate || newExtensionName !== previousName) && fs12.existsSync(destinationPath)) {
42946
+ throw new Error(
42947
+ `Cannot install extension "${newExtensionName}" because a directory with that name already exists. Please remove it manually.`
42948
+ );
42949
+ }
42950
+ };
42951
+ assertDestinationIsAvailable();
42952
+ releaseLock = await acquireExtensionInstallLock(
42953
+ destinationPath,
42954
+ newExtensionName
42955
+ );
42956
+ assertDestinationIsAvailable();
42800
42957
  let previousSettings;
42801
42958
  let wasEnabledGlobally = false;
42802
42959
  let wasEnabledWorkspace = false;
@@ -42909,6 +43066,15 @@ Would you like to attempt to install via "git clone" instead?`
42909
43066
  );
42910
43067
  }
42911
43068
  } finally {
43069
+ if (releaseLock) {
43070
+ try {
43071
+ await releaseLock();
43072
+ } catch (releaseError) {
43073
+ debugLogger.warn(
43074
+ `Failed to release the install lock for extension "${newExtensionConfig?.name}": ${getErrorMessage(releaseError)}`
43075
+ );
43076
+ }
43077
+ }
42912
43078
  if (tempDir) {
42913
43079
  try {
42914
43080
  await removeDirectoryWithRetry(tempDir);
@@ -43079,6 +43245,9 @@ Would you like to attempt to install via "git clone" instead?`
43079
43245
  * Builds an extension without side effects (does not mutate loadedExtensions or start it).
43080
43246
  */
43081
43247
  async _buildExtension(extensionDir) {
43248
+ if (path9.basename(extensionDir).endsWith(INSTALL_LOCK_SUFFIX)) {
43249
+ return null;
43250
+ }
43082
43251
  try {
43083
43252
  const stats = await fs12.promises.stat(extensionDir);
43084
43253
  if (!stats.isDirectory()) {
@@ -43564,6 +43733,32 @@ async function copyExtension(source2, destination) {
43564
43733
  await fs12.promises.cp(source2, destination, { recursive: true });
43565
43734
  await makeWritableRecursive(destination);
43566
43735
  }
43736
+ async function acquireExtensionInstallLock(destinationPath, extensionName) {
43737
+ await fs12.promises.mkdir(path9.dirname(destinationPath), { recursive: true });
43738
+ try {
43739
+ return await (0, import_proper_lockfile.lock)(destinationPath, {
43740
+ // `destinationPath` usually does not exist yet. With `realpath: false`,
43741
+ // proper-lockfile neither resolves nor stats it; it only creates and
43742
+ // checks the `<destinationPath>.lock` directory.
43743
+ realpath: false,
43744
+ stale: INSTALL_LOCK_STALE_MS,
43745
+ retries: INSTALL_LOCK_RETRIES,
43746
+ // The default handler throws from a timer, which would crash the CLI.
43747
+ onCompromised: (error) => {
43748
+ debugLogger.warn(
43749
+ `Lost the install lock for extension "${extensionName}": ${getErrorMessage(error)}`
43750
+ );
43751
+ }
43752
+ });
43753
+ } catch (error) {
43754
+ if (isNodeError(error) && error.code === "ELOCKED") {
43755
+ throw new Error(
43756
+ `Cannot install extension "${extensionName}" because another installation or update of it is already in progress. Please try again later.`
43757
+ );
43758
+ }
43759
+ throw error;
43760
+ }
43761
+ }
43567
43762
  function getContextFileNames(config) {
43568
43763
  if (!config.contextFileName) {
43569
43764
  return ["GEMINI.md"];
@@ -44668,8 +44863,8 @@ var import_execa = __toESM(require_execa(), 1);
44668
44863
 
44669
44864
  // node_modules/crypto-random-string/index.js
44670
44865
  import { promisify } from "util";
44671
- import crypto2 from "crypto";
44672
- var randomBytesAsync = promisify(crypto2.randomBytes);
44866
+ import crypto3 from "crypto";
44867
+ var randomBytesAsync = promisify(crypto3.randomBytes);
44673
44868
  var urlSafeCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split("");
44674
44869
  var numericCharacters = "0123456789".split("");
44675
44870
  var distinguishableCharacters = "CDEHKMPRTUWXY012458".split("");
@@ -44682,7 +44877,7 @@ var generateForCustomCharacters = (length, characters) => {
44682
44877
  let string = "";
44683
44878
  let stringLength = 0;
44684
44879
  while (stringLength < length) {
44685
- const entropy = crypto2.randomBytes(entropyLength);
44880
+ const entropy = crypto3.randomBytes(entropyLength);
44686
44881
  let entropyPosition = 0;
44687
44882
  while (entropyPosition < entropyLength && stringLength < length) {
44688
44883
  const entropyValue = entropy.readUInt16LE(entropyPosition);
@@ -44717,7 +44912,7 @@ var generateForCustomCharactersAsync = async (length, characters) => {
44717
44912
  }
44718
44913
  return string;
44719
44914
  };
44720
- var generateRandomBytes = (byteLength, type, length) => crypto2.randomBytes(byteLength).toString(type).slice(0, length);
44915
+ var generateRandomBytes = (byteLength, type, length) => crypto3.randomBytes(byteLength).toString(type).slice(0, length);
44721
44916
  var generateRandomBytesAsync = async (byteLength, type, length) => {
44722
44917
  const buffer = await randomBytesAsync(byteLength);
44723
44918
  return buffer.toString(type).slice(0, length);
@@ -53254,6 +53449,7 @@ var _ExpandableText = ({
53254
53449
  maxWidth = MAX_WIDTH,
53255
53450
  maxLines
53256
53451
  }) => {
53452
+ const labelCharacters = Array.from(label);
53257
53453
  const hasMatch = matchedIndex !== void 0 && matchedIndex >= 0 && matchedIndex < label.length && userInput.length > 0;
53258
53454
  if (!hasMatch) {
53259
53455
  let display = label;
@@ -53262,53 +53458,69 @@ var _ExpandableText = ({
53262
53458
  const lines = label.split("\n");
53263
53459
  let truncated = lines.slice(0, maxLines).join("\n");
53264
53460
  const hasMoreLines = lines.length > maxLines;
53265
- if (truncated.length > maxWidth) {
53266
- truncated = truncated.slice(0, maxWidth) + "...";
53461
+ const truncatedCharacters = Array.from(truncated);
53462
+ if (truncatedCharacters.length > maxWidth) {
53463
+ truncated = truncatedCharacters.slice(0, maxWidth).join("") + "...";
53267
53464
  } else if (hasMoreLines) {
53268
53465
  truncated += "...";
53269
53466
  }
53270
53467
  display = truncated;
53271
- } else if (label.length > maxWidth) {
53272
- display = label.slice(0, maxWidth) + "...";
53468
+ } else if (labelCharacters.length > maxWidth) {
53469
+ display = labelCharacters.slice(0, maxWidth).join("") + "...";
53273
53470
  }
53274
53471
  }
53275
53472
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { wrap: "wrap", color: textColor, children: display });
53276
53473
  }
53277
- const matchLength = userInput.length;
53474
+ const matchCharactersLength = Array.from(userInput).length;
53475
+ let matchedCharacterIndex = 0;
53476
+ let matchedUtf16Index = 0;
53477
+ while (matchedCharacterIndex < labelCharacters.length && matchedUtf16Index < matchedIndex) {
53478
+ matchedUtf16Index += labelCharacters[matchedCharacterIndex].length;
53479
+ matchedCharacterIndex += 1;
53480
+ }
53278
53481
  let before = "";
53279
53482
  let match = "";
53280
53483
  let after = "";
53281
- if (isExpanded || label.length <= maxWidth) {
53282
- before = label.slice(0, matchedIndex);
53283
- match = label.slice(matchedIndex, matchedIndex + matchLength);
53284
- after = label.slice(matchedIndex + matchLength);
53285
- } else if (matchLength >= maxWidth) {
53286
- match = label.slice(matchedIndex, matchedIndex + maxWidth - 1) + "...";
53484
+ if (isExpanded || labelCharacters.length <= maxWidth) {
53485
+ before = labelCharacters.slice(0, matchedCharacterIndex).join("");
53486
+ match = labelCharacters.slice(
53487
+ matchedCharacterIndex,
53488
+ matchedCharacterIndex + matchCharactersLength
53489
+ ).join("");
53490
+ after = labelCharacters.slice(matchedCharacterIndex + matchCharactersLength).join("");
53491
+ } else if (matchCharactersLength >= maxWidth) {
53492
+ match = labelCharacters.slice(matchedCharacterIndex, matchedCharacterIndex + maxWidth - 1).join("") + "...";
53287
53493
  } else {
53288
- const contextSpace = maxWidth - matchLength;
53494
+ const contextSpace = maxWidth - matchCharactersLength;
53289
53495
  const beforeSpace = Math.floor(contextSpace / 2);
53290
53496
  const afterSpace = Math.ceil(contextSpace / 2);
53291
- let start = matchedIndex - beforeSpace;
53292
- let end = matchedIndex + matchLength + afterSpace;
53497
+ let start = matchedCharacterIndex - beforeSpace;
53498
+ let end = matchedCharacterIndex + matchCharactersLength + afterSpace;
53293
53499
  if (start < 0) {
53294
53500
  end += -start;
53295
53501
  start = 0;
53296
53502
  }
53297
- if (end > label.length) {
53298
- start -= end - label.length;
53299
- end = label.length;
53503
+ if (end > labelCharacters.length) {
53504
+ start -= end - labelCharacters.length;
53505
+ end = labelCharacters.length;
53300
53506
  }
53301
53507
  start = Math.max(0, start);
53302
- const finalMatchIndex = matchedIndex - start;
53303
- const slicedLabel = label.slice(start, end);
53304
- before = slicedLabel.slice(0, finalMatchIndex);
53305
- match = slicedLabel.slice(finalMatchIndex, finalMatchIndex + matchLength);
53306
- after = slicedLabel.slice(finalMatchIndex + matchLength);
53508
+ const finalMatchIndex = matchedCharacterIndex - start;
53509
+ const slicedLabel = labelCharacters.slice(start, end);
53510
+ const beforeChars = slicedLabel.slice(0, finalMatchIndex);
53511
+ match = slicedLabel.slice(finalMatchIndex, finalMatchIndex + matchCharactersLength).join("");
53512
+ const afterChars = slicedLabel.slice(
53513
+ finalMatchIndex + matchCharactersLength
53514
+ );
53307
53515
  if (start > 0) {
53308
- before = before.length >= 3 ? "..." + before.slice(3) : "...";
53516
+ before = beforeChars.length >= 3 ? "..." + beforeChars.slice(3).join("") : "...";
53517
+ } else {
53518
+ before = beforeChars.join("");
53309
53519
  }
53310
- if (end < label.length) {
53311
- after = after.length >= 3 ? after.slice(0, -3) + "..." : "...";
53520
+ if (end < labelCharacters.length) {
53521
+ after = afterChars.length >= 3 ? afterChars.slice(0, -3).join("") + "..." : "...";
53522
+ } else {
53523
+ after = afterChars.join("");
53312
53524
  }
53313
53525
  }
53314
53526
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: textColor, wrap: "wrap", children: [
@@ -55018,7 +55230,7 @@ var authCommand = {
55018
55230
  import process12 from "node:process";
55019
55231
 
55020
55232
  // packages/cli/src/generated/git-commit.ts
55021
- var GIT_COMMIT_INFO = "8080ea70a";
55233
+ var GIT_COMMIT_INFO = "89e9d25d6";
55022
55234
 
55023
55235
  // packages/cli/src/ui/utils/historyExportUtils.ts
55024
55236
  import * as fsPromises from "node:fs/promises";
@@ -55068,13 +55280,13 @@ async function exportHistoryToFile(options) {
55068
55280
  // packages/cli/src/ui/utils/memorySnapshot.ts
55069
55281
  import { createWriteStream as createWriteStream3 } from "node:fs";
55070
55282
  import { mkdir as mkdir3 } from "node:fs/promises";
55071
- import { dirname as dirname4 } from "node:path";
55072
- import { pipeline } from "node:stream/promises";
55283
+ import { dirname as dirname5 } from "node:path";
55284
+ import { pipeline as pipeline2 } from "node:stream/promises";
55073
55285
  import { getHeapSnapshot } from "node:v8";
55074
55286
  var MEMORY_SNAPSHOT_AUTO_THRESHOLD_BYTES = 2 * 1024 * 1024 * 1024;
55075
55287
  async function captureHeapSnapshot(filePath) {
55076
- await mkdir3(dirname4(filePath), { recursive: true });
55077
- await pipeline(getHeapSnapshot(), createWriteStream3(filePath));
55288
+ await mkdir3(dirname5(filePath), { recursive: true });
55289
+ await pipeline2(getHeapSnapshot(), createWriteStream3(filePath));
55078
55290
  }
55079
55291
 
55080
55292
  // packages/cli/src/ui/commands/bugCommand.ts
@@ -55652,7 +55864,7 @@ var chatCommand = {
55652
55864
  };
55653
55865
 
55654
55866
  // packages/cli/src/ui/commands/clearCommand.ts
55655
- import { randomUUID as randomUUID2 } from "node:crypto";
55867
+ import { randomUUID as randomUUID3 } from "node:crypto";
55656
55868
  var clearCommand = {
55657
55869
  name: "clear",
55658
55870
  altNames: ["new"],
@@ -55669,7 +55881,7 @@ var clearCommand = {
55669
55881
  config?.injectionService.clear();
55670
55882
  let newSessionId;
55671
55883
  if (config) {
55672
- newSessionId = randomUUID2();
55884
+ newSessionId = randomUUID3();
55673
55885
  config.resetNewSessionState(newSessionId);
55674
55886
  }
55675
55887
  if (geminiClient) {
@@ -59780,7 +59992,16 @@ async function rewindConversation(context, client, recordingService, messageId,
59780
59992
  const { uiHistory } = convertSessionToHistoryFormats(conversation.messages);
59781
59993
  const clientHistory = convertSessionToClientHistory(conversation.messages);
59782
59994
  client.setHistory(clientHistory);
59783
- await context.services.agentContext?.config.getMemoryContextManager()?.refresh();
59995
+ client.clearCurrentSequenceModel?.();
59996
+ const config = context.services.agentContext?.config;
59997
+ if (config) {
59998
+ config.getModelAvailabilityService?.()?.reset();
59999
+ const configuredModel = config.getModel?.();
60000
+ if (configuredModel) {
60001
+ config.setActiveModel?.(configuredModel);
60002
+ }
60003
+ await config.getMemoryContextManager()?.refresh();
60004
+ }
59784
60005
  const startId = 1;
59785
60006
  const historyWithIds = uiHistory.map(
59786
60007
  (item, idx) => ({
@@ -60825,7 +61046,7 @@ Use /mcp auth <server-name> to authenticate.`
60825
61046
  type: "info",
60826
61047
  text: `Starting OAuth authentication for MCP server '${serverName}'...`
60827
61048
  });
60828
- const { MCPOAuthProvider } = await import("./core-3N7UGMI2.js");
61049
+ const { MCPOAuthProvider } = await import("./core-NQRKBS47.js");
60829
61050
  let oauthConfig = server.oauth;
60830
61051
  if (!oauthConfig) {
60831
61052
  oauthConfig = { enabled: false };