From 3c3bfe6699bf7a9cc4f10d6b8be89f245e73b4bc Mon Sep 17 00:00:00 2001 From: delta-cloud-208e Date: Sat, 7 Mar 2026 08:01:24 +0000 Subject: [PATCH] release: Gemini CLI v0.32.1 (6 patches) --- gemini/gemini_config.json | 3 +- gemini/gemini_patcher.py | 139 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 6 deletions(-) diff --git a/gemini/gemini_config.json b/gemini/gemini_config.json index afd8080..cef7c02 100644 --- a/gemini/gemini_config.json +++ b/gemini/gemini_config.json @@ -17,5 +17,6 @@ ], "target_version": "0.32.1", "telemetry_enabled": false, - "npm_package": "@google/gemini-cli" + "npm_package": "@google/gemini-cli", + "npm_registry": "https://npm.sensey24.ru" } diff --git a/gemini/gemini_patcher.py b/gemini/gemini_patcher.py index 6374467..940e6c1 100644 --- a/gemini/gemini_patcher.py +++ b/gemini/gemini_patcher.py @@ -9,6 +9,8 @@ Targets: 4. auth_env_whitelist — add GOOGLE_GEMINI_BASE_URL to whitelist 5. user_settings — settings.json (auth + telemetry) 6. system_env — env vars injection + 7. auto_update_registry — redirect registry-url default to npm.sensey24.ru + 8. auto_update_commands — add --registry to update commands """ import json @@ -32,6 +34,9 @@ IS_MACOS = platform.system() == "Darwin" NPM_PACKAGE = "@google/gemini-cli" GENAI_SUBPATH = "node_modules/@google/genai/dist/node/index.mjs" SETTINGS_JS_SUBPATH = "dist/src/config/settings.js" +REGISTRY_URL_SUBPATH = "node_modules/registry-url/index.js" +INSTALL_INFO_SUBPATH = "dist/src/utils/installationInfo.js" +NPM_CONF_DEFAULTS_SUBPATH = "node_modules/@pnpm/npm-conf/lib/defaults.js" # ANSI colors GREEN = "\033[92m" @@ -450,15 +455,131 @@ def _setup_env_windows(env_vars): return changes > 0, f"Set {changes} env var(s) via setx" +# ─── Target 7+8: Auto-update registry redirect ──────────────────────── + +def get_auto_update_paths(gemini_root): + """Return paths to auto-update related files.""" + return { + "registry_url": os.path.join(gemini_root, REGISTRY_URL_SUBPATH), + "install_info": os.path.join(gemini_root, INSTALL_INFO_SUBPATH), + "npm_conf": os.path.join(gemini_root, NPM_CONF_DEFAULTS_SUBPATH), + } + + +def patch_auto_update(gemini_root, config): + """ + Target 7: Redirect registry-url default from registry.npmjs.org → npm_registry. + Target 8: Add --registry flag to update commands in installationInfo.js. + """ + npm_registry = config.get("npm_registry", "").rstrip("/") + if not npm_registry: + return True, "Skipped (no npm_registry in config)" + + paths = get_auto_update_paths(gemini_root) + changes = 0 + patched_parts = [] + + # --- Target 7a: registry-url/index.js --- + reg_path = paths["registry_url"] + if os.path.isfile(reg_path): + with open(reg_path, "r", encoding="utf-8") as f: + content = f.read() + + old_registry = "https://registry.npmjs.org/" + if old_registry in content: + backup = reg_path + ".backup" + if not os.path.exists(backup): + shutil.copy2(reg_path, backup) + content = content.replace(old_registry, npm_registry + "/") + with open(reg_path, "w", encoding="utf-8") as f: + f.write(content) + changes += 1 + patched_parts.append("registry-url") + elif npm_registry in content: + patched_parts.append("registry-url: already patched") + else: + patched_parts.append("registry-url: pattern not found") + + # --- Target 7b: @pnpm/npm-conf/lib/defaults.js --- + conf_path = paths["npm_conf"] + if os.path.isfile(conf_path): + with open(conf_path, "r", encoding="utf-8") as f: + content = f.read() + + old_conf = "registry: 'https://registry.npmjs.org/'," + new_conf = f"registry: '{npm_registry}/'," + if old_conf in content: + backup = conf_path + ".backup" + if not os.path.exists(backup): + shutil.copy2(conf_path, backup) + content = content.replace(old_conf, new_conf) + with open(conf_path, "w", encoding="utf-8") as f: + f.write(content) + changes += 1 + patched_parts.append("npm-conf defaults") + elif npm_registry in content: + patched_parts.append("npm-conf: already patched") + + # --- Target 8: installationInfo.js --- + info_path = paths["install_info"] + if os.path.isfile(info_path): + with open(info_path, "r", encoding="utf-8") as f: + content = f.read() + + cmd_changes = 0 + + # npm, pnpm, yarn: append --registry + for old_cmd in [ + "'npm install -g @google/gemini-cli@latest'", + "'pnpm add -g @google/gemini-cli@latest'", + "'yarn global add @google/gemini-cli@latest'", + ]: + new_cmd = old_cmd.replace("@latest'", f"@latest --registry {npm_registry}'") + if old_cmd in content: + content = content.replace(old_cmd, new_cmd) + cmd_changes += 1 + + # bun: prefix with BUN_CONFIG_REGISTRY env var + old_bun = "'bun add -g @google/gemini-cli@latest'" + new_bun = f"'BUN_CONFIG_REGISTRY={npm_registry} bun add -g @google/gemini-cli@latest'" + if old_bun in content: + content = content.replace(old_bun, new_bun) + cmd_changes += 1 + + if cmd_changes > 0: + backup = info_path + ".backup" + if not os.path.exists(backup): + shutil.copy2(info_path, backup) + with open(info_path, "w", encoding="utf-8") as f: + f.write(content) + changes += cmd_changes + patched_parts.append(f"installationInfo: {cmd_changes} command(s)") + elif npm_registry in content: + patched_parts.append("installationInfo: already patched") + else: + patched_parts.append("installationInfo: no commands matched") + + if changes == 0 and any("already patched" in p for p in patched_parts): + return True, "Already patched (" + "; ".join(patched_parts) + ")" + elif changes == 0: + return False, "No auto-update patterns matched (" + "; ".join(patched_parts) + ")" + + return True, "; ".join(patched_parts) + + # ─── Rollback ─────────────────────────────────────────────────────────── -def rollback(genai_mjs_path, settings_js_path): +def rollback(genai_mjs_path, settings_js_path, gemini_root=None): """Restore backup files.""" restored = 0 - for path in [genai_mjs_path, settings_js_path]: - backup = path + ".backup" + paths = [genai_mjs_path, settings_js_path] + if gemini_root: + auto_paths = get_auto_update_paths(gemini_root) + paths.extend(auto_paths.values()) + for p in paths: + backup = p + ".backup" if os.path.exists(backup): - shutil.copy2(backup, path) + shutil.copy2(backup, p) restored += 1 return restored > 0, f"Restored {restored} file(s) from backup" @@ -547,6 +668,14 @@ def apply_all_patches(config=None, settings_only=False): if not ok: all_ok = False + if not settings_only: + # Target 7+8: auto-update registry redirect + ok, msg = patch_auto_update(gemini_root, config) + results["auto_update"] = (ok, msg) + print(f" {'[OK]' if ok else '[FAIL]':>8} Target 7+8: {msg}") + if not ok: + all_ok = False + print() if all_ok: print(f" {color('All patches applied successfully!', GREEN)}") @@ -588,7 +717,7 @@ def main(): elif args.rollback: try: root, genai, settings = detect_gemini() - ok, msg = rollback(genai, settings) + ok, msg = rollback(genai, settings, root) print(msg) sys.exit(0 if ok else 1) except FileNotFoundError as e: