<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cernalo</title>
    <description>The latest articles on DEV Community by Cernalo (@cernalo).</description>
    <link>https://dev.to/cernalo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4191662%2F61405271-d3fc-45f9-8c99-3bbacfc7ed8b.png</url>
      <title>DEV Community: Cernalo</title>
      <link>https://dev.to/cernalo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cernalo"/>
    <language>en</language>
    <item>
      <title>Why Our AI Desktop Assistant Never Stores Model API Keys on Your Computer</title>
      <dc:creator>Cernalo</dc:creator>
      <pubDate>Sun, 18 Oct 2026 07:29:42 +0000</pubDate>
      <link>https://dev.to/cernalo/why-our-ai-desktop-assistant-never-stores-model-api-keys-on-your-computer-5h79</link>
      <guid>https://dev.to/cernalo/why-our-ai-desktop-assistant-never-stores-model-api-keys-on-your-computer-5h79</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://cernalo.com/blog/why-ai-api-keys-stay-off-your-desktop" rel="noopener noreferrer"&gt;cernalo.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Provider keys stay on the server. The desktop app sends a session and the context you choose, and the service checks the plan before it calls a model.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern we chose not to copy
&lt;/h2&gt;

&lt;p&gt;I build Cernalo. This post explains one architectural decision and its costs. It is meant to help you evaluate any desktop AI tool, not just ours.&lt;/p&gt;

&lt;p&gt;Before I wrote any product code for Cernalo, I spent time reading how open-source desktop AI assistants are put together. Many of them share a pattern that makes sense for a weekend project: the AI provider's API key sits in a configuration file on your computer, the desktop app calls the model provider directly, and nothing in between knows who is asking, how much they have used, or whether the request should be allowed.&lt;/p&gt;

&lt;p&gt;It is simple and needs no server. For a product that people pay for and trust with their screen and voice, I think it is the wrong default. Here is what we do instead, why, and what it costs us and you.&lt;/p&gt;

&lt;p&gt;When a desktop app holds a provider key and calls the model directly, three things follow. The key is only as safe as the least-protected machine it is on. A plaintext key in an app-data folder can be read by anything running as that user: malware, a sync tool that uploads the folder, a support bundle that zips the logs. Nobody can enforce limits. If the client talks to the provider with its own credentials, the product has no reliable way to apply plan limits, stop abuse, or show you an accurate usage history. Any limit lives in code the user controls. Changing providers means shipping a new app. If a provider has an outage, changes a model, or raises prices, every installed copy needs an update before anything changes.&lt;/p&gt;

&lt;p&gt;So the decision record says it in one line: all production AI provider keys live only on our backend. The desktop app never calls a model provider directly for production AI features. It calls Cernalo's service, which checks your plan, routes the request, and records usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  What server-side credentials means in practice
&lt;/h2&gt;

&lt;p&gt;When you ask Cernalo something, by typing, by voice transcribed locally first, or with a screen region you chose, this is what happens. Your device sends your question, plus any screen or region you captured, and your session token. The token is stored with the operating system's secure credential storage, not as a plaintext file. The call is HTTPS to the Cernalo service. The service authenticates the session, checks plan entitlements, chooses a route for the request's capability, and calls the provider with server-held credentials. The provider's answer comes back through the service to your device.&lt;/p&gt;

&lt;p&gt;Plan entitlements cover model classes, monthly credits, and a rolling 24-hour safety cap. The route is chosen for the capability, such as coding or vision.&lt;/p&gt;

&lt;p&gt;Your device holds a session, not a provider key. If you revoke a device in the account portal, that session stops working. No provider key is ever on your machine to rotate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plans, credits, and model classes
&lt;/h2&gt;

&lt;p&gt;Plans map to model classes, not model names. Internally every supported model is classified as economy, standard, or advanced. The Free plan uses economy models. Pro adds standard. Premium adds advanced. Economy requests typically use 1 credit, standard requests 2, and advanced requests 5, and a screen analysis may add one. The classification is an explicit list, never a guess from the model's name. Changing a route does not silently change what a plan can access.&lt;/p&gt;

&lt;p&gt;Usage is recorded where it can be trusted. Because metering happens on the server, the usage dashboard in your account shows what the service actually did, not what a client claims it did.&lt;/p&gt;

&lt;p&gt;We do not advertise which vendor answered. Model availability changes. Public material describes model classes rather than naming vendors, and the assistant is instructed not to invent a model name if you ask it. I would rather under-promise on brand names than promise a model we might route away from next week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Routing and fallback without guessing
&lt;/h2&gt;

&lt;p&gt;Holding keys server-side also lets us handle provider failures in one place. The rules are deliberately boring, and boring is the point.&lt;/p&gt;

&lt;p&gt;Cooldowns can be shared between server instances, so one worker discovering that a provider is rate-limited can save the others from repeating the mistake. Those shared records contain only routing metadata: which provider or model is cooling, and for how long. They never contain your prompt, images, audio, or any key. Routing logs record categories such as provider, model, result, and error category. Prompts, conversation text, images, audio, and keys are never logged.&lt;/p&gt;

&lt;p&gt;Every fallback still happens inside your plan's allowed model classes. A fallback never upgrades or downgrades you out of what your plan includes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication, an invalid request, or a content-policy refusal: stop. Do not retry elsewhere. Another provider will not fix a bad request, and retrying a refusal elsewhere would be wrong.&lt;/li&gt;
&lt;li&gt;A billing problem on the first route: stop, and cool that provider down.&lt;/li&gt;
&lt;li&gt;A rate limit or quota on a model: fall back to the next allowed route, and cool down that model.&lt;/li&gt;
&lt;li&gt;An account-wide quota on a provider: fall back, and cool down the whole provider.&lt;/li&gt;
&lt;li&gt;A server error, a timeout, a network error, or an empty answer: fall back, with no cooldown.&lt;/li&gt;
&lt;li&gt;A request too large for the model: fall back only to a route with a larger known context window.&lt;/li&gt;
&lt;li&gt;Part of an answer has already been shown to you: no silent switch. We do not splice another model's continuation onto a half-finished answer. You can ask again.&lt;/li&gt;
&lt;li&gt;A request that includes an image: only routes that support vision are eligible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Treating on-screen text as untrusted
&lt;/h2&gt;

&lt;p&gt;A desktop assistant that reads screenshots has a problem that chat apps have less often: the content can contain instructions. A web page, an email, or a document on screen might include text like "ignore your previous instructions". That is prompt injection, delivered as pixels.&lt;/p&gt;

&lt;p&gt;Because every request passes through our service, we can apply the same policy to all of them. Every mode's system instruction begins by telling the model to treat text inside screenshots, quoted material, and transcripts as untrusted context, not as instructions, and not to claim it consulted sources or took actions that were not provided.&lt;/p&gt;

&lt;p&gt;That reduces the risk. It does not eliminate it. No current technique does. Practically: do not snap content you do not trust, and read answers about untrusted content more sceptically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trade-offs we accept
&lt;/h2&gt;

&lt;p&gt;This design is not free, and I think vendors should say so.&lt;/p&gt;

&lt;p&gt;There is no fully offline AI mode. Local voice transcription works without a network, but answering a question requires our service. If our backend is down, AI answers are down, even if a provider is fine.&lt;/p&gt;

&lt;p&gt;Our backend sits in every AI request. That is one more network hop and one more system that has to be secured, monitored, and kept running. It also means your question and any capture you choose to send pass through our service. The &lt;a href="https://cernalo.com/security" rel="noopener noreferrer"&gt;security notes&lt;/a&gt; and the &lt;a href="https://cernalo.com/privacy" rel="noopener noreferrer"&gt;privacy policy&lt;/a&gt; describe how that is handled, and say plainly that we do not hold SOC 2 or ISO 27001 certifications today.&lt;/p&gt;

&lt;p&gt;You cannot bring your own key. Some developers would prefer to use their own provider account. We do not support that today, because it conflicts with server-side limits. It could come later as an explicit, separately designed option.&lt;/p&gt;

&lt;p&gt;You are trusting us as an intermediary. Server-side keys protect you from a class of client-side leaks. They do not remove the need to trust the service in the middle. That is a fair trade for some people and not for others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions to ask any desktop AI vendor
&lt;/h2&gt;

&lt;p&gt;Whether you use Cernalo or something else, these are worth asking. A vendor who can answer them plainly, including "we do not do that yet", is usually one you can work with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are the model provider keys stored? On my machine, or on your servers?&lt;/li&gt;
&lt;li&gt;What does my device store to stay signed in, and how is it protected?&lt;/li&gt;
&lt;li&gt;Can I revoke a device?&lt;/li&gt;
&lt;li&gt;What exactly is sent with a request? Only what I chose, or more?&lt;/li&gt;
&lt;li&gt;What do you log? Are prompts, images, or audio ever written to logs?&lt;/li&gt;
&lt;li&gt;What happens when a provider fails? A silent model switch, or clear rules?&lt;/li&gt;
&lt;li&gt;How do you handle instructions hidden in screenshots or documents?&lt;/li&gt;
&lt;li&gt;Which certifications do you actually hold? Enterprise-grade is not one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Questions about Cernalo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does Cernalo store my provider API key?&lt;/strong&gt; There is not one to store. Cernalo does not ask for your provider key, and the desktop app holds no provider keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which AI models does Cernalo use?&lt;/strong&gt; Cernalo picks a supported model from the classes your plan includes: everyday models on Free, plus more capable classes on Pro and Premium. Provider credentials stay on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I see my usage?&lt;/strong&gt; Yes. Usage and model-class analytics are in the account portal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is my screen sent automatically?&lt;/strong&gt; No. Screen and region capture start only when you start them, and a capture is sent only with the request you submit.&lt;/p&gt;

&lt;p&gt;The context you choose, in one place. If this is the kind of trade-off you care about, read the &lt;a href="https://cernalo.com/security" rel="noopener noreferrer"&gt;security notes&lt;/a&gt; or try the free plan on the &lt;a href="https://cernalo.com/download" rel="noopener noreferrer"&gt;download page&lt;/a&gt;. Questions and objections go to &lt;a href="mailto:cernalo.ops@gmail.com"&gt;cernalo.ops@gmail.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue exploring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/security" rel="noopener noreferrer"&gt;Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/privacy" rel="noopener noreferrer"&gt;Privacy Policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/pricing" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/download" rel="noopener noreferrer"&gt;Download Cernalo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/features" rel="noopener noreferrer"&gt;What Cernalo can do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/blog/local-speech-to-text-whisper-cpp-desktop-app" rel="noopener noreferrer"&gt;Shipping local speech-to-text in a desktop AI assistant: what we learned bundling whisper.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Cernalo is an AI desktop assistant: snap part of your screen or ask by voice. Try it free at &lt;a href="https://cernalo.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=why-ai-api-keys-stay-off-your-desktop" rel="noopener noreferrer"&gt;https://cernalo.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=why-ai-api-keys-stay-off-your-desktop&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>architecture</category>
      <category>api</category>
    </item>
    <item>
      <title>Shipping Local Speech-to-Text in a Desktop AI Assistant: What We Learned Bundling whisper.cpp</title>
      <dc:creator>Cernalo</dc:creator>
      <pubDate>Sun, 18 Oct 2026 07:23:06 +0000</pubDate>
      <link>https://dev.to/cernalo/shipping-local-speech-to-text-in-a-desktop-ai-assistant-what-we-learned-bundling-whispercpp-jh4</link>
      <guid>https://dev.to/cernalo/shipping-local-speech-to-text-in-a-desktop-ai-assistant-what-we-learned-bundling-whispercpp-jh4</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://cernalo.com/blog/local-speech-to-text-whisper-cpp-desktop-app" rel="noopener noreferrer"&gt;cernalo.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The desktop app turns speech into text on your computer with a bundled whisper.cpp runtime. The question is answered only after you send the text.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The audio stays on the computer
&lt;/h2&gt;

&lt;p&gt;I build Cernalo, an AI desktop assistant, on my own. This is an engineering write-up of one decision: transcribing your voice on your own device. It includes the version that did not work.&lt;/p&gt;

&lt;p&gt;When you click the microphone in Cernalo, or press Ctrl+Shift+V, and ask a question out loud, the audio does not leave your computer to be transcribed. A small speech-to-text engine bundled with the app turns it into text locally. You see the transcript, and only when you send it does the text go to our service and on to the AI model that answers.&lt;/p&gt;

&lt;p&gt;That sounds like a small product detail. It took two attempts, one of which I would now call a mistake, and it shaped how the whole desktop app is packaged. If you are thinking about putting local speech recognition into an Electron app, or any desktop app, this is what I would tell you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why transcription stays on the device
&lt;/h2&gt;

&lt;p&gt;Three reasons, in order of importance.&lt;/p&gt;

&lt;p&gt;Voice is the most sensitive input we handle. A screenshot is something you frame on purpose. A microphone picks up whatever is in the room: a colleague's side conversation, a phone call in the background, a child asking for snacks. If speech can become text without sending raw audio anywhere, that audio is not in flight and it is not stored on a server for transcription.&lt;/p&gt;

&lt;p&gt;You should see what you said before anyone else does. Local transcription makes a review step natural. The transcript appears, you can correct a misheard word or decide not to send it at all, and only then does it become a request. That is the same "you choose the context" principle the rest of Cernalo is built on.&lt;/p&gt;

&lt;p&gt;The current desktop app has one speech path: the bundled local runtime. It does not include a cloud speech option, so microphone audio is not uploaded to be transcribed. The text you review is the part you can choose to send.&lt;/p&gt;

&lt;p&gt;Here is what local transcription is not: a claim that Cernalo is offline AI. Answering your question still uses hosted models through our service. I will come back to that split, because being vague about it is how desktop AI products lose trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version one: a script subprocess
&lt;/h2&gt;

&lt;p&gt;The first working prototype did what most tutorials suggest. A small worker script, written in a popular scripting language, loaded an open-source Whisper package and transcribed a temporary audio file. The Electron main process spawned it, waited, and read the text back. On my development machine it worked on the first afternoon.&lt;/p&gt;

&lt;p&gt;Then I tried to package it.&lt;/p&gt;

&lt;p&gt;A desktop app launched from the desktop does not inherit your developer shell. My terminal had the right interpreter, the right package manager, a virtual environment, and the model files on its &lt;code&gt;PATH&lt;/code&gt;. A packaged app has none of that. The worker simply could not find its runtime.&lt;/p&gt;

&lt;p&gt;The fix would have pushed my toolchain onto every customer. To make it work, a user would have had to install a language runtime, a package manager, a virtual environment, and the speech package, and keep them working through updates. That is not a product. It is a setup guide with a logo on it.&lt;/p&gt;

&lt;p&gt;The worker could not run from inside the app archive. Electron apps ship most files inside a packed archive, &lt;code&gt;app.asar&lt;/code&gt;. An external interpreter cannot execute a script that lives inside it. Workarounds exist, and every one of them felt like a new class of bug.&lt;/p&gt;

&lt;p&gt;I had been tempted by the principle "do not rewrite a working subprocess". The packaging requirement overrode it: the shipped app has to transcribe using files that ship beside the app, not a toolchain the customer assembles. That sentence became the decision record.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version two: bundled whisper.cpp and FFmpeg
&lt;/h2&gt;

&lt;p&gt;The approach that shipped uses whisper.cpp, a native implementation of the Whisper model, plus a bundled FFmpeg for audio conversion. Both are plain executable files that sit in the app's resources directory, outside the packed archive: &lt;code&gt;whisper/bin/whisper-cli&lt;/code&gt;, &lt;code&gt;whisper/bin/ffmpeg&lt;/code&gt;, and &lt;code&gt;whisper/models/ggml-&amp;lt;model&amp;gt;.en.bin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The pipeline from the microphone to text is: the microphone runs only after you start it, audio is recorded in the app, a temporary local file is written, bundled FFmpeg converts it, bundled whisper.cpp transcribes it, the transcript is shown to you, you edit or send or discard it, and only then does a text request go to Cernalo's service.&lt;/p&gt;

&lt;p&gt;Five implementation details made the difference between "works on my machine" and "works when installed".&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolve paths and fail closed
&lt;/h2&gt;

&lt;p&gt;The build copies the speech runtime into the app's resources outside the packed archive, using electron-builder &lt;code&gt;extraResources&lt;/code&gt;. The main process resolves those exact paths at runtime. It does not search &lt;code&gt;PATH&lt;/code&gt; and it does not look for a system copy of FFmpeg. If a binary is not where we put it, that is a packaging bug, and I want to see it as one.&lt;/p&gt;

&lt;p&gt;When the packaged app cannot find the binary or the model, it fails with a clear error, internally &lt;code&gt;RUNTIME_NOT_FOUND&lt;/code&gt; or &lt;code&gt;MODEL_NOT_READY&lt;/code&gt;. It does not quietly try a system interpreter or a cloud service instead. Silent fallbacks are how a local feature turns into a non-local one without anyone noticing, and that is the failure I most wanted to rule out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spawn safely, pin the build, and keep licences honest
&lt;/h2&gt;

&lt;p&gt;The transcriber is spawned with an argument array and shell set to false, so nothing from the audio path or settings is interpreted by a shell. Each run has a timeout, can be cancelled when you stop or close the app, and the temporary audio file is deleted afterwards. Small things, but they are the difference between a helper process and a liability.&lt;/p&gt;

