@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-SJ64DOGM.js";
5
+ } from "./chunk-ODU7Z2RJ.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-2BG2OMW3.js";
72
+ } from "./chunk-VCO4TMD6.js";
73
73
  import {
74
74
  isDevelopment,
75
75
  require_semver
76
- } from "./chunk-6HF2HP2S.js";
76
+ } from "./chunk-KKKD4FID.js";
77
77
  import {
78
78
  emptyIcon,
79
79
  mapCoreStatusToDisplayStatus,
80
80
  require_react
81
- } from "./chunk-4HG5TEPY.js";
81
+ } from "./chunk-44PCK4QK.js";
82
82
  import {
83
83
  ALL_EDITORS,
84
84
  ApprovalMode,
@@ -232,6 +232,7 @@ import {
232
232
  require_cross_spawn,
233
233
  require_is_stream,
234
234
  require_path_key,
235
+ require_proper_lockfile,
235
236
  require_pump,
236
237
  require_toml,
237
238
  resetBrowserSession,
@@ -252,7 +253,7 @@ import {
252
253
  uiTelemetryService,
253
254
  unescapePath,
254
255
  validateUrlDestination
255
- } from "./chunk-5FYAQBC3.js";
256
+ } from "./chunk-L57AYV6U.js";
256
257
  import {
257
258
  require_src
258
259
  } from "./chunk-L6PII3GR.js";
@@ -6513,7 +6514,7 @@ var require_extract_zip = __commonJS({
6513
6514
  var stream = __require("stream");
6514
6515
  var yauzl = require_yauzl();
6515
6516
  var openZip = promisify5(yauzl.open);
6516
- var pipeline2 = promisify5(stream.pipeline);
6517
+ var pipeline3 = promisify5(stream.pipeline);
6517
6518
  var Extractor = class {
6518
6519
  constructor(zipPath, opts) {
6519
6520
  this.zipPath = zipPath;
@@ -6601,7 +6602,7 @@ var require_extract_zip = __commonJS({
6601
6602
  debug("creating symlink", link, dest);
6602
6603
  await fs33.symlink(link, dest);
6603
6604
  } else {
6604
- await pipeline2(readStream, createWriteStream5(dest, { mode: procMode }));
6605
+ await pipeline3(readStream, createWriteStream5(dest, { mode: procMode }));
6605
6606
  }
6606
6607
  }
6607
6608
  getExtractedMode(entryMode, isDir) {
@@ -15337,11 +15338,11 @@ var require_util4 = __commonJS({
15337
15338
  var { isUint8Array } = __require("node:util/types");
15338
15339
  var { webidl } = require_webidl();
15339
15340
  var supportedHashes = [];
15340
- var crypto3;
15341
+ var crypto4;
15341
15342
  try {
15342
- crypto3 = __require("node:crypto");
15343
+ crypto4 = __require("node:crypto");
15343
15344
  const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
15344
- supportedHashes = crypto3.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
15345
+ supportedHashes = crypto4.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
15345
15346
  } catch {
15346
15347
  }
15347
15348
  function responseURL(response) {
@@ -15644,7 +15645,7 @@ var require_util4 = __commonJS({
15644
15645
  return isOriginPotentiallyTrustworthy(url.origin);
15645
15646
  }
15646
15647
  function bytesMatch(bytes, metadataList) {
15647
- if (crypto3 === void 0) {
15648
+ if (crypto4 === void 0) {
15648
15649
  return true;
15649
15650
  }
15650
15651
  const parsedMetadata = parseMetadata(metadataList);
@@ -15659,7 +15660,7 @@ var require_util4 = __commonJS({
15659
15660
  for (const item of metadata) {
15660
15661
  const algorithm = item.algo;
15661
15662
  const expectedValue = item.hash;
15662
- let actualValue = crypto3.createHash(algorithm).update(bytes).digest("base64");
15663
+ let actualValue = crypto4.createHash(algorithm).update(bytes).digest("base64");
15663
15664
  if (actualValue[actualValue.length - 1] === "=") {
15664
15665
  if (actualValue[actualValue.length - 2] === "=") {
15665
15666
  actualValue = actualValue.slice(0, -2);
@@ -16677,8 +16678,8 @@ var require_body = __commonJS({
16677
16678
  var { multipartFormDataParser } = require_formdata_parser();
16678
16679
  var random;
16679
16680
  try {
16680
- const crypto3 = __require("node:crypto");
16681
- random = (max) => crypto3.randomInt(0, max);
16681
+ const crypto4 = __require("node:crypto");
16682
+ random = (max) => crypto4.randomInt(0, max);
16682
16683
  } catch {
16683
16684
  random = (max) => Math.floor(Math.random() * max);
16684
16685
  }
@@ -18129,7 +18130,7 @@ var require_client_h2 = __commonJS({
18129
18130
  "packages/cli/node_modules/undici/lib/dispatcher/client-h2.js"(exports, module) {
18130
18131
  "use strict";
18131
18132
  var assert = __require("node:assert");
18132
- var { pipeline: pipeline2 } = __require("node:stream");
18133
+ var { pipeline: pipeline3 } = __require("node:stream");
18133
18134
  var util2 = require_util3();
18134
18135
  var {
18135
18136
  RequestContentLengthMismatchError,
@@ -18624,7 +18625,7 @@ var require_client_h2 = __commonJS({
18624
18625
  }
18625
18626
  function writeStream(abort, socket, expectsPayload, h2stream, body, client, request, contentLength) {
18626
18627
  assert(contentLength !== 0 || client[kRunning] === 0, "stream body cannot be pipelined");
18627
- const pipe = pipeline2(
18628
+ const pipe = pipeline3(
18628
18629
  body,
18629
18630
  h2stream,
18630
18631
  (err) => {
@@ -21518,7 +21519,7 @@ var require_api_pipeline = __commonJS({
21518
21519
  util2.destroy(ret, err);
21519
21520
  }
21520
21521
  };
21521
- function pipeline2(opts, handler2) {
21522
+ function pipeline3(opts, handler2) {
21522
21523
  try {
21523
21524
  const pipelineHandler = new PipelineHandler(opts, handler2);
21524
21525
  this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler);
@@ -21527,7 +21528,7 @@ var require_api_pipeline = __commonJS({
21527
21528
  return new PassThrough().destroy(err);
21528
21529
  }
21529
21530
  }
21530
- module.exports = pipeline2;
21531
+ module.exports = pipeline3;
21531
21532
  }
21532
21533
  });
21533
21534
 
@@ -26943,7 +26944,7 @@ var require_fetch = __commonJS({
26943
26944
  subresourceSet
26944
26945
  } = require_constants3();
26945
26946
  var EE = __require("node:events");
26946
- var { Readable, pipeline: pipeline2, finished, isErrored, isReadable } = __require("node:stream");
26947
+ var { Readable, pipeline: pipeline3, finished, isErrored, isReadable } = __require("node:stream");
26947
26948
  var { addAbortListener, bufferToLowerCasedHeaderName } = require_util3();
26948
26949
  var { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require_data_url();
26949
26950
  var { getGlobalDispatcher } = require_global2();
@@ -27886,7 +27887,7 @@ var require_fetch = __commonJS({
27886
27887
  status,
27887
27888
  statusText,
27888
27889
  headersList,
27889
- body: decoders.length ? pipeline2(this.body, ...decoders, (err) => {
27890
+ body: decoders.length ? pipeline3(this.body, ...decoders, (err) => {
27890
27891
  if (err) {
27891
27892
  this.onError(err);
27892
27893
  }
@@ -29595,13 +29596,13 @@ var require_frame = __commonJS({
29595
29596
  "use strict";
29596
29597
  var { maxUnsigned16Bit, opcodes } = require_constants5();
29597
29598
  var BUFFER_SIZE = 8 * 1024;
29598
- var crypto3;
29599
+ var crypto4;
29599
29600
  var buffer = null;
29600
29601
  var bufIdx = BUFFER_SIZE;
29601
29602
  try {
29602
- crypto3 = __require("node:crypto");
29603
+ crypto4 = __require("node:crypto");
29603
29604
  } catch {
29604
- crypto3 = {
29605
+ crypto4 = {
29605
29606
  // not full compatibility, but minimum.
29606
29607
  randomFillSync: function randomFillSync(buffer2, _offset, _size) {
29607
29608
  for (let i = 0; i < buffer2.length; ++i) {
@@ -29614,7 +29615,7 @@ var require_frame = __commonJS({
29614
29615
  function generateMask() {
29615
29616
  if (bufIdx === BUFFER_SIZE) {
29616
29617
  bufIdx = 0;
29617
- crypto3.randomFillSync(buffer ??= Buffer.allocUnsafeSlow(BUFFER_SIZE), 0, BUFFER_SIZE);
29618
+ crypto4.randomFillSync(buffer ??= Buffer.allocUnsafeSlow(BUFFER_SIZE), 0, BUFFER_SIZE);
29618
29619
  }
29619
29620
  return [buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++], buffer[bufIdx++]];
29620
29621
  }
@@ -29712,9 +29713,9 @@ var require_connection = __commonJS({
29712
29713
  var { getDecodeSplit } = require_util4();
29713
29714
  var { WebsocketFrameSend } = require_frame();
29714
29715
  var assert = __require("node:assert");
29715
- var crypto3;
29716
+ var crypto4;
29716
29717
  try {
29717
- crypto3 = __require("node:crypto");
29718
+ crypto4 = __require("node:crypto");
29718
29719
  } catch {
29719
29720
  }
29720
29721
  function establishWebSocketConnection(url, protocols, client, handler2, options) {
@@ -29734,7 +29735,7 @@ var require_connection = __commonJS({
29734
29735
  const headersList = getHeadersList(new Headers(options.headers));
29735
29736
  request.headersList = headersList;
29736
29737
  }
29737
- const keyValue = crypto3.randomBytes(16).toString("base64");
29738
+ const keyValue = crypto4.randomBytes(16).toString("base64");
29738
29739
  request.headersList.append("sec-websocket-key", keyValue, true);
29739
29740
  request.headersList.append("sec-websocket-version", "13", true);
29740
29741
  for (const protocol of protocols) {
@@ -29767,7 +29768,7 @@ var require_connection = __commonJS({
29767
29768
  return;
29768
29769
  }
29769
29770
  const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
29770
- const digest = crypto3.createHash("sha1").update(keyValue + uid).digest("base64");
29771
+ const digest = crypto4.createHash("sha1").update(keyValue + uid).digest("base64");
29771
29772
  if (secWSAccept !== digest) {
29772
29773
  failWebsocketConnection(handler2, 1002, "Incorrect hash received in Sec-WebSocket-Accept header.");
29773
29774
  return;
@@ -31379,7 +31380,7 @@ ${value}`;
31379
31380
  var require_eventsource = __commonJS({
31380
31381
  "packages/cli/node_modules/undici/lib/web/eventsource/eventsource.js"(exports, module) {
31381
31382
  "use strict";
31382
- var { pipeline: pipeline2 } = __require("node:stream");
31383
+ var { pipeline: pipeline3 } = __require("node:stream");
31383
31384
  var { fetching } = require_fetch();
31384
31385
  var { makeRequest } = require_request2();
31385
31386
  var { webidl } = require_webidl();
@@ -31540,7 +31541,7 @@ var require_eventsource = __commonJS({
31540
31541
  ));
31541
31542
  }
31542
31543
  });
31543
- pipeline2(
31544
+ pipeline3(
31544
31545
  response.body.stream,
31545
31546
  eventSourceStream,
31546
31547
  (error) => {
@@ -38674,6 +38675,7 @@ async function getMissingSettings(extensionConfig, extensionId, workspaceDir) {
38674
38675
 
38675
38676
  // packages/cli/src/config/extension-manager.ts
38676
38677
  var import_chalk2 = __toESM(require_source(), 1);
38678
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
38677
38679
  import * as fs12 from "node:fs";
38678
38680
  import * as path9 from "node:path";
38679
38681
  import { stat } from "node:fs/promises";
@@ -38845,7 +38847,7 @@ var ExtensionEnablementManager = class {
38845
38847
  };
38846
38848
 
38847
38849
  // packages/cli/src/config/extension-manager.ts
38848
- import { createHash as createHash2, randomUUID } from "node:crypto";
38850
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
38849
38851
 
38850
38852
  // packages/cli/src/config/extension.ts
38851
38853
  import * as fs8 from "node:fs";
@@ -38942,10 +38944,12 @@ function extensionUpdatesReducer(state, action) {
38942
38944
  }
38943
38945
 
38944
38946
  // packages/cli/src/config/extensions/github.ts
38947
+ import * as crypto2 from "node:crypto";
38945
38948
  import * as os3 from "node:os";
38946
38949
  import * as https2 from "node:https";
38947
38950
  import * as fs10 from "node:fs";
38948
38951
  import * as path8 from "node:path";
38952
+ import { pipeline } from "node:stream/promises";
38949
38953
 
38950
38954
  // packages/cli/node_modules/tar/dist/esm/index.min.js
38951
38955
  import Hr from "events";
@@ -41860,6 +41864,14 @@ import * as https from "node:https";
41860
41864
  function getGitHubToken() {
41861
41865
  return process.env["GITHUB_TOKEN"] || void 0;
41862
41866
  }
41867
+ function isTrustedGitHubUrl(url) {
41868
+ try {
41869
+ const parsedUrl = new URL(url);
41870
+ return parsedUrl.protocol === "https:" && (parsedUrl.hostname === "github.com" || parsedUrl.hostname.endsWith(".github.com"));
41871
+ } catch {
41872
+ return false;
41873
+ }
41874
+ }
41863
41875
  var lookupPublicAddress = (hostname, options, callback) => safeLookup(
41864
41876
  hostname,
41865
41877
  {
@@ -41869,6 +41881,7 @@ var lookupPublicAddress = (hostname, options, callback) => safeLookup(
41869
41881
  callback
41870
41882
  );
41871
41883
  var REDIRECT_STATUS_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
41884
+ var REQUEST_TIMEOUT_MS = 3e4;
41872
41885
  async function fetchJson(url, redirectCount = 0) {
41873
41886
  if (!await validateUrlDestination(url)) {
41874
41887
  throw new Error(`Access to blocked or private host ${url} is not allowed.`);
@@ -41877,14 +41890,8 @@ async function fetchJson(url, redirectCount = 0) {
41877
41890
  "User-Agent": "gemini-cli"
41878
41891
  };
41879
41892
  const token = getGitHubToken();
41880
- if (token) {
41881
- try {
41882
- const parsedUrl = new URL(url);
41883
- if (parsedUrl.protocol === "https:" && (parsedUrl.hostname === "github.com" || parsedUrl.hostname.endsWith(".github.com"))) {
41884
- headers.Authorization = `token ${token}`;
41885
- }
41886
- } catch {
41887
- }
41893
+ if (token && isTrustedGitHubUrl(url)) {
41894
+ headers.Authorization = `token ${token}`;
41888
41895
  }
41889
41896
  return new Promise((resolve9, reject) => {
41890
41897
  let settled = false;
@@ -41909,7 +41916,7 @@ async function fetchJson(url, redirectCount = 0) {
41909
41916
  const requestOptions = {
41910
41917
  headers,
41911
41918
  lookup: lookupPublicAddress,
41912
- timeout: 3e4
41919
+ timeout: REQUEST_TIMEOUT_MS
41913
41920
  };
41914
41921
  const req = https.get(url, requestOptions, (res) => {
41915
41922
  res.on(
@@ -42002,7 +42009,9 @@ async function fetchJson(url, redirectCount = 0) {
42002
42009
  });
42003
42010
  req.on("error", (error) => failUnlessRedirecting(() => error));
42004
42011
  req.on("timeout", () => {
42005
- failUnlessRedirecting(() => new Error("Request timed out after 30000ms"));
42012
+ failUnlessRedirecting(
42013
+ () => new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`)
42014
+ );
42006
42015
  req.destroy();
42007
42016
  });
42008
42017
  });
@@ -42072,7 +42081,7 @@ function tryParseGithubUrl(source2) {
42072
42081
  );
42073
42082
  }
42074
42083
  const owner = parts[0];
42075
- const repo = parts[1].replace(".git", "");
42084
+ const repo = parts[1].replace(/\.git$/i, "");
42076
42085
  return {
42077
42086
  owner,
42078
42087
  repo
@@ -42353,39 +42362,175 @@ function findReleaseAsset(assets) {
42353
42362
  return void 0;
42354
42363
  }
42355
42364
  async function downloadFile(url, dest, options, redirectCount = 0) {
42365
+ let parsedUrl;
42366
+ try {
42367
+ parsedUrl = new URL(url);
42368
+ } catch (error) {
42369
+ throw new Error(`Invalid download URL ${url}: ${getErrorMessage(error)}`, {
42370
+ cause: error
42371
+ });
42372
+ }
42373
+ if (parsedUrl.protocol !== "https:") {
42374
+ throw new Error(
42375
+ `Refusing to download from insecure protocol ${parsedUrl.protocol} for URL ${url}. Only HTTPS is supported.`
42376
+ );
42377
+ }
42378
+ const requestUrl = parsedUrl.toString();
42379
+ if (!await validateUrlDestination(requestUrl)) {
42380
+ throw new Error(
42381
+ `Access to blocked or private host ${requestUrl} is not allowed.`
42382
+ );
42383
+ }
42356
42384
  const headers = {
42357
42385
  "User-agent": "gemini-cli",
42358
42386
  Accept: "application/octet-stream",
42359
42387
  ...options?.headers
42360
42388
  };
42389
+ const trustedGitHubUrl = isTrustedGitHubUrl(requestUrl);
42390
+ if (!trustedGitHubUrl) {
42391
+ for (const key of Object.keys(headers)) {
42392
+ if (key.toLowerCase() === "authorization") {
42393
+ delete headers[key];
42394
+ }
42395
+ }
42396
+ }
42361
42397
  const token = getGitHubToken();
42362
- if (token) {
42398
+ if (token && trustedGitHubUrl) {
42363
42399
  headers["Authorization"] = `token ${token}`;
42364
42400
  }
42365
- return new Promise((resolve9, reject) => {
42366
- https2.get(url, { headers }, (res) => {
42367
- if (res.statusCode === 302 || res.statusCode === 301) {
42368
- if (redirectCount >= 10) {
42369
- return reject(new Error("Too many redirects"));
42401
+ let tempDest;
42402
+ let downloadPipeline;
42403
+ try {
42404
+ await new Promise((resolve9, reject) => {
42405
+ let settled = false;
42406
+ let isRedirecting = false;
42407
+ let responseStream;
42408
+ const settleResolve = () => {
42409
+ if (!settled) {
42410
+ settled = true;
42411
+ resolve9();
42370
42412
  }
42371
- if (!res.headers.location) {
42372
- return reject(
42373
- new Error("Redirect response missing Location header")
42413
+ };
42414
+ const settleReject = (error) => {
42415
+ if (!settled) {
42416
+ settled = true;
42417
+ reject(
42418
+ error instanceof Error ? error : new Error(getErrorMessage(error))
42374
42419
  );
42375
42420
  }
42376
- downloadFile(res.headers.location, dest, options, redirectCount + 1).then(resolve9).catch(reject);
42377
- return;
42421
+ };
42422
+ const requestOptions = {
42423
+ headers,
42424
+ lookup: lookupPublicAddress,
42425
+ timeout: REQUEST_TIMEOUT_MS
42426
+ };
42427
+ const req = https2.get(requestUrl, requestOptions, (res) => {
42428
+ res.on("error", (error) => {
42429
+ if (!isRedirecting) {
42430
+ settleReject(error);
42431
+ }
42432
+ });
42433
+ if (res.statusCode && REDIRECT_STATUS_CODES.has(res.statusCode)) {
42434
+ if (redirectCount >= 10) {
42435
+ res.resume?.();
42436
+ settleReject(new Error("Too many redirects"));
42437
+ return;
42438
+ }
42439
+ if (!res.headers.location) {
42440
+ res.resume?.();
42441
+ settleReject(
42442
+ new Error("Redirect response missing Location header")
42443
+ );
42444
+ return;
42445
+ }
42446
+ let redirectUrl;
42447
+ try {
42448
+ redirectUrl = new URL(res.headers.location, requestUrl).toString();
42449
+ } catch (error) {
42450
+ res.resume?.();
42451
+ settleReject(
42452
+ new Error(
42453
+ `Invalid redirect URL from ${requestUrl} (status ${res.statusCode}): ${getErrorMessage(error)}`,
42454
+ { cause: error }
42455
+ )
42456
+ );
42457
+ return;
42458
+ }
42459
+ isRedirecting = true;
42460
+ res.resume?.();
42461
+ void downloadFile(redirectUrl, dest, options, redirectCount + 1).then(
42462
+ settleResolve,
42463
+ settleReject
42464
+ );
42465
+ return;
42466
+ }
42467
+ if (res.statusCode !== 200) {
42468
+ res.resume?.();
42469
+ settleReject(
42470
+ new Error(`Request failed with status code ${res.statusCode}`)
42471
+ );
42472
+ return;
42473
+ }
42474
+ responseStream = res;
42475
+ const currentTempDest = `${dest}.${crypto2.randomUUID()}.tmp`;
42476
+ tempDest = currentTempDest;
42477
+ let file;
42478
+ try {
42479
+ file = fs10.createWriteStream(currentTempDest);
42480
+ } catch (error) {
42481
+ res.destroy?.();
42482
+ settleReject(error);
42483
+ return;
42484
+ }
42485
+ file.on("error", settleReject);
42486
+ downloadPipeline = pipeline(res, file);
42487
+ void downloadPipeline.then(() => {
42488
+ if (res.complete === false) {
42489
+ settleReject(
42490
+ new Error(
42491
+ `Response ended prematurely while downloading ${requestUrl}`
42492
+ )
42493
+ );
42494
+ return;
42495
+ }
42496
+ settleResolve();
42497
+ }, settleReject);
42498
+ });
42499
+ req.on("error", (error) => {
42500
+ if (isRedirecting) {
42501
+ return;
42502
+ }
42503
+ settleReject(error);
42504
+ responseStream?.destroy?.();
42505
+ });
42506
+ req.on("timeout", () => {
42507
+ if (!isRedirecting) {
42508
+ settleReject(
42509
+ new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`)
42510
+ );
42511
+ responseStream?.destroy?.();
42512
+ }
42513
+ req.destroy?.();
42514
+ });
42515
+ });
42516
+ if (tempDest) {
42517
+ await fs10.promises.rename(tempDest, dest);
42518
+ }
42519
+ } catch (error) {
42520
+ if (downloadPipeline) {
42521
+ try {
42522
+ await downloadPipeline;
42523
+ } catch {
42378
42524
  }
42379
- if (res.statusCode !== 200) {
42380
- return reject(
42381
- new Error(`Request failed with status code ${res.statusCode}`)
42382
- );
42525
+ }
42526
+ if (tempDest) {
42527
+ try {
42528
+ await fs10.promises.unlink(tempDest);
42529
+ } catch {
42383
42530
  }
42384
- const file = fs10.createWriteStream(dest);
42385
- res.pipe(file);
42386
- file.on("finish", () => file.close(resolve9));
42387
- }).on("error", reject);
42388
- });
42531
+ }
42532
+ throw error;
42533
+ }
42389
42534
  }
42390
42535
  async function extractFile(file, dest) {
42391
42536
  if (file.endsWith(".tar.gz")) {
@@ -42613,6 +42758,9 @@ async function removeDirectoryWithRetry(path37, options = {}) {
42613
42758
  }
42614
42759
 
42615
42760
  // packages/cli/src/config/extension-manager.ts
42761
+ var INSTALL_LOCK_SUFFIX = ".lock";
42762
+ var INSTALL_LOCK_STALE_MS = 15e3;
42763
+ var INSTALL_LOCK_RETRIES = { retries: 15, minTimeout: 200, maxTimeout: 500 };
42616
42764
  var ExtensionManager = class extends ExtensionLoader {
42617
42765
  extensionEnablementManager;
42618
42766
  integrityManager;
@@ -42633,7 +42781,7 @@ var ExtensionManager = class extends ExtensionLoader {
42633
42781
  this.telemetryConfig = new Config({
42634
42782
  telemetry: options.settings.telemetry,
42635
42783
  interactive: false,
42636
- sessionId: randomUUID(),
42784
+ sessionId: randomUUID2(),
42637
42785
  clientVersion: options.clientVersion ?? "unknown",
42638
42786
  targetDir: options.workspaceDir,
42639
42787
  cwd: options.workspaceDir,
@@ -42757,6 +42905,7 @@ Would you like to attempt to install via "git clone" instead?`
42757
42905
  } else {
42758
42906
  throw new Error(`Unsupported install type: ${installMetadata.type}`);
42759
42907
  }
42908
+ let releaseLock;
42760
42909
  try {
42761
42910
  newExtensionConfig = await this.loadExtensionConfig(localSourcePath);
42762
42911
  const newExtensionName = newExtensionConfig.name;
@@ -42805,11 +42954,19 @@ Would you like to attempt to install via "git clone" instead?`
42805
42954
  const destinationPath = new ExtensionStorage(
42806
42955
  newExtensionName
42807
42956
  ).getExtensionDir();
42808
- if ((!isUpdate || newExtensionName !== previousName) && fs12.existsSync(destinationPath)) {
42809
- throw new Error(
42810
- `Cannot install extension "${newExtensionName}" because a directory with that name already exists. Please remove it manually.`
42811
- );
42812
- }
42957
+ const assertDestinationIsAvailable = () => {
42958
+ if ((!isUpdate || newExtensionName !== previousName) && fs12.existsSync(destinationPath)) {
42959
+ throw new Error(
42960
+ `Cannot install extension "${newExtensionName}" because a directory with that name already exists. Please remove it manually.`
42961
+ );
42962
+ }
42963
+ };
42964
+ assertDestinationIsAvailable();
42965
+ releaseLock = await acquireExtensionInstallLock(
42966
+ destinationPath,
42967
+ newExtensionName
42968
+ );
42969
+ assertDestinationIsAvailable();
42813
42970
  let previousSettings;
42814
42971
  let wasEnabledGlobally = false;
42815
42972
  let wasEnabledWorkspace = false;
@@ -42922,6 +43079,15 @@ Would you like to attempt to install via "git clone" instead?`
42922
43079
  );
42923
43080
  }
42924
43081
  } finally {
43082
+ if (releaseLock) {
43083
+ try {
43084
+ await releaseLock();
43085
+ } catch (releaseError) {
43086
+ debugLogger.warn(
43087
+ `Failed to release the install lock for extension "${newExtensionConfig?.name}": ${getErrorMessage(releaseError)}`
43088
+ );
43089
+ }
43090
+ }
42925
43091
  if (tempDir) {
42926
43092
  try {
42927
43093
  await removeDirectoryWithRetry(tempDir);
@@ -43092,6 +43258,9 @@ Would you like to attempt to install via "git clone" instead?`
43092
43258
  * Builds an extension without side effects (does not mutate loadedExtensions or start it).
43093
43259
  */
43094
43260
  async _buildExtension(extensionDir) {
43261
+ if (path9.basename(extensionDir).endsWith(INSTALL_LOCK_SUFFIX)) {
43262
+ return null;
43263
+ }
43095
43264
  try {
43096
43265
  const stats = await fs12.promises.stat(extensionDir);
43097
43266
  if (!stats.isDirectory()) {
@@ -43577,6 +43746,32 @@ async function copyExtension(source2, destination) {
43577
43746
  await fs12.promises.cp(source2, destination, { recursive: true });
43578
43747
  await makeWritableRecursive(destination);
43579
43748
  }
43749
+ async function acquireExtensionInstallLock(destinationPath, extensionName) {
43750
+ await fs12.promises.mkdir(path9.dirname(destinationPath), { recursive: true });
43751
+ try {
43752
+ return await (0, import_proper_lockfile.lock)(destinationPath, {
43753
+ // `destinationPath` usually does not exist yet. With `realpath: false`,
43754
+ // proper-lockfile neither resolves nor stats it; it only creates and
43755
+ // checks the `<destinationPath>.lock` directory.
43756
+ realpath: false,
43757
+ stale: INSTALL_LOCK_STALE_MS,
43758
+ retries: INSTALL_LOCK_RETRIES,
43759
+ // The default handler throws from a timer, which would crash the CLI.
43760
+ onCompromised: (error) => {
43761
+ debugLogger.warn(
43762
+ `Lost the install lock for extension "${extensionName}": ${getErrorMessage(error)}`
43763
+ );
43764
+ }
43765
+ });
43766
+ } catch (error) {
43767
+ if (isNodeError(error) && error.code === "ELOCKED") {
43768
+ throw new Error(
43769
+ `Cannot install extension "${extensionName}" because another installation or update of it is already in progress. Please try again later.`
43770
+ );
43771
+ }
43772
+ throw error;
43773
+ }
43774
+ }
43580
43775
  function getContextFileNames(config) {
43581
43776
  if (!config.contextFileName) {
43582
43777
  return ["GEMINI.md"];
@@ -44681,8 +44876,8 @@ var import_execa = __toESM(require_execa(), 1);
44681
44876
 
44682
44877
  // node_modules/crypto-random-string/index.js
44683
44878
  import { promisify } from "util";
44684
- import crypto2 from "crypto";
44685
- var randomBytesAsync = promisify(crypto2.randomBytes);
44879
+ import crypto3 from "crypto";
44880
+ var randomBytesAsync = promisify(crypto3.randomBytes);
44686
44881
  var urlSafeCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split("");
44687
44882
  var numericCharacters = "0123456789".split("");
44688
44883
  var distinguishableCharacters = "CDEHKMPRTUWXY012458".split("");
@@ -44695,7 +44890,7 @@ var generateForCustomCharacters = (length, characters) => {
44695
44890
  let string = "";
44696
44891
  let stringLength = 0;
44697
44892
  while (stringLength < length) {
44698
- const entropy = crypto2.randomBytes(entropyLength);
44893
+ const entropy = crypto3.randomBytes(entropyLength);
44699
44894
  let entropyPosition = 0;
44700
44895
  while (entropyPosition < entropyLength && stringLength < length) {
44701
44896
  const entropyValue = entropy.readUInt16LE(entropyPosition);
@@ -44730,7 +44925,7 @@ var generateForCustomCharactersAsync = async (length, characters) => {
44730
44925
  }
44731
44926
  return string;
44732
44927
  };
44733
- var generateRandomBytes = (byteLength, type, length) => crypto2.randomBytes(byteLength).toString(type).slice(0, length);
44928
+ var generateRandomBytes = (byteLength, type, length) => crypto3.randomBytes(byteLength).toString(type).slice(0, length);
44734
44929
  var generateRandomBytesAsync = async (byteLength, type, length) => {
44735
44930
  const buffer = await randomBytesAsync(byteLength);
44736
44931
  return buffer.toString(type).slice(0, length);
@@ -53267,6 +53462,7 @@ var _ExpandableText = ({
53267
53462
  maxWidth = MAX_WIDTH,
53268
53463
  maxLines
53269
53464
  }) => {
53465
+ const labelCharacters = Array.from(label);
53270
53466
  const hasMatch = matchedIndex !== void 0 && matchedIndex >= 0 && matchedIndex < label.length && userInput.length > 0;
53271
53467
  if (!hasMatch) {
53272
53468
  let display = label;
@@ -53275,53 +53471,69 @@ var _ExpandableText = ({
53275
53471
  const lines = label.split("\n");
53276
53472
  let truncated = lines.slice(0, maxLines).join("\n");
53277
53473
  const hasMoreLines = lines.length > maxLines;
53278
- if (truncated.length > maxWidth) {
53279
- truncated = truncated.slice(0, maxWidth) + "...";
53474
+ const truncatedCharacters = Array.from(truncated);
53475
+ if (truncatedCharacters.length > maxWidth) {
53476
+ truncated = truncatedCharacters.slice(0, maxWidth).join("") + "...";
53280
53477
  } else if (hasMoreLines) {
53281
53478
  truncated += "...";
53282
53479
  }
53283
53480
  display = truncated;
53284
- } else if (label.length > maxWidth) {
53285
- display = label.slice(0, maxWidth) + "...";
53481
+ } else if (labelCharacters.length > maxWidth) {
53482
+ display = labelCharacters.slice(0, maxWidth).join("") + "...";
53286
53483
  }
53287
53484
  }
53288
53485
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { wrap: "wrap", color: textColor, children: display });
53289
53486
  }
53290
- const matchLength = userInput.length;
53487
+ const matchCharactersLength = Array.from(userInput).length;
53488
+ let matchedCharacterIndex = 0;
53489
+ let matchedUtf16Index = 0;
53490
+ while (matchedCharacterIndex < labelCharacters.length && matchedUtf16Index < matchedIndex) {
53491
+ matchedUtf16Index += labelCharacters[matchedCharacterIndex].length;
53492
+ matchedCharacterIndex += 1;
53493
+ }
53291
53494
  let before = "";
53292
53495
  let match = "";
53293
53496
  let after = "";
53294
- if (isExpanded || label.length <= maxWidth) {
53295
- before = label.slice(0, matchedIndex);
53296
- match = label.slice(matchedIndex, matchedIndex + matchLength);
53297
- after = label.slice(matchedIndex + matchLength);
53298
- } else if (matchLength >= maxWidth) {
53299
- match = label.slice(matchedIndex, matchedIndex + maxWidth - 1) + "...";
53497
+ if (isExpanded || labelCharacters.length <= maxWidth) {
53498
+ before = labelCharacters.slice(0, matchedCharacterIndex).join("");
53499
+ match = labelCharacters.slice(
53500
+ matchedCharacterIndex,
53501
+ matchedCharacterIndex + matchCharactersLength
53502
+ ).join("");
53503
+ after = labelCharacters.slice(matchedCharacterIndex + matchCharactersLength).join("");
53504
+ } else if (matchCharactersLength >= maxWidth) {
53505
+ match = labelCharacters.slice(matchedCharacterIndex, matchedCharacterIndex + maxWidth - 1).join("") + "...";
53300
53506
  } else {
53301
- const contextSpace = maxWidth - matchLength;
53507
+ const contextSpace = maxWidth - matchCharactersLength;
53302
53508
  const beforeSpace = Math.floor(contextSpace / 2);
53303
53509
  const afterSpace = Math.ceil(contextSpace / 2);
53304
- let start = matchedIndex - beforeSpace;
53305
- let end = matchedIndex + matchLength + afterSpace;
53510
+ let start = matchedCharacterIndex - beforeSpace;
53511
+ let end = matchedCharacterIndex + matchCharactersLength + afterSpace;
53306
53512
  if (start < 0) {
53307
53513
  end += -start;
53308
53514
  start = 0;
53309
53515
  }
53310
- if (end > label.length) {
53311
- start -= end - label.length;
53312
- end = label.length;
53516
+ if (end > labelCharacters.length) {
53517
+ start -= end - labelCharacters.length;
53518
+ end = labelCharacters.length;
53313
53519
  }
53314
53520
  start = Math.max(0, start);
53315
- const finalMatchIndex = matchedIndex - start;
53316
- const slicedLabel = label.slice(start, end);
53317
- before = slicedLabel.slice(0, finalMatchIndex);
53318
- match = slicedLabel.slice(finalMatchIndex, finalMatchIndex + matchLength);
53319
- after = slicedLabel.slice(finalMatchIndex + matchLength);
53521
+ const finalMatchIndex = matchedCharacterIndex - start;
53522
+ const slicedLabel = labelCharacters.slice(start, end);
53523
+ const beforeChars = slicedLabel.slice(0, finalMatchIndex);
53524
+ match = slicedLabel.slice(finalMatchIndex, finalMatchIndex + matchCharactersLength).join("");
53525
+ const afterChars = slicedLabel.slice(
53526
+ finalMatchIndex + matchCharactersLength
53527
+ );
53320
53528
  if (start > 0) {
53321
- before = before.length >= 3 ? "..." + before.slice(3) : "...";
53529
+ before = beforeChars.length >= 3 ? "..." + beforeChars.slice(3).join("") : "...";
53530
+ } else {
53531
+ before = beforeChars.join("");
53322
53532
  }
53323
- if (end < label.length) {
53324
- after = after.length >= 3 ? after.slice(0, -3) + "..." : "...";
53533
+ if (end < labelCharacters.length) {
53534
+ after = afterChars.length >= 3 ? afterChars.slice(0, -3).join("") + "..." : "...";
53535
+ } else {
53536
+ after = afterChars.join("");
53325
53537
  }
53326
53538
  }
53327
53539
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: textColor, wrap: "wrap", children: [
@@ -55031,7 +55243,7 @@ var authCommand = {
55031
55243
  import process12 from "node:process";
55032
55244
 
55033
55245
  // packages/cli/src/generated/git-commit.ts
55034
- var GIT_COMMIT_INFO = "b367c7296";
55246
+ var GIT_COMMIT_INFO = "6ee817519";
55035
55247
 
55036
55248
  // packages/cli/src/ui/utils/historyExportUtils.ts
55037
55249
  import * as fsPromises from "node:fs/promises";
@@ -55081,13 +55293,13 @@ async function exportHistoryToFile(options) {
55081
55293
  // packages/cli/src/ui/utils/memorySnapshot.ts
55082
55294
  import { createWriteStream as createWriteStream3 } from "node:fs";
55083
55295
  import { mkdir as mkdir3 } from "node:fs/promises";
55084
- import { dirname as dirname4 } from "node:path";
55085
- import { pipeline } from "node:stream/promises";
55296
+ import { dirname as dirname5 } from "node:path";
55297
+ import { pipeline as pipeline2 } from "node:stream/promises";
55086
55298
  import { getHeapSnapshot } from "node:v8";
55087
55299
  var MEMORY_SNAPSHOT_AUTO_THRESHOLD_BYTES = 2 * 1024 * 1024 * 1024;
55088
55300
  async function captureHeapSnapshot(filePath) {
55089
- await mkdir3(dirname4(filePath), { recursive: true });
55090
- await pipeline(getHeapSnapshot(), createWriteStream3(filePath));
55301
+ await mkdir3(dirname5(filePath), { recursive: true });
55302
+ await pipeline2(getHeapSnapshot(), createWriteStream3(filePath));
55091
55303
  }
55092
55304
 
55093
55305
  // packages/cli/src/ui/commands/bugCommand.ts
@@ -55665,7 +55877,7 @@ var chatCommand = {
55665
55877
  };
55666
55878
 
55667
55879
  // packages/cli/src/ui/commands/clearCommand.ts
55668
- import { randomUUID as randomUUID2 } from "node:crypto";
55880
+ import { randomUUID as randomUUID3 } from "node:crypto";
55669
55881
  var clearCommand = {
55670
55882
  name: "clear",
55671
55883
  altNames: ["new"],
@@ -55682,7 +55894,7 @@ var clearCommand = {
55682
55894
  config?.injectionService.clear();
55683
55895
  let newSessionId;
55684
55896
  if (config) {
55685
- newSessionId = randomUUID2();
55897
+ newSessionId = randomUUID3();
55686
55898
  config.resetNewSessionState(newSessionId);
55687
55899
  }
55688
55900
  if (geminiClient) {
@@ -59793,7 +60005,16 @@ async function rewindConversation(context, client, recordingService, messageId,
59793
60005
  const { uiHistory } = convertSessionToHistoryFormats(conversation.messages);
59794
60006
  const clientHistory = convertSessionToClientHistory(conversation.messages);
59795
60007
  client.setHistory(clientHistory);
59796
- await context.services.agentContext?.config.getMemoryContextManager()?.refresh();
60008
+ client.clearCurrentSequenceModel?.();
60009
+ const config = context.services.agentContext?.config;
60010
+ if (config) {
60011
+ config.getModelAvailabilityService?.()?.reset();
60012
+ const configuredModel = config.getModel?.();
60013
+ if (configuredModel) {
60014
+ config.setActiveModel?.(configuredModel);
60015
+ }
60016
+ await config.getMemoryContextManager()?.refresh();
60017
+ }
59797
60018
  const startId = 1;
59798
60019
  const historyWithIds = uiHistory.map(
59799
60020
  (item, idx) => ({
@@ -60838,7 +61059,7 @@ Use /mcp auth <server-name> to authenticate.`
60838
61059
  type: "info",
60839
61060
  text: `Starting OAuth authentication for MCP server '${serverName}'...`
60840
61061
  });
60841
- const { MCPOAuthProvider } = await import("./dist-XT4ZXTSC.js");
61062
+ const { MCPOAuthProvider } = await import("./dist-OYZDNSTI.js");
60842
61063
  let oauthConfig = server.oauth;
60843
61064
  if (!oauthConfig) {
60844
61065
  oauthConfig = { enabled: false };