Compare commits

...

10 Commits

Author SHA1 Message Date
morgankrey
a1146c1024 Script experiment 2025-11-21 14:25:34 -06:00
morgankrey
15e327b2c2 Merge branch 'main' of https://github.com/zed-industries/zed 2025-11-21 10:37:14 -06:00
morgankrey
d0e9243cdf Merge branch 'main' of https://github.com/zed-industries/zed 2025-11-14 00:09:21 -06:00
morgankrey
94dcf3fa6e Merge branch 'main' of https://github.com/zed-industries/zed 2025-11-07 13:04:31 -06:00
morgankrey
279364340e Merge branch 'main' of https://github.com/zed-industries/zed 2025-11-05 11:46:34 -06:00
morgankrey
8e2727721b Merge branch 'main' of https://github.com/zed-industries/zed 2025-11-05 05:42:57 -06:00
morgankrey
57d5fd0c0b undo 2025-10-10 10:23:55 -05:00
morgankrey
817e486ec0 Merge branch 'main' of https://github.com/zed-industries/zed 2025-10-10 10:21:27 -05:00
morgankrey
887570d852 Merge branch 'main' of https://github.com/zed-industries/zed 2025-10-10 08:08:53 -05:00
morgankrey
5fb4109309 Add Grok 2025-10-10 08:08:51 -05:00
3 changed files with 391 additions and 0 deletions

149
.zed_docs_hashes.json Normal file
View File

