Cognitive onboarding in minutes. Visualize any repository as a complete graph and navigate it with Qwen 3 32B through Groq, while keeping Ollama as a local fallback.
- Point it at a folder on your disk.
- Spoon-Map walks the repo (JS · TS · Python · Dart · Go · Rust · Java · …) and builds a dependency graph between files.
- It renders the full graph with Obsidian-style physics: circular nodes, size based on how many files import them, thin gray edges, and an organic force-directed layout.
- You say or type where you want to go and Qwen 3 32B (via Groq) picks an important entry point, refines it through nearby connections, and returns both the final focus and a short summary of the file it found.
- If Groq is unavailable, navigation automatically falls back to the existing local flow with Ollama.
- Node 20+
- A Groq API key in
GROQ_API_KEYto useqwen/qwen3-32bas the primary navigator. - Ollama is optional, but recommended as a local fallback (
ollama serve) with thegemma4:e2bmodel:ollama pull gemma4:e2b
npm install
npm run devOpen http://localhost:3000, paste the absolute path to any local project, and press Map.
Then you can:
- click any node to center it,
- press the bottom microphone and say something like
take me to the import resolverso Qwen moves the focus and answers out loud too, - or type the request manually and let the AI move the focus.
app/api/analyze → walker + regex extractors + import resolver → {nodes, links}
app/api/warm → validates the main provider and falls back to Ollama when needed
app/api/navigate → shortlist of important nodes + Qwen 3 32B (Groq) + neighbor refinement → final focus + summary
components/
ObsidianGraph → react-force-graph-2d (Canvas + D3 force)
VoiceNavigator → bottom bar with microphone, inferred route, summary, and focus control
RepoLoader → initial screen with path picker
lib/analyzer/
walker → globby + .gitignore (excludes node_modules, .git, dist…)
extractors/ → JS/TS, Python, Dart (including `part` / `part of`), generic fallback
resolver → resolves relative specs, `@/*` aliases, Dart imports, and `package:my_app/...`
graph → builds nodes/edges and marks entry points
metrics → degree, neighbors, hubs
NAVIGATION_MODEL_PROVIDER=groq # groq or ollama; defaults to groq when GROQ_API_KEY exists
GROQ_API_KEY=gsk_... # Groq key for the primary navigator
GROQ_BASE_URL=https://api.groq.com/openai/v1
GROQ_MODEL=qwen/qwen3-32b
GROQ_TEMPERATURE=0.6
GROQ_TOP_P=0.95
GROQ_REASONING_EFFORT=none # omit it or use "none" to avoid <think> blocks
GROQ_MAX_TOKENS=4096
OLLAMA_BASE_URL=http://localhost:11434 # local fallback
OLLAMA_MODEL=gemma4:e2b # local fallback
OLLAMA_KEEP_ALIVE=-1 # keeps the model loaded to avoid cold starts
OLLAMA_TEMPERATURE=0.1 # more direct and stable answers
OLLAMA_MAX_TOKENS=320 # output cap for faster responses
OLLAMA_MAX_CODE_CHARS=18000 # shorter prompt to reduce latency
OLLAMA_NAV_MAX_CODE_CHARS=7000 # cap on the snippet used to summarize the target file
ELEVENLABS_API_KEY=xi_... # the backend calls ElevenLabs and returns the MP3 without exposing the key
ELEVENLABS_TTS_MODEL=eleven_flash_v2_5
NEXT_PUBLIC_ELEVENLABS_API_KEY_SANDBOX=xi_... # optional fallback
NEXT_PUBLIC_ELEVENLABS_VOICE_ID=EXAVITQu4vr4xnSDxMaL
NEXT_PUBLIC_ELEVENLABS_TTS_MODEL_ID=eleven_flash_v2_5- 5000-file cap per repo (configurable in
lib/analyzer/walker.ts). - Files larger than 512 KB are ignored.
- Fast navigation uses an in-memory cache of the repo's latest analysis; if you restart the server, you will need to map it again.