<?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: Crade</title>
    <description>The latest articles on DEV Community by Crade (@crade).</description>
    <link>https://dev.to/crade</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%2F3990678%2F02cfcaa6-844a-4a69-a314-8b26f56ab280.png</url>
      <title>DEV Community: Crade</title>
      <link>https://dev.to/crade</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crade"/>
    <language>en</language>
    <item>
      <title>We let ChatGPT and Claude see your screen</title>
      <dc:creator>Crade</dc:creator>
      <pubDate>Thu, 18 Jun 2026 10:48:26 +0000</pubDate>
      <link>https://dev.to/crade/we-let-chatgpt-and-claude-see-your-screen-3dph</link>
      <guid>https://dev.to/crade/we-let-chatgpt-and-claude-see-your-screen-3dph</guid>
      <description>&lt;p&gt;ChatGPT and Claude are great. But they can't see what's on your screen. The default workflow is: take screenshot, switch to ChatGPT, paste it, ask, switch back. Doing this 30 times a day burns hours.&lt;/p&gt;

&lt;p&gt;We shipped Crade to fix that. A Mac and Windows app that floats over your screen, captures it on demand, and pipes it to your own ChatGPT or Claude account. No screenshots, no tab switching.&lt;/p&gt;

&lt;p&gt;This is what we learned building it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;p&gt;Three flows, depending on which AI you bring:&lt;/p&gt;

&lt;p&gt;** ChatGPT (free or paid OpenAI account)**: we OAuth into OpenAI, spawn the &lt;code&gt;codex&lt;/code&gt; CLI as a subprocess. Each prompt becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"your prompt"&lt;/span&gt; &lt;span class="nt"&gt;--image&lt;/span&gt; screenshot.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI usage is billed by OpenAI directly to your account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude (Pro/Max account)&lt;/strong&gt;: same pattern with the &lt;code&gt;claude&lt;/code&gt; CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"your prompt"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--allowedTools&lt;/span&gt; &lt;span class="s2"&gt;"Read,Write,Edit,Bash,Glob,Grep,WebFetch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output-format&lt;/span&gt; stream-json &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Streaming JSON lets us show tool-use events as they happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in tier&lt;/strong&gt;: HTTP to our Cloudflare Worker, which proxies to OpenAI (Free) or Anthropic (Pro). For users who don't want to bring their own.&lt;/p&gt;

&lt;p&gt;The point: in BYO mode, we never sit in the middle. The screenshot goes directly from the user's machine to OpenAI or Anthropic.&lt;/p&gt;

&lt;p&gt;Fix: bump our window level to &lt;strong&gt;1500 (kCGAssistiveTechHighWindowLevel)&lt;/strong&gt;. This is the level used by accessibility tools like VoiceOver. It's above NSScreenSaverWindowLevel, so we win.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setWindowLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# kCGAssistiveTechHighWindowLevel
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We re-assert it every 500ms in a periodic check because some apps fight back.&lt;/p&gt;

&lt;p&gt;For Windows, &lt;code&gt;Qt.WindowStaysOnTopHint&lt;/code&gt; is enough. Browsers don't compete the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Python + PyQt6
&lt;/h2&gt;

&lt;p&gt;This is where we make some readers angry: we picked Python + PyQt6 over Electron.&lt;/p&gt;

&lt;p&gt;Reasoning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Window control&lt;/strong&gt;: direct access to NSWindow on macOS, no native module dance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller footprint&lt;/strong&gt;: ~50 MB installer vs Electron's 100+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subprocess management&lt;/strong&gt;: spawning &lt;code&gt;claude&lt;/code&gt; and &lt;code&gt;codex&lt;/code&gt; is trivial from Python&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen capture stays in Python&lt;/strong&gt;: pyautogui + native bindings, no IPC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoffs: PyInstaller distribution is finicky, default PyQt6 UI looks dated (real stylesheet work needed), and the talent pool for desktop Python devs is smaller than for Electron.&lt;/p&gt;

&lt;p&gt;Worth it for our use case. Maybe not for yours.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bundle the CLIs&lt;/strong&gt;: we initially required users to install &lt;code&gt;claude&lt;/code&gt; and &lt;code&gt;codex&lt;/code&gt; separately. Bundling them in the app made onboarding 10x smoother.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sign and notarize from commit 1&lt;/strong&gt;: macOS treats unsigned apps as malware. We learned this the hard way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth flows have edge cases&lt;/strong&gt;: Anthropic's "Grove notice" (Oct 2025 Consumer Terms update) breaks first-run for users who haven't accepted it in the CLI. We auto-accept it during connect now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File descriptor limits on macOS&lt;/strong&gt;: GUI-launched apps inherit a soft limit of 256 file descriptors. The Anthropic CLI needs more. We bump rlimit before spawning subprocesses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Crade is at &lt;a href="https://crade.ai" rel="noopener noreferrer"&gt;crade.ai&lt;/a&gt;. Free tier covers daily use. Pro ($7.99/mo) and Premium ($19.99/mo) add higher caps and Agent mode (file system + shell access for the AI).&lt;/p&gt;

&lt;p&gt;Curious what other devs would build on this pattern. The CLI-as-subprocess approach for desktop AI tools feels under-explored.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