&lt;p&gt;The release build pins a specific whisper.cpp revision, a specific model file, and an FFmpeg build compiled with LGPL-only options. It checks their hashes during packaging. The model weights ship with the app. They are not downloaded the first time you speak. That makes installers larger, and in exchange the thing you install is the thing we tested.&lt;/p&gt;

&lt;p&gt;FFmpeg's licensing depends on how it is built. Our packaging includes a guard that checks the FFmpeg build flags, and the third-party notices ship with the app. If you are bundling native tools, budget time for this. It is not optional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model choice and honest limits
&lt;/h2&gt;

&lt;p&gt;We use a small English Whisper model by default. That choice comes with limits I would rather state than have you discover.&lt;/p&gt;

&lt;p&gt;It is English-focused. Other languages and heavy code-switching will not transcribe as well with this model.&lt;/p&gt;

&lt;p&gt;Performance depends on your hardware. Transcription runs on your computer, so an older machine will do the same work with more effort than a recent one. That is why the site says performance varies by hardware, rather than quoting a number.&lt;/p&gt;

&lt;p&gt;It is basic speech-to-text. It turns what you said into text. It is not a meeting notetaker, and it does not identify speakers. Voice questions use the microphone you start. They do not take audio from other applications.&lt;/p&gt;

&lt;p&gt;Accuracy is not perfect, which is exactly why the transcript is shown to you before it is sent.&lt;/p&gt;

&lt;p&gt;Could we use a larger model? Yes, with a bigger download and more work for your machine on every question. For short spoken questions, the small model was the right balance for us. If you have a strong opinion, I would like to hear it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What still goes to the cloud, and why
&lt;/h2&gt;

&lt;p&gt;Being precise matters here. Microphone capture, when you start it, happens on your device. Speech-to-text happens on your device, with bundled whisper.cpp. Reviewing and editing the transcript happens on your device. Answering the question happens on Cernalo's service, then the configured AI model for your plan. Screen or region capture, when you start it, is captured on your device and sent with the request you submit.&lt;/p&gt;

&lt;p&gt;The language models that answer your question are hosted. We broker every AI request through our own service, so provider credentials never sit on your machine and plan limits are enforced server-side. I have written separately about &lt;a href="https://cernalo.com/blog/why-ai-api-keys-stay-off-your-desktop" rel="noopener noreferrer"&gt;why API keys stay off your desktop&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Running a capable answering model locally on a typical computer is a different trade-off with different costs, and we do not claim to do it today.&lt;/p&gt;

&lt;p&gt;So the honest summary is: your voice is transcribed locally, and your question is answered in the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  A checklist if you are bundling whisper.cpp
&lt;/h2&gt;

&lt;p&gt;If you are building something similar, here is the list I wish I had had.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decide early whether local is a promise. If it is, design the failure mode first: what happens when the binary or model is missing? Our answer is to fail closed and show an error.&lt;/li&gt;
&lt;li&gt;Ship binaries and models outside your app archive and resolve them by absolute path. Do not rely on &lt;code&gt;PATH&lt;/code&gt; in a packaged app.&lt;/li&gt;
&lt;li&gt;Spawn with argument arrays and no shell. Add a timeout and a cancel path. Delete temporary audio.&lt;/li&gt;
&lt;li&gt;Pin versions and hashes for the runtime, the model, and FFmpeg. Verify them in the build, not by hand.&lt;/li&gt;
&lt;li&gt;Check FFmpeg licensing for the exact build you ship, and include notices.&lt;/li&gt;
&lt;li&gt;Show the transcript before sending. It handles both accuracy and consent.&lt;/li&gt;
&lt;li&gt;Say plainly which parts are local and which are not. People notice when local quietly means partly local.&lt;/li&gt;
&lt;li&gt;Test on modest hardware, not just your development machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does Cernalo record in the background?&lt;/strong&gt; No. The microphone runs only after you start it, and the app shows when it is active.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you use cloud speech-to-text instead?&lt;/strong&gt; Not in the current desktop app. Transcription uses the bundled local runtime. There is no cloud speech switch. Only the text you send continues to the AI request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does local transcription mean Cernalo works offline?&lt;/strong&gt; Transcription itself does not need a network. Getting an AI answer does, because answers come from hosted models through our service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which languages are supported?&lt;/strong&gt; The default local model is English. Other languages may transcribe poorly.&lt;/p&gt;

