From 9716b3260657886657316200663d9bfd15f81d14 Mon Sep 17 00:00:00 2001 From: Tkavelli <99182519+tkavelli@users.noreply.github.com> Date: Fri, 13 Feb 2026 00:56:08 +0300 Subject: [PATCH] fix(wizard): move semantic_search config out of ~/.claude/settings.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WHAT CHANGED: 1. opc/scripts/setup/wizard.py: - Semantic search config now writes to ~/.config/tldr/config.json instead of ~/.claude/settings.json - Added cleanup: removes stale "semantic_search" key from ~/.claude/settings.json if present from previous installations - WHY: Claude Code does not recognise the "semantic_search" key and reports the settings file as invalid ("Found N invalid settings files"). The tldr daemon reads per-project config from /.tldr/config.json at runtime anyway. CONTEXT: The wizard was injecting a non-standard key into Claude Code's global settings file. Claude Code validates its settings schema and flags unknown keys, causing a warning on every startup. The daemon's default config already matches the wizard's defaults (bge-large-en-v1.5, threshold=20), so the global write was mostly redundant — but the GPU-detection logic (choosing all-MiniLM-L6-v2 for CPU-only systems) is preserved in the new location. --- opc/scripts/setup/wizard.py | 44 +++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/opc/scripts/setup/wizard.py b/opc/scripts/setup/wizard.py index 142ddc78..8fd87231 100644 --- a/opc/scripts/setup/wizard.py +++ b/opc/scripts/setup/wizard.py @@ -991,15 +991,6 @@ async def run_setup_wizard() -> None: except ValueError: threshold = 20 - # Save config to global ~/.claude/settings.json - settings_path = get_global_claude_dir() / "settings.json" - settings = {} - if settings_path.exists(): - try: - settings = json.loads(settings_path.read_text()) - except Exception: - pass - # Detect GPU for model selection # BGE-large (1.3GB) needs GPU, MiniLM (80MB) works on CPU has_gpu = False @@ -1017,14 +1008,43 @@ async def run_setup_wizard() -> None: timeout = 300 # 5 min for small model console.print(" [dim]No GPU detected, using lightweight model[/dim]") - settings["semantic_search"] = { + # Save config to ~/.config/tldr/config.json (TLDR-specific). + # Previously this was written to ~/.claude/settings.json, but + # Claude Code does not recognise the "semantic_search" key and + # reports the settings file as invalid. The tldr daemon reads + # config from /.tldr/config.json at runtime; this + # global file serves as a reference for the chosen model. + tldr_config_dir = Path.home() / ".config" / "tldr" + tldr_config_path = tldr_config_dir / "config.json" + tldr_config: dict[str, Any] = {} + if tldr_config_path.exists(): + try: + tldr_config = json.loads(tldr_config_path.read_text()) + except Exception: + pass + + tldr_config["semantic"] = { "enabled": True, "auto_reindex_threshold": threshold, "model": model, } - settings_path.parent.mkdir(parents=True, exist_ok=True) - settings_path.write_text(json.dumps(settings, indent=2)) + tldr_config_dir.mkdir(parents=True, exist_ok=True) + tldr_config_path.write_text(json.dumps(tldr_config, indent=2)) + + # Clean up stale key from ~/.claude/settings.json if present + global_settings_path = get_global_claude_dir() / "settings.json" + if global_settings_path.exists(): + try: + global_settings = json.loads(global_settings_path.read_text()) + if "semantic_search" in global_settings: + del global_settings["semantic_search"] + global_settings_path.write_text( + json.dumps(global_settings, indent=2) + ) + except Exception: + pass + console.print(f" [green]OK[/green] Semantic search enabled (threshold: {threshold})") # Offer to pre-download embedding model