Documentation
Overview Requirements Install Config Socratic Gate Query Modes Memory Habits Dashboard API Troubleshoot

Documentation

Synaptic is a local-first AI dev companion powered by Gemma 4. It watches your development environment, builds a persistent memory of your coding history, and surfaces the right context at the right moment, entirely on your machine.

The centrepiece is the Socratic gate. Before you write code, Synaptic asks you to explain your intent. Gemma 4 evaluates the answer and either lets you through or asks a sharper follow-up. Over time, you stop copy-pasting patterns you don't understand.

Everything runs locally. No API keys required. Your code, errors, and history never leave your machine.

Requirements

RequirementVersionNotes
Node.js20+Required for the server and Electron app
OllamaLatestRuns Gemma 4 locally. See ollama.com
gemma4:e4b-Compression, vision, and reasoning model
nomic-embed-text-Embedding model for semantic search
macOS12+Full support. Linux/Windows: file watching + terminal work; vision and HUD are macOS-only.
On macOS, Ollama installs as a menu bar app that starts automatically. If ollama serve fails, it's already running. Just pull the models.

Installation

  • 1
    Clone and install dependencies
    git clone https://github.com/cybort360/synaptic
    cd synaptic
    npm install
  • 2
    Pull the AI models via Ollama
    ollama pull gemma4:e4b        # compression + vision + reasoning
    ollama pull nomic-embed-text   # semantic search embeddings
  • 3
    Create your config file
    cp synaptic.config.example.json synaptic.config.json
    Then edit synaptic.config.json. At minimum, add your project paths to watchPaths.
  • 4
    Launch
    npm run launch   # starts server + opens Electron HUD
    # or, server only:
    npm run dev
    The dashboard opens at http://localhost:3777. The HUD overlay toggles with Cmd+Shift+S.

First run

On first launch, a setup wizard walks you through:

  • Choosing what to observe (files, terminal, windows, shell history)
  • Adding directories to watch
  • Selecting a reasoning model (Local via Gemma 4, or Cloud via Gemini Flash)
  • Setting your language pair for habit detection and translation
  • Enabling the Socratic gate

Nothing is observed until you complete the wizard and click Start Observing.

Save a file in a watched directory after setup. Synaptic will compress it within 3 seconds and it will appear in the Activity tab.

Configuration

All settings live in synaptic.config.json at the project root. This file is gitignored so it never gets committed. The example file synaptic.config.example.json shows all available fields with defaults.

{
  "watchPaths": ["/Users/you/projects/my-app"],
  "fromLang": "JavaScript",
  "toLang": "Rust",
  "ollamaModel": "gemma4:e4b",
  "visionModel": "gemma4:e4b",
  "ollamaReasoningModel": "gemma4:e4b",
  "embeddingModel": "nomic-embed-text",
  "socraticMode": true,
  "socraticStrictness": "followup",
  "port": 3777
}

Changes made via the Settings panel in the dashboard are written to disk immediately and broadcast to all connected clients via WebSocket. No restart needed.

Watch paths

Synaptic watches the directories in watchPaths for file changes. Add or remove paths in Settings → Watched Paths. New paths take effect immediately. No restart required.

Exclude patterns

Files and directories matching these glob patterns are ignored by default:

"**/node_modules/**"
"**/.git/**"
"**/*.env"
"**/dist/**"
"**/build/**"
"**/.next/**"
"**/*.db"
"**/*.lock"
Synaptic watches its own source directory if you add it to watchPaths. This will generate memories about Synaptic's own code, which can pollute query results. Use a separate project directory for the best experience.

Models

Synaptic uses two tiers: a fast local model for ambient processing, and optionally a cloud model for reasoning.

FieldDefaultRole
ollamaModelgemma4:e4bEvent compression, runs every 3 seconds
visionModelgemma4:e4bTerminal screenshot reading on errors
ollamaReasoningModelgemma4:e4bQueries, Socratic engine, stuck detection
embeddingModelnomic-embed-textSemantic search vectors
reasoningModelApiKey""Optional Google AI Studio key that switches reasoning to Gemini Flash

Cloud reasoning (optional)

If your machine struggles with local reasoning speed, set a Google AI Studio API key in Settings → Reasoning Model → Cloud. Gemma 4 always stays local for compression and vision.

Language pair

Set fromLang and toLang to enable habit mismatch detection and the Mentor Bridge. Any language pair works: Python → Go, Java → Kotlin, JavaScript → Rust.

Change your language pair any time in Settings → Language Pair. The Bridge and Translate mode update immediately.

Leave both fields empty to use Synaptic as a general memory tool without language-specific features.

Socratic gate

The centrepiece feature. Before you write code, you explain yourself. Gemma 4 decides whether your explanation holds up.

When you save a recognized code file (.rs, .ts, .py, .go, etc.), Synaptic reads your recent activity and generates a targeted question about the file. The HUD opens within a couple of seconds. The question then streams in word-by-word as Gemma generates it.

How evaluation works

Gemma 4 evaluates your answer against three criteria:

  • Did you name a specific approach?
  • Did you describe at least one design decision?
  • Did you mention a potential failure mode or edge case?

Vague answers get a sharper follow-up. The maximum is 3 follow-up questions before the session auto-closes.

Strictness modes

ModeBehaviourBest for
followupQuestion appears in HUD. Answer or skip. Non-blocking.Daily learning, regular use
gateHUD persists until Gemma accepts your explanation. Cannot skip.Structured study, interview prep

Cooldown

After a session closes (passed or skipped), the same file won't trigger a new gate for 30 minutes. This prevents the gate from firing on every incremental save.

Enable

# In synaptic.config.json
"socraticMode": true,
"socraticStrictness": "followup"

Or toggle in Settings → Socratic Gate.

Query modes

The dashboard's Query tab offers four modes. All stream tokens as they arrive. You see the first word within seconds.

Translate
How do I do X in [language]?
Finds your own past code doing the equivalent pattern and maps it across to the target language. Grounded in your history, not generic docs.
POST /api/translate
Explain
What is [concept]?
Explains a concept using examples from your own coding history as anchors. Structured: WHAT IT IS → HOW IT WORKS → WHY IT MATTERS → EXAMPLE.
POST /api/explain
Map Concept
Map [concept] to what I know
Maps a new concept to things you already understand, using your recent activity as the anchor points. Click any concept in the Concepts tab to trigger this instantly.
POST /api/map-concept
Find Solution
Have I solved this before?
Semantic search over your full history. Finds past errors, resolutions, and patterns relevant to your current question. Answers start from your solutions, not the internet's.
POST /api/query

Memory pipeline

Events from your development environment flow through a pipeline every 3 seconds:

File save / terminal command / errorObserver  (chokidar + shell history polling)
           ↓
Compressor  gemma4:e4b → JSON
  summary, concepts[], significance, error_verbatim, resolution
           ↓
isConceptEvolution  gate: drops noise, keeps signal
           ↓
Embedder  nomic-embed-text → vector
           ↓
SQLite  local database: events + connections tables

Significance scoring

ScoreMeaningRetention
0.9+New error root cause, concept breakthrough, approach change365 days
0.7–0.89Error resolution, new API or pattern, significant refactor365 days
0.4–0.69Continued work on an established pattern30 days
<0.4Routine edit with no conceptual shift7 days

Habit mismatch detection

Runs every 15 seconds in the background. Analyses recent activity in your toLang files and checks whether you're applying patterns from your fromLang that won't work.

When a mismatch is detected, a warning banner appears in the dashboard and the HUD auto-shows. Examples caught:

  • Using try/catch syntax in Rust (should be Result<T,E>)
  • Checking for null in Go (should be nil checks)
  • Using var in TypeScript (should be let or const)
  • Async patterns that differ between languages
Habit detection requires both fromLang and toLang to be set in config.

Stuck detection

Synaptic monitors a rolling 5-minute window. If two or more of these signals appear together, it fires a stuck alert and auto-shows the HUD:

SignalThreshold
Terminal errors3 or more
Same command repeated3 or more times
App switches6 or more
Same file saved repeatedly5 or more times (thrashing)

The HUD appears with a "Get Help" button that pre-fills the query with the detected signals and submits to Find Solution mode.

Vision pipeline

On macOS, when Synaptic detects a terminal error, it captures a screenshot of your screen before compression. Gemma 4's multimodal capability reads the actual stack trace, including content that would otherwise be truncated in shell history.

This produces higher-quality memories for errors: exact line numbers, complete error messages, and the full context visible on screen at the moment the error occurred.

Requires macOS with Accessibility permissions granted to the Synaptic Electron app. Linux and Windows use text-only compression for terminal errors.

Dashboard

Open at http://localhost:3777 while the server is running.

TabWhat it shows
QueryFour query modes with streaming responses. Cmd+K to focus input, Cmd+Enter to send.
ActivityReal-time feed of compressed events. Filter by type (Code, Errors, Shell) or project folder.
ConceptsAll concepts extracted from your history, weighted by frequency. Click any concept to map it.
ProjectsPer-project stats: event count, error rate, last active, top concepts.
BridgePaste an error message. Gemma explains it using your coding history as the mental anchor.

HUD overlay

An always-on-top Electron window that lives in the bottom-right corner of your screen.

ShortcutAction
Cmd+Shift+SToggle HUD visibility
Cmd+Shift+VPush-to-talk voice input
EnterSend query (Ask tab)
Shift+EnterNew line in query input
Cmd+EnterSubmit Socratic answer

The HUD auto-shows (without you pressing a shortcut) when a Socratic gate fires, when stuck detection triggers, or when a habit mismatch is detected.

Voice input

Press Cmd+Shift+V in the HUD to start recording. Release or click again to stop. The audio is transcribed locally via whisper and the result is sent as a query.

Voice input requires whisper and ffmpeg installed locally. Install with: pip install openai-whisper and brew install ffmpeg. Falls back gracefully if not available.

API reference

All endpoints are served at http://localhost:3777. Streaming endpoints return text/event-stream with data: {"token":"..."} events.

Query endpoints

Method + PathBodyResponse
POST /api/query{ question }SSE stream. Find solution.
POST /api/explain{ question }SSE stream. Concept explanation.
POST /api/translate{ question, fromLang?, toLang? }SSE stream. Language translation.
POST /api/map-concept{ concept }SSE stream. Concept mapping.
POST /api/bridge{ error, lang, concepts?, imageBase64? }SSE stream. Error explanation.
POST /api/voice{ audio (base64), mimeType }{ transcript }

Socratic endpoints

Method + PathBodyNotes
POST /api/socratic/respond{ sessionId, answer }Submit explanation. Result arrives via WebSocket.
POST /api/socratic/skip{ sessionId }Skip session. Returns 403 in gate mode.
GET /api/socratic/session/:id-Full session history including Q&A turns

Data endpoints

Method + PathNotes
GET /api/events/recent?hours=24Recent compressed events
GET /api/events/significant?min=0.7High-significance events
GET /api/events/project/:nameEvents for a specific project
GET /api/events/concept/:conceptEvents containing a concept
GET /api/events/:id/connectionsSemantic connections for an event
GET /api/statsTotal events, connections, concepts, projects
GET /api/configCurrent configuration (API key redacted)
POST /api/configPatch config. Saves to disk and broadcasts update.
DELETE /api/events?olderThanDays=NClear old events

WebSocket events

Connect to ws://localhost:3777. All messages are { type, data }.

TypeDirectionPayload
new_eventserver → clientCompressedEvent
stuck_detectedserver → client{ file, duration, signals[] }
habit_mismatchserver → client{ pattern, oldLang, newLang, warning }
socratic_questionserver → client{ sessionId, question, isFollowUp, strictness }
socratic_resultserver → client{ sessionId, passed, feedback, totalTurns }
config_changedserver → clientFull config object

Troubleshooting

No events in Activity tab

Open the Activity tab. If it says "No activity recorded yet", check the diagnostic panel:

  • Ollama not running: open Ollama.app or run ollama serve
  • Models not pulled: run ollama pull gemma4:e4b
  • No watch paths: add a directory in Settings → Watched Paths

Click Fire test event in the diagnostic panel. If an event appears within 5 seconds, the pipeline is working.

Electron closes immediately on launch

A stale Electron process from a previous session is holding the single-instance lock. Run:

pkill -f "Electron"
npm run launch

npm run launch now does this automatically at startup, so this should only happen if you launch Electron directly.

Socratic gate not firing

Check that socraticMode: true is in your config. Then save any recognized code file (.rs, .ts, .py, etc.). The gate fires on save, not on open. There's a 30-minute cooldown per file after a session completes.

Queries return no response

Check that Ollama is running and the model is pulled. Open http://localhost:3777/api/debug. The response shows ollamaRunning and missingModels. If a model is listed as missing, pull it with ollama pull <model-name>.

Voice input not working

Requires whisper and ffmpeg:

pip install openai-whisper
brew install ffmpeg