&lt;p&gt;The context you choose, in one place. You can try voice questions on the free plan from the &lt;a href="https://cernalo.com/download" rel="noopener noreferrer"&gt;download page&lt;/a&gt;. If you are an engineer and think I made the wrong call somewhere above, tell me: &lt;a href="mailto:cernalo.ops@gmail.com"&gt;cernalo.ops@gmail.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue exploring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/download" rel="noopener noreferrer"&gt;Download Cernalo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/security" rel="noopener noreferrer"&gt;Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/features" rel="noopener noreferrer"&gt;What Cernalo can do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/blog/why-ai-api-keys-stay-off-your-desktop" rel="noopener noreferrer"&gt;Why our AI desktop assistant never stores model API keys on your computer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/blog/privacy-for-desktop-ai-assistants" rel="noopener noreferrer"&gt;Seven privacy questions to ask before using a desktop AI assistant&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Cernalo is an AI desktop assistant: snap part of your screen or ask by voice. Try it free at &lt;a href="https://cernalo.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=local-speech-to-text-whisper-cpp-desktop-app" rel="noopener noreferrer"&gt;https://cernalo.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=local-speech-to-text-whisper-cpp-desktop-app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>electron</category>
      <category>whisper</category>
      <category>desktop</category>
    </item>
    <item>
      <title>Ask AI About Part of Your Screen: A Region-Snap Workflow That Beats Copy-Paste</title>
      <dc:creator>Cernalo</dc:creator>
      <pubDate>Sun, 18 Oct 2026 07:22:53 +0000</pubDate>
      <link>https://dev.to/cernalo/ask-ai-about-part-of-your-screen-a-region-snap-workflow-that-beats-copy-paste-3i6j</link>
      <guid>https://dev.to/cernalo/ask-ai-about-part-of-your-screen-a-region-snap-workflow-that-beats-copy-paste-3i6j</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://cernalo.com/blog/ask-ai-about-part-of-your-screen" rel="noopener noreferrer"&gt;cernalo.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Snap the region that matters, ask one specific question, and check the answer against the screen before you act.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The question is already on the screen
&lt;/h2&gt;

&lt;p&gt;I build Cernalo. This is the workflow the product is built around, and the habits are useful even if you never install it.&lt;/p&gt;

&lt;p&gt;Most of the questions I ask an AI are not really questions about the world. They are questions about something already in front of me: an error in a terminal, a chart someone dropped into a slide, a paragraph in a contract that reads three ways at once.&lt;/p&gt;

&lt;p&gt;For a long time the routine looked like this. I would take a screenshot, open a chat tab, paste the image, type a sentence explaining what I was looking at, wait, read, switch back, and lose my place. If the answer led to a follow-up, I would do half of that loop again.&lt;/p&gt;

&lt;p&gt;None of these steps is hard. Together they add up to a tax on every small question, and the tax has two parts that matter more than the clicks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You rebuild context that was already on your screen. When you describe the problem in words, you summarise it. When you summarise, you drop details, often the very detail that mattered.&lt;/li&gt;
&lt;li&gt;You share more than you meant to. A full-screen screenshot of a work computer is rarely just the thing you are asking about. It is also an email preview, a teammate's name in a chat window, and a browser tab you forgot was open.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Region, full screen, or typing
&lt;/h2&gt;

&lt;p&gt;The workflow I use now is: snap only the region that matters, ask one question about it, then verify. I built Cernalo around it, but the habits work with any tool that lets you choose what it sees.&lt;/p&gt;

&lt;p&gt;There are three ways to give an assistant context, and none of them is always the right choice.&lt;/p&gt;

&lt;p&gt;Type it when the question does not depend on layout. Asking for the difference between a left join and an inner join does not need pixels. Typing also has a privacy advantage: you share exactly the words you write and nothing else.&lt;/p&gt;

&lt;p&gt;Snap a region when the answer depends on something visual and local: an error message with its stack trace, a chart and its legend, a table, a code block, a form field you do not understand. A region keeps the relevant detail and drops everything around it. In Cernalo that shortcut is Ctrl+Shift+R: drag a box and ask.&lt;/p&gt;

&lt;p&gt;Take a full screenshot when the relationship between parts of the screen is the question, for example why a dashboard shows a different total than the table beside it. In Cernalo that shortcut is Ctrl+Shift+S. Use it deliberately, because it is the option most likely to include something you did not intend to share.&lt;/p&gt;

