Problem
graphify extract <path> refuses to run on a code-only corpus unless an LLM API key is set — even though code extraction is pure local AST (tree-sitter) and never calls a model. This blocks the common "just give me an AST graph, no LLM" use case from the headless CLI.
Repro (all LLM keys unset)
mkdir -p /tmp/x/src
printf 'def login(u):\n return validate(u)\n\ndef validate(u):\n return True\n' > /tmp/x/src/auth.py
graphify extract /tmp/x/src
# error: no LLM API key found. Set GEMINI_API_KEY ... or pass --backend.
# exit 1, no graph.json produced
The AST-only path does work via a different command:
graphify update /tmp/x/src --no-cluster
# Re-extracting code files ... (no LLM needed) -> graph.json written
So the capability exists; extract just gates on a key it doesn't need.
Cause
The extract command (graphify/__main__.py) resolves and validates an LLM backend upfront — it calls detect_backend() and exits with no LLM API key found if none is set — before detecting the corpus composition. A code-only corpus (no docs/papers/images) needs no model, but is blocked at that gate anyway.
Expected
A code-only extract should run with no API key, producing graph.json from AST alone (matching graphify update --no-cluster). The key should only be required when there's actual semantic work — docs/papers/images, or --dedup-llm.
Proposed fix
Defer backend resolution until after file detection and only require a key when semantic_files is non-empty or --dedup-llm is passed. Improve the error to name why a key is needed and note that code-only corpora need none.
Problem
graphify extract <path>refuses to run on a code-only corpus unless an LLM API key is set — even though code extraction is pure local AST (tree-sitter) and never calls a model. This blocks the common "just give me an AST graph, no LLM" use case from the headless CLI.Repro (all LLM keys unset)
The AST-only path does work via a different command:
graphify update /tmp/x/src --no-cluster # Re-extracting code files ... (no LLM needed) -> graph.json writtenSo the capability exists;
extractjust gates on a key it doesn't need.Cause
The
extractcommand (graphify/__main__.py) resolves and validates an LLM backend upfront — it callsdetect_backend()and exits withno LLM API key foundif none is set — before detecting the corpus composition. A code-only corpus (no docs/papers/images) needs no model, but is blocked at that gate anyway.Expected
A code-only
extractshould run with no API key, producinggraph.jsonfrom AST alone (matchinggraphify update --no-cluster). The key should only be required when there's actual semantic work — docs/papers/images, or--dedup-llm.Proposed fix
Defer backend resolution until after file detection and only require a key when
semantic_filesis non-empty or--dedup-llmis passed. Improve the error to name why a key is needed and note that code-only corpora need none.