@@ -0,0 +1,149 @@
{
"docs/src/uninstall.md": "c1bb40843e74eb1a713b5cf668c38b4d",
"docs/src/authentication.md": "0a7a3bf9c64f71dbda2e6eb6df93e07a",
"docs/src/collaboration.md": "d964aa733688c07fe5ab26051de23363",
"docs/src/configuring-zed.md": "c5e50262589e9f675039d388aec70071",
"docs/src/vim.md": "bd9f44e3c0849b449eb1992cdbd138cf",
"docs/src/environment.md": "02d6ceefa5237451458edca3bf66a82e",
"docs/src/snippets.md": "c528ed73947e82b974753eb2dde5f333",
"docs/src/extensions.md": "293b78557b7344a30b02cd0224357bd6",
"docs/src/completions.md": "3170312b15baf4320ec38f2e0146e3f9",
"docs/src/debugger.md": "7b3b293cf44c92316de2cb5cfb5d9b5f",
"docs/src/configuring-languages.md": "4a4644dd87db8971630a2bd48b10a929",
"docs/src/troubleshooting.md": "1cb933be508b80656f67e9a3e6bdf25a",
"docs/src/SUMMARY.md": "e169efe683c9283d24884c10717ae771",
"docs/src/languages.md": "b0d6f399ffcbe884a8dacf60de9a60e6",
"docs/src/command-line-interface.md": "f13619d015e91b9d7eeaa5f56ebe5899",
"docs/src/key-bindings.md": "00e46b0f0eb3b113a344118e916e62eb",
"docs/src/multibuffers.md": "bf0d3746f8f78f4b700366bcb720d8a6",
"docs/src/outline-panel.md": "7e1cacd91178c8ffdf3b672dc8407288",
"docs/src/icon-themes.md": "facc5a7276c9ad0cbd8ffd291eab8477",
"docs/src/quick-start.md": "f379205d1384e10655c4c1f3cca37a4c",
"docs/src/windows.md": "21d4201ea6c67e1a3965b1ff21bdc1dc",
"docs/src/channels.md": "ffaf76acecb1106c383197653b303359",
"docs/src/linux.md": "98c0f49c0ed40ed4728c85488ec478df",
"docs/src/getting-started.md": "8dabaea3cbeaf4bff92f8a6e38a83931",
"docs/src/tasks.md": "71d9e360e0f9ef91488877114a90f814",
"docs/src/all-actions.md": "d34ef8711615b275ec74891aad4a3ef8",
"docs/src/remote-development.md": "6010ef47464d84301e2bdb0cf423c2de",
"docs/src/globs.md": "5f16689eaa0eeec1713d0a6e00a40d95",
"docs/src/update.md": "a901a02b54819f40329a55560ce93d41",
"docs/src/themes.md": "982c3ecc4b36fe0fb473651116142902",
"docs/src/visual-customization.md": "550b82e9183b87596086bc4ff7e7922a",
"docs/src/git.md": "0c9e0739760300c3c2245a06f4a38e90",
"docs/src/telemetry.md": "89913845f7cf3883bf3056c4c426e1dd",
"docs/src/command-palette.md": "5039bd1f3536254290c69d5681d5d096",
"docs/src/toolchains.md": "7f70b1c3ad06dba39ad5bf202fc0d3a7",
"docs/src/development.md": "72412bdb126f35b5a6f5f245a9403b63",
"docs/src/installation.md": "3684d4756e950438c6fdc8c166f6b785",
"docs/src/repl.md": "1f6500670f9ffd29ebe06f8c3a68f2ad",
"docs/src/diagnostics.md": "06f08ad96b72b1678fb27fb60ddb21e7",
"docs/src/helix.md": "bd444b7badc72025af2615258f240cd2",
"docs/src/development/debugging-crashes.md": "617f4e9c6f8310f4b075f5089e49fd16",
"docs/src/development/release-notes.md": "8cdb72f13729b17b7a9bad861569b9b3",
"docs/src/development/glossary.md": "7737f7d1cb769c54796803dc36e7d6b8",
"docs/src/development/windows.md": "76ec88b0fe594938647a5576cd500bb1",
"docs/src/development/linux.md": "94515b58679866ee86f247b3d2d3ec67",
"docs/src/development/macos.md": "d96a76289db1816b7c99a452070e0142",
"docs/src/development/debuggers.md": "afa1ad628774f85d273bf29dd608ca4a",
"docs/src/development/local-collaboration.md": "8ed324dc6379a9bb3cc4c6ceee9f169e",
"docs/src/development/freebsd.md": "5526de5366eddbac5b016e5f09ba12aa",
"docs/src/extensions/slash-commands.md": "2b1cbb8e7f69da8286036b6144fb20b1",
"docs/src/extensions/capabilities.md": "72b94b9ae459cbee8a361ce0f3ff801d",
"docs/src/extensions/languages.md": "c8b42796c7314dc1585f45c01ac3e4db",
"docs/src/extensions/installing-extensions.md": "ae3513eb5ba446a158d655dfc594d530",
"docs/src/extensions/icon-themes.md": "a645329b8119d407e309454b6e870d77",
"docs/src/extensions/debugger-extensions.md": "e012a67dbb5736fb6e1658641922812c",
"docs/src/extensions/developing-extensions.md": "477730e6776cb34259f0b3f2b5dc19e5",
"docs/src/extensions/agent-servers.md": "e45053fef95d84dbda722e00126f013c",
"docs/src/extensions/themes.md": "f7aba7595a0fd0049b8c04c11218f1e3",
"docs/src/extensions/mcp-extensions.md": "c7a99bc767804490892144dc1939ca3d",
"docs/src/languages/rego.md": "2fbabccf99fc007b926cf93b835e72ff",
"docs/src/languages/swift.md": "897d32a9e2e1efa5bb3f8de399690dbe",
"docs/src/languages/uiua.md": "001fa39e958755caa425e63ba393387f",
"docs/src/languages/gleam.md": "52d2d3eabb0e39e8ae1b20f4bccc008d",
"docs/src/languages/markdown.md": "2dceeb4a1407122c6071550deebc9739",
"docs/src/languages/kotlin.md": "85bd5432f9d910f91421040736f6648a",
"docs/src/languages/diff.md": "e0d97827d3fda213a0e7bf6b704b12fb",
"docs/src/languages/astro.md": "1ca4d480524ee21ea5bd44d975d05342",
"docs/src/languages/go.md": "aad8cb4ad15bbba3abaeac109d1b03be",
"docs/src/languages/makefile.md": "c198906c573879bdef14e175e87ef055",
"docs/src/languages/python.md": "0b3fc31c61659646afa5c964ef94ed2f",
"docs/src/languages/svelte.md": "6636fa7c490e465da047a9ab8c194002",
"docs/src/languages/yaml.md": "6c6a379ab4ad00f5f74d3ede106f35b0",
"docs/src/languages/css.md": "d2833d46353e43c4b6c31c8d876db151",
"docs/src/languages/tailwindcss.md": "ae0b43b559aa4f2eae71c5b34dbbc88c",
"docs/src/languages/csharp.md": "eb821e6ecdc105a946363bc816a62d1c",
"docs/src/languages/c.md": "46340612b34b13b4c888502b48e9dce0",
"docs/src/languages/nim.md": "b15339115b3eddca7c540392f4157097",
"docs/src/languages/yarn.md": "fbfb97dc76792bed294f4538a189f89c",
"docs/src/languages/elixir.md": "63d7b6ff84c2d0d217529d476df30843",
"docs/src/languages/luau.md": "588b22c4f975228effdc5873f51c1f5a",
"docs/src/languages/clojure.md": "33ce58b39d4f3cc75555b49821fcf5f8",
"docs/src/languages/scheme.md": "70bc5a3afbe3fdeb49991508fa628b39",
"docs/src/languages/rst.md": "79ea25cb2f248fa93e45545f4869d045",
"docs/src/languages/fish.md": "b0ca0d53dba9a52b2958e52e163c7734",
"docs/src/languages/json.md": "b8f0d953aa9656181bf66e802fd37564",
"docs/src/languages/zig.md": "49cf69e90551f33d1e81c3a616ea179e",
"docs/src/languages/proto.md": "52e0f3ff3f8b8c8aef75eabd531c5b5e",
"docs/src/languages/scala.md": "885ea898b31d6ef953b42a414f46c5c5",
"docs/src/languages/rust.md": "322ca854abe0356e737ff532e80f4256",
"docs/src/languages/groovy.md": "1b18942fccf4f9137c80ad3cf426b8a6",
"docs/src/languages/vue.md": "c3a65a43e0ce79aa5806a8c354e0db98",
"docs/src/languages/toml.md": "d1e3eaf4a0dc0b9751b9aee2cfa1a993",
"docs/src/languages/prisma.md": "12cf1811320b3e2bee76a78f51ef6848",
"docs/src/languages/purescript.md": "26a5c4fe7e068c710b9a6d74e59cf5b1",
"docs/src/languages/yara.md": "9133f1a21d408aa1d00f66ceb57b49f4",
"docs/src/languages/helm.md": "85ec28eea828ccdb4683f8c2729ef89e",
"docs/src/languages/php.md": "b253cb7aa93a724308d500ab36524204",
"docs/src/languages/deno.md": "0a898904271dd30ea2cab26d0350a19f",
"docs/src/languages/sql.md": "768cafa24090c5a9ee05c8904cf60395",
"docs/src/languages/asciidoc.md": "ed160f90d7ecc2f4b1c679da77b262b4",
"docs/src/languages/julia.md": "a573001a0022dd4cc537f0bf7ac7df44",
"docs/src/languages/javascript.md": "015c2a3a17412802551c7b5103be88e9",
"docs/src/languages/racket.md": "99147b908ce6ce4e1f418d4d95ed1277",
"docs/src/languages/elm.md": "67c6f471bdd1fb884c7fedc1e3cdf94b",
"docs/src/languages/haskell.md": "3dd1723e2aab7d9d689d8ee754f400e8",
"docs/src/languages/ocaml.md": "0fcbbbc11aa03d2f75842eb1ad85b606",
"docs/src/languages/terraform.md": "64a5ef6d90317ad1a5508228f1350353",
"docs/src/languages/erlang.md": "a6af6d54033d1e8cfe65e81e9f51e69a",
"docs/src/languages/r.md": "2dc9e86b72eabaec6d98ef880b50a297",
"docs/src/languages/java.md": "58477c6ee750b7112d0e09dea8722d4a",
"docs/src/languages/glsl.md": "362e680cfe383fe92bc910a1aaa6a293",
"docs/src/languages/lua.md": "12007ce8ac980025e7b56df33142d668",
"docs/src/languages/opentofu.md": "c530c548ea30bb86ea66e1e8ed6271cc",
"docs/src/languages/biome.md": "0b9f75efdd3e07a182fe017f1953b08b",
"docs/src/languages/ansible.md": "be3c3c27533be904f919ca1e53ddaabf",
"docs/src/languages/dart.md": "8b0ecc7c44005d1e9d9887d46707daa9",
"docs/src/languages/ruby.md": "298b11fe66916e1155ad983c98c3b06a",
"docs/src/languages/xml.md": "6608c1409a851d25dea7f4428fbc451c",
"docs/src/languages/cpp.md": "f0be63d4b3b908b379e2cc2fb0069d46",
"docs/src/languages/docker.md": "4265cc0c2eaf6cfc9ddf1ef03c6d9871",
"docs/src/languages/jsonnet.md": "48ed10b70c047ba6b85b759cfc3e6adb",
"docs/src/languages/powershell.md": "f583ed381553af8a83e342fee616f2a9",
"docs/src/languages/emmet.md": "f8203dfd9fec19cbb282376a1c065430",
"docs/src/languages/typescript.md": "da990cb18ec2b82e51a5f424966d386c",
"docs/src/languages/gdscript.md": "5e28240d06ccede7f5140aa2e0b85c96",
"docs/src/languages/roc.md": "423ce93da7fe18b0535e0602c12be9ac",
"docs/src/languages/bash.md": "2072f33d5aa33ebb2213d16def7da32b",
"docs/src/languages/html.md": "2b1c8e14364de85f08e1f66c19fb6fb8",
"docs/src/languages/sh.md": "7daa2333e99830215a50fdeecc61fafb",
"docs/src/ai/edit-prediction.md": "283d543aa7286251804b90f49fa351b1",
"docs/src/ai/overview.md": "ff098cdff58350ea764e80b41093e60c",
"docs/src/ai/mcp.md": "06bf8d9cc4c0bb40b90aea8032e809d7",
"docs/src/ai/llm-providers.md": "eab04bb1fb53e0f14fd1c2d043cac697",
"docs/src/ai/agent-panel.md": "72771371e3d9222b14ece20365ba9b40",
"docs/src/ai/ai-improvement.md": "101096734814b4ffb0c120c857f466bd",
"docs/src/ai/plans-and-usage.md": "a4b7d6bfeac12ac9bed97b730408b1c4",
"docs/src/ai/billing.md": "cbc3c1ca05f2d59a9888736251140717",
"docs/src/ai/subscription.md": "59f5f23f6486ef47bd59ed8e48898482",
"docs/src/ai/models.md": "575b3511c9a34c827da10cf3b5c13c09",
"docs/src/ai/configuration.md": "b899c6c4292bc75e023afbf99098bdcc",
"docs/src/ai/inline-assistant.md": "9a716b67327767122bc6a153e312d092",
"docs/src/ai/agent-settings.md": "57a74fbaa990722ce97a16128e8bbcbc",
"docs/src/ai/text-threads.md": "3ead1779bb763f15e23401127d52ba62",
"docs/src/ai/rules.md": "8a39bf545ce43bff2fe3096eebfe0774",
"docs/src/ai/external-agents.md": "c5b73e68bff489ee7133d66a314fd865",
"docs/src/ai/privacy-and-security.md": "ce5fccde9aabddff3cc6170b3145e88e",
"docs/src/ai/tools.md": "9fa76e75df7c65cad5b99d5f81ccacf3"
}