&lt;p&gt;My rule of thumb: default to the smallest context that could possibly answer the question. If the answer comes back confused, widen the context. Do not start wide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pick the region and look at it before you send it
&lt;/h2&gt;

&lt;p&gt;Draw the box around the problem plus the minimum surrounding information needed to interpret it.&lt;/p&gt;

&lt;p&gt;Then do the thing most people skip: glance at what you captured. Is there a name, an email address, an API key, or a customer record in the box? Shrink the box. Capture should start only when you start it, and Cernalo works that way, but the decision about what goes into the box is still yours.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For an error, include the error line, the stack trace, and the line of code it points to.&lt;/li&gt;
&lt;li&gt;For a chart, include the plot, the axis labels, the legend, and the title. Without units and dates, a chart is just a shape.&lt;/li&gt;
&lt;li&gt;For a paragraph, include the paragraph plus the heading above it, so the assistant knows what document it is in.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ask one specific question
&lt;/h2&gt;

&lt;p&gt;The screenshot provides the what. Your question should provide the why.&lt;/p&gt;

&lt;p&gt;Good snap questions usually start with why, what changed, which one, or what you would check next. Asking for the fix invites a confident answer. Asking for the most likely cause and how to confirm it invites a checkable one.&lt;/p&gt;

&lt;p&gt;In Cernalo you can pick a mode before you ask, such as Coding, Research, Screen, or General. The mode shapes the answer. Coding leads with the likely issue and a code suggestion. Research is more explicit about uncertainty. Pick the one that matches the job.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What is this?" is vague. You will get a description of the screenshot.&lt;/li&gt;
&lt;li&gt;"Why does this request fail when the payload is empty?" is specific. You will get a hypothesis you can test.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Read the answer, then verify it against the screen
&lt;/h2&gt;

&lt;p&gt;This step is the point of keeping the answer next to the work instead of in another tab. With the source still visible, you can check the answer against it immediately.&lt;/p&gt;

&lt;p&gt;A screenshot gives an AI pixels, not the program state, database, or business context behind them. The answer is a hypothesis. Treating it as a review aid rather than a verdict is the habit that makes this workflow safe.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the explanation refer to text that is actually in the snapped region, or did it invent a line?&lt;/li&gt;
&lt;li&gt;If it quotes a number from a chart, does that number match the axis?&lt;/li&gt;
&lt;li&gt;If it suggests a code change, does the variable name it uses exist in your file?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ask the follow-up while the context is still there
&lt;/h2&gt;

&lt;p&gt;The second question is often the valuable one: how would I confirm that, or what else could produce the same symptom? Because the session keeps the conversation, you can follow up without snapping again.&lt;/p&gt;

&lt;p&gt;When you move to a different problem, clear the session so the old context does not leak into the new answer. In Cernalo you can clear or end a session whenever you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  A coding error
&lt;/h2&gt;

&lt;p&gt;These worked examples show the question shape. They are not presented as recordings, and the paragraph example later in this post is illustrative wording.&lt;/p&gt;

&lt;p&gt;The screen shows an error in a code editor: a function fails on a particular input. Instead of copying the stack trace into a chat, snap the error and the highlighted line and ask: what is the most likely cause, and how can I confirm it?&lt;/p&gt;

&lt;p&gt;The useful answer names the likely cause, points to the line where it happens, and suggests a check. What you do next is not AI work: reproduce the error, apply the change, and run the test. If the test passes, good. If it does not, snap the new error and ask again, with the previous answer still in the session.&lt;/p&gt;

&lt;p&gt;The anti-pattern is pasting the suggested fix without reading it. A suggestion that makes an error disappear is not the same as a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  A chart on a slide
&lt;/h2&gt;

&lt;p&gt;A sample-data sales slide shows revenue by region. Snap the chart with its legend and title and ask: which region is highest, which is lowest, and what stands out?&lt;/p&gt;

&lt;p&gt;A good answer reads the chart back: the highest, the lowest, and the outlier. Before you repeat any of it in a meeting, check three things the AI cannot know: the units, the date range, and whether the slide uses a non-zero baseline. If the chart does not show those, the honest answer is that the chart does not say, and a good assistant should tell you that rather than guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  A dense paragraph
&lt;/h2&gt;

&lt;p&gt;This example uses illustrative wording. It is not a transcript of a recorded document.&lt;/p&gt;

&lt;p&gt;A paragraph in a policy document says something like "unless otherwise agreed in writing, notwithstanding clause 4". Snap the paragraph and its heading and ask: what is the main claim, and what would weaken it?&lt;/p&gt;

