* fix(mobile): handle desktop-encrypted API keys on mobile (follow-up to #2443) PR #2443 added the Buffer polyfill to base64.ts, utils.ts, and BedrockChatModel.ts but missed src/encryptionService.ts:119. My original write-up incorrectly claimed mobile never enters the DESKTOP_PREFIX branch of getDecryptedKey — it does, whenever a user encrypts their API keys on desktop and then syncs the vault to mobile via Obsidian Sync. Mobile reads the same encrypted blob, enters the DESKTOP_PREFIX branch, and hits `Buffer.from(...)`, which throws "Can't find variable: Buffer" on iOS WebKit. User reproducer: "Model request failed: Can't find variable: Buffer" during normal chat send on mobile after PR #2443 merged. Two-part fix: 1. Add `import { Buffer } from "buffer"` (the npm polyfill, already in dependencies and used in PR #2443) so the literal ReferenceError is gone. The legacy ENCRYPTION_PREFIX branch at line 137 also benefits. 2. Even with Buffer available, the next line `getSafeStorage()!.decryptString(buffer)` cannot succeed on mobile because there is no Electron safeStorage there. The encrypted blob uses OS-level encryption (Keychain on macOS, DPAPI on Windows, libsecret on Linux) that cannot be replayed from mobile. Add a Platform.isMobile guard that throws a clear, actionable error asking the user to re-enter their API key on this device instead of crashing on the unreachable decryption call. Out of scope: - The DESKTOP_PREFIX-on-mobile situation requires the user to re-save their key in mobile settings (which will re-encrypt with WEBCRYPTO_PREFIX, the cross-platform path that Web Crypto handles). Surfacing a clear error is the right user experience until the plugin auto-migrates on first mobile launch — that's a larger follow-up not appropriate for a same-day hotfix. - The legacy ENCRYPTION_PREFIX branch at line 137 still references Buffer, but it's already gated by `getSafeStorage()?.isEncryptionAvailable()` which returns false on mobile, so mobile never enters it. The new import covers it defensively if that gate ever changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(mobile): list desktop-encrypted keys on mobile load + block desktop encryption Two additions on top of the existing fix in this PR: 1. **Guard the encryption side with Platform.isDesktop.** Mobile should NEVER produce DESKTOP_PREFIX keys, even if `require("electron")` happens to return a truthy shim. Before this change, the only gate was `getSafeStorage()?.isEncryptionAvailable()` — fragile, since any mobile environment that exposes a partial Electron-like shim could slip through and save a key as DESKTOP_PREFIX that the same device then can't decrypt. 2. **Surface a Notice on mobile load** listing every key field that's still DESKTOP_PREFIX-encrypted. Without this, the user only finds out which key needs re-entry by hitting a chat error and having to guess. With it, they see the full list at startup: "Copilot: 3 API key(s) encrypted on desktop and unusable on mobile. Re-enter in Copilot settings: plusLicenseKey, openAIApiKey, activeModels[gpt-5.5]" Notice has timeout 0 so it stays until dismissed. The new exported `findDesktopEncryptedKeyFields(settings)` walks: - All top-level string settings (catches plusLicenseKey, openAIApiKey, anthropicApiKey, githubCopilotToken, etc.) - settings.activeModels[*].apiKey (per-model custom keys) - settings.activeEmbeddingModels[*].apiKey The exact field names returned match the keys in data.json so the user can grep / inspect / re-enter them confidently. This addresses the user report after the first commit in this PR: "despite reentering api key on mobile" — which happened because they re-entered one key but a *different* key (likely plusLicenseKey or a model-specific apiKey) was still DESKTOP_PREFIX, causing the chat to fail on that other key. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(encryption): deprecate encryption-at-rest; make encrypt/save a no-op The encryption toggle has created repeated incidents: 1. Mobile cannot decrypt DESKTOP_PREFIX (Electron safeStorage) keys that synced over from desktop, because mobile has no safeStorage. 2. The WebCrypto path is security theater — the AES-GCM key is a hardcoded "obsidian-copilot-v1" string, so anyone with data.json can decrypt every "encrypted" key in seconds. 3. PRs #2401 and #2403 (3.3.0) introduced bare `Buffer.from` in the encryption + base64 paths, which crashed mobile WebView with "Can't find variable: Buffer" — see #2443 and earlier commits in this PR. 4. Even with that fixed, the eager dispatch-map builders in chatModelManager / embeddingManager await getDecryptedKey for every provider; a throw on the one bad desktop-encrypted key killed chats that used a different provider with a valid key. Rather than continue patching, deprecate the toggle and stop adding encryption to new keys. Existing encrypted blobs in data.json remain readable via getDecryptedKey (for all three legacy formats: DESKTOP_PREFIX, WEBCRYPTO_PREFIX, and the original `enc_`); they migrate organically to plaintext the next time the user re-saves any given key. Changes: - `encryptAllKeys` → no-op (returns settings unchanged). 6+ lines of per-field encryption gone. - `getEncryptedKey` → no-op (returns plaintext, strips `dec_` marker if present). 25 lines of safeStorage / WebCrypto / DESKTOP_PREFIX branching gone. - `main.ts` settings-save → unconditionally `saveData(next)` instead of branching on `enableEncryption`. The setting field stays in the CopilotSettings interface for backwards-compat with existing data.json files but is no longer read or written. - `AdvancedSettings.tsx` → "Enable Encryption" toggle removed from the UI. Users who had it on get no further encryption; users who had it off see no change. Mobile-specific path inside `getDecryptedKey`: - DESKTOP_PREFIX keys on mobile return `DESKTOP_KEY_ON_MOBILE_SENTINEL` (no longer throw). chatModelManager / embeddingManager's eager dispatch-map construction completes; the sentinel sits harmlessly in unused config slots; providers actually being used with valid plaintext keys work. The startup Notice (already in this PR) surfaces which fields the user must re-enter. Tests: - `getEncryptedKey` test suite rewritten to verify the new no-op behavior (plaintext passthrough, dec_ stripping, empty-string). - `encryptAllKeys` test suite shrunk to one identity-return assertion. - Cross-platform encrypt/decrypt round-trip tests removed (encryption is gone). Added a legacy WebCrypto decrypt test to confirm we can still read existing enc_web_* blobs. - 1974 tests pass (was 1975; -1 for the dropped round-trip test). Net change: encryptionService.ts down from 207 to 130 lines. Risk: - `data.json` now contains plaintext API keys after first re-save. Worth saying explicitly in release notes. The previous "encryption" was indistinguishable from plaintext for anyone with filesystem access (hardcoded WebCrypto key), so this is a documentation change more than a security change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(mobile): simplify to a throw; drop sentinel + Notice + helper User feedback: the sentinel + startup-Notice approach added 70+ lines of transitional code that we'd have to delete later. Replace with the lightest viable shape. - Mobile DESKTOP_PREFIX branch in getDecryptedKey now throws a generic but actionable error ("re-enter your API keys on this device") and nothing else. - Removed DESKTOP_KEY_ON_MOBILE_SENTINEL constant. - Removed findDesktopEncryptedKeyFields function. - Removed the startup Notice block in main.ts and its import. Trade-off accepted: with multiple desktop-encrypted keys present, the chat fails on the first one the eager dispatch-map encounters; user re-enters that key, retries, hits the next bad key, repeats. The generic message tells them what to do; they iterate rather than seeing the full list up front. Net: -71 lines vs. previous approach. Future cleanup (when no users have desktop-encrypted keys anymore) is one small if-branch in getDecryptedKey instead of a sentinel + assert + helper + Notice spread across four files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .claude/agents | ||
| .cursor/rules | ||
| .github | ||
| .husky | ||
| __mocks__ | ||
| designdocs | ||
| docs | ||
| images | ||
| scripts | ||
| src | ||
| typings | ||
| .editorconfig | ||
| .gitignore | ||
| .npmrc | ||
| .prettierrc | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| components.json | ||
| CONTRIBUTING.md | ||
| esbuild.config.mjs | ||
| eslint.config.mjs | ||
| jest.config.js | ||
| jest.setup.js | ||
| LICENSE | ||
| local_copilot.md | ||
| manifest.json | ||
| nodeModuleShim.mjs | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| RELEASES.md | ||
| tailwind.config.js | ||
| tsconfig.json | ||
| version-bump.mjs | ||
| versions.json | ||
| wasmPlugin.mjs | ||
Copilot for Obsidian
The Ultimate AI Assistant for Your Second Brain
Documentation | Youtube | Report Bug | Request Feature
The What
Copilot for Obsidian is your in‑vault AI assistant with chat-based vault search, web and YouTube support, powerful context processing, and ever-expanding agentic capabilities within Obsidian's highly customizable workspace - all while keeping your data under your control.
The Why
Today's AI giants want you trapped: your data on their servers, prompts locked to their models, and switching costs that keep you paying. When they change pricing, shut down features, or terminate your account, you lose everything you built.
We are building the opposite. Our goal is to create a portable agentic experience with no provider lock-in. Data is always yours. Use whatever LLM you like. Imagine that a brand new model drops, you run it on your own hardware, and it already knows about you (long-term memory), knows how to run the same commands and tools you have defined over time (as just markdown files), and becomes the thought partner and assistant that you own. This is AI that grows with you, not a subscription you're hostage to.
This is the future we believe in. If you share this vision, please support this project!
Key Features
- 🔒 Your data is 100% yours: Local search and storage, and full control of your data if you use self-hosted models.
- 🧠 Bring Your Own Model: Tap any OpenAI-compatible or local model to uncover insights, spark connections, and create content.
- 🖼️ Multimedia understanding: Drop in webpages, YouTube videos, images, PDFs, EPUBS, or real-time web search for quick insights.
- 🔍 Smart Vault Search: Search your vault with chat, no setup required. Embeddings are optional. Copilot delivers results right away.
- ✍️ Composer and Quick Commands: Interact with your writing with chat, apply changes with 1 click.
- 🗂️ Project Mode: Create AI-ready context based on folders and tags. Think NotebookLM but inside your vault!
- 🤖 Agent Mode (Plus): Unlock an autonomous agent with built-in tool calling. No commands needed. Copilot automatically triggers vault, web searches or any other relevant tool when relevant.
Copilot's Agent can call the proper tools on its own upon your request.
Table of Contents
- The What
- The Why
- Key Features
- Copilot V3 is a New Era 🔥
- Why People Love It ❤️
- Get Started
- Usage
- Need Help?
- FAQ
- 🙏 Thank You
- Copilot Plus Disclosure
- Authors
Copilot V3 is a New Era 🔥
After months of hard work, we have revamped the codebase and adopted a new paradigm for our agentic infrastructure. It opens the door for easier addition of agentic tools (MCP support coming). We will provide a new version of the documentation soon. Here is a couple of new things that you cannot miss!
- FOR ALL USERS: You can do vault search out-of-the-box without building an index first (Indexing is still available but optional behind the "Semantic Search" toggle in QA settings).
- FOR FREE USERS: Image support and chat context menu are available to all users starting from v3.0.0!
- FOR PLUS USERS: Autonomous agent is available with vault search, web search, youtube, composer and soon a lot other tools! Long-term memory is also a tool the agent can use by itself starting from 3.1.0!
Read the Changelog.
Why People Love It ❤️
- "Copilot is the missing link that turns Obsidian into a true second brain. I use it to draft investment memos with text, code, and visuals—all in one place. It’s the first tool that truly unifies how I search, process, organize, and retrieve knowledge without ever leaving Obsidian. With AI-powered search, organization, and reasoning built into my notes, it unlocks insights I’d otherwise miss. My workflow is faster, deeper, and more connected than ever—I can’t imagine working without it." - @jasonzhangb, Investor & Research Analyst
- "Since discovering Copilot, my writing process has been completely transformed. Conversing with my own articles and thoughts is the most refreshing experience I’ve had in decades.” - Mat QV, Writer
- "Copilot has transformed our family—not just as a productivity assistant, but as a therapist. I introduced it to my non‑technical wife, Mania, who was stressed about our daughter’s upcoming exam; within an hour, she gained clarity on her mindset and next steps, finding calm and confidence." - @screenfluent, A Loving Husband
Get Started
Install Obsidian Copilot
- Open Obsidian → Settings → Community plugins.
- Turn off Safe mode (if enabled).
- Click Browse, search for “Copilot for Obsidian”.
- Click Install, then Enable.
Set API Keys
Free User
- Go to Obsidian → Settings → Copilot → Basic and click Set Keys.
- Choose your AI provider(s) (e.g., OpenRouter, Gemini, OpenAI, Anthropic, Cohere) and paste your API key(s). OpenRouter is recommended.
Copilot Plus/Believer
- Copy your license key at your dashboard. Don’t forget to join our wonderful Discord community!
- Go to Obsidian → Settings → Copilot → Basic and paste the key into in the Copilot Plus card.
Usage
Free User
Chat Mode: reference notes and discuss ideas with Copilot
Use @ to add context and chat with your note.
Ask Copilot:
Summarize Q3 Retrospective and identify the top 3 action items for Q4 based on the notes in {01-Projects}.
Vault QA Mode: chat with your entire vault
Ask Copilot:
What are the recurring themes in my research regarding the intersection of AI and SaaS?
Copilot's Command Palette
Copilot's Command Palette puts powerful AI capabilities at your fingertips. Access all commands in chat window via / or via
right-click menu on selected text.
Add selection to chat context
Select text and add it to context. Recommend shortcut: ctrl/cmd + L
Quick Command
Select text and apply action without opening chat. Recommend shortcut: ctrl/cmd + K
Edit and Apply with One Click
Select text and edit with one RIGHT click.
Create your Command
Create commands and workflows in Settings → Copilot → Command → Add Cmd.
Command Palette in Chat
Type / to use Command Palette in chat window.
Relevant Notes: notes suggestions based on semantic similarity and links
Appears automatically when there's useful related content and links.
Use it to quickly reference past research, ideas, or decisions—no need to search or switch tabs.
Copilot Plus/Believer
Copilot Plus brings powerful AI agentic capabilities, context-aware actions and seamless tool integration—built to elevate your knowledge work in Obsidian.
Get Precision Insights From a Specific Time Window
In agent mode, ask copilot:
What did I do last week?
Agent Mode: Autonomous Tool Calling
Copilot's agent automatically calls the right tools—no manual commands needed. Just ask, and it searches the web, queries your vault, and combines insights seamlessly.
Ask Copilot in agent mode:
Research web and my vault and draft a note on AI SaaS onboarding best practices.
Understand Images in Your Notes
Copilot can analyze images embedded in your notes—from wireframes and diagrams to screenshots and photos. Get detailed feedback, suggestions, and insights based on visual content.
Ask Copilot to analyze your wireframes:
Analyze the wireframe in UX Design - Mobile App Wireframes and suggest improvements for the navigation flow.
One Prompt, Every Source—Instant Summaries from PDFs, Videos, and Web
In agent mode, ask Copilot
*Compare the information about [Agent Memory] from this youtube video: [URL], this PDF [file], and @web[search results]. Start with your
conclusion in bullet points in your response*
Need Help?
- Check the documentation for setup guides, how-tos, and advanced features.
- Watch Youtube for walkthroughs.
- If you're experiencing a bug or have a feature idea, please follow the steps below to help us help you faster:
- 🐛 Bug Report Checklist
- ☑️Use the bug report template when reporting an issue
- ☑️Enable Debug Mode in Copilot Settings → Advanced for more detailed logs
- ☑️Open the dev console to collect error messages:
- Mac: Cmd + Option + I
- Windows: Ctrl + Shift + I
- ☑️Turn off all other plugins, keeping only Copilot enabled
- ☑️Attach relevant console logs to your report
- ☑️Submit your bug report here
- 💡 Feature Request Checklist
- ☑️Use the feature request template for requesting a new feature
- ☑️Clearly describe the feature, why it matters, and how it would help
- ☑️Submit your feature request here
- 🐛 Bug Report Checklist
FAQ
Why isn’t Vault search finding my notes?
If you're using the Vault QA mode (or the tool @vault in Plus), try the following:
- Ensure you have a working embedding model from your AI model's provider (e.g. OpenAI). Watch this video: AI Model Setup (API Key)
- Ensure your Copilot indexing is up-to-date. Watch this video: Vault Mode
- If issues persist, run Force Re-Index or use List Indexed Files from the Command Palette to inspect what's included in the index.
- ⚠️ Don’t switch embedding models after indexing—it can break the results.
Why is my AI model returning error code 429: ‘Insufficient Quota’?
Most likely this is happening because you haven’t configured billing with your chosen model provider—or you’ve hit your monthly quota. For example, OpenAI typically caps individual accounts at $120/month. To resolve:
- ▶️ Watch the “AI Model Setup” video: AI Model Setup (API Key)
- 🔍 Verify your billing settings in your OpenAI dashboard
- 💳 Add a payment method if one isn’t already on file
- 📊 Check your usage dashboard for any quota or limit warnings
If you’re using a different provider, please refer to their documentation and billing policies for the equivalent steps.
Why am I getting a token limit error?
Please refer to your model provider’s documentation for the context window size.
⚠️ If you set a large max token limit in your Copilot settings, you may encounter this error.
- Max tokens refers to completion tokens, not input tokens.
- A higher output token limit means less room for input!
🧠 Behind-the-scenes prompts for Copilot commands also consume tokens, so:
- Keep your message length short
- Set a reasonable max token value to avoid hitting the cap
💡 For QA with unlimited context, switch to the Vault QA mode in the dropdown (Copilot v2.1.0+ required).
🙏 Thank You
If you share the vision of building the most powerful AI agent for our second brain, consider sponsoring this project or buying me a coffee. Help spread the word by sharing Copilot for Obsidian on Twitter/X, Reddit, or your favorite platform!
Acknowledgments
Special thanks to our top sponsors: @mikelaaron, @pedramamini, @Arlorean, @dashinja, @azagore, @MTGMAD, @gpythomas, @emaynard, @scmarinelli, @borthwick, @adamhill, @gluecode, @rusi, @timgrote, @JiaruiYu-Consilium, @ddocta, @AMOz1, @chchwy, @pborenstein, @GitTom, @kazukgw, @mjluser1, @joesfer, @rwaal, @turnoutnow-harpreet, @dreznicek, @xrise-informatik, @jeremygentles, @ZhengRui, @bfoujols, @jsmith0475, @pagiaddlemon, @sebbyyyywebbyyy, @royschwartz2, @vikram11, @amiable-dev, @khalidhalim, @DrJsPBs, @chishaku, @Andrea18500, @shayonpal, @rhm2k, @snorcup, @JohnBub, @obstinatelark, @jonashaefele, @vishnu2kmohan
Copilot Plus Disclosure
Copilot Plus is a premium product of Brevilabs LLC and it is not affiliated with Obsidian. It offers a powerful agentic AI integration into Obsidian. Please check out our website obsidiancopilot.com for more details!
- An account and payment are required for full access.
- Copilot Plus requires network use to facilitate the AI agent.
- Privacy & Data Handling:
- Free tier: Your messages and notes are sent only to your configured LLM provider (OpenAI, Anthropic, Google, etc.). Nothing goes to Brevilabs servers.
- Plus tier: Messages go to your configured LLM provider. File conversions (PDF, DOCX, EPUB, images, etc.) are processed by Brevilabs servers only when you explicitly trigger these features via
@commands. - Processing vs. Retention: We process your data to deliver the feature you requested, then discard it. No message content, file uploads, or documents are retained on our servers after processing.
- User ID: A randomly generated UUID is sent with Plus API requests for service delivery (license abuse prevention, rate limiting) but is not used for user tracking, profiling, or analytics.
- Please see the privacy policy on the website for more details.
- The frontend code of Copilot plugin is fully open-source. However, the backend code facilitating the AI agents is close-sourced and proprietary.
- We offer a full refund if you are not satisfied with the product within 14 days of your purchase, no questions asked.
Authors
Brevilabs Team | Email: logan@brevilabs.com | X/Twitter: @logancyang