1
.zed_docs_store_id Normal file
View File

@@ -0,0 +1 @@
fileSearchStores/baicyhv73bbi-1g3hkppa3834

241
script/semantic_search.py Normal file
View File

@@ -0,0 +1,241 @@
import os
import glob
import time
import sys
import hashlib
import json
from google import genai
from google.genai import types
try:
from rich.console import Console
from rich.markdown import Markdown
from rich.panel import Panel
RICH_AVAILABLE = True
except ImportError:
RICH_AVAILABLE = False
def calculate_md5(file_path):
"""Calculates the MD5 hash of a file."""
hash_md5 = hashlib.md5()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def main():
# 1. Initialize Client
api_key = os.environ.get("GOOGLE_API_KEY")
if not api_key:
print("Error: GOOGLE_API_KEY environment variable not set.")
print("Please export it: export GOOGLE_API_KEY='your_key_here'")
sys.exit(1)
print("Initializing Gemini Client...")
client = genai.Client(api_key=api_key)
# 2. Discover Files
# Assuming script is run from project root, otherwise adjust path
docs_path = "docs/src"
if not os.path.exists(docs_path):
# Fallback if run from inside script/
if os.path.exists("../docs/src"):
docs_path = "../docs/src"
else:
print(f"Error: Could not find docs path at {docs_path}")
sys.exit(1)
md_files = glob.glob(f"{docs_path}/**/*.md", recursive=True)
if not md_files:
print(f"No markdown files found in {docs_path}")
sys.exit(1)
# LIMIT for PoC to avoid long wait times
# Ensure key-bindings.md is included if present
# priority_files = [f for f in md_files if "key-bindings.md" in f]
# other_files = [f for f in md_files if "key-bindings.md" not in f]
# md_files = priority_files + other_files
# if len(md_files) > 20:
# print(f"Found {len(md_files)} files. Limiting to first 20 for PoC speed.")
# md_files = md_files[:20]
print(f"Processing {len(md_files)} markdown files...")
# 3. Manage Store
store_name = "Zed Docs Prototype"
store_id_file = ".zed_docs_store_id"
file_hashes_file = ".zed_docs_hashes.json"
store = None
created_new = False
# A. Try loading from local cache
if os.path.exists(store_id_file):
with open(store_id_file, "r") as f:
cached_id = f.read().strip()
if cached_id:
try:
print(f"Attempting to load store from cache: {cached_id}")
store = client.file_search_stores.get(name=cached_id)
print(f"Loaded store: {store.name}")
except Exception:
print("Cached store not found or invalid.")
store = None
# B. If not found in cache, try finding by display name (fallback)
if not store:
print("Checking for existing File Search Store by name...")
for s in client.file_search_stores.list():
if hasattr(s, 'display_name') and s.display_name == store_name:
store = s
print(f"Found existing store by name: {store.name}")
# Update cache
with open(store_id_file, "w") as f:
f.write(store.name)
break
# C. If still not found, create new
if not store:
print("Creating new File Search Store...")
try:
# Try to set display_name if the SDK supports it in the create payload
# We'll try passing the config object if possible, or just bare create
# For the python SDK 'google-genai', exact syntax varies, but let's try basic first
store = client.file_search_stores.create()
print(f"Store created: {store.name}")
created_new = True
# Persist ID immediately
with open(store_id_file, "w") as f:
f.write(store.name)
except Exception as e:
print(f"Failed to create store: {e}")
sys.exit(1)
# 4. Upload Files (Incremental)
# We track file hashes to avoid re-uploading unchanged files.
file_hashes = {}
if not created_new and os.path.exists(file_hashes_file):
try:
with open(file_hashes_file, "r") as f:
file_hashes = json.load(f)
except Exception:
print("Warning: Could not load hash cache. Re-indexing may occur.")
file_hashes = {}
elif created_new:
# If we created a new store, we must upload everything, so ignore old hashes
file_hashes = {}
print("Checking files for updates...")
uploaded_count = 0
skipped_count = 0
failed_count = 0
# Track current hashes to clean up deleted files from cache later (optional cleanup)
new_file_hashes = {}
for file_path in md_files:
try:
current_hash = calculate_md5(file_path)
new_file_hashes[file_path] = current_hash
if file_path in file_hashes and file_hashes[file_path] == current_hash:
skipped_count += 1
continue
print(f"Uploading {file_path}...")
upload_op = client.file_search_stores.upload_to_file_search_store(
file_search_store_name=store.name,
file=file_path
)
while not upload_op.done:
time.sleep(0.5)
upload_op = client.operations.get(upload_op)
uploaded_count += 1
if uploaded_count % 5 == 0:
print(f"Uploaded {uploaded_count} new/modified files...")
except Exception as e:
print(f"Failed to upload {file_path}: {e}")
failed_count += 1
# If upload failed, don't update the hash in the new map so we retry next time?
# Or keep old hash? Let's just not add it to new_file_hashes if we want strict sync,
# but simpler to just keep the loop going.
# If we fail, we likely won't query correctly anyway.
# Save the new state
# We merge old and new to avoid losing history of files that might have been temporarily skipped?
# Actually, strictly speaking, we should only keep what exists now.
# But for simplicity, let's just save what we processed.
with open(file_hashes_file, "w") as f:
json.dump(new_file_hashes, f, indent=2)
print(f"Finished processing. Uploaded: {uploaded_count}, Skipped: {skipped_count}, Failed: {failed_count}")
# 5. Query
if len(sys.argv) > 1:
query = " ".join(sys.argv[1:])
else:
query = "How do I configure key bindings?"
print(f"\nAsking question: '{query}'")
try:
response = client.models.generate_content(
model='gemini-2.5-flash',
contents=query,
config=types.GenerateContentConfig(
tools=[types.Tool(
file_search=types.FileSearch(
file_search_store_names=[store.name]
)
)]
)
)
# 6. Output
if RICH_AVAILABLE:
console = Console()
console.print("\n[bold green]Response:[/bold green]")
console.print(Panel(Markdown(response.text), title="Gemini Response", border_style="blue"))
else:
print("\nResponse:")
print(response.text)
print("\n(Tip: Install 'rich' library for prettier output: pip install rich)")
# Print citations/grounding
if response.candidates[0].grounding_metadata:
if RICH_AVAILABLE:
console.print("\n[bold yellow]Sources used:[/bold yellow]")
else:
print("\nSources used:")
chunks = response.candidates[0].grounding_metadata.grounding_chunks
if chunks:
seen_sources = set()
for chunk in chunks:
if chunk.retrieved_context:
title = chunk.retrieved_context.title
if title not in seen_sources:
if RICH_AVAILABLE:
console.print(f"- [cyan]{title}[/cyan]")
else:
print(f"- {title}")
seen_sources.add(title)
else:
print("No specific grounding chunks returned.")
else:
print("\nNo grounding metadata returned.")
except Exception as e:
print(f"Error during generation: {e}")
print("\nDemo complete. Note: You may want to delete the store manually if not needed.")
if __name__ == "__main__":
main()