&lt;p&gt;That question gives you something to check against the source, which "summarise this" often does not. Read the clause it points to and decide for yourself. For anything legal, medical, or financial, the AI's job is to help you read, not to tell you what to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a screenshot cannot tell an AI
&lt;/h2&gt;

&lt;p&gt;This is where screen-aware tools disappoint people, so it is worth being explicit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hidden state. A screenshot does not include the database row, the environment variable, or the network response behind the UI.&lt;/li&gt;
&lt;li&gt;Off-screen content. If the cause is in a file you did not capture, the AI can only guess.&lt;/li&gt;
&lt;li&gt;Small or low-contrast text. Tiny fonts and dense tables get misread. Zoom in before you snap.&lt;/li&gt;
&lt;li&gt;Instructions inside the image. Text in a screenshot is data, and it may contain instructions such as "ignore previous directions". Cernalo's service tells the model to treat on-screen and quoted text as untrusted context, not as instructions. That reduces the risk. It does not remove it. If something on screen looks like it is trying to steer the assistant, do not send it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Privacy habits for screen questions
&lt;/h2&gt;

&lt;p&gt;These apply to any tool, including ours. The &lt;a href="https://cernalo.com/security" rel="noopener noreferrer"&gt;security notes&lt;/a&gt; say plainly what Cernalo does and does not do, including that we do not hold SOC 2 or ISO 27001 certifications today. Current plans, including the free plan's monthly credit allowance, are on the &lt;a href="https://cernalo.com/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt;. Screen analysis may use one extra credit per request.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prefer a region over a full screen. It is both clearer context and less exposure.&lt;/li&gt;
&lt;li&gt;Check the box before you send. Names, email addresses, keys, and customer data have no business in a casual question.&lt;/li&gt;
&lt;li&gt;Know what runs where. In Cernalo, basic voice transcription runs on your device, but the question and any capture you send go to our service and then to the AI model needed to answer it.&lt;/li&gt;
&lt;li&gt;Clear the session when you switch topics.&lt;/li&gt;
&lt;li&gt;Follow the rules of the room. If your workplace, school, or a meeting does not allow AI assistance, do not use it there. Cernalo is built to be used openly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When is a region snap the right input, and when is pasted text?&lt;/strong&gt; When the layout matters, such as charts, tables, error output, and forms, a region keeps the structure. When it does not, pasting or typing the text shares less and answers the same question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the AI see the whole screen all the time?&lt;/strong&gt; Not in Cernalo. Screen and region capture start only when you start them, and the app shows when capture is active. Other tools work differently. Some record continuously by design, so check each tool's documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you use voice instead of typing the question?&lt;/strong&gt; Yes. In Cernalo you can ask by voice with Ctrl+Shift+V. Basic transcription runs locally, and performance depends on your hardware. Review the transcript before you send it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it cost?&lt;/strong&gt; Cernalo has a free plan with a monthly credit allowance. Current plans are on the &lt;a href="https://cernalo.com/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt;. Screen analysis may use one extra credit per request.&lt;/p&gt;

&lt;p&gt;The context you choose, in one place. If you want to try the snap-and-ask workflow, the free plan is on the &lt;a href="https://cernalo.com/download" rel="noopener noreferrer"&gt;download page&lt;/a&gt;. Feedback, especially about where the workflow breaks for you, goes straight to me at &lt;a href="mailto:cernalo.ops@gmail.com"&gt;cernalo.ops@gmail.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue exploring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/features/screen-aware-ai-assistant" rel="noopener noreferrer"&gt;Ask about the screen or region you choose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/features" rel="noopener noreferrer"&gt;What Cernalo can do&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/modes" rel="noopener noreferrer"&gt;One copilot. Six ways to work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/pricing" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/download" rel="noopener noreferrer"&gt;Download Cernalo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/security" rel="noopener noreferrer"&gt;Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cernalo.com/blog/privacy-for-desktop-ai-assistants" rel="noopener noreferrer"&gt;Seven privacy questions to ask before using a desktop AI assistant&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Cernalo is an AI desktop assistant: snap part of your screen or ask by voice. Try it free at &lt;a href="https://cernalo.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=ask-ai-about-part-of-your-screen" rel="noopener noreferrer"&gt;https://cernalo.com/?utm_source=devto&amp;amp;utm_medium=crosspost&amp;amp;utm_campaign=ask-ai-about-part-of-your-screen&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>privacy</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
