Visor is an Electron-based AI co‑pilot that overlays live, step‑by‑step guidance on your desktop. It captures your screen (or a mock image in dev), sends context to an LLM, and renders pointers (arrows, circles, tooltips) to guide you through tasks.
- Node.js 18+ and npm
- macOS, Windows, or Linux
- An LLM API key (OpenRouter recommended)
# 1) Clone and enter the project
git clone https://github.com/yassinvila/Visor.git
cd Visor
# 2) Install dependencies
npm install
# 3) Create your OWN .env (do not use ours)
# See the template below; keep it private and never commit it.
# 4) Start the app
npm startDo NOT use or share any .env that ships with this repo. Create a fresh .env file at the project root with your own values. You can start from the template:
cp .env.example .env
# then open .env and fill in your valuesUse this template as a guide:
# Required for live LLM calls
OPENROUTER_API_KEY=your_api_key_here
# Optional model/tuning (defaults shown)
OPENROUTER_MODEL=openai/gpt-4o
OPENROUTER_TEMPERATURE=0.2
# Screen capture controls
# Set to 'false' to use mock screenshots (no native capture required)
VISOR_USE_REAL_CAPTURE=true
# If using mock or capture fails, this maps to a default resolution
# Options: macbook-pro-14 | macbook-pro-13 | macbook-air-13 | surface-laptop | default
LAPTOP_VERSION=default
# Storage & logs (optional)
# VISOR_DATA_PATH=/absolute/path/to/visor-data
# VISOR_STRUCTURED_LOGS=true
# VISOR_MAX_LOG_SIZE_MB=10
# VISOR_MAX_LOG_FILES=30Important:
- Keep your
.envlocal and private..envis in.gitignore— do not commit secrets. - If you previously pulled someone else’s
.env, delete it and create your own.
npm start: Launch Electron (main + windows). This is the normal way to run Visor.npm run renderer:dev: Start Vite HMR for the renderer (overlay + chatbox) during UI work.npm run renderer:build: Build production assets todist/.npm run renderer:preview: Preview the built renderer.
You can also test the splash animation alone:
npx electron test-splash.js- Splash screen with a liquid‑glass panel and logo.
- Overlay window (transparent) and Chat window.
- Type a goal in chat — Visor captures a screenshot and asks the LLM for the next step.
- Overlay draws an arrow/circle/tooltip to guide your action.
- Mark steps done; Visor advances until finished.
OPENROUTER_API_KEY(required): Your OpenRouter API key.OPENROUTER_MODEL(optional): e.g.,openai/gpt-4o(defaults inside code).OPENROUTER_TEMPERATURE(optional): 0.0–1.0, default0.2.VISOR_USE_REAL_CAPTURE(optional): Set to'false'to use mock screenshots.LAPTOP_VERSION(optional): A resolution hint for mocks or when dimensions can’t be detected.VISOR_DATA_PATH(optional): Where logs/sessions are stored (else app userData).VISOR_STRUCTURED_LOGS(optional):'true'to enable JSONL structured logs.
- Missing API key:
OPENROUTER_API_KEY not set in environment→ Create.envwith your key. - Can’t capture screen: set
VISOR_USE_REAL_CAPTURE=falseto use mock images. - Non‑fast‑forward push to main: update local
mainthen merge your branch (see Git tips below).
electron-main/: Electron main process (windows, IPC, services)windows/: overlay, chat, splashservices/:screenCapture,storage, step controllerllm/: OpenRouter client wrapper
renderer/: Overlay + Chat (React + TS + Vite)config/: Defaults and schemascripts/: Utilities and dev tests
# Update main, merge your branch, push
git fetch origin
git switch main && git pull --rebase origin main
git merge --no-ff <your-branch>
git push origin main- Electron main process owns windows, IPC, capture, storage, and LLM calls. It exposes a safe bridge (
preload) aswindow.visorto the renderer. - Renderer (React + Vite) draws the overlay and chat UI. It receives step updates over IPC and renders guidance shapes.
- Environment variables control capture mode, storage location, and LLM behavior. No secrets are committed.
-
electron-main/main.js: App lifecycle. Shows the splash, then creates overlay + chat after splash completion. Registers IPC.preload.js: Context-isolated bridge exposingwindow.visorAPIs (splash.complete, overlay controls, chat events).windows/overlayWindow.js: Transparent always-on-top overlay window.chatWindow.js: Chat side panel.splashWindow.js: Fullscreen transparent splash, closes viasplash:complete.
services/screenCapture.js: Captures screenshots. RespectsVISOR_USE_REAL_CAPTUREandLAPTOP_VERSION. Temporarily hides overlay to avoid capturing it.storage.js: Persists sessions, steps, chat, and errors. Supports legacy JSON files or structured JSONL directories (VISOR_STRUCTURED_LOGS=true).stepController.js: Orchestrates goals into steps and emits them to the overlay (uses LLM client under the hood).
llm/client.js: Thin wrapper over OpenRouter SDK. ReadsOPENROUTER_API_KEY,OPENROUTER_MODEL,OPENROUTER_TEMPERATURE.
-
renderer/overlay/: Overlay app (entrymain.tsx) that renders guidance (arrows, circles, tooltips) driven by IPC updates.chatbox/: Chat UI to enter goals and show conversation history.splash/: HTML/CSS/JS for the splash animation.src/renderer: Starter React app (demo components used by some test flows).
-
assets/: Icons and static media. -
config/: Default JSON configs and schema placeholders. -
scripts/: Utilities for testing and packaging experiments.
- Default storage lives under Electron’s
userDatapath (platform-specific). Override withVISOR_DATA_PATH. - Enable structured logs with
VISOR_STRUCTURED_LOGS=trueto write JSONL files underlogs/anderrors/with daily rotation. - The repository includes a
demo-logs/folder used for local examples. It’s ignored by Git so it won’t be committed.
- A liquid‑glass panel expands, shows the VISOR wordmark, then gracefully closes back to the center.
- Animation respects
prefers-reduced-motionand completes deterministically, after whichsplash:completeis sent to the main process. - You can test it quickly with
npx electron test-splash.js.
scripts/verify-services.js: Sanity-checks storage, screen capture (mock), and OpenRouter connectivity (requires.env).scripts/testServices*.js: Unit-style tests for capture and storage in mock mode.scripts/build.js,scripts/packageApp.js: Experimental build/package helpers.
- Never commit
.envor real API keys..envis already in.gitignore. - Use
.env.exampleas a template to create your own.envlocally. - If sharing logs, redact any sensitive content first.
- “I don’t have a screen capture dependency installed.”
- Set
VISOR_USE_REAL_CAPTURE=falseto use mock screenshots.
- Set
- “OpenRouter key error at startup.”
- Create
.envwithOPENROUTER_API_KEY=...and restart.
- Create
- “Main branch rejects my push.”
- Update local
main(git pull --rebase origin main), merge your branch, push.
